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 
raw_part_get_info_by_name(struct blk_desc * dev_desc,const char * name,struct disk_partition * info)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, PART_NAME_LEN);
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 
do_get_part_info(struct blk_desc ** dev_desc,const char * name,struct disk_partition * info)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 
part_get_info_by_name_or_alias(struct blk_desc ** dev_desc,const char * name,struct disk_partition * info)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, PART_NAME_LEN);
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  */
fb_mmc_blk_write(struct blk_desc * block_dev,lbaint_t start,lbaint_t blkcnt,const void * buffer)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 
fb_mmc_sparse_write(struct sparse_storage * info,lbaint_t blk,lbaint_t blkcnt,const void * buffer)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 
fb_mmc_sparse_reserve(struct sparse_storage * info,lbaint_t blk,lbaint_t blkcnt)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 
write_raw_image(struct blk_desc * dev_desc,struct disk_partition * info,const char * part_name,void * buffer,u32 download_bytes,char * response)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)
fb_mmc_erase_mmc_hwpart(struct blk_desc * dev_desc)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
fb_mmc_boot_ops(struct blk_desc * dev_desc,void * buffer,int hwpart,u32 buff_sz,char * response)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  */
fb_mmc_get_boot_header(struct blk_desc * dev_desc,struct disk_partition * info,struct andr_img_hdr * hdr,char * response)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  */
fb_mmc_update_zimage(struct blk_desc * dev_desc,void * download_buffer,u32 download_bytes,char * response)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  */
fastboot_mmc_get_part_info(const char * part_name,struct blk_desc ** dev_desc,struct disk_partition * part_info,char * response)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 
fastboot_mmc_get_dev(char * response)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  */
fastboot_mmc_flash_write(const char * cmd,void * download_buffer,u32 download_bytes,char * response)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;
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, 1,
529 					download_bytes, response);
530 		return;
531 	}
532 #endif
533 
534 #if CONFIG_IS_ENABLED(EFI_PARTITION)
535 #ifndef CONFIG_FASTBOOT_MMC_USER_SUPPORT
536 	if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
537 #else
538 	if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 ||
539 	    strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
540 #endif
541 		dev_desc = fastboot_mmc_get_dev(response);
542 		if (!dev_desc)
543 			return;
544 
545 		printf("%s: updating MBR, Primary and Backup GPT(s)\n",
546 		       __func__);
547 		if (is_valid_gpt_buf(dev_desc, download_buffer)) {
548 			printf("%s: invalid GPT - refusing to write to flash\n",
549 			       __func__);
550 			fastboot_fail("invalid GPT partition", response);
551 			return;
552 		}
553 		if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
554 			printf("%s: writing GPT partitions failed\n", __func__);
555 			fastboot_fail("writing GPT partitions failed",
556 				      response);
557 			return;
558 		}
559 		part_init(dev_desc);
560 		printf("........ success\n");
561 		fastboot_okay(NULL, response);
562 		return;
563 	}
564 #endif
565 
566 #if CONFIG_IS_ENABLED(DOS_PARTITION)
567 	if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
568 		dev_desc = fastboot_mmc_get_dev(response);
569 		if (!dev_desc)
570 			return;
571 
572 		printf("%s: updating MBR\n", __func__);
573 		if (is_valid_dos_buf(download_buffer)) {
574 			printf("%s: invalid MBR - refusing to write to flash\n",
575 			       __func__);
576 			fastboot_fail("invalid MBR partition", response);
577 			return;
578 		}
579 		if (write_mbr_sector(dev_desc, download_buffer)) {
580 			printf("%s: writing MBR partition failed\n", __func__);
581 			fastboot_fail("writing MBR partition failed",
582 				      response);
583 			return;
584 		}
585 		part_init(dev_desc);
586 		printf("........ success\n");
587 		fastboot_okay(NULL, response);
588 		return;
589 	}
590 #endif
591 
592 #ifdef CONFIG_ANDROID_BOOT_IMAGE
593 	if (strncasecmp(cmd, "zimage", 6) == 0) {
594 		dev_desc = fastboot_mmc_get_dev(response);
595 		if (dev_desc)
596 			fb_mmc_update_zimage(dev_desc, download_buffer,
597 					     download_bytes, response);
598 		return;
599 	}
600 #endif
601 
602 	if (fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
603 		return;
604 
605 	if (is_sparse_image(download_buffer)) {
606 		struct fb_mmc_sparse sparse_priv;
607 		struct sparse_storage sparse;
608 		int err;
609 
610 		sparse_priv.dev_desc = dev_desc;
611 
612 		sparse.blksz = info.blksz;
613 		sparse.start = info.start;
614 		sparse.size = info.size;
615 		sparse.write = fb_mmc_sparse_write;
616 		sparse.reserve = fb_mmc_sparse_reserve;
617 		sparse.mssg = fastboot_fail;
618 
619 		printf("Flashing sparse image at offset " LBAFU "\n",
620 		       sparse.start);
621 
622 		sparse.priv = &sparse_priv;
623 		err = write_sparse_image(&sparse, cmd, download_buffer,
624 					 response);
625 		if (!err)
626 			fastboot_okay(NULL, response);
627 	} else {
628 		write_raw_image(dev_desc, &info, cmd, download_buffer,
629 				download_bytes, response);
630 	}
631 }
632 
633 /**
634  * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
635  *
636  * @cmd: Named partition to erase
637  * @response: Pointer to fastboot response buffer
638  */
639 void fastboot_mmc_erase(const char *cmd, char *response)
640 {
641 	struct blk_desc *dev_desc;
642 	struct disk_partition info;
643 	lbaint_t blks, blks_start, blks_size, grp_size;
644 	struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
645 
646 #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
647 	if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
648 		/* erase EMMC boot1 */
649 		dev_desc = fastboot_mmc_get_dev(response);
650 		if (dev_desc)
651 			fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
652 		return;
653 	}
654 	if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
655 		/* erase EMMC boot2 */
656 		dev_desc = fastboot_mmc_get_dev(response);
657 		if (dev_desc)
658 			fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
659 		return;
660 	}
661 #endif
662 
663 #ifdef CONFIG_FASTBOOT_MMC_USER_SUPPORT
664 	if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
665 		/* erase EMMC userdata */
666 		dev_desc = fastboot_mmc_get_dev(response);
667 		if (!dev_desc)
668 			return;
669 
670 		if (fb_mmc_erase_mmc_hwpart(dev_desc))
671 			fastboot_fail("Failed to erase EMMC_USER", response);
672 		else
673 			fastboot_okay(NULL, response);
674 		return;
675 	}
676 #endif
677 
678 	if (fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
679 		return;
680 
681 	/* Align blocks to erase group size to avoid erasing other partitions */
682 	grp_size = mmc->erase_grp_size;
683 	blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
684 	if (info.size >= grp_size)
685 		blks_size = (info.size - (blks_start - info.start)) &
686 				(~(grp_size - 1));
687 	else
688 		blks_size = 0;
689 
690 	printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
691 	       blks_start, blks_start + blks_size);
692 
693 	blks = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL);
694 
695 	if (blks != blks_size) {
696 		pr_err("failed erasing from device %d\n", dev_desc->devnum);
697 		fastboot_fail("failed erasing from device", response);
698 		return;
699 	}
700 
701 	printf("........ erased " LBAFU " bytes from '%s'\n",
702 	       blks_size * info.blksz, cmd);
703 	fastboot_okay(NULL, response);
704 }
705