xref: /rk3399_rockchip-uboot/drivers/usb/gadget/f_fastboot.c (revision e17ddcea32b2fa7b82fb079f37195855a55e39a2)
1 /*
2  * (C) Copyright 2008 - 2009
3  * Windriver, <www.windriver.com>
4  * Tom Rix <Tom.Rix@windriver.com>
5  *
6  * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
7  *
8  * Copyright 2014 Linaro, Ltd.
9  * Rob Herring <robh@kernel.org>
10  *
11  * SPDX-License-Identifier:	GPL-2.0+
12  */
13 #include <config.h>
14 #include <common.h>
15 #include <console.h>
16 #include <errno.h>
17 #include <fastboot.h>
18 #include <malloc.h>
19 #include <linux/usb/ch9.h>
20 #include <linux/usb/gadget.h>
21 #include <linux/usb/composite.h>
22 #include <linux/compiler.h>
23 #include <u-boot/sha256.h>
24 #include <version.h>
25 #include <g_dnl.h>
26 #include <fs.h>
27 #include <android_avb/avb_ops_user.h>
28 #include <android_avb/rk_avb_ops_user.h>
29 #include <dm/uclass.h>
30 #include <power/fuel_gauge.h>
31 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
32 #include <fb_mmc.h>
33 #endif
34 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
35 #include <fb_nand.h>
36 #endif
37 #ifdef CONFIG_OPTEE_CLIENT
38 #include <optee_include/OpteeClientInterface.h>
39 #endif
40 
41 #define FASTBOOT_VERSION		"0.4"
42 
43 #define FASTBOOT_INTERFACE_CLASS	0xff
44 #define FASTBOOT_INTERFACE_SUB_CLASS	0x42
45 #define FASTBOOT_INTERFACE_PROTOCOL	0x03
46 
47 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0  (0x0200)
48 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1  (0x0040)
49 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE      (0x0040)
50 
51 #define EP_BUFFER_SIZE			4096
52 #define SLEEP_COUNT 20000
53 /*
54  * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
55  * (64 or 512 or 1024), else we break on certain controllers like DWC3
56  * that expect bulk OUT requests to be divisible by maxpacket size.
57  */
58 
59 struct f_fastboot {
60 	struct usb_function usb_function;
61 
62 	/* IN/OUT EP's and corresponding requests */
63 	struct usb_ep *in_ep, *out_ep;
64 	struct usb_request *in_req, *out_req;
65 };
66 
67 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
68 {
69 	return container_of(f, struct f_fastboot, usb_function);
70 }
71 
72 static struct f_fastboot *fastboot_func;
73 static unsigned int download_size;
74 static unsigned int download_bytes;
75 static unsigned int upload_size;
76 static unsigned int upload_bytes;
77 static bool start_upload;
78 static unsigned intthread_wakeup_needed;
79 
80 static struct usb_endpoint_descriptor fs_ep_in = {
81 	.bLength            = USB_DT_ENDPOINT_SIZE,
82 	.bDescriptorType    = USB_DT_ENDPOINT,
83 	.bEndpointAddress   = USB_DIR_IN,
84 	.bmAttributes       = USB_ENDPOINT_XFER_BULK,
85 	.wMaxPacketSize     = cpu_to_le16(64),
86 };
87 
88 static struct usb_endpoint_descriptor fs_ep_out = {
89 	.bLength		= USB_DT_ENDPOINT_SIZE,
90 	.bDescriptorType	= USB_DT_ENDPOINT,
91 	.bEndpointAddress	= USB_DIR_OUT,
92 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
93 	.wMaxPacketSize		= cpu_to_le16(64),
94 };
95 
96 static struct usb_endpoint_descriptor hs_ep_in = {
97 	.bLength		= USB_DT_ENDPOINT_SIZE,
98 	.bDescriptorType	= USB_DT_ENDPOINT,
99 	.bEndpointAddress	= USB_DIR_IN,
100 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
101 	.wMaxPacketSize		= cpu_to_le16(512),
102 };
103 
104 static struct usb_endpoint_descriptor hs_ep_out = {
105 	.bLength		= USB_DT_ENDPOINT_SIZE,
106 	.bDescriptorType	= USB_DT_ENDPOINT,
107 	.bEndpointAddress	= USB_DIR_OUT,
108 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
109 	.wMaxPacketSize		= cpu_to_le16(512),
110 };
111 
112 static struct usb_interface_descriptor interface_desc = {
113 	.bLength		= USB_DT_INTERFACE_SIZE,
114 	.bDescriptorType	= USB_DT_INTERFACE,
115 	.bInterfaceNumber	= 0x00,
116 	.bAlternateSetting	= 0x00,
117 	.bNumEndpoints		= 0x02,
118 	.bInterfaceClass	= FASTBOOT_INTERFACE_CLASS,
119 	.bInterfaceSubClass	= FASTBOOT_INTERFACE_SUB_CLASS,
120 	.bInterfaceProtocol	= FASTBOOT_INTERFACE_PROTOCOL,
121 };
122 
123 static struct usb_descriptor_header *fb_fs_function[] = {
124 	(struct usb_descriptor_header *)&interface_desc,
125 	(struct usb_descriptor_header *)&fs_ep_in,
126 	(struct usb_descriptor_header *)&fs_ep_out,
127 };
128 
129 static struct usb_descriptor_header *fb_hs_function[] = {
130 	(struct usb_descriptor_header *)&interface_desc,
131 	(struct usb_descriptor_header *)&hs_ep_in,
132 	(struct usb_descriptor_header *)&hs_ep_out,
133 	NULL,
134 };
135 
136 static struct usb_endpoint_descriptor *
137 fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
138 	    struct usb_endpoint_descriptor *hs)
139 {
140 	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
141 		return hs;
142 	return fs;
143 }
144 
145 /*
146  * static strings, in UTF-8
147  */
148 static const char fastboot_name[] = "Android Fastboot";
149 
150 static struct usb_string fastboot_string_defs[] = {
151 	[0].s = fastboot_name,
152 	{  }			/* end of list */
153 };
154 
155 static struct usb_gadget_strings stringtab_fastboot = {
156 	.language	= 0x0409,	/* en-us */
157 	.strings	= fastboot_string_defs,
158 };
159 
160 static struct usb_gadget_strings *fastboot_strings[] = {
161 	&stringtab_fastboot,
162 	NULL,
163 };
164 
165 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
166 static int strcmp_l1(const char *s1, const char *s2);
167 static void wakeup_thread(void)
168 {
169 	intthread_wakeup_needed = false;
170 }
171 
172 static void busy_indicator(void)
173 {
174 	static int state;
175 
176 	switch (state) {
177 	case 0:
178 		puts("\r|"); break;
179 	case 1:
180 		puts("\r/"); break;
181 	case 2:
182 		puts("\r-"); break;
183 	case 3:
184 		puts("\r\\"); break;
185 	case 4:
186 		puts("\r|"); break;
187 	case 5:
188 		puts("\r/"); break;
189 	case 6:
190 		puts("\r-"); break;
191 	case 7:
192 		puts("\r\\"); break;
193 	default:
194 		state = 0;
195 	}
196 	if (state++ == 8)
197 		state = 0;
198 }
199 
200 static int sleep_thread(void)
201 {
202 	int rc = 0;
203 	int i = 0, k = 0;
204 
205 	/* Wait until a signal arrives or we are woken up */
206 	for (;;) {
207 		if (!intthread_wakeup_needed)
208 			break;
209 
210 		if (++i == SLEEP_COUNT) {
211 			busy_indicator();
212 			i = 0;
213 			k++;
214 		}
215 
216 		if (k == 10) {
217 			/* Handle CTRL+C */
218 			if (ctrlc())
219 				return -EPIPE;
220 
221 			/* Check cable connection */
222 			if (!g_dnl_board_usb_cable_connected())
223 				return -EIO;
224 
225 			k = 0;
226 		}
227 
228 		usb_gadget_handle_interrupts(0);
229 	}
230 	intthread_wakeup_needed = true;
231 	return rc;
232 }
233 
234 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
235 {
236 	int status = req->status;
237 
238 	wakeup_thread();
239 	if (!status)
240 		return;
241 	printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual);
242 }
243 
244 static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
245 {
246 	int id;
247 	struct usb_gadget *gadget = c->cdev->gadget;
248 	struct f_fastboot *f_fb = func_to_fastboot(f);
249 	const char *s;
250 
251 	/* DYNAMIC interface numbers assignments */
252 	id = usb_interface_id(c, f);
253 	if (id < 0)
254 		return id;
255 	interface_desc.bInterfaceNumber = id;
256 
257 	id = usb_string_id(c->cdev);
258 	if (id < 0)
259 		return id;
260 	fastboot_string_defs[0].id = id;
261 	interface_desc.iInterface = id;
262 
263 	f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in);
264 	if (!f_fb->in_ep)
265 		return -ENODEV;
266 	f_fb->in_ep->driver_data = c->cdev;
267 
268 	f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out);
269 	if (!f_fb->out_ep)
270 		return -ENODEV;
271 	f_fb->out_ep->driver_data = c->cdev;
272 
273 	f->descriptors = fb_fs_function;
274 
275 	if (gadget_is_dualspeed(gadget)) {
276 		/* Assume endpoint addresses are the same for both speeds */
277 		hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
278 		hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
279 		/* copy HS descriptors */
280 		f->hs_descriptors = fb_hs_function;
281 	}
282 
283 	s = env_get("serial#");
284 	if (s)
285 		g_dnl_set_serialnumber((char *)s);
286 
287 	return 0;
288 }
289 
290 static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
291 {
292 	memset(fastboot_func, 0, sizeof(*fastboot_func));
293 }
294 
295 static void fastboot_disable(struct usb_function *f)
296 {
297 	struct f_fastboot *f_fb = func_to_fastboot(f);
298 
299 	usb_ep_disable(f_fb->out_ep);
300 	usb_ep_disable(f_fb->in_ep);
301 
302 	if (f_fb->out_req) {
303 		free(f_fb->out_req->buf);
304 		usb_ep_free_request(f_fb->out_ep, f_fb->out_req);
305 		f_fb->out_req = NULL;
306 	}
307 	if (f_fb->in_req) {
308 		free(f_fb->in_req->buf);
309 		usb_ep_free_request(f_fb->in_ep, f_fb->in_req);
310 		f_fb->in_req = NULL;
311 	}
312 }
313 
314 static struct usb_request *fastboot_start_ep(struct usb_ep *ep)
315 {
316 	struct usb_request *req;
317 
318 	req = usb_ep_alloc_request(ep, 0);
319 	if (!req)
320 		return NULL;
321 
322 	req->length = EP_BUFFER_SIZE;
323 	req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE);
324 	if (!req->buf) {
325 		usb_ep_free_request(ep, req);
326 		return NULL;
327 	}
328 
329 	memset(req->buf, 0, req->length);
330 	return req;
331 }
332 
333 static int fastboot_set_alt(struct usb_function *f,
334 			    unsigned interface, unsigned alt)
335 {
336 	int ret;
337 	struct usb_composite_dev *cdev = f->config->cdev;
338 	struct usb_gadget *gadget = cdev->gadget;
339 	struct f_fastboot *f_fb = func_to_fastboot(f);
340 	const struct usb_endpoint_descriptor *d;
341 
342 	debug("%s: func: %s intf: %d alt: %d\n",
343 	      __func__, f->name, interface, alt);
344 
345 	d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out);
346 	ret = usb_ep_enable(f_fb->out_ep, d);
347 	if (ret) {
348 		puts("failed to enable out ep\n");
349 		return ret;
350 	}
351 
352 	f_fb->out_req = fastboot_start_ep(f_fb->out_ep);
353 	if (!f_fb->out_req) {
354 		puts("failed to alloc out req\n");
355 		ret = -EINVAL;
356 		goto err;
357 	}
358 	f_fb->out_req->complete = rx_handler_command;
359 
360 	d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in);
361 	ret = usb_ep_enable(f_fb->in_ep, d);
362 	if (ret) {
363 		puts("failed to enable in ep\n");
364 		goto err;
365 	}
366 
367 	f_fb->in_req = fastboot_start_ep(f_fb->in_ep);
368 	if (!f_fb->in_req) {
369 		puts("failed alloc req in\n");
370 		ret = -EINVAL;
371 		goto err;
372 	}
373 	f_fb->in_req->complete = fastboot_complete;
374 
375 	ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0);
376 	if (ret)
377 		goto err;
378 
379 	return 0;
380 err:
381 	fastboot_disable(f);
382 	return ret;
383 }
384 
385 static int fastboot_add(struct usb_configuration *c)
386 {
387 	struct f_fastboot *f_fb = fastboot_func;
388 	int status;
389 
390 	debug("%s: cdev: 0x%p\n", __func__, c->cdev);
391 
392 	if (!f_fb) {
393 		f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));
394 		if (!f_fb)
395 			return -ENOMEM;
396 
397 		fastboot_func = f_fb;
398 		memset(f_fb, 0, sizeof(*f_fb));
399 	}
400 
401 	f_fb->usb_function.name = "f_fastboot";
402 	f_fb->usb_function.bind = fastboot_bind;
403 	f_fb->usb_function.unbind = fastboot_unbind;
404 	f_fb->usb_function.set_alt = fastboot_set_alt;
405 	f_fb->usb_function.disable = fastboot_disable;
406 	f_fb->usb_function.strings = fastboot_strings;
407 
408 	status = usb_add_function(c, &f_fb->usb_function);
409 	if (status) {
410 		free(f_fb);
411 		fastboot_func = f_fb;
412 	}
413 
414 	return status;
415 }
416 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
417 
418 static int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
419 {
420 	struct usb_request *in_req = fastboot_func->in_req;
421 	int ret;
422 
423 	memcpy(in_req->buf, buffer, buffer_size);
424 	in_req->length = buffer_size;
425 
426 	usb_ep_dequeue(fastboot_func->in_ep, in_req);
427 
428 	ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
429 	if (ret)
430 		printf("Error %d on queue\n", ret);
431 	return 0;
432 }
433 
434 static int fastboot_tx_write_str(const char *buffer)
435 {
436 	int ret;
437 
438 	ret = sleep_thread();
439 	if (ret < 0)
440 		printf("warning: 0x%x, usb transmission is abnormal!\n", ret);
441 
442 	return fastboot_tx_write(buffer, strlen(buffer));
443 }
444 
445 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
446 {
447 	do_reset(NULL, 0, 0, NULL);
448 }
449 
450 int __weak fb_set_reboot_flag(void)
451 {
452 	return -ENOSYS;
453 }
454 
455 static void cb_reboot(struct usb_ep *ep, struct usb_request *req)
456 {
457 	char *cmd = req->buf;
458 	if (!strcmp_l1("reboot-bootloader", cmd)) {
459 		if (fb_set_reboot_flag()) {
460 			fastboot_tx_write_str("FAILCannot set reboot flag");
461 			return;
462 		}
463 	}
464 	fastboot_func->in_req->complete = compl_do_reset;
465 	fastboot_tx_write_str("OKAY");
466 }
467 
468 static int strcmp_l1(const char *s1, const char *s2)
469 {
470 	if (!s1 || !s2)
471 		return -1;
472 	return strncmp(s1, s2, strlen(s1));
473 }
474 
475 static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
476 {
477 	char *cmd = req->buf;
478 	char response[FASTBOOT_RESPONSE_LEN];
479 	const char *s;
480 	size_t chars_left;
481 
482 	strcpy(response, "OKAY");
483 	chars_left = sizeof(response) - strlen(response) - 1;
484 
485 	strsep(&cmd, ":");
486 	if (!cmd) {
487 		pr_err("missing variable");
488 		fastboot_tx_write_str("FAILmissing var");
489 		return;
490 	}
491 
492 	if (!strcmp_l1("version", cmd)) {
493 		strncat(response, FASTBOOT_VERSION, chars_left);
494 	} else if (!strcmp_l1("bootloader-version", cmd)) {
495 		strncat(response, U_BOOT_VERSION, chars_left);
496 	} else if (!strcmp_l1("product", cmd)) {
497 		strncat(response, CONFIG_SYS_BOARD, chars_left);
498 	} else if (!strcmp_l1("variant", cmd)) {
499 		strncat(response, "userdebug", chars_left);
500 	} else if (!strcmp_l1("secure", cmd)) {
501 		strncat(response, "no", chars_left);
502 	} else if (!strcmp_l1("unlocked", cmd)) {
503 		strncat(response, "yes", chars_left);
504 	} else if (!strcmp_l1("off-mode-charge", cmd)) {
505 		strncat(response, "0", chars_left);
506 	} else if (!strcmp_l1("battery-voltage", cmd)) {
507 		strncat(response, "7.4", chars_left);
508 	} else if (!strcmp_l1("battery-soc-ok", cmd)) {
509 		strncat(response, "yes", chars_left);
510 	} else if (!strcmp_l1("downloadsize", cmd) ||
511 		!strcmp_l1("max-download-size", cmd)) {
512 		char str_num[12];
513 
514 		sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
515 		strncat(response, str_num, chars_left);
516 	} else if (!strcmp_l1("serialno", cmd)) {
517 		s = env_get("serial#");
518 		if (s)
519 			strncat(response, s, chars_left);
520 		else
521 			strcpy(response, "FAILValue not set");
522 	} else if (strncmp("at-attest-dh", cmd, 12) == 0) {
523 #ifdef CONFIG_OPTEE_CLIENT
524 		char dhbuf[8];
525 		uint32_t dh_len = 8;
526 		uint32_t res = trusty_attest_dh((uint8_t *)dhbuf, &dh_len);
527 		if (res)
528 			strcpy(response, "FAILdh not set");
529 		else
530 			strncat(response, dhbuf, chars_left);
531 #else
532 		fastboot_tx_write_str("FAILnot implemented");
533 		return;
534 #endif
535 	} else if (strncmp("at-attest-uuid", cmd, 14) == 0) {
536 #ifdef CONFIG_OPTEE_CLIENT
537 		char uuid[32] = {0};
538 		uint32_t uuid_len = 32;
539 		uint32_t res = trusty_attest_uuid((uint8_t *)uuid, &uuid_len);
540 		if (res)
541 			strcpy(response, "FAILuuid not set");
542 		else
543 			strncat(response, uuid, chars_left);
544 #else
545 		fastboot_tx_write_str("FAILnot implemented");
546 		return;
547 #endif
548 	} else if (strncmp("at-vboot-state", cmd, 14) == 0) {
549 		char uuid[32] = {0};
550 
551 		strncat(response, uuid, chars_left);
552 	} else if (!strcmp_l1("slot-count", cmd)) {
553 #ifdef CONFIG_RK_AVB_LIBAVB_USER
554 		char slot_count[2];
555 		char temp;
556 
557 		slot_count[1] = '\0';
558 		rk_avb_read_slot_count(&temp);
559 		slot_count[0] = temp + 0x30;
560 		strncat(response, slot_count, chars_left);
561 #else
562 		fastboot_tx_write_str("FAILnot implemented");
563 		return;
564 #endif
565 	} else if (!strcmp_l1("current-slot", cmd)) {
566 #ifdef CONFIG_RK_AVB_LIBAVB_USER
567 		char slot_surrent[8] = {0};
568 
569 		if (!rk_avb_get_current_slot(slot_surrent))
570 			strncat(response, slot_surrent+1, chars_left);
571 		else
572 			strcpy(response, "FAILgeterror");
573 #else
574 		fastboot_tx_write_str("FAILnot implemented");
575 		return;
576 #endif
577 	} else if (!strcmp_l1("slot-suffixes", cmd)) {
578 #ifdef CONFIG_RK_AVB_LIBAVB_USER
579 		char slot_suffixes_temp[4];
580 		char slot_suffixes[9];
581 		int slot_cnt = 0;
582 
583 		memset(slot_suffixes_temp, 0, 4);
584 		memset(slot_suffixes, 0, 9);
585 		rk_avb_read_slot_suffixes(slot_suffixes_temp);
586 		while (slot_suffixes_temp[slot_cnt] != '\0') {
587 			slot_suffixes[slot_cnt * 2]
588 				= slot_suffixes_temp[slot_cnt];
589 			slot_suffixes[slot_cnt * 2 + 1] = ',';
590 			slot_cnt++;
591 		}
592 		strncat(response, slot_suffixes, chars_left);
593 #else
594 		fastboot_tx_write_str("FAILnot implemented");
595 		return;
596 #endif
597 	} else if (!strncmp("has-slot", cmd, 8)) {
598 #ifdef CONFIG_RK_AVB_LIBAVB_USER
599 		char *part_name = cmd;
600 
601 		cmd = strsep(&part_name, ":");
602 		if (!strcmp(part_name, "boot") ||
603 		    !strcmp(part_name, "system") ||
604 		    !strcmp(part_name, "vendor") ||
605 		    !strcmp(part_name, "vbmeta") ||
606 		    !strcmp(part_name, "oem")) {
607 			strncat(response, "yes", chars_left);
608 		} else {
609 			strcpy(response, "FAILno");
610 		}
611 #else
612 		fastboot_tx_write_str("FAILnot implemented");
613 		return;
614 #endif
615 	} else if (!strncmp("slot-unbootable", cmd, 15)) {
616 #ifdef CONFIG_RK_AVB_LIBAVB_USER
617 		char *slot_name = cmd;
618 
619 		cmd = strsep(&slot_name, ":");
620 		if (!strcmp(slot_name, "a") ||
621 		    !strcmp(slot_name, "b")) {
622 			strncat(response, "no", chars_left);
623 		} else {
624 			strcpy(response, "FAILno");
625 		}
626 #else
627 		fastboot_tx_write_str("FAILnot implemented");
628 		return;
629 #endif
630 	} else if (!strncmp("slot-successful", cmd, 15)) {
631 #ifdef CONFIG_RK_AVB_LIBAVB_USER
632 		char *slot_name = cmd;
633 
634 		cmd = strsep(&slot_name, ":");
635 		if (!strcmp(slot_name, "a") ||
636 		    !strcmp(slot_name, "b")) {
637 			strncat(response, "no", chars_left);
638 		} else {
639 			strcpy(response, "FAILno");
640 		}
641 #else
642 		fastboot_tx_write_str("FAILnot implemented");
643 		return;
644 #endif
645 	} else if (!strncmp("slot-retry-count", cmd, 16)) {
646 #ifdef CONFIG_RK_AVB_LIBAVB_USER
647 		char *slot_name = cmd;
648 		char count[10] = {0};
649 		static int cnt[2] = {0};
650 
651 		cmd = strsep(&slot_name, ":");
652 		if (!strcmp(slot_name, "a")) {
653 			sprintf(count, "%c", 0x30+cnt[0]);
654 			strncat(response, count, chars_left);
655 			if (cnt[0] > 0)
656 				cnt[0]--;
657 		} else if (!strcmp(slot_name, "b")) {
658 			sprintf(count, "%c", 0x30+cnt[1]);
659 			strncat(response, count, chars_left);
660 			if (cnt[1] > 0)
661 				cnt[1]--;
662 		} else {
663 			strcpy(response, "FAILno");
664 		}
665 #else
666 		fastboot_tx_write_str("FAILnot implemented");
667 		return;
668 #endif
669 	} else if (!strncmp("partition-type", cmd, 14) ||
670 		   !strncmp("partition-size", cmd, 14)) {
671 		disk_partition_t part_info;
672 		struct blk_desc *dev_desc;
673 		char *part_name = cmd;
674 		char part_size_str[20];
675 
676 		cmd = strsep(&part_name, ":");
677 		dev_desc = blk_get_dev("mmc", 0);
678 		if (!dev_desc) {
679 			strcpy(response, "FAILblock device not found");
680 		} else if (part_get_info_by_name(dev_desc, part_name, &part_info) < 0) {
681 			strcpy(response, "FAILpartition not found");
682 		} else if (!strncmp("partition-type", cmd, 14)) {
683 			strncat(response, (char *)part_info.type, chars_left);
684 		} else if (!strncmp("partition-size", cmd, 14)) {
685 			sprintf(part_size_str, "0x%016x", (int)part_info.size);
686 			strncat(response, part_size_str, chars_left);
687 		}
688 	} else {
689 		char *envstr;
690 
691 		envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1);
692 		if (!envstr) {
693 			fastboot_tx_write_str("FAILmalloc error");
694 			return;
695 		}
696 
697 		sprintf(envstr, "fastboot.%s", cmd);
698 		s = env_get(envstr);
699 		if (s) {
700 			strncat(response, s, chars_left);
701 		} else {
702 			printf("WARNING: unknown variable: %s\n", cmd);
703 			strcpy(response, "FAILVariable not implemented");
704 		}
705 
706 		free(envstr);
707 	}
708 	fastboot_tx_write_str(response);
709 }
710 
711 static unsigned int rx_bytes_expected(struct usb_ep *ep)
712 {
713 	int rx_remain = download_size - download_bytes;
714 	unsigned int rem;
715 	unsigned int maxpacket = ep->maxpacket;
716 
717 	if (rx_remain <= 0)
718 		return 0;
719 	else if (rx_remain > EP_BUFFER_SIZE)
720 		return EP_BUFFER_SIZE;
721 
722 	/*
723 	 * Some controllers e.g. DWC3 don't like OUT transfers to be
724 	 * not ending in maxpacket boundary. So just make them happy by
725 	 * always requesting for integral multiple of maxpackets.
726 	 * This shouldn't bother controllers that don't care about it.
727 	 */
728 	rem = rx_remain % maxpacket;
729 	if (rem > 0)
730 		rx_remain = rx_remain + (maxpacket - rem);
731 
732 	return rx_remain;
733 }
734 
735 #define BYTES_PER_DOT	0x20000
736 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
737 {
738 	char response[FASTBOOT_RESPONSE_LEN];
739 	unsigned int transfer_size = download_size - download_bytes;
740 	const unsigned char *buffer = req->buf;
741 	unsigned int buffer_size = req->actual;
742 	unsigned int pre_dot_num, now_dot_num;
743 
744 	if (req->status != 0) {
745 		printf("Bad status: %d\n", req->status);
746 		return;
747 	}
748 
749 	if (buffer_size < transfer_size)
750 		transfer_size = buffer_size;
751 
752 	memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
753 	       buffer, transfer_size);
754 
755 	pre_dot_num = download_bytes / BYTES_PER_DOT;
756 	download_bytes += transfer_size;
757 	now_dot_num = download_bytes / BYTES_PER_DOT;
758 
759 	if (pre_dot_num != now_dot_num) {
760 		putc('.');
761 		if (!(now_dot_num % 74))
762 			putc('\n');
763 	}
764 
765 	/* Check if transfer is done */
766 	if (download_bytes >= download_size) {
767 		/*
768 		 * Reset global transfer variable, keep download_bytes because
769 		 * it will be used in the next possible flashing command
770 		 */
771 		download_size = 0;
772 		req->complete = rx_handler_command;
773 		req->length = EP_BUFFER_SIZE;
774 
775 		strcpy(response, "OKAY");
776 		fastboot_tx_write_str(response);
777 
778 		printf("\ndownloading of %d bytes finished\n", download_bytes);
779 	} else {
780 		req->length = rx_bytes_expected(ep);
781 	}
782 
783 	req->actual = 0;
784 	usb_ep_queue(ep, req, 0);
785 }
786 
787 static void cb_download(struct usb_ep *ep, struct usb_request *req)
788 {
789 	char *cmd = req->buf;
790 	char response[FASTBOOT_RESPONSE_LEN];
791 
792 	strsep(&cmd, ":");
793 	download_size = simple_strtoul(cmd, NULL, 16);
794 	download_bytes = 0;
795 
796 	printf("Starting download of %d bytes\n", download_size);
797 
798 	if (0 == download_size) {
799 		strcpy(response, "FAILdata invalid size");
800 	} else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
801 		download_size = 0;
802 		strcpy(response, "FAILdata too large");
803 	} else {
804 		sprintf(response, "DATA%08x", download_size);
805 		req->complete = rx_handler_dl_image;
806 		req->length = rx_bytes_expected(ep);
807 	}
808 
809 	fastboot_tx_write_str(response);
810 }
811 
812 static void tx_handler_ul(struct usb_ep *ep, struct usb_request *req)
813 {
814 	unsigned int xfer_size = 0;
815 	unsigned int pre_dot_num, now_dot_num;
816 	unsigned int remain_size = 0;
817 	unsigned int transferred_size = req->actual;
818 
819 	if (req->status != 0) {
820 		printf("Bad status: %d\n", req->status);
821 		return;
822 	}
823 
824 	if (start_upload) {
825 		pre_dot_num = upload_bytes / BYTES_PER_DOT;
826 		upload_bytes += transferred_size;
827 		now_dot_num = upload_bytes / BYTES_PER_DOT;
828 
829 		if (pre_dot_num != now_dot_num) {
830 			putc('.');
831 			if (!(now_dot_num % 74))
832 				putc('\n');
833 		}
834 	}
835 
836 	remain_size = upload_size - upload_bytes;
837 	xfer_size = (remain_size > EP_BUFFER_SIZE) ?
838 		    EP_BUFFER_SIZE : remain_size;
839 
840 	debug("%s: remain_size=%d, transferred_size=%d",
841 	      __func__, remain_size, transferred_size);
842 	debug("xfer_size=%d, upload_bytes=%d, upload_size=%d!\n",
843 	      xfer_size, upload_bytes, upload_size);
844 
845 	if (remain_size <= 0) {
846 		fastboot_func->in_req->complete = fastboot_complete;
847 		fastboot_tx_write_str("OKAY");
848 		printf("\nuploading of %d bytes finished\n", upload_bytes);
849 		upload_bytes = 0;
850 		upload_size = 0;
851 		start_upload = false;
852 		return;
853 	}
854 
855 	/* Remove the transfer callback which response the upload */
856 	/* request from host */
857 	if (!upload_bytes)
858 		start_upload = true;
859 
860 	fastboot_tx_write((char *)((phys_addr_t)CONFIG_FASTBOOT_BUF_ADDR + \
861 			  upload_bytes),
862 			  xfer_size);
863 }
864 
865 static void cb_upload(struct usb_ep *ep, struct usb_request *req)
866 {
867 	char response[FASTBOOT_RESPONSE_LEN];
868 
869 	printf("Starting upload of %d bytes\n", upload_size);
870 
871 	if (0 == upload_size) {
872 		strcpy(response, "FAILdata invalid size");
873 	} else {
874 		start_upload = false;
875 		sprintf(response, "DATA%08x", upload_size);
876 		fastboot_func->in_req->complete = tx_handler_ul;
877 	}
878 
879 	fastboot_tx_write_str(response);
880 }
881 
882 static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
883 {
884 	char boot_addr_start[12];
885 	char *bootm_args[] = { "bootm", boot_addr_start, NULL };
886 
887 	puts("Booting kernel..\n");
888 
889 	sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR);
890 	do_bootm(NULL, 0, 2, bootm_args);
891 
892 	/* This only happens if image is somehow faulty so we start over */
893 	do_reset(NULL, 0, 0, NULL);
894 }
895 
896 static void cb_boot(struct usb_ep *ep, struct usb_request *req)
897 {
898 	fastboot_func->in_req->complete = do_bootm_on_complete;
899 	fastboot_tx_write_str("OKAY");
900 }
901 
902 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
903 {
904 	g_dnl_trigger_detach();
905 }
906 
907 static void cb_continue(struct usb_ep *ep, struct usb_request *req)
908 {
909 	fastboot_func->in_req->complete = do_exit_on_complete;
910 	fastboot_tx_write_str("OKAY");
911 }
912 
913 static void cb_set_active(struct usb_ep *ep, struct usb_request *req)
914 {
915 	char *cmd = req->buf;
916 
917 	debug("%s: %s\n", __func__, cmd);
918 
919 	strsep(&cmd, ":");
920 	if (!cmd) {
921 		pr_err("missing slot name");
922 		fastboot_tx_write_str("FAILmissing slot name");
923 		return;
924 	}
925 #ifdef CONFIG_RK_AVB_LIBAVB_USER
926 	unsigned int slot_number;
927 	if (strncmp("a", cmd, 1) == 0) {
928 		slot_number = 0;
929 		rk_avb_set_slot_active(&slot_number);
930 	} else if (strncmp("b", cmd, 1) == 0) {
931 		slot_number = 1;
932 		rk_avb_set_slot_active(&slot_number);
933 	} else {
934 		fastboot_tx_write_str("FAILunkown slot name");
935 		return;
936 	}
937 
938 	fastboot_tx_write_str("OKAY");
939 	return;
940 #else
941 	fastboot_tx_write_str("FAILnot implemented");
942 	return;
943 #endif
944 }
945 
946 #ifdef CONFIG_FASTBOOT_FLASH
947 static void cb_flash(struct usb_ep *ep, struct usb_request *req)
948 {
949 	char *cmd = req->buf;
950 	char response[FASTBOOT_RESPONSE_LEN] = {0};
951 #ifdef CONFIG_RK_AVB_LIBAVB_USER
952 	uint8_t flash_lock_state;
953 
954 	if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
955 		/* write the device flashing unlock when first read */
956 		if (rk_avb_write_flash_lock_state(1)) {
957 			fastboot_tx_write_str("FAILflash lock state write failure");
958 			return;
959 		}
960 		if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
961 			fastboot_tx_write_str("FAILflash lock state read failure");
962 			return;
963 		}
964 	}
965 
966 	if (flash_lock_state == 0) {
967 		fastboot_tx_write_str("FAILThe device is locked, can not flash!");
968 		printf("The device is locked, can not flash!\n");
969 		return;
970 	}
971 #endif
972 	strsep(&cmd, ":");
973 	if (!cmd) {
974 		pr_err("missing partition name");
975 		fastboot_tx_write_str("FAILmissing partition name");
976 		return;
977 	}
978 
979 	fastboot_fail("no flash device defined", response);
980 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
981 	fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
982 				download_bytes, response);
983 #endif
984 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
985 	fb_nand_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
986 				download_bytes, response);
987 #endif
988 	fastboot_tx_write_str(response);
989 }
990 
991 static void cb_flashing(struct usb_ep *ep, struct usb_request *req)
992 {
993 	char *cmd = req->buf;
994 
995 	if (strncmp("lock", cmd + 9, 4) == 0) {
996 #ifdef CONFIG_RK_AVB_LIBAVB_USER
997 		uint8_t flash_lock_state;
998 		flash_lock_state = 0;
999 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1000 			fastboot_tx_write_str("FAILflash lock state"
1001 					      " write failure");
1002 		else
1003 			fastboot_tx_write_str("OKAY");
1004 #else
1005 		fastboot_tx_write_str("FAILnot implemented");
1006 #endif
1007 	} else if (strncmp("unlock", cmd + 9, 6) == 0) {
1008 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1009 		uint8_t flash_lock_state;
1010 		flash_lock_state = 1;
1011 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1012 			fastboot_tx_write_str("FAILflash lock state"
1013 					      " write failure");
1014 		else
1015 			fastboot_tx_write_str("OKAY");
1016 #else
1017 		fastboot_tx_write_str("FAILnot implemented");
1018 #endif
1019 	} else if (strncmp("lock_critical", cmd + 9, 12) == 0) {
1020 		fastboot_tx_write_str("FAILnot implemented");
1021 	} else if (strncmp("unlock_critical", cmd + 9, 14) == 0) {
1022 		fastboot_tx_write_str("FAILnot implemented");
1023 	} else if (strncmp("get_unlock_ability", cmd + 9, 17) == 0) {
1024 		fastboot_tx_write_str("FAILnot implemented");
1025 	} else if (strncmp("get_unlock_bootloader_nonce", cmd + 4, 27) == 0) {
1026 		fastboot_tx_write_str("FAILnot implemented");
1027 	} else if (strncmp("unlock_bootloader", cmd + 9, 17) == 0) {
1028 		fastboot_tx_write_str("FAILnot implemented");
1029 	} else if (strncmp("lock_bootloader", cmd + 9, 15) == 0) {
1030 		fastboot_tx_write_str("FAILnot implemented");
1031 	} else {
1032 		fastboot_tx_write_str("FAILunknown flashing command");
1033 	}
1034 }
1035 #endif
1036 
1037 static void cb_oem_perm_attr(void)
1038 {
1039 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1040 	sha256_context ctx;
1041 	uint8_t digest[SHA256_SUM_LEN] = {0};
1042 	uint8_t digest_temp[SHA256_SUM_LEN] = {0};
1043 	uint8_t perm_attr_temp[PERM_ATTR_TOTAL_SIZE] = {0};
1044 	uint8_t flag = 0;
1045 
1046 	if (PERM_ATTR_TOTAL_SIZE != download_bytes) {
1047 		printf("Permanent attribute size is not equal!\n");
1048 		fastboot_tx_write_str("FAILincorrect perm attribute size");
1049 		return;
1050 	}
1051 
1052 	if (rk_avb_read_perm_attr_flag(&flag)) {
1053 		printf("rk_avb_read_perm_attr_flag error!\n");
1054 		fastboot_tx_write_str("FAILperm attr read failed");
1055 		return;
1056 	}
1057 
1058 	if (flag == PERM_ATTR_SUCCESS_FLAG) {
1059 		if (rk_avb_read_attribute_hash(digest_temp,
1060 					       SHA256_SUM_LEN)) {
1061 			printf("The efuse IO can not be used!\n");
1062 			fastboot_tx_write_str("FAILefuse IO can not be used");
1063 			return;
1064 		}
1065 
1066 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1067 			if (rk_avb_read_permanent_attributes(perm_attr_temp,
1068 							     PERM_ATTR_TOTAL_SIZE)) {
1069 				printf("rk_avb_write_permanent_attributes error!\n");
1070 				fastboot_tx_write_str("FAILread perm attr error");
1071 				return;
1072 			}
1073 
1074 			sha256_starts(&ctx);
1075 			sha256_update(&ctx,
1076 				      (const uint8_t *)perm_attr_temp,
1077 				      PERM_ATTR_TOTAL_SIZE);
1078 			sha256_finish(&ctx, digest);
1079 			if (memcmp(digest, digest_temp, SHA256_SUM_LEN) == 0) {
1080 				printf("The hash has been written!\n");
1081 				fastboot_tx_write_str("OKAY");
1082 				return;
1083 			}
1084 		}
1085 
1086 		if (rk_avb_write_perm_attr_flag(0)) {
1087 			fastboot_tx_write_str("FAILperm attr flag write failure");
1088 			return;
1089 		}
1090 	}
1091 
1092 	if (rk_avb_write_permanent_attributes((uint8_t *)
1093 					      CONFIG_FASTBOOT_BUF_ADDR,
1094 					      download_bytes)) {
1095 		if (rk_avb_write_perm_attr_flag(0)) {
1096 			fastboot_tx_write_str("FAILperm attr flag write failure");
1097 			return;
1098 		}
1099 		fastboot_tx_write_str("FAILperm attr write failed");
1100 		return;
1101 	}
1102 
1103 	memset(digest, 0, SHA256_SUM_LEN);
1104 	sha256_starts(&ctx);
1105 	sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1106 		      PERM_ATTR_TOTAL_SIZE);
1107 	sha256_finish(&ctx, digest);
1108 
1109 	if (rk_avb_write_attribute_hash((uint8_t *)digest,
1110 					SHA256_SUM_LEN)) {
1111 		if (rk_avb_read_attribute_hash(digest_temp,
1112 						SHA256_SUM_LEN)) {
1113 			printf("The efuse IO can not be used!\n");
1114 			fastboot_tx_write_str("FAILefuse IO can not be used");
1115 			return;
1116 		}
1117 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1118 			if (rk_avb_write_perm_attr_flag(0)) {
1119 				fastboot_tx_write_str("FAILperm attr flag write failure");
1120 				return;
1121 			}
1122 			printf("The hash has been written, but is different!\n");
1123 			fastboot_tx_write_str("FAILhash comparison failure");
1124 			return;
1125 		}
1126 	}
1127 
1128 	if (rk_avb_write_perm_attr_flag(PERM_ATTR_SUCCESS_FLAG)) {
1129 		fastboot_tx_write_str("FAILperm attr flag write failure");
1130 		return;
1131 	}
1132 
1133 	fastboot_tx_write_str("OKAY");
1134 #else
1135 	fastboot_tx_write_str("FAILnot implemented");
1136 #endif
1137 }
1138 
1139 static void cb_oem(struct usb_ep *ep, struct usb_request *req)
1140 {
1141 	char *cmd = req->buf;
1142 
1143 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1144 	if (strncmp("format", cmd + 4, 6) == 0) {
1145 		char cmdbuf[32];
1146                 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1147 			CONFIG_FASTBOOT_FLASH_MMC_DEV);
1148                 if (run_command(cmdbuf, 0))
1149 			fastboot_tx_write_str("FAILmmc write failure");
1150                 else
1151 			fastboot_tx_write_str("OKAY");
1152 	} else
1153 #endif
1154 	if (strncmp("unlock", cmd + 4, 8) == 0) {
1155 		fastboot_tx_write_str("FAILnot implemented");
1156 	} else if (strncmp("at-get-ca-request", cmd + 4, 17) == 0) {
1157 #ifdef CONFIG_OPTEE_CLIENT
1158 		uint8_t out[ATTEST_CA_OUT_SIZE];
1159 		uint32_t operation_size = download_bytes;
1160 		uint32_t out_len = ATTEST_CA_OUT_SIZE;
1161 		uint32_t res = 0;
1162 
1163 		res = trusty_attest_get_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1164 					   &operation_size, out, &out_len);
1165 		if (res) {
1166 			fastboot_tx_write_str("FAILtrusty_attest_get_ca failed");
1167 			return;
1168 		}
1169 		upload_size = out_len;
1170 		memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR, out, out_len);
1171 		fastboot_tx_write_str("OKAY");
1172 #else
1173 		fastboot_tx_write_str("FAILnot implemented");
1174 		return;
1175 #endif
1176 	} else if (strncmp("at-set-ca-response", cmd + 4, 18) == 0) {
1177 #ifdef CONFIG_OPTEE_CLIENT
1178 		uint32_t ca_response_size = download_bytes;
1179 		uint32_t res = 0;
1180 
1181 		res = trusty_attest_set_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1182 					   &ca_response_size);
1183 		if (res)
1184 			fastboot_tx_write_str("FAILtrusty_attest_set_ca failed");
1185 		else
1186 			fastboot_tx_write_str("OKAY");
1187 #else
1188 		fastboot_tx_write_str("FAILnot implemented");
1189 		return;
1190 #endif
1191 	} else if (strncmp("at-lock-vboot", cmd + 4, 13) == 0) {
1192 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1193 		uint8_t lock_state;
1194 		lock_state = 0;
1195 		if (rk_avb_write_lock_state(lock_state))
1196 			fastboot_tx_write_str("FAILwrite lock state failed");
1197 		else
1198 			fastboot_tx_write_str("OKAY");
1199 #else
1200 		fastboot_tx_write_str("FAILnot implemented");
1201 #endif
1202 	} else if (strncmp("at-unlock-vboot", cmd + 4, 15) == 0) {
1203 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1204 		uint8_t lock_state;
1205 		if (rk_avb_read_lock_state(&lock_state))
1206 			fastboot_tx_write_str("FAILlock sate read failure");
1207 		if (lock_state >> 1 == 1) {
1208 			fastboot_tx_write_str("FAILThe vboot is disable!");
1209 		} else {
1210 			lock_state = 1;
1211 			if (rk_avb_write_lock_state(lock_state))
1212 				fastboot_tx_write_str("FAILwrite lock state failed");
1213 			else
1214 				fastboot_tx_write_str("OKAY");
1215 		}
1216 #else
1217 		fastboot_tx_write_str("FAILnot implemented");
1218 #endif
1219 	} else if (strncmp("at-disable-unlock-vboot", cmd + 4, 23) == 0) {
1220 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1221 		uint8_t lock_state;
1222 		lock_state = 2;
1223 		if (rk_avb_write_lock_state(lock_state))
1224 			fastboot_tx_write_str("FAILwrite lock state failed");
1225 		else
1226 			fastboot_tx_write_str("OKAY");
1227 #else
1228 		fastboot_tx_write_str("FAILnot implemented");
1229 #endif
1230 	} else if (strncmp("fuse at-perm-attr", cmd + 4, 16) == 0) {
1231 		cb_oem_perm_attr();
1232 	} else if (strncmp("fuse at-bootloader-vboot-key", cmd + 4, 27) == 0) {
1233 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1234 		sha256_context ctx;
1235 		uint8_t digest[SHA256_SUM_LEN];
1236 
1237 		if (download_bytes != VBOOT_KEY_HASH_SIZE) {
1238 			fastboot_tx_write_str("FAILinvalid vboot key length");
1239 			printf("The vboot key size error!\n");
1240 			return;
1241 		}
1242 
1243 		sha256_starts(&ctx);
1244 		sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1245 			      VBOOT_KEY_SIZE);
1246 		sha256_finish(&ctx, digest);
1247 
1248 		if (rk_avb_write_vbootkey_hash((uint8_t *)digest,
1249 					       SHA256_SUM_LEN)) {
1250 			fastboot_tx_write_str("FAILvbootkey hash write failure");
1251 			return;
1252 		}
1253 		fastboot_tx_write_str("OKAY");
1254 #else
1255 		fastboot_tx_write_str("FAILnot implemented");
1256 #endif
1257 	} else {
1258 		fastboot_tx_write_str("FAILunknown oem command");
1259 	}
1260 }
1261 
1262 #ifdef CONFIG_FASTBOOT_FLASH
1263 static void cb_erase(struct usb_ep *ep, struct usb_request *req)
1264 {
1265 	char *cmd = req->buf;
1266 	char response[FASTBOOT_RESPONSE_LEN];
1267 
1268 	strsep(&cmd, ":");
1269 	if (!cmd) {
1270 		pr_err("missing partition name");
1271 		fastboot_tx_write_str("FAILmissing partition name");
1272 		return;
1273 	}
1274 
1275 	fastboot_fail("no flash device defined", response);
1276 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1277 	fb_mmc_erase(cmd, response);
1278 #endif
1279 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
1280 	fb_nand_erase(cmd, response);
1281 #endif
1282 	fastboot_tx_write_str(response);
1283 }
1284 #endif
1285 
1286 struct cmd_dispatch_info {
1287 	char *cmd;
1288 	void (*cb)(struct usb_ep *ep, struct usb_request *req);
1289 };
1290 
1291 static const struct cmd_dispatch_info cmd_dispatch_info[] = {
1292 	{
1293 		.cmd = "reboot",
1294 		.cb = cb_reboot,
1295 	}, {
1296 		.cmd = "getvar:",
1297 		.cb = cb_getvar,
1298 	}, {
1299 		.cmd = "download:",
1300 		.cb = cb_download,
1301 	}, {
1302 		.cmd = "upload",
1303 		.cb = cb_upload,
1304 	}, {
1305 		.cmd = "boot",
1306 		.cb = cb_boot,
1307 	}, {
1308 		.cmd = "continue",
1309 		.cb = cb_continue,
1310 	}, {
1311 		.cmd = "set_active",
1312 		.cb = cb_set_active,
1313 	},
1314 #ifdef CONFIG_FASTBOOT_FLASH
1315 	{
1316 		.cmd = "flashing",
1317 		.cb = cb_flashing,
1318 	},
1319 	{
1320 		.cmd = "flash",
1321 		.cb = cb_flash,
1322 	}, {
1323 		.cmd = "erase",
1324 		.cb = cb_erase,
1325 	},
1326 #endif
1327 	{
1328 		.cmd = "oem",
1329 		.cb = cb_oem,
1330 	},
1331 };
1332 
1333 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
1334 {
1335 	char *cmdbuf = req->buf;
1336 	void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
1337 	int i;
1338 
1339 	if (req->status != 0 || req->length == 0)
1340 		return;
1341 
1342 	for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
1343 		if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
1344 			func_cb = cmd_dispatch_info[i].cb;
1345 			break;
1346 		}
1347 	}
1348 
1349 	if (!func_cb) {
1350 		pr_err("unknown command: %.*s", req->actual, cmdbuf);
1351 		fastboot_tx_write_str("FAILunknown command");
1352 	} else {
1353 		if (req->actual < req->length) {
1354 			u8 *buf = (u8 *)req->buf;
1355 			buf[req->actual] = 0;
1356 			func_cb(ep, req);
1357 		} else {
1358 			pr_err("buffer overflow");
1359 			fastboot_tx_write_str("FAILbuffer overflow");
1360 		}
1361 	}
1362 
1363 	*cmdbuf = '\0';
1364 	req->actual = 0;
1365 	usb_ep_queue(ep, req, 0);
1366 }
1367