2738dc836e1e94bfc98cf2c3e3b2a6cdb53f2c79
[platform/kernel/u-boot.git] / drivers / fastboot / fb_mmc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2014 Broadcom Corporation.
4  */
5
6 #include <config.h>
7 #include <common.h>
8 #include <blk.h>
9 #include <env.h>
10 #include <fastboot.h>
11 #include <fastboot-internal.h>
12 #include <fb_mmc.h>
13 #include <flash.h>
14 #include <image-sparse.h>
15 #include <image.h>
16 #include <log.h>
17 #include <part.h>
18 #include <mmc.h>
19 #include <div64.h>
20 #include <linux/compat.h>
21 #include <android_image.h>
22
23 #define FASTBOOT_MAX_BLK_WRITE 16384
24
25 #define BOOT_PARTITION_NAME "boot"
26
27 struct fb_mmc_sparse {
28         struct blk_desc *dev_desc;
29 };
30
31 static int raw_part_get_info_by_name(struct blk_desc *dev_desc,
32                                      const char *name,
33                                      struct disk_partition *info)
34 {
35         /* strlen("fastboot_raw_partition_") + PART_NAME_LEN + 1 */
36         char env_desc_name[23 + PART_NAME_LEN + 1];
37         char *raw_part_desc;
38         const char *argv[2];
39         const char **parg = argv;
40
41         /* check for raw partition descriptor */
42         strcpy(env_desc_name, "fastboot_raw_partition_");
43         strlcat(env_desc_name, name, sizeof(env_desc_name));
44         raw_part_desc = strdup(env_get(env_desc_name));
45         if (raw_part_desc == NULL)
46                 return -ENODEV;
47
48         /*
49          * parse partition descriptor
50          *
51          * <lba_start> <lba_size> [mmcpart <num>]
52          */
53         for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) {
54                 *parg = strsep(&raw_part_desc, " ");
55                 if (*parg == NULL) {
56                         pr_err("Invalid number of arguments.\n");
57                         return -ENODEV;
58                 }
59         }
60
61         info->start = simple_strtoul(argv[0], NULL, 0);
62         info->size = simple_strtoul(argv[1], NULL, 0);
63         info->blksz = dev_desc->blksz;
64         strlcpy((char *)info->name, name, PART_NAME_LEN);
65
66         if (raw_part_desc) {
67                 if (strcmp(strsep(&raw_part_desc, " "), "mmcpart") == 0) {
68                         ulong mmcpart = simple_strtoul(raw_part_desc, NULL, 0);
69                         int ret = blk_dselect_hwpart(dev_desc, mmcpart);
70
71                         if (ret)
72                                 return ret;
73                 }
74         }
75
76         return 0;
77 }
78
79 static int do_get_part_info(struct blk_desc **dev_desc, const char *name,
80                             struct disk_partition *info)
81 {
82         int ret;
83
84         /* First try partition names on the default device */
85         *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
86         if (*dev_desc) {
87                 ret = part_get_info_by_name(*dev_desc, name, info);
88                 if (ret >= 0)
89                         return ret;
90
91                 /* Then try raw partitions */
92                 ret = raw_part_get_info_by_name(*dev_desc, name, info);
93                 if (ret >= 0)
94                         return ret;
95         }
96
97         /* Then try dev.hwpart:part */
98         ret = part_get_info_by_dev_and_name_or_num("mmc", name, dev_desc,
99                                                    info, true);
100         return ret;
101 }
102
103 static int part_get_info_by_name_or_alias(struct blk_desc **dev_desc,
104                                           const char *name,
105                                           struct disk_partition *info)
106 {
107         int ret;
108
109         ret = do_get_part_info(dev_desc, name, info);
110         if (ret < 0) {
111                 /* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
112                 char env_alias_name[25 + PART_NAME_LEN + 1];
113                 char *aliased_part_name;
114
115                 /* check for alias */
116                 strcpy(env_alias_name, "fastboot_partition_alias_");
117                 strlcat(env_alias_name, name, sizeof(env_alias_name));
118                 aliased_part_name = env_get(env_alias_name);
119                 if (aliased_part_name != NULL)
120                         ret = do_get_part_info(dev_desc, aliased_part_name,
121                                                info);
122         }
123         return ret;
124 }
125
126 /**
127  * fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
128  *
129  * @block_dev: Pointer to block device
130  * @start: First block to write/erase
131  * @blkcnt: Count of blocks
132  * @buffer: Pointer to data buffer for write or NULL for erase
133  */
134 static lbaint_t fb_mmc_blk_write(struct blk_desc *block_dev, lbaint_t start,
135                                  lbaint_t blkcnt, const void *buffer)
136 {
137         lbaint_t blk = start;
138         lbaint_t blks_written;
139         lbaint_t cur_blkcnt;
140         lbaint_t blks = 0;
141         int i;
142
143         for (i = 0; i < blkcnt; i += FASTBOOT_MAX_BLK_WRITE) {
144                 cur_blkcnt = min((int)blkcnt - i, FASTBOOT_MAX_BLK_WRITE);
145                 if (buffer) {
146                         if (fastboot_progress_callback)
147                                 fastboot_progress_callback("writing");
148                         blks_written = blk_dwrite(block_dev, blk, cur_blkcnt,
149                                                   buffer + (i * block_dev->blksz));
150                 } else {
151                         if (fastboot_progress_callback)
152                                 fastboot_progress_callback("erasing");
153                         blks_written = blk_derase(block_dev, blk, cur_blkcnt);
154                 }
155                 blk += blks_written;
156                 blks += blks_written;
157         }
158         return blks;
159 }
160
161 static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
162                 lbaint_t blk, lbaint_t blkcnt, const void *buffer)
163 {
164         struct fb_mmc_sparse *sparse = info->priv;
165         struct blk_desc *dev_desc = sparse->dev_desc;
166
167         return fb_mmc_blk_write(dev_desc, blk, blkcnt, buffer);
168 }
169
170 static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
171                 lbaint_t blk, lbaint_t blkcnt)
172 {
173         return blkcnt;
174 }
175
176 static void write_raw_image(struct blk_desc *dev_desc,
177                             struct disk_partition *info, const char *part_name,
178                             void *buffer, u32 download_bytes, char *response)
179 {
180         lbaint_t blkcnt;
181         lbaint_t blks;
182
183         /* determine number of blocks to write */
184         blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
185         blkcnt = lldiv(blkcnt, info->blksz);
186
187         if (blkcnt > info->size) {
188                 pr_err("too large for partition: '%s'\n", part_name);
189                 fastboot_fail("too large for partition", response);
190                 return;
191         }
192
193         puts("Flashing Raw Image\n");
194
195         blks = fb_mmc_blk_write(dev_desc, info->start, blkcnt, buffer);
196
197         if (blks != blkcnt) {
198                 pr_err("failed writing to device %d\n", dev_desc->devnum);
199                 fastboot_fail("failed writing to device", response);
200                 return;
201         }
202
203         printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
204                part_name);
205         fastboot_okay(NULL, response);
206 }
207
208 #if defined(CONFIG_FASTBOOT_MMC_BOOT_SUPPORT) || \
209         defined(CONFIG_FASTBOOT_MMC_USER_SUPPORT)
210 static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc)
211 {
212         lbaint_t blks;
213
214         debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart);
215
216         blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL);
217
218         if (blks != dev_desc->lba) {
219                 pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart);
220                 return 1;
221         }
222
223         printf("........ erased %lu bytes from mmc hwpart[%u]\n",
224                dev_desc->lba * dev_desc->blksz, dev_desc->hwpart);
225
226         return 0;
227 }
228 #endif
229
230 #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
231 static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer,
232                             int hwpart, u32 buff_sz, char *response)
233 {
234         lbaint_t blkcnt;
235         lbaint_t blks;
236         unsigned long blksz;
237
238         // To operate on EMMC_BOOT1/2 (mmc0boot0/1) we first change the hwpart
239         if (blk_dselect_hwpart(dev_desc, hwpart)) {
240                 pr_err("Failed to select hwpart\n");
241                 fastboot_fail("Failed to select hwpart", response);
242                 return;
243         }
244
245         if (buffer) { /* flash */
246
247                 /* determine number of blocks to write */
248                 blksz = dev_desc->blksz;
249                 blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1));
250                 blkcnt = lldiv(blkcnt, blksz);
251
252                 if (blkcnt > dev_desc->lba) {
253                         pr_err("Image size too large\n");
254                         fastboot_fail("Image size too large", response);
255                         return;
256                 }
257
258                 debug("Start Flashing Image to EMMC_BOOT%d...\n", hwpart);
259
260                 blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer);
261
262                 if (blks != blkcnt) {
263                         pr_err("Failed to write EMMC_BOOT%d\n", hwpart);
264                         fastboot_fail("Failed to write EMMC_BOOT part",
265                                       response);
266                         return;
267                 }
268
269                 printf("........ wrote %lu bytes to EMMC_BOOT%d\n",
270                        blkcnt * blksz, hwpart);
271         } else { /* erase */
272                 if (fb_mmc_erase_mmc_hwpart(dev_desc)) {
273                         pr_err("Failed to erase EMMC_BOOT%d\n", hwpart);
274                         fastboot_fail("Failed to erase EMMC_BOOT part",
275                                       response);
276                         return;
277                 }
278         }
279
280         fastboot_okay(NULL, response);
281 }
282 #endif
283
284 #ifdef CONFIG_ANDROID_BOOT_IMAGE
285 /**
286  * Read Android boot image header from boot partition.
287  *
288  * @param[in] dev_desc MMC device descriptor
289  * @param[in] info Boot partition info
290  * @param[out] hdr Where to store read boot image header
291  *
292  * @return Boot image header sectors count or 0 on error
293  */
294 static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
295                                        struct disk_partition *info,
296                                        struct andr_img_hdr *hdr,
297                                        char *response)
298 {
299         ulong sector_size;              /* boot partition sector size */
300         lbaint_t hdr_sectors;           /* boot image header sectors count */
301         int res;
302
303         /* Calculate boot image sectors count */
304         sector_size = info->blksz;
305         hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
306         if (hdr_sectors == 0) {
307                 pr_err("invalid number of boot sectors: 0\n");
308                 fastboot_fail("invalid number of boot sectors: 0", response);
309                 return 0;
310         }
311
312         /* Read the boot image header */
313         res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
314         if (res != hdr_sectors) {
315                 pr_err("cannot read header from boot partition\n");
316                 fastboot_fail("cannot read header from boot partition",
317                               response);
318                 return 0;
319         }
320
321         /* Check boot header magic string */
322         res = android_image_check_header(hdr);
323         if (res != 0) {
324                 pr_err("bad boot image magic\n");
325                 fastboot_fail("boot partition not initialized", response);
326                 return 0;
327         }
328
329         return hdr_sectors;
330 }
331
332 /**
333  * Write downloaded zImage to boot partition and repack it properly.
334  *
335  * @param dev_desc MMC device descriptor
336  * @param download_buffer Address to fastboot buffer with zImage in it
337  * @param download_bytes Size of fastboot buffer, in bytes
338  *
339  * @return 0 on success or -1 on error
340  */
341 static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
342                                 void *download_buffer,
343                                 u32 download_bytes,
344                                 char *response)
345 {
346         uintptr_t hdr_addr;                     /* boot image header address */
347         struct andr_img_hdr *hdr;               /* boot image header */
348         lbaint_t hdr_sectors;                   /* boot image header sectors */
349         u8 *ramdisk_buffer;
350         u32 ramdisk_sector_start;
351         u32 ramdisk_sectors;
352         u32 kernel_sector_start;
353         u32 kernel_sectors;
354         u32 sectors_per_page;
355         struct disk_partition info;
356         int res;
357
358         puts("Flashing zImage\n");
359
360         /* Get boot partition info */
361         res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
362         if (res < 0) {
363                 pr_err("cannot find boot partition\n");
364                 fastboot_fail("cannot find boot partition", response);
365                 return -1;
366         }
367
368         /* Put boot image header in fastboot buffer after downloaded zImage */
369         hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
370         hdr = (struct andr_img_hdr *)hdr_addr;
371
372         /* Read boot image header */
373         hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response);
374         if (hdr_sectors == 0) {
375                 pr_err("unable to read boot image header\n");
376                 fastboot_fail("unable to read boot image header", response);
377                 return -1;
378         }
379
380         /* Check if boot image has second stage in it (we don't support it) */
381         if (hdr->second_size > 0) {
382                 pr_err("moving second stage is not supported yet\n");
383                 fastboot_fail("moving second stage is not supported yet",
384                               response);
385                 return -1;
386         }
387
388         /* Extract ramdisk location */
389         sectors_per_page = hdr->page_size / info.blksz;
390         ramdisk_sector_start = info.start + sectors_per_page;
391         ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
392                                              sectors_per_page;
393         ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
394                                        sectors_per_page;
395
396         /* Read ramdisk and put it in fastboot buffer after boot image header */
397         ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
398         res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
399                         ramdisk_buffer);
400         if (res != ramdisk_sectors) {
401                 pr_err("cannot read ramdisk from boot partition\n");
402                 fastboot_fail("cannot read ramdisk from boot partition",
403                               response);
404                 return -1;
405         }
406
407         /* Write new kernel size to boot image header */
408         hdr->kernel_size = download_bytes;
409         res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
410         if (res == 0) {
411                 pr_err("cannot writeback boot image header\n");
412                 fastboot_fail("cannot write back boot image header", response);
413                 return -1;
414         }
415
416         /* Write the new downloaded kernel */
417         kernel_sector_start = info.start + sectors_per_page;
418         kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
419                                       sectors_per_page;
420         res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
421                          download_buffer);
422         if (res == 0) {
423                 pr_err("cannot write new kernel\n");
424                 fastboot_fail("cannot write new kernel", response);
425                 return -1;
426         }
427
428         /* Write the saved ramdisk back */
429         ramdisk_sector_start = info.start + sectors_per_page;
430         ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
431                                              sectors_per_page;
432         res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
433                          ramdisk_buffer);
434         if (res == 0) {
435                 pr_err("cannot write back original ramdisk\n");
436                 fastboot_fail("cannot write back original ramdisk", response);
437                 return -1;
438         }
439
440         puts("........ zImage was updated in boot partition\n");
441         fastboot_okay(NULL, response);
442         return 0;
443 }
444 #endif
445
446 /**
447  * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
448  *
449  * @part_name: Named partition to lookup
450  * @dev_desc: Pointer to returned blk_desc pointer
451  * @part_info: Pointer to returned struct disk_partition
452  * @response: Pointer to fastboot response buffer
453  */
454 int fastboot_mmc_get_part_info(const char *part_name,
455                                struct blk_desc **dev_desc,
456                                struct disk_partition *part_info, char *response)
457 {
458         int ret;
459
460         if (!part_name || !strcmp(part_name, "")) {
461                 fastboot_fail("partition not given", response);
462                 return -ENOENT;
463         }
464
465         ret = part_get_info_by_name_or_alias(dev_desc, part_name, part_info);
466         if (ret < 0) {
467                 switch (ret) {
468                 case -ENOSYS:
469                 case -EINVAL:
470                         fastboot_fail("invalid partition or device", response);
471                         break;
472                 case -ENODEV:
473                         fastboot_fail("no such device", response);
474                         break;
475                 case -ENOENT:
476                         fastboot_fail("no such partition", response);
477                         break;
478                 case -EPROTONOSUPPORT:
479                         fastboot_fail("unknown partition table type", response);
480                         break;
481                 default:
482                         fastboot_fail("unanticipated error", response);
483                         break;
484                 }
485         }
486
487         return ret;
488 }
489
490 static struct blk_desc *fastboot_mmc_get_dev(char *response)
491 {
492         struct blk_desc *ret = blk_get_dev("mmc",
493                                            CONFIG_FASTBOOT_FLASH_MMC_DEV);
494
495         if (!ret || ret->type == DEV_TYPE_UNKNOWN) {
496                 pr_err("invalid mmc device\n");
497                 fastboot_fail("invalid mmc device", response);
498                 return NULL;
499         }
500         return ret;
501 }
502
503 /**
504  * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
505  *
506  * @cmd: Named partition to write image to
507  * @download_buffer: Pointer to image data
508  * @download_bytes: Size of image data
509  * @response: Pointer to fastboot response buffer
510  */
511 void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
512                               u32 download_bytes, char *response)
513 {
514         struct blk_desc *dev_desc;
515         struct disk_partition info = {0};
516
517 #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
518         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
519                 dev_desc = fastboot_mmc_get_dev(response);
520                 if (dev_desc)
521                         fb_mmc_boot_ops(dev_desc, download_buffer, 1,
522                                         download_bytes, response);
523                 return;
524         }
525         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
526                 dev_desc = fastboot_mmc_get_dev(response);
527                 if (dev_desc)
528                         fb_mmc_boot_ops(dev_desc, download_buffer, 2,
529                                         download_bytes, response);
530                 return;
531         }
532 #endif
533
534 #if CONFIG_IS_ENABLED(EFI_PARTITION)
535         if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
536                 dev_desc = fastboot_mmc_get_dev(response);
537                 if (!dev_desc)
538                         return;
539
540                 printf("%s: updating MBR, Primary and Backup GPT(s)\n",
541                        __func__);
542                 if (is_valid_gpt_buf(dev_desc, download_buffer)) {
543                         printf("%s: invalid GPT - refusing to write to flash\n",
544                                __func__);
545                         fastboot_fail("invalid GPT partition", response);
546                         return;
547                 }
548                 if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
549                         printf("%s: writing GPT partitions failed\n", __func__);
550                         fastboot_fail("writing GPT partitions failed",
551                                       response);
552                         return;
553                 }
554                 part_init(dev_desc);
555                 printf("........ success\n");
556                 fastboot_okay(NULL, response);
557                 return;
558         }
559 #endif
560
561 #if CONFIG_IS_ENABLED(DOS_PARTITION)
562         if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
563                 dev_desc = fastboot_mmc_get_dev(response);
564                 if (!dev_desc)
565                         return;
566
567                 printf("%s: updating MBR\n", __func__);
568                 if (is_valid_dos_buf(download_buffer)) {
569                         printf("%s: invalid MBR - refusing to write to flash\n",
570                                __func__);
571                         fastboot_fail("invalid MBR partition", response);
572                         return;
573                 }
574                 if (write_mbr_sector(dev_desc, download_buffer)) {
575                         printf("%s: writing MBR partition failed\n", __func__);
576                         fastboot_fail("writing MBR partition failed",
577                                       response);
578                         return;
579                 }
580                 part_init(dev_desc);
581                 printf("........ success\n");
582                 fastboot_okay(NULL, response);
583                 return;
584         }
585 #endif
586
587 #ifdef CONFIG_ANDROID_BOOT_IMAGE
588         if (strncasecmp(cmd, "zimage", 6) == 0) {
589                 dev_desc = fastboot_mmc_get_dev(response);
590                 if (dev_desc)
591                         fb_mmc_update_zimage(dev_desc, download_buffer,
592                                              download_bytes, response);
593                 return;
594         }
595 #endif
596
597 #if CONFIG_IS_ENABLED(FASTBOOT_MMC_USER_SUPPORT)
598         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
599                 dev_desc = fastboot_mmc_get_dev(response);
600                 if (!dev_desc)
601                         return;
602
603                 strlcpy((char *)&info.name, cmd, sizeof(info.name));
604                 info.size       = dev_desc->lba;
605                 info.blksz      = dev_desc->blksz;
606         }
607 #endif
608
609         if (!info.name[0] &&
610             fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
611                 return;
612
613         if (is_sparse_image(download_buffer)) {
614                 struct fb_mmc_sparse sparse_priv;
615                 struct sparse_storage sparse;
616                 int err;
617
618                 sparse_priv.dev_desc = dev_desc;
619
620                 sparse.blksz = info.blksz;
621                 sparse.start = info.start;
622                 sparse.size = info.size;
623                 sparse.write = fb_mmc_sparse_write;
624                 sparse.reserve = fb_mmc_sparse_reserve;
625                 sparse.mssg = fastboot_fail;
626
627                 printf("Flashing sparse image at offset " LBAFU "\n",
628                        sparse.start);
629
630                 sparse.priv = &sparse_priv;
631                 err = write_sparse_image(&sparse, cmd, download_buffer,
632                                          response);
633                 if (!err)
634                         fastboot_okay(NULL, response);
635         } else {
636                 write_raw_image(dev_desc, &info, cmd, download_buffer,
637                                 download_bytes, response);
638         }
639 }
640
641 /**
642  * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
643  *
644  * @cmd: Named partition to erase
645  * @response: Pointer to fastboot response buffer
646  */
647 void fastboot_mmc_erase(const char *cmd, char *response)
648 {
649         struct blk_desc *dev_desc;
650         struct disk_partition info;
651         lbaint_t blks, blks_start, blks_size, grp_size;
652         struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
653
654 #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
655         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
656                 /* erase EMMC boot1 */
657                 dev_desc = fastboot_mmc_get_dev(response);
658                 if (dev_desc)
659                         fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
660                 return;
661         }
662         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
663                 /* erase EMMC boot2 */
664                 dev_desc = fastboot_mmc_get_dev(response);
665                 if (dev_desc)
666                         fb_mmc_boot_ops(dev_desc, NULL, 2, 0, response);
667                 return;
668         }
669 #endif
670
671 #ifdef CONFIG_FASTBOOT_MMC_USER_SUPPORT
672         if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
673                 /* erase EMMC userdata */
674                 dev_desc = fastboot_mmc_get_dev(response);
675                 if (!dev_desc)
676                         return;
677
678                 if (fb_mmc_erase_mmc_hwpart(dev_desc))
679                         fastboot_fail("Failed to erase EMMC_USER", response);
680                 else
681                         fastboot_okay(NULL, response);
682                 return;
683         }
684 #endif
685
686         if (fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
687                 return;
688
689         /* Align blocks to erase group size to avoid erasing other partitions */
690         grp_size = mmc->erase_grp_size;
691         blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
692         if (info.size >= grp_size)
693                 blks_size = (info.size - (blks_start - info.start)) &
694                                 (~(grp_size - 1));
695         else
696                 blks_size = 0;
697
698         printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
699                blks_start, blks_start + blks_size);
700
701         blks = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL);
702
703         if (blks != blks_size) {
704                 pr_err("failed erasing from device %d\n", dev_desc->devnum);
705                 fastboot_fail("failed erasing from device", response);
706                 return;
707         }
708
709         printf("........ erased " LBAFU " bytes from '%s'\n",
710                blks_size * info.blksz, cmd);
711         fastboot_okay(NULL, response);
712 }