+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ addr = (void *)simple_strtoul(argv[1], NULL, 16);
+ blk = simple_strtoul(argv[2], NULL, 16);
+ cnt = simple_strtoul(argv[3], NULL, 16);
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ printf("\nMMC read: dev # %d, block # %d, count %d ... ",
+ curr_device, blk, cnt);
+
+ n = mmc->block_dev.block_read(curr_device, blk, cnt, addr);
+ /* flush cache after read */
+ flush_cache((ulong)addr, cnt * 512); /* FIXME */
+ printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+
+ return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ struct mmc *mmc;
+ u32 blk, cnt, n;
+ void *addr;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ addr = (void *)simple_strtoul(argv[1], NULL, 16);
+ blk = simple_strtoul(argv[2], NULL, 16);
+ cnt = simple_strtoul(argv[3], NULL, 16);
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ printf("\nMMC write: dev # %d, block # %d, count %d ... ",
+ curr_device, blk, cnt);
+
+ if (mmc_getwp(mmc) == 1) {
+ printf("Error: card is write protected!\n");
+ return CMD_RET_FAILURE;
+ }
+ n = mmc->block_dev.block_write(curr_device, blk, cnt, addr);
+ printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+
+ return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ struct mmc *mmc;
+ u32 blk, cnt, n;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+
+ blk = simple_strtoul(argv[1], NULL, 16);
+ cnt = simple_strtoul(argv[2], NULL, 16);
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ printf("\nMMC erase: dev # %d, block # %d, count %d ... ",
+ curr_device, blk, cnt);
+
+ if (mmc_getwp(mmc) == 1) {
+ printf("Error: card is write protected!\n");
+ return CMD_RET_FAILURE;
+ }
+ n = mmc->block_dev.block_erase(curr_device, blk, cnt);
+ printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+
+ return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ struct mmc *mmc;
+
+ mmc = init_mmc_device(curr_device, true);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
+static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ block_dev_desc_t *mmc_dev;
+ struct mmc *mmc;
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ mmc_dev = mmc_get_dev(curr_device);
+ if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
+ print_part(mmc_dev);
+ return CMD_RET_SUCCESS;
+ }
+
+ puts("get mmc type error!\n");
+ return CMD_RET_FAILURE;
+}
+static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ int dev, part = 0, ret;
+ struct mmc *mmc;
+
+ if (argc == 1) {
+ dev = curr_device;
+ } else if (argc == 2) {
+ dev = simple_strtoul(argv[1], NULL, 10);
+ } else if (argc == 3) {
+ dev = (int)simple_strtoul(argv[1], NULL, 10);
+ part = (int)simple_strtoul(argv[2], NULL, 10);
+ if (part > PART_ACCESS_MASK) {
+ printf("#part_num shouldn't be larger than %d\n",
+ PART_ACCESS_MASK);
+ return CMD_RET_FAILURE;