Commit 873cc1d7775ed5de07e6722c7ff423080c2e8f71

Authored by Stephen Warren
Committed by Tom Rini
1 parent 7c4213f6a5

mmc: store hwpart in the block device

This will allow us to have multiple block device structs each referring
to the same eMMC device, yet different HW partitions.

For now, there is still a single block device per eMMC device. As before,
this block device always accesses whichever HW partition was most recently
selected. Clients wishing to make use of multiple block devices referring
to different HW partitions can simply take a copy of this block device
once it points at the correct HW partition, and use each one as they wish.
This feature will be used by the next patch.

In the future, perhaps get_device() could be enhanced to return a
dynamically allocated block device struct, to avoid the client needing to
copy it in order to maintain multiple block devices. However, this would
require all users to be updated to free those block device structs at some
point, which is rather a large change.

Most callers of mmc_switch_part() wish to permanently switch the default
MMC block device's HW partition. Enhance mmc_switch_part() so that it does
this. This removes the need for callers to do this. However,
common/env_mmc.c needs to save and restore the current HW partition. Make
it do this more explicitly.

Replace use of mmc_switch_part() with mmc_select_hwpart() in order to
remove duplicate code that skips the call if that HW partition is already
selected.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Tom Rini <trini@konsulko.com>

Showing 7 changed files with 40 additions and 47 deletions Side-by-side Diff

... ... @@ -312,20 +312,14 @@
312 312 return CMD_RET_FAILURE;
313 313 }
314 314 /* Switch to the RPMB partition */
315   - original_part = mmc->part_num;
316   - if (mmc->part_num != MMC_PART_RPMB) {
317   - if (mmc_switch_part(curr_device, MMC_PART_RPMB) != 0)
318   - return CMD_RET_FAILURE;
319   - mmc->part_num = MMC_PART_RPMB;
320   - }
  315 + original_part = mmc->block_dev.part_num;
  316 + if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0)
  317 + return CMD_RET_FAILURE;
321 318 ret = cp->cmd(cmdtp, flag, argc, argv);
322 319  
323 320 /* Return to original partition */
324   - if (mmc->part_num != original_part) {
325   - if (mmc_switch_part(curr_device, original_part) != 0)
326   - return CMD_RET_FAILURE;
327   - mmc->part_num = original_part;
328   - }
  321 + if (mmc_select_hwpart(curr_device, original_part) != 0)
  322 + return CMD_RET_FAILURE;
329 323 return ret;
330 324 }
331 325 #endif
... ... @@ -483,7 +477,7 @@
483 477 printf("mmc%d is current device\n", curr_device);
484 478 else
485 479 printf("mmc%d(part %d) is current device\n",
486   - curr_device, mmc->part_num);
  480 + curr_device, mmc->block_dev.hwpart);
487 481  
488 482 return CMD_RET_SUCCESS;
489 483 }
... ... @@ -69,6 +69,8 @@
69 69 return CONFIG_SYS_MMC_ENV_PART;
70 70 }
71 71  
  72 +static unsigned char env_mmc_orig_hwpart;
  73 +
72 74 static int mmc_set_env_part(struct mmc *mmc)
73 75 {
74 76 uint part = mmc_get_env_part(mmc);
... ... @@ -79,11 +81,10 @@
79 81 dev = 0;
80 82 #endif
81 83  
82   - if (part != mmc->part_num) {
83   - ret = mmc_switch_part(dev, part);
84   - if (ret)
85   - puts("MMC partition switch failed\n");
86   - }
  84 + env_mmc_orig_hwpart = mmc->block_dev.hwpart;
  85 + ret = mmc_select_hwpart(dev, part);
  86 + if (ret)
  87 + puts("MMC partition switch failed\n");
87 88  
88 89 return ret;
89 90 }
... ... @@ -113,8 +114,7 @@
113 114 #ifdef CONFIG_SPL_BUILD
114 115 dev = 0;
115 116 #endif
116   - if (mmc_get_env_part(mmc) != mmc->part_num)
117   - mmc_switch_part(dev, mmc->part_num);
  117 + mmc_select_hwpart(dev, env_mmc_orig_hwpart);
118 118 #endif
119 119 }
120 120  
drivers/dfu/dfu_mmc.c
... ... @@ -20,23 +20,6 @@
20 20 static long dfu_file_buf_len;
21 21 static long dfu_file_buf_filled;
22 22  
23   -static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
24   -{
25   - int ret;
26   -
27   - if (part == mmc->part_num)
28   - return 0;
29   -
30   - ret = mmc_switch_part(dfu->data.mmc.dev_num, part);
31   - if (ret) {
32   - error("Cannot switch to partition %d\n", part);
33   - return ret;
34   - }
35   - mmc->part_num = part;
36   -
37   - return 0;
38   -}
39   -
40 23 static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
41 24 u64 offset, void *buf, long *len)
42 25 {
... ... @@ -66,8 +49,9 @@
66 49 }
67 50  
68 51 if (dfu->data.mmc.hw_partition >= 0) {
69   - part_num_bkp = mmc->part_num;
70   - ret = mmc_access_part(dfu, mmc, dfu->data.mmc.hw_partition);
  52 + part_num_bkp = mmc->block_dev.hwpart;
  53 + ret = mmc_select_hwpart(dfu->data.mmc.dev_num,
  54 + dfu->data.mmc.hw_partition);
71 55 if (ret)
72 56 return ret;
73 57 }
74 58  
... ... @@ -91,12 +75,12 @@
91 75 if (n != blk_count) {
92 76 error("MMC operation failed");
93 77 if (dfu->data.mmc.hw_partition >= 0)
94   - mmc_access_part(dfu, mmc, part_num_bkp);
  78 + mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
95 79 return -EIO;
96 80 }
97 81  
98 82 if (dfu->data.mmc.hw_partition >= 0) {
99   - ret = mmc_access_part(dfu, mmc, part_num_bkp);
  83 + ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
100 84 if (ret)
101 85 return ret;
102 86 }
... ... @@ -238,6 +238,7 @@
238 238 lbaint_t blkcnt, void *dst)
239 239 {
240 240 int dev_num = block_dev->dev;
  241 + int err;
241 242 lbaint_t cur, blocks_todo = blkcnt;
242 243  
243 244 if (blkcnt == 0)
... ... @@ -247,6 +248,10 @@
247 248 if (!mmc)
248 249 return 0;
249 250  
  251 + err = mmc_select_hwpart(dev_num, block_dev->hwpart);
  252 + if (err < 0)
  253 + return 0;
  254 +
250 255 if ((start + blkcnt) > mmc->block_dev.lba) {
251 256 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
252 257 printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
... ... @@ -581,7 +586,7 @@
581 586 if (!mmc)
582 587 return -ENODEV;
583 588  
584   - if (mmc->part_num == hwpart)
  589 + if (mmc->block_dev.hwpart == hwpart)
585 590 return 0;
586 591  
587 592 if (mmc->part_config == MMCPART_NOAVAILABLE) {
... ... @@ -593,8 +598,6 @@
593 598 if (ret)
594 599 return ret;
595 600  
596   - mmc->part_num = hwpart;
597   -
598 601 return 0;
599 602 }
600 603  
601 604  
... ... @@ -615,8 +618,10 @@
615 618 * Set the capacity if the switch succeeded or was intended
616 619 * to return to representing the raw device.
617 620 */
618   - if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
  621 + if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
619 622 ret = mmc_set_capacity(mmc, part_num);
  623 + mmc->block_dev.hwpart = part_num;
  624 + }
620 625  
621 626 return ret;
622 627 }
... ... @@ -1326,7 +1331,7 @@
1326 1331 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
1327 1332 }
1328 1333  
1329   - err = mmc_set_capacity(mmc, mmc->part_num);
  1334 + err = mmc_set_capacity(mmc, mmc->block_dev.hwpart);
1330 1335 if (err)
1331 1336 return err;
1332 1337  
... ... @@ -1467,6 +1472,7 @@
1467 1472  
1468 1473 /* fill in device description */
1469 1474 mmc->block_dev.lun = 0;
  1475 + mmc->block_dev.hwpart = 0;
1470 1476 mmc->block_dev.type = 0;
1471 1477 mmc->block_dev.blksz = mmc->read_bl_len;
1472 1478 mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
... ... @@ -1626,7 +1632,7 @@
1626 1632 return err;
1627 1633  
1628 1634 /* The internal partition reset to user partition(0) at every CMD0*/
1629   - mmc->part_num = 0;
  1635 + mmc->block_dev.hwpart = 0;
1630 1636  
1631 1637 /* Test for SD version 2 */
1632 1638 err = mmc_send_if_cond(mmc);
drivers/mmc/mmc_write.c
... ... @@ -78,6 +78,10 @@
78 78 if (!mmc)
79 79 return -1;
80 80  
  81 + err = mmc_select_hwpart(dev_num, block_dev->hwpart);
  82 + if (err < 0)
  83 + return -1;
  84 +
81 85 /*
82 86 * We want to see if the requested start or total block count are
83 87 * unaligned. We discard the whole numbers and only care about the
84 88  
... ... @@ -172,9 +176,14 @@
172 176 {
173 177 int dev_num = block_dev->dev;
174 178 lbaint_t cur, blocks_todo = blkcnt;
  179 + int err;
175 180  
176 181 struct mmc *mmc = find_mmc_device(dev_num);
177 182 if (!mmc)
  183 + return 0;
  184 +
  185 + err = mmc_select_hwpart(dev_num, block_dev->hwpart);
  186 + if (err < 0)
178 187 return 0;
179 188  
180 189 if (mmc_set_blocklen(mmc, mmc->write_bl_len))
... ... @@ -364,7 +364,6 @@
364 364 u8 part_attr;
365 365 u8 wr_rel_set;
366 366 char part_config;
367   - char part_num;
368 367 uint tran_speed;
369 368 uint read_bl_len;
370 369 uint write_bl_len;
... ... @@ -18,6 +18,7 @@
18 18 unsigned char part_type; /* partition type */
19 19 unsigned char target; /* target SCSI ID */
20 20 unsigned char lun; /* target LUN */
  21 + unsigned char hwpart; /* HW partition, e.g. for eMMC */
21 22 unsigned char type; /* device type */
22 23 unsigned char removable; /* removable device */
23 24 #ifdef CONFIG_LBA48