xref: /rk3399_rockchip-uboot/drivers/usb/gadget/f_fastboot.c (revision bc04a3dd9a41813372820ba50655022a6a28bfbf)
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 #include <boot_rkimg.h>
41 #include <optee_include/tee_client_api.h>
42 
43 #define FASTBOOT_VERSION		"0.4"
44 
45 #define FASTBOOT_INTERFACE_CLASS	0xff
46 #define FASTBOOT_INTERFACE_SUB_CLASS	0x42
47 #define FASTBOOT_INTERFACE_PROTOCOL	0x03
48 
49 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0  (0x0200)
50 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1  (0x0040)
51 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE      (0x0040)
52 
53 #define EP_BUFFER_SIZE			4096
54 #define SLEEP_COUNT 20000
55 #define MAX_PART_NUM_STR_SIZE 4
56 #define PARTITION_TYPE_STRINGS "partition-type"
57 
58 /*
59  * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
60  * (64 or 512 or 1024), else we break on certain controllers like DWC3
61  * that expect bulk OUT requests to be divisible by maxpacket size.
62  */
63 
64 struct f_fastboot {
65 	struct usb_function usb_function;
66 
67 	/* IN/OUT EP's and corresponding requests */
68 	struct usb_ep *in_ep, *out_ep;
69 	struct usb_request *in_req, *out_req;
70 };
71 
72 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
73 {
74 	return container_of(f, struct f_fastboot, usb_function);
75 }
76 
77 static struct f_fastboot *fastboot_func;
78 static unsigned int download_size;
79 static unsigned int download_bytes;
80 static unsigned int upload_size;
81 static unsigned int upload_bytes;
82 static bool start_upload;
83 static unsigned intthread_wakeup_needed;
84 
85 static struct usb_endpoint_descriptor fs_ep_in = {
86 	.bLength            = USB_DT_ENDPOINT_SIZE,
87 	.bDescriptorType    = USB_DT_ENDPOINT,
88 	.bEndpointAddress   = USB_DIR_IN,
89 	.bmAttributes       = USB_ENDPOINT_XFER_BULK,
90 	.wMaxPacketSize     = cpu_to_le16(64),
91 };
92 
93 static struct usb_endpoint_descriptor fs_ep_out = {
94 	.bLength		= USB_DT_ENDPOINT_SIZE,
95 	.bDescriptorType	= USB_DT_ENDPOINT,
96 	.bEndpointAddress	= USB_DIR_OUT,
97 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
98 	.wMaxPacketSize		= cpu_to_le16(64),
99 };
100 
101 static struct usb_endpoint_descriptor hs_ep_in = {
102 	.bLength		= USB_DT_ENDPOINT_SIZE,
103 	.bDescriptorType	= USB_DT_ENDPOINT,
104 	.bEndpointAddress	= USB_DIR_IN,
105 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
106 	.wMaxPacketSize		= cpu_to_le16(512),
107 };
108 
109 static struct usb_endpoint_descriptor hs_ep_out = {
110 	.bLength		= USB_DT_ENDPOINT_SIZE,
111 	.bDescriptorType	= USB_DT_ENDPOINT,
112 	.bEndpointAddress	= USB_DIR_OUT,
113 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
114 	.wMaxPacketSize		= cpu_to_le16(512),
115 };
116 
117 static struct usb_endpoint_descriptor ss_ep_in = {
118 	.bLength		= USB_DT_ENDPOINT_SIZE,
119 	.bDescriptorType	= USB_DT_ENDPOINT,
120 	.bEndpointAddress	= USB_DIR_IN,
121 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
122 	.wMaxPacketSize		= cpu_to_le16(1024),
123 };
124 
125 static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = {
126 	.bLength		= sizeof(ss_ep_in_comp_desc),
127 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
128 	/* .bMaxBurst		= DYNAMIC, */
129 };
130 
131 static struct usb_endpoint_descriptor ss_ep_out = {
132 	.bLength		= USB_DT_ENDPOINT_SIZE,
133 	.bDescriptorType	= USB_DT_ENDPOINT,
134 	.bEndpointAddress	= USB_DIR_OUT,
135 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
136 	.wMaxPacketSize		= cpu_to_le16(1024),
137 };
138 
139 static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = {
140 	.bLength		= sizeof(ss_ep_out_comp_desc),
141 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
142 	/* .bMaxBurst		= DYNAMIC, */
143 };
144 
145 static struct usb_interface_descriptor interface_desc = {
146 	.bLength		= USB_DT_INTERFACE_SIZE,
147 	.bDescriptorType	= USB_DT_INTERFACE,
148 	.bInterfaceNumber	= 0x00,
149 	.bAlternateSetting	= 0x00,
150 	.bNumEndpoints		= 0x02,
151 	.bInterfaceClass	= FASTBOOT_INTERFACE_CLASS,
152 	.bInterfaceSubClass	= FASTBOOT_INTERFACE_SUB_CLASS,
153 	.bInterfaceProtocol	= FASTBOOT_INTERFACE_PROTOCOL,
154 };
155 
156 static struct usb_descriptor_header *fb_fs_function[] = {
157 	(struct usb_descriptor_header *)&interface_desc,
158 	(struct usb_descriptor_header *)&fs_ep_in,
159 	(struct usb_descriptor_header *)&fs_ep_out,
160 };
161 
162 static struct usb_descriptor_header *fb_hs_function[] = {
163 	(struct usb_descriptor_header *)&interface_desc,
164 	(struct usb_descriptor_header *)&hs_ep_in,
165 	(struct usb_descriptor_header *)&hs_ep_out,
166 	NULL,
167 };
168 
169 static struct usb_descriptor_header *fb_ss_function[] = {
170 	(struct usb_descriptor_header *)&interface_desc,
171 	(struct usb_descriptor_header *)&ss_ep_in,
172 	(struct usb_descriptor_header *)&ss_ep_in_comp_desc,
173 	(struct usb_descriptor_header *)&ss_ep_out,
174 	(struct usb_descriptor_header *)&ss_ep_out_comp_desc,
175 	NULL,
176 };
177 
178 static struct usb_endpoint_descriptor *
179 fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
180 	   struct usb_endpoint_descriptor *hs,
181 	   struct usb_endpoint_descriptor *ss,
182 	   struct usb_ss_ep_comp_descriptor *comp_desc,
183 	   struct usb_ep *ep)
184 {
185 	struct usb_endpoint_descriptor *speed_desc = NULL;
186 
187 	/* select desired speed */
188 	switch (g->speed) {
189 	case USB_SPEED_SUPER:
190 		if (gadget_is_superspeed(g)) {
191 			speed_desc = ss;
192 			ep->comp_desc = comp_desc;
193 			break;
194 		}
195 		/* else: Fall trough */
196 	case USB_SPEED_HIGH:
197 		if (gadget_is_dualspeed(g)) {
198 			speed_desc = hs;
199 			break;
200 		}
201 		/* else: fall through */
202 	default:
203 		speed_desc = fs;
204 	}
205 
206 	return speed_desc;
207 }
208 
209 /*
210  * static strings, in UTF-8
211  */
212 static const char fastboot_name[] = "Android Fastboot";
213 
214 static struct usb_string fastboot_string_defs[] = {
215 	[0].s = fastboot_name,
216 	{  }			/* end of list */
217 };
218 
219 static struct usb_gadget_strings stringtab_fastboot = {
220 	.language	= 0x0409,	/* en-us */
221 	.strings	= fastboot_string_defs,
222 };
223 
224 static struct usb_gadget_strings *fastboot_strings[] = {
225 	&stringtab_fastboot,
226 	NULL,
227 };
228 
229 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
230 static int strcmp_l1(const char *s1, const char *s2);
231 static void wakeup_thread(void)
232 {
233 	intthread_wakeup_needed = false;
234 }
235 
236 static void busy_indicator(void)
237 {
238 	static int state;
239 
240 	switch (state) {
241 	case 0:
242 		puts("\r|"); break;
243 	case 1:
244 		puts("\r/"); break;
245 	case 2:
246 		puts("\r-"); break;
247 	case 3:
248 		puts("\r\\"); break;
249 	case 4:
250 		puts("\r|"); break;
251 	case 5:
252 		puts("\r/"); break;
253 	case 6:
254 		puts("\r-"); break;
255 	case 7:
256 		puts("\r\\"); break;
257 	default:
258 		state = 0;
259 	}
260 	if (state++ == 8)
261 		state = 0;
262 }
263 
264 static int fb_get_fstype(const char *ifname, const int part_num,
265 			 const char **fs_type)
266 {
267 	char part_num_str[MAX_PART_NUM_STR_SIZE] = {0};
268 
269 	snprintf(part_num_str, ARRAY_SIZE(part_num_str), ":%x", part_num);
270 
271 	if (fs_set_blk_dev(ifname, part_num_str, FS_TYPE_ANY))
272 		return -1;
273 
274 	if (fs_get_fstype(fs_type))
275 		return -1;
276 
277 	return 0;
278 }
279 
280 static int sleep_thread(void)
281 {
282 	int rc = 0;
283 	int i = 0, k = 0;
284 
285 	/* Wait until a signal arrives or we are woken up */
286 	for (;;) {
287 		if (!intthread_wakeup_needed)
288 			break;
289 
290 		if (++i == SLEEP_COUNT) {
291 			busy_indicator();
292 			i = 0;
293 			k++;
294 		}
295 
296 		if (k == 10) {
297 			/* Handle CTRL+C */
298 			if (ctrlc())
299 				return -EPIPE;
300 
301 			/* Check cable connection */
302 			if (!g_dnl_board_usb_cable_connected())
303 				return -EIO;
304 
305 			k = 0;
306 		}
307 
308 		usb_gadget_handle_interrupts(0);
309 	}
310 	intthread_wakeup_needed = true;
311 	return rc;
312 }
313 
314 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
315 {
316 	int status = req->status;
317 
318 	wakeup_thread();
319 	if (!status)
320 		return;
321 	printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual);
322 }
323 
324 static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
325 {
326 	int id;
327 	struct usb_gadget *gadget = c->cdev->gadget;
328 	struct f_fastboot *f_fb = func_to_fastboot(f);
329 	const char *s;
330 
331 	/* DYNAMIC interface numbers assignments */
332 	id = usb_interface_id(c, f);
333 	if (id < 0)
334 		return id;
335 	interface_desc.bInterfaceNumber = id;
336 
337 	id = usb_string_id(c->cdev);
338 	if (id < 0)
339 		return id;
340 	fastboot_string_defs[0].id = id;
341 	interface_desc.iInterface = id;
342 
343 	f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in);
344 	if (!f_fb->in_ep)
345 		return -ENODEV;
346 	f_fb->in_ep->driver_data = c->cdev;
347 
348 	f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out);
349 	if (!f_fb->out_ep)
350 		return -ENODEV;
351 	f_fb->out_ep->driver_data = c->cdev;
352 
353 	f->descriptors = fb_fs_function;
354 
355 	if (gadget_is_dualspeed(gadget)) {
356 		/* Assume endpoint addresses are the same for both speeds */
357 		hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
358 		hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
359 		/* copy HS descriptors */
360 		f->hs_descriptors = fb_hs_function;
361 	}
362 
363 	if (gadget_is_superspeed(gadget)) {
364 		/* Assume endpoint addresses are the same as full speed */
365 		ss_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
366 		ss_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
367 		/* copy SS descriptors */
368 		f->ss_descriptors = fb_ss_function;
369 	}
370 
371 	s = env_get("serial#");
372 	if (s)
373 		g_dnl_set_serialnumber((char *)s);
374 
375 	return 0;
376 }
377 
378 static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
379 {
380 	memset(fastboot_func, 0, sizeof(*fastboot_func));
381 }
382 
383 static void fastboot_disable(struct usb_function *f)
384 {
385 	struct f_fastboot *f_fb = func_to_fastboot(f);
386 
387 	usb_ep_disable(f_fb->out_ep);
388 	usb_ep_disable(f_fb->in_ep);
389 
390 	if (f_fb->out_req) {
391 		free(f_fb->out_req->buf);
392 		usb_ep_free_request(f_fb->out_ep, f_fb->out_req);
393 		f_fb->out_req = NULL;
394 	}
395 	if (f_fb->in_req) {
396 		free(f_fb->in_req->buf);
397 		usb_ep_free_request(f_fb->in_ep, f_fb->in_req);
398 		f_fb->in_req = NULL;
399 	}
400 }
401 
402 static struct usb_request *fastboot_start_ep(struct usb_ep *ep)
403 {
404 	struct usb_request *req;
405 
406 	req = usb_ep_alloc_request(ep, 0);
407 	if (!req)
408 		return NULL;
409 
410 	req->length = EP_BUFFER_SIZE;
411 	req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE);
412 	if (!req->buf) {
413 		usb_ep_free_request(ep, req);
414 		return NULL;
415 	}
416 
417 	memset(req->buf, 0, req->length);
418 	return req;
419 }
420 
421 static int fastboot_set_alt(struct usb_function *f,
422 			    unsigned interface, unsigned alt)
423 {
424 	int ret;
425 	struct usb_composite_dev *cdev = f->config->cdev;
426 	struct usb_gadget *gadget = cdev->gadget;
427 	struct f_fastboot *f_fb = func_to_fastboot(f);
428 	const struct usb_endpoint_descriptor *d;
429 
430 	debug("%s: func: %s intf: %d alt: %d\n",
431 	      __func__, f->name, interface, alt);
432 
433 	d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out, &ss_ep_out,
434 		       &ss_ep_out_comp_desc, f_fb->out_ep);
435 	ret = usb_ep_enable(f_fb->out_ep, d);
436 	if (ret) {
437 		puts("failed to enable out ep\n");
438 		return ret;
439 	}
440 
441 	f_fb->out_req = fastboot_start_ep(f_fb->out_ep);
442 	if (!f_fb->out_req) {
443 		puts("failed to alloc out req\n");
444 		ret = -EINVAL;
445 		goto err;
446 	}
447 	f_fb->out_req->complete = rx_handler_command;
448 
449 	d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in, &ss_ep_in,
450 		       &ss_ep_in_comp_desc, f_fb->in_ep);
451 	ret = usb_ep_enable(f_fb->in_ep, d);
452 	if (ret) {
453 		puts("failed to enable in ep\n");
454 		goto err;
455 	}
456 
457 	f_fb->in_req = fastboot_start_ep(f_fb->in_ep);
458 	if (!f_fb->in_req) {
459 		puts("failed alloc req in\n");
460 		ret = -EINVAL;
461 		goto err;
462 	}
463 	f_fb->in_req->complete = fastboot_complete;
464 
465 	ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0);
466 	if (ret)
467 		goto err;
468 
469 	return 0;
470 err:
471 	fastboot_disable(f);
472 	return ret;
473 }
474 
475 static int fastboot_add(struct usb_configuration *c)
476 {
477 	struct f_fastboot *f_fb = fastboot_func;
478 	int status;
479 
480 	debug("%s: cdev: 0x%p\n", __func__, c->cdev);
481 
482 	if (!f_fb) {
483 		f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));
484 		if (!f_fb)
485 			return -ENOMEM;
486 
487 		fastboot_func = f_fb;
488 		memset(f_fb, 0, sizeof(*f_fb));
489 	}
490 
491 	f_fb->usb_function.name = "f_fastboot";
492 	f_fb->usb_function.bind = fastboot_bind;
493 	f_fb->usb_function.unbind = fastboot_unbind;
494 	f_fb->usb_function.set_alt = fastboot_set_alt;
495 	f_fb->usb_function.disable = fastboot_disable;
496 	f_fb->usb_function.strings = fastboot_strings;
497 
498 	status = usb_add_function(c, &f_fb->usb_function);
499 	if (status) {
500 		free(f_fb);
501 		fastboot_func = f_fb;
502 	}
503 
504 	return status;
505 }
506 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
507 
508 static int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
509 {
510 	struct usb_request *in_req = fastboot_func->in_req;
511 	int ret;
512 
513 	memcpy(in_req->buf, buffer, buffer_size);
514 	in_req->length = buffer_size;
515 
516 	usb_ep_dequeue(fastboot_func->in_ep, in_req);
517 
518 	ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
519 	if (ret)
520 		printf("Error %d on queue\n", ret);
521 	return 0;
522 }
523 
524 static int fastboot_tx_write_str(const char *buffer)
525 {
526 	int ret;
527 
528 	ret = sleep_thread();
529 	if (ret < 0)
530 		printf("warning: 0x%x, usb transmission is abnormal!\n", ret);
531 
532 	return fastboot_tx_write(buffer, strlen(buffer));
533 }
534 
535 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
536 {
537 	do_reset(NULL, 0, 0, NULL);
538 }
539 
540 int __weak fb_set_reboot_flag(void)
541 {
542 	return -ENOSYS;
543 }
544 
545 static void cb_reboot(struct usb_ep *ep, struct usb_request *req)
546 {
547 	char *cmd = req->buf;
548 	if (!strcmp_l1("reboot-bootloader", cmd)) {
549 		if (fb_set_reboot_flag()) {
550 			fastboot_tx_write_str("FAILCannot set reboot flag");
551 			return;
552 		}
553 	}
554 	fastboot_func->in_req->complete = compl_do_reset;
555 	fastboot_tx_write_str("OKAY");
556 }
557 
558 static int strcmp_l1(const char *s1, const char *s2)
559 {
560 	if (!s1 || !s2)
561 		return -1;
562 	return strncmp(s1, s2, strlen(s1));
563 }
564 
565 struct name_string {
566 	const char *str;
567 	int expects_args;
568 	char delim;
569 };
570 
571 #define NAME_NO_ARGS(s)	{.str = s, .expects_args = 0}
572 #define NAME_ARGS(s, d)	{.str = s, .expects_args = 1, .delim = d}
573 
574 static size_t name_check_match(const char *str, size_t len,
575 			       const struct name_string *name)
576 {
577 	size_t str_len = strlen(name->str);
578 
579 	/* If name len is greater than input, return 0. */
580 	if (str_len > len)
581 		return 0;
582 
583 	/* If name str does not match input string, return 0. */
584 	if (memcmp(name->str, str, str_len))
585 		return 0;
586 
587 	if (name->expects_args) {
588 		/* string should have space for delim */
589 		if (len == str_len)
590 			return 0;
591 
592 		/* Check delim match */
593 		if (name->delim != str[str_len])
594 			return 0;
595 	} else {
596 		/* Name str len should match input len */
597 		if (str_len != len)
598 			return 0;
599 	}
600 
601 	return str_len + name->expects_args;
602 }
603 
604 static void fb_add_string(char *dst, size_t chars_left,
605 			  const char *str, const char *args)
606 {
607 	if (!str)
608 		return;
609 
610 	int ret = snprintf(dst, chars_left, str, args);
611 
612 	if (ret < 0)
613 		pr_err("snprintf is error!");
614 }
615 
616 static void fb_add_number(char *dst, size_t chars_left,
617 			  const char *format, size_t num)
618 {
619 	if (!format)
620 		return;
621 
622 	int ret = snprintf(dst, chars_left, format, num);
623 
624 	if (ret > chars_left)
625 		pr_err("snprintf is error!");
626 }
627 
628 static int fb_read_var(char *cmd, char *response,
629 		       fb_getvar_t var, size_t chars_left)
630 {
631 	const char *s;
632 	int ret = 0;
633 
634 	switch (var) {
635 	case FB_VERSION:
636 		fb_add_string(response, chars_left, FASTBOOT_VERSION, NULL);
637 		break;
638 	case FB_BOOTLOADER_VERSION:
639 		fb_add_string(response, chars_left, U_BOOT_VERSION, NULL);
640 		break;
641 	case FB_BASEBAND_VERSION:
642 		fb_add_string(response, chars_left, "N/A", NULL);
643 		break;
644 	case FB_PRODUCT:
645 		fb_add_string(response, chars_left, CONFIG_SYS_BOARD, NULL);
646 		break;
647 	case FB_SERIAL_NO:
648 		s = env_get("serial#");
649 		if (s)
650 			fb_add_string(response, chars_left, s, NULL);
651 		else
652 			ret = -1;
653 		break;
654 	case FB_SECURE:
655 		fb_add_string(response, chars_left, "yes", NULL);
656 		break;
657 	case FB_VARIANT:
658 		fb_add_string(response, chars_left, "userdebug", NULL);
659 		break;
660 	case FB_DWNLD_SIZE:
661 		fb_add_number(response, chars_left, "0x%08x",
662 			      CONFIG_FASTBOOT_BUF_SIZE);
663 		break;
664 	case FB_PART_SIZE:
665 	case FB_PART_TYPE: {
666 		char *part_name = cmd;
667 
668 		cmd = strsep(&part_name, ":");
669 		if (!cmd || !part_name) {
670 			fb_add_string(response, chars_left,
671 				      "argument Invalid!", NULL);
672 			ret = -1;
673 			break;
674 		}
675 
676 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
677 		disk_partition_t part_info;
678 		struct blk_desc *dev_desc;
679 		int part_num = -1;
680 		const char *fs_type = NULL;
681 
682 #ifdef CONFIG_RKIMG_BOOTLOADER
683 		dev_desc = rockchip_get_bootdev();
684 #else
685 		dev_desc = NULL;
686 #endif
687 		if (!dev_desc) {
688 			fb_add_string(response, chars_left,
689 				      "block device not found", NULL);
690 			ret = -1;
691 			break;
692 		}
693 
694 		part_num = part_get_info_by_name(dev_desc, part_name,
695 						 &part_info);
696 		if (part_num < 0) {
697 			fb_add_string(response, chars_left,
698 				      "partition not found", NULL);
699 			ret = -1;
700 		} else if (!strncmp(PARTITION_TYPE_STRINGS, cmd,
701 					strlen(PARTITION_TYPE_STRINGS))) {
702 			if (fb_get_fstype("mmc", part_num, &fs_type)) {
703 				fb_add_string(response, chars_left,
704 					      (char *)part_info.type, NULL);
705 			} else {
706 				fb_add_string(response, chars_left,
707 					      fs_type, NULL);
708 			}
709 		} else if (!strncmp("partition-size", cmd, 14)) {
710 			u64 part_size;
711 
712 			part_size = (uint64_t)part_info.size;
713 			snprintf(response, chars_left, "0x%llx",
714 				 part_size * dev_desc->blksz);
715 		}
716 #else
717 		fb_add_string(response, chars_left, "not implemented", NULL);
718 		ret = -1;
719 #endif
720 		break;
721 	}
722 	case FB_BLK_SIZE: {
723 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
724 		struct blk_desc *dev_desc;
725 
726 #ifdef CONFIG_RKIMG_BOOTLOADER
727 		dev_desc = rockchip_get_bootdev();
728 #else
729 		dev_desc = NULL;
730 #endif
731 		if (!dev_desc) {
732 			fb_add_string(response, chars_left,
733 				      "block device not found", NULL);
734 			ret = -1;
735 		} else {
736 			fb_add_number(response, chars_left,
737 				      "0x%lx", dev_desc->blksz);
738 		}
739 #else
740 		fb_add_string(response, chars_left, "not implemented", NULL);
741 		ret = -1;
742 #endif
743 		break;
744 	}
745 	case FB_ERASE_SIZE: {
746 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
747 		lbaint_t erase_grp_size;
748 
749 		erase_grp_size = fb_mmc_get_erase_grp_size();
750 		if (erase_grp_size < 0) {
751 			fb_add_string(response, chars_left,
752 				      "block device not found", NULL);
753 			ret = -1;
754 		} else {
755 			fb_add_number(response, chars_left, "0x"LBAF"",
756 				      erase_grp_size);
757 		}
758 #else
759 		fb_add_string(response, chars_left, "not implemented", NULL);
760 		ret = -1;
761 #endif
762 		break;
763 	}
764 	case FB_UNLOCKED: {
765 #ifdef CONFIG_RK_AVB_LIBAVB_USER
766 		uint8_t flash_lock_state = 0;
767 
768 		if (rk_avb_read_flash_lock_state(&flash_lock_state))
769 			fb_add_string(response, chars_left, "yes", NULL);
770 		else
771 			fb_add_string(response, chars_left, "no", NULL);
772 #else
773 		fb_add_string(response, chars_left, "not implemented", NULL);
774 		ret = -1;
775 #endif
776 		break;
777 	}
778 	case  FB_OFF_MODE_CHARGE: {
779 		fb_add_string(response, chars_left, "not implemented", NULL);
780 		break;
781 	}
782 	case FB_BATT_VOLTAGE: {
783 		fb_add_string(response, chars_left, "not implemented", NULL);
784 		break;
785 	}
786 	case FB_BATT_SOC_OK: {
787 		fb_add_string(response, chars_left, "no", NULL);
788 		break;
789 	}
790 #ifdef CONFIG_RK_AVB_LIBAVB_USER
791 	case FB_HAS_COUNT: {
792 		char slot_count[2];
793 		char temp;
794 
795 		slot_count[1] = '\0';
796 		if (rk_avb_read_slot_count(&temp) < 0) {
797 			fb_add_number(response, chars_left, "%d", 0);
798 			ret = -1;
799 			break;
800 		}
801 		slot_count[0] = temp + 0x30;
802 		fb_add_string(response, chars_left, slot_count, NULL);
803 		break;
804 	}
805 	case FB_HAS_SLOT: {
806 		char *part_name = cmd;
807 		int has_slot = -1;
808 
809 		cmd = strsep(&part_name, ":");
810 		if (!cmd || !part_name) {
811 			fb_add_string(response, chars_left,
812 				      "argument Invalid!", NULL);
813 			ret = -1;
814 			break;
815 		}
816 
817 		has_slot = rk_avb_get_part_has_slot_info(part_name);
818 		if (has_slot < 0)
819 			fb_add_string(response, chars_left, "no", NULL);
820 		else
821 			fb_add_string(response, chars_left, "yes", NULL);
822 		break;
823 	}
824 	case FB_CURR_SLOT: {
825 		char slot_surrent[8] = {0};
826 
827 		if (!rk_avb_get_current_slot(slot_surrent)) {
828 			fb_add_string(response, chars_left,
829 				      slot_surrent + 1, NULL);
830 		} else {
831 			fb_add_string(response, chars_left, "get error", NULL);
832 			ret = -1;
833 		}
834 		break;
835 	}
836 	case FB_SLOT_SUFFIXES: {
837 		char slot_suffixes_temp[4] = {0};
838 		char slot_suffixes[9] = {0};
839 		int slot_cnt = 0;
840 
841 		rk_avb_read_slot_suffixes(slot_suffixes_temp);
842 		while (slot_suffixes_temp[slot_cnt] != '\0') {
843 			slot_suffixes[slot_cnt * 2]
844 				= slot_suffixes_temp[slot_cnt];
845 			slot_suffixes[slot_cnt * 2 + 1] = ',';
846 			slot_cnt++;
847 		}
848 
849 		slot_suffixes[(slot_cnt - 1) * 2 + 1] = '\0';
850 		fb_add_string(response, chars_left, slot_suffixes, NULL);
851 		break;
852 	}
853 	case FB_SLOT_SUCCESSFUL:{
854 		char *slot_name = cmd;
855 		AvbABData ab_info;
856 
857 		cmd = strsep(&slot_name, ":");
858 		if (!cmd || !slot_name) {
859 			fb_add_string(response, chars_left,
860 				      "argument Invalid!", NULL);
861 			ret = -1;
862 			break;
863 		}
864 
865 		if (rk_avb_get_ab_info(&ab_info) < 0) {
866 			fb_add_string(response, chars_left,
867 				      "get ab info failed!", NULL);
868 			ret = -1;
869 			break;
870 		}
871 
872 		if (!strcmp(slot_name, "a")) {
873 			if (ab_info.slots[0].successful_boot)
874 				fb_add_string(response, chars_left,
875 					      "yes", NULL);
876 			else
877 				fb_add_string(response, chars_left,
878 					      "no", NULL);
879 		} else if (!strcmp(slot_name, "b")) {
880 			if (ab_info.slots[1].successful_boot)
881 				fb_add_string(response, chars_left,
882 					      "yes", NULL);
883 			else
884 				fb_add_string(response, chars_left,
885 					      "no", NULL);
886 		} else {
887 			fb_add_string(response, chars_left, "no", NULL);
888 		}
889 		break;
890 	}
891 	case FB_SLOT_UNBOOTABLE: {
892 		char *slot_name = cmd;
893 		AvbABData ab_info;
894 
895 		cmd = strsep(&slot_name, ":");
896 
897 		if (!cmd || !slot_name) {
898 			fb_add_string(response, chars_left,
899 				      "argument Invalid!", NULL);
900 			ret = -1;
901 			break;
902 		}
903 
904 		if (rk_avb_get_ab_info(&ab_info) < 0) {
905 			fb_add_string(response, chars_left,
906 				      "get ab info failed!", NULL);
907 			ret = -1;
908 			break;
909 		}
910 
911 		if (!strcmp(slot_name, "a")) {
912 			if (!ab_info.slots[0].successful_boot &&
913 			    !ab_info.slots[0].tries_remaining &&
914 			    !ab_info.slots[0].priority)
915 				fb_add_string(response, chars_left,
916 					      "yes", NULL);
917 			else
918 				fb_add_string(response, chars_left, "no", NULL);
919 		} else if (!strcmp(slot_name, "b")) {
920 			if (!ab_info.slots[1].successful_boot &&
921 			    !ab_info.slots[1].tries_remaining &&
922 			    !ab_info.slots[1].priority)
923 				fb_add_string(response, chars_left,
924 					      "yes", NULL);
925 			else
926 				fb_add_string(response, chars_left, "no", NULL);
927 		} else {
928 			fb_add_string(response, chars_left, "no", NULL);
929 		}
930 		break;
931 	}
932 	case FB_SLOT_RETRY_COUNT: {
933 		char *slot_name = cmd;
934 		AvbABData ab_info;
935 
936 		cmd = strsep(&slot_name, ":");
937 		if (!cmd || !slot_name) {
938 			fb_add_string(response, chars_left,
939 				      "argument Invalid!", NULL);
940 			ret = -1;
941 			break;
942 		}
943 
944 		if (rk_avb_get_ab_info(&ab_info) < 0) {
945 			fb_add_string(response, chars_left,
946 				      "get ab info failed!", NULL);
947 			ret = -1;
948 			break;
949 		}
950 
951 		if (!strcmp(slot_name, "a")) {
952 			fb_add_number(response, chars_left,
953 				      "%d", ab_info.slots[0].tries_remaining);
954 		} else if (!strcmp(slot_name, "b")) {
955 			fb_add_number(response, chars_left, "%d",
956 				      ab_info.slots[1].tries_remaining);
957 
958 		} else {
959 			strcpy(response, "FAILno");
960 		}
961 		break;
962 	}
963 	case FB_AT_VBST: {
964 		char vbst[VBOOT_STATE_SIZE] = {0};
965 		char *p_vbst;
966 
967 		strcpy(response, "INFO");
968 		rk_avb_get_at_vboot_state(vbst);
969 		p_vbst = vbst;
970 		do {
971 			cmd = strsep(&p_vbst, "\n");
972 			if (strlen(cmd) > 0) {
973 				memcpy(&response[4], cmd, chars_left);
974 				fastboot_tx_write_str(response);
975 			}
976 		} while (strlen(cmd));
977 		break;
978 	}
979 #endif
980 #ifdef CONFIG_OPTEE_CLIENT
981 	case FB_AT_DH: {
982 		char dhbuf[ATTEST_DH_SIZE];
983 		uint32_t dh_len = ATTEST_DH_SIZE;
984 		uint32_t res = trusty_attest_dh((uint8_t *)dhbuf, &dh_len);
985 
986 		if (res) {
987 			fb_add_string(response, chars_left, "dh not set", NULL);
988 			ret = -1;
989 		} else {
990 			fb_add_string(response, chars_left, dhbuf, NULL);
991 		}
992 		break;
993 	}
994 	case FB_AT_UUID: {
995 		char uuid[ATTEST_UUID_SIZE] = {0};
996 		uint32_t uuid_len = ATTEST_UUID_SIZE;
997 		uint32_t res = trusty_attest_uuid((uint8_t *)uuid, &uuid_len);
998 
999 		uuid[ATTEST_UUID_SIZE - 1] = 0;
1000 		if (res) {
1001 			fb_add_string(response, chars_left, "dh not set", NULL);
1002 			ret = -1;
1003 		} else {
1004 			fb_add_string(response, chars_left, uuid, NULL);
1005 		}
1006 		break;
1007 	}
1008 #endif
1009 	default: {
1010 			char *envstr;
1011 
1012 			envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1);
1013 			if (!envstr) {
1014 				fb_add_string(response, chars_left,
1015 					      "malloc error", NULL);
1016 				ret = -1;
1017 				break;
1018 			}
1019 
1020 			sprintf(envstr, "fastboot.%s", cmd);
1021 			s = env_get(envstr);
1022 			if (s) {
1023 				strncat(response, s, chars_left);
1024 			} else {
1025 				printf("WARNING: unknown variable: %s\n", cmd);
1026 				fb_add_string(response, chars_left,
1027 					      "not implemented", NULL);
1028 			}
1029 
1030 			free(envstr);
1031 			break;
1032 		}
1033 	}
1034 
1035 	return ret;
1036 }
1037 
1038 static const struct {
1039 	/*
1040 	 *any changes to this array require an update to the corresponding
1041 	 *enum in fastboot.h
1042 	 */
1043 	struct name_string name;
1044 	fb_getvar_t var;
1045 } getvar_table[] = {
1046 	{ NAME_NO_ARGS("version"), FB_VERSION},
1047 	{ NAME_NO_ARGS("version-bootloader"), FB_BOOTLOADER_VERSION},
1048 	{ NAME_NO_ARGS("version-baseband"), FB_BASEBAND_VERSION},
1049 	{ NAME_NO_ARGS("product"), FB_PRODUCT},
1050 	{ NAME_NO_ARGS("serialno"), FB_SERIAL_NO},
1051 	{ NAME_NO_ARGS("secure"), FB_SECURE},
1052 	{ NAME_NO_ARGS("max-download-size"), FB_DWNLD_SIZE},
1053 	{ NAME_NO_ARGS("logical-block-size"), FB_BLK_SIZE},
1054 	{ NAME_NO_ARGS("erase-block-size"), FB_ERASE_SIZE},
1055 	{ NAME_ARGS("partition-type", ':'), FB_PART_TYPE},
1056 	{ NAME_ARGS("partition-size", ':'), FB_PART_SIZE},
1057 	{ NAME_NO_ARGS("unlocked"), FB_UNLOCKED},
1058 	{ NAME_NO_ARGS("off-mode-charge"), FB_OFF_MODE_CHARGE},
1059 	{ NAME_NO_ARGS("battery-voltage"), FB_BATT_VOLTAGE},
1060 	{ NAME_NO_ARGS("variant"), FB_VARIANT},
1061 	{ NAME_NO_ARGS("battery-soc-ok"), FB_BATT_SOC_OK},
1062 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1063 	/* Slots related */
1064 	{ NAME_NO_ARGS("slot-count"), FB_HAS_COUNT},
1065 	{ NAME_ARGS("has-slot", ':'), FB_HAS_SLOT},
1066 	{ NAME_NO_ARGS("current-slot"), FB_CURR_SLOT},
1067 	{ NAME_NO_ARGS("slot-suffixes"), FB_SLOT_SUFFIXES},
1068 	{ NAME_ARGS("slot-successful", ':'), FB_SLOT_SUCCESSFUL},
1069 	{ NAME_ARGS("slot-unbootable", ':'), FB_SLOT_UNBOOTABLE},
1070 	{ NAME_ARGS("slot-retry-count", ':'), FB_SLOT_RETRY_COUNT},
1071 	{ NAME_NO_ARGS("at-vboot-state"), FB_AT_VBST},
1072 #endif
1073 	/*
1074 	 * OEM specific :
1075 	 * Spec says names starting with lowercase letter are reserved.
1076 	 */
1077 #ifdef CONFIG_OPTEE_CLIENT
1078 	{ NAME_NO_ARGS("at-attest-dh"), FB_AT_DH},
1079 	{ NAME_NO_ARGS("at-attest-uuid"), FB_AT_UUID},
1080 #endif
1081 };
1082 
1083 static int fb_getvar_single(char *cmd, char *response, size_t chars_left)
1084 {
1085 	int i;
1086 	size_t match_len = 0;
1087 	size_t len = strlen(cmd);
1088 
1089 	for (i = 0; i < ARRAY_SIZE(getvar_table); i++) {
1090 		match_len = name_check_match(cmd, len, &getvar_table[i].name);
1091 		if (match_len)
1092 			break;
1093 	}
1094 
1095 	if (match_len == 0) {
1096 		fb_add_string(response, chars_left, "unknown variable", NULL);
1097 		return -1;
1098 	}
1099 
1100 	if (fb_read_var(cmd, response, getvar_table[i].var, chars_left) < 0)
1101 		return -1;
1102 
1103 	return 0;
1104 }
1105 
1106 static void fb_getvar_all(void)
1107 {
1108 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1109 	char resp_tmp[FASTBOOT_RESPONSE_LEN] = {0};
1110 	char *actual_resp;
1111 	size_t chars_left;
1112 	int i, p;
1113 	disk_partition_t part_info;
1114 	struct blk_desc *dev_desc;
1115 
1116 	strcpy(response, "INFO");
1117 	chars_left = sizeof(response) - strlen(response) - 1;
1118 	actual_resp = response + strlen(response);
1119 
1120 	for (i = 0; i < ARRAY_SIZE(getvar_table); i++) {
1121 		fb_getvar_t var = getvar_table[i].var;
1122 
1123 		switch (var) {
1124 		case FB_PART_TYPE:
1125 		case FB_PART_SIZE: {
1126 			const char *fs_type = NULL;
1127 #ifdef CONFIG_RKIMG_BOOTLOADER
1128 			dev_desc = rockchip_get_bootdev();
1129 #else
1130 			dev_desc = NULL;
1131 #endif
1132 			if (!dev_desc) {
1133 				fb_add_string(actual_resp, chars_left,
1134 					      "%s:block device not found",
1135 					      getvar_table[i].name.str);
1136 				fastboot_tx_write_str(response);
1137 				break;
1138 			}
1139 
1140 			for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
1141 				if (part_get_info(dev_desc, p,
1142 						  &part_info) < 0) {
1143 					break;
1144 				}
1145 
1146 				if (var == FB_PART_TYPE) {
1147 					fs_type = NULL;
1148 					if (fb_get_fstype("mmc", p,
1149 							  &fs_type)) {
1150 						fb_add_string(
1151 							resp_tmp,
1152 							FASTBOOT_RESPONSE_LEN,
1153 							(char *)part_info.type,
1154 							NULL);
1155 					} else {
1156 						fb_add_string(
1157 							resp_tmp,
1158 							FASTBOOT_RESPONSE_LEN,
1159 							fs_type,
1160 							NULL);
1161 					}
1162 
1163 					snprintf(actual_resp,
1164 						 chars_left,
1165 						 "%s:%s:%s",
1166 						 getvar_table[i].name.str,
1167 						 part_info.name,
1168 						 resp_tmp);
1169 				} else {
1170 					uint64_t part_size;
1171 
1172 					part_size = (uint64_t)part_info.size;
1173 					snprintf(actual_resp,
1174 						 chars_left,
1175 						 "%s:%s:0x%llx",
1176 						 getvar_table[i].name.str,
1177 						 part_info.name,
1178 						 part_size * dev_desc->blksz);
1179 				}
1180 				fastboot_tx_write_str(response);
1181 			}
1182 			break;
1183 		}
1184 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1185 		case FB_HAS_SLOT: {
1186 			uchar *ptr_name_tmp;
1187 			char c = '_';
1188 			int has_slot = -1;
1189 
1190 #ifdef CONFIG_RKIMG_BOOTLOADER
1191 			dev_desc = rockchip_get_bootdev();
1192 #else
1193 			dev_desc = NULL;
1194 #endif
1195 			if (!dev_desc) {
1196 				fb_add_string(actual_resp, chars_left,
1197 					      "%s:block device not found",
1198 					      getvar_table[i].name.str);
1199 				fastboot_tx_write_str(response);
1200 				break;
1201 			}
1202 
1203 			for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
1204 				if (part_get_info(dev_desc, p,
1205 						  &part_info) < 0) {
1206 					break;
1207 				} else {
1208 					ptr_name_tmp = (uchar *)strrchr(
1209 						(char *)part_info.name, c);
1210 					if (ptr_name_tmp &&
1211 					    part_info.name[ptr_name_tmp -
1212 						part_info.name + 2] == '\0')
1213 						fb_add_string(
1214 							resp_tmp,
1215 							ptr_name_tmp -
1216 							part_info.name + 1,
1217 							(char *)part_info.name,
1218 							NULL);
1219 					else
1220 						strcpy(resp_tmp,
1221 						       (char *)part_info.name);
1222 
1223 					has_slot = rk_avb_get_part_has_slot_info(
1224 						resp_tmp);
1225 					if (has_slot < 0) {
1226 						snprintf(actual_resp,
1227 							 chars_left,
1228 							 "%s:%s:no",
1229 							 getvar_table[i].name.str,
1230 							 resp_tmp);
1231 					} else {
1232 						snprintf(actual_resp,
1233 							 chars_left,
1234 							 "%s:%s:yes",
1235 							 getvar_table[i].name.str,
1236 							 resp_tmp);
1237 						p++;
1238 					}
1239 
1240 					fastboot_tx_write_str(response);
1241 				}
1242 			}
1243 			break;
1244 		}
1245 
1246 		case FB_SLOT_SUCCESSFUL: {
1247 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1248 			AvbABData ab_info;
1249 
1250 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1251 				fb_add_string(actual_resp,
1252 					      chars_left,
1253 					      "%s:get ab info failed!",
1254 					      getvar_table[i].name.str);
1255 				fastboot_tx_write_str(response);
1256 				break;
1257 			}
1258 
1259 			if (ab_info.slots[0].successful_boot)
1260 				fb_add_string(actual_resp, chars_left,
1261 					      "%s:a:yes",
1262 					      getvar_table[i].name.str);
1263 			else
1264 				fb_add_string(actual_resp, chars_left,
1265 					      "%s:a:no",
1266 					      getvar_table[i].name.str);
1267 			fastboot_tx_write_str(response);
1268 
1269 			if (ab_info.slots[1].successful_boot)
1270 				fb_add_string(actual_resp, chars_left,
1271 					      "%s:b:yes",
1272 					      getvar_table[i].name.str);
1273 			else
1274 				fb_add_string(actual_resp, chars_left,
1275 					      "%s:b:no",
1276 					      getvar_table[i].name.str);
1277 			fastboot_tx_write_str(response);
1278 #else
1279 			fb_add_string(actual_resp, chars_left,
1280 				      "%s:not find ab info!",
1281 				      getvar_table[i].name.str);
1282 			fastboot_tx_write_str(response);
1283 #endif
1284 			break;
1285 		}
1286 
1287 		case FB_SLOT_UNBOOTABLE: {
1288 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1289 			AvbABData ab_info;
1290 
1291 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1292 				fb_add_string(actual_resp, chars_left,
1293 					      "%s:not find ab info!",
1294 					      getvar_table[i].name.str);
1295 				fastboot_tx_write_str(response);
1296 				break;
1297 			}
1298 
1299 			if (!ab_info.slots[0].successful_boot &&
1300 			    !ab_info.slots[0].tries_remaining &&
1301 			    !ab_info.slots[0].priority)
1302 				fb_add_string(actual_resp, chars_left,
1303 					      "%s:a:yes",
1304 					      getvar_table[i].name.str);
1305 			else
1306 				fb_add_string(actual_resp, chars_left,
1307 					      "%s:a:no",
1308 					      getvar_table[i].name.str);
1309 			fastboot_tx_write_str(response);
1310 
1311 			if (!ab_info.slots[1].successful_boot &&
1312 			    !ab_info.slots[1].tries_remaining &&
1313 			    !ab_info.slots[1].priority)
1314 				fb_add_string(actual_resp, chars_left,
1315 					      "%s:b:yes",
1316 					      getvar_table[i].name.str);
1317 			else
1318 				fb_add_string(actual_resp, chars_left,
1319 					      "%s:b:no",
1320 					      getvar_table[i].name.str);
1321 
1322 			fastboot_tx_write_str(response);
1323 #else
1324 			fb_add_string(actual_resp, chars_left,
1325 				      "%s:not find ab info!",
1326 				      getvar_table[i].name.str);
1327 			fastboot_tx_write_str(response);
1328 #endif
1329 			break;
1330 		}
1331 
1332 		case FB_SLOT_RETRY_COUNT: {
1333 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1334 			AvbABData ab_info;
1335 
1336 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1337 				fb_add_string(actual_resp, chars_left,
1338 					      "%s:not find ab info!",
1339 					      getvar_table[i].name.str);
1340 				fastboot_tx_write_str(response);
1341 				break;
1342 			}
1343 
1344 			snprintf(actual_resp, chars_left, "%s:a:%d",
1345 				 getvar_table[i].name.str,
1346 				 ab_info.slots[1].tries_remaining);
1347 			fastboot_tx_write_str(response);
1348 			snprintf(actual_resp, chars_left, "%s:b:%d",
1349 				 getvar_table[i].name.str,
1350 				 ab_info.slots[1].tries_remaining);
1351 			fastboot_tx_write_str(response);
1352 #else
1353 			fb_add_string(actual_resp, chars_left,
1354 				      "%s:not find ab info!",
1355 				      getvar_table[i].name.str);
1356 			fastboot_tx_write_str(response);
1357 #endif
1358 			break;
1359 		}
1360 #endif
1361 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1362 		case FB_AT_VBST:
1363 			break;
1364 #endif
1365 		default:
1366 			fb_getvar_single((char *)getvar_table[i].name.str,
1367 					 resp_tmp, FASTBOOT_RESPONSE_LEN);
1368 			snprintf(actual_resp, chars_left, "%s:%s",
1369 				 getvar_table[i].name.str, resp_tmp);
1370 			fastboot_tx_write_str(response);
1371 		}
1372 	}
1373 }
1374 
1375 static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
1376 {
1377 	char *cmd = req->buf;
1378 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1379 	const char *str_read_all = "all";
1380 	size_t len = 0;
1381 	size_t chars_left;
1382 
1383 	strsep(&cmd, ":");
1384 	if (!cmd) {
1385 		pr_err("missing variable");
1386 		fastboot_tx_write_str("FAILmissing var");
1387 		return;
1388 	}
1389 
1390 	len = strlen(cmd);
1391 	if (len == strlen(str_read_all) &&
1392 	    (strncmp(cmd, str_read_all, len) == 0)) {
1393 		fb_getvar_all();
1394 		fastboot_tx_write_str("OKAYDone!");
1395 	} else {
1396 		strcpy(response, "OKAY");
1397 		chars_left = sizeof(response) - strlen(response) - 1;
1398 
1399 		if (fb_getvar_single(cmd, &response[strlen(response)],
1400 				     chars_left) < 0) {
1401 			strcpy(cmd, "FAILunknown variable");
1402 			strncat(cmd, &response[strlen(response)], chars_left);
1403 			fastboot_tx_write_str(cmd);
1404 			return;
1405 		}
1406 		fastboot_tx_write_str(response);
1407 	}
1408 
1409 	return;
1410 }
1411 
1412 static unsigned int rx_bytes_expected(struct usb_ep *ep)
1413 {
1414 	int rx_remain = download_size - download_bytes;
1415 	unsigned int rem;
1416 	unsigned int maxpacket = ep->maxpacket;
1417 
1418 	if (rx_remain <= 0)
1419 		return 0;
1420 	else if (rx_remain > EP_BUFFER_SIZE)
1421 		return EP_BUFFER_SIZE;
1422 
1423 	/*
1424 	 * Some controllers e.g. DWC3 don't like OUT transfers to be
1425 	 * not ending in maxpacket boundary. So just make them happy by
1426 	 * always requesting for integral multiple of maxpackets.
1427 	 * This shouldn't bother controllers that don't care about it.
1428 	 */
1429 	rem = rx_remain % maxpacket;
1430 	if (rem > 0)
1431 		rx_remain = rx_remain + (maxpacket - rem);
1432 
1433 	return rx_remain;
1434 }
1435 
1436 #define BYTES_PER_DOT	0x20000
1437 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
1438 {
1439 	char response[FASTBOOT_RESPONSE_LEN];
1440 	unsigned int transfer_size = download_size - download_bytes;
1441 	const unsigned char *buffer = req->buf;
1442 	unsigned int buffer_size = req->actual;
1443 	unsigned int pre_dot_num, now_dot_num;
1444 
1445 	if (req->status != 0) {
1446 		printf("Bad status: %d\n", req->status);
1447 		return;
1448 	}
1449 
1450 	if (buffer_size < transfer_size)
1451 		transfer_size = buffer_size;
1452 
1453 	memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
1454 	       buffer, transfer_size);
1455 
1456 	pre_dot_num = download_bytes / BYTES_PER_DOT;
1457 	download_bytes += transfer_size;
1458 	now_dot_num = download_bytes / BYTES_PER_DOT;
1459 
1460 	if (pre_dot_num != now_dot_num) {
1461 		putc('.');
1462 		if (!(now_dot_num % 74))
1463 			putc('\n');
1464 	}
1465 
1466 	/* Check if transfer is done */
1467 	if (download_bytes >= download_size) {
1468 		/*
1469 		 * Reset global transfer variable, keep download_bytes because
1470 		 * it will be used in the next possible flashing command
1471 		 */
1472 		download_size = 0;
1473 		req->complete = rx_handler_command;
1474 		req->length = EP_BUFFER_SIZE;
1475 
1476 		strcpy(response, "OKAY");
1477 		fastboot_tx_write_str(response);
1478 
1479 		printf("\ndownloading of %d bytes finished\n", download_bytes);
1480 	} else {
1481 		req->length = rx_bytes_expected(ep);
1482 	}
1483 
1484 	req->actual = 0;
1485 	usb_ep_queue(ep, req, 0);
1486 }
1487 
1488 static void cb_download(struct usb_ep *ep, struct usb_request *req)
1489 {
1490 	char *cmd = req->buf;
1491 	char response[FASTBOOT_RESPONSE_LEN];
1492 
1493 	strsep(&cmd, ":");
1494 	download_size = simple_strtoul(cmd, NULL, 16);
1495 	download_bytes = 0;
1496 
1497 	printf("Starting download of %d bytes\n", download_size);
1498 
1499 	if (0 == download_size) {
1500 		strcpy(response, "FAILdata invalid size");
1501 	} else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
1502 		download_size = 0;
1503 		strcpy(response, "FAILdata too large");
1504 	} else {
1505 		sprintf(response, "DATA%08x", download_size);
1506 		req->complete = rx_handler_dl_image;
1507 		req->length = rx_bytes_expected(ep);
1508 	}
1509 
1510 	fastboot_tx_write_str(response);
1511 }
1512 
1513 static void tx_handler_ul(struct usb_ep *ep, struct usb_request *req)
1514 {
1515 	unsigned int xfer_size = 0;
1516 	unsigned int pre_dot_num, now_dot_num;
1517 	unsigned int remain_size = 0;
1518 	unsigned int transferred_size = req->actual;
1519 
1520 	if (req->status != 0) {
1521 		printf("Bad status: %d\n", req->status);
1522 		return;
1523 	}
1524 
1525 	if (start_upload) {
1526 		pre_dot_num = upload_bytes / BYTES_PER_DOT;
1527 		upload_bytes += transferred_size;
1528 		now_dot_num = upload_bytes / BYTES_PER_DOT;
1529 
1530 		if (pre_dot_num != now_dot_num) {
1531 			putc('.');
1532 			if (!(now_dot_num % 74))
1533 				putc('\n');
1534 		}
1535 	}
1536 
1537 	remain_size = upload_size - upload_bytes;
1538 	xfer_size = (remain_size > EP_BUFFER_SIZE) ?
1539 		    EP_BUFFER_SIZE : remain_size;
1540 
1541 	debug("%s: remain_size=%d, transferred_size=%d",
1542 	      __func__, remain_size, transferred_size);
1543 	debug("xfer_size=%d, upload_bytes=%d, upload_size=%d!\n",
1544 	      xfer_size, upload_bytes, upload_size);
1545 
1546 	if (remain_size <= 0) {
1547 		fastboot_func->in_req->complete = fastboot_complete;
1548 		wakeup_thread();
1549 		fastboot_tx_write_str("OKAY");
1550 		printf("\nuploading of %d bytes finished\n", upload_bytes);
1551 		upload_bytes = 0;
1552 		upload_size = 0;
1553 		start_upload = false;
1554 		return;
1555 	}
1556 
1557 	/* Remove the transfer callback which response the upload */
1558 	/* request from host */
1559 	if (!upload_bytes)
1560 		start_upload = true;
1561 
1562 	fastboot_tx_write((char *)((phys_addr_t)CONFIG_FASTBOOT_BUF_ADDR + \
1563 			  upload_bytes),
1564 			  xfer_size);
1565 }
1566 
1567 static void cb_upload(struct usb_ep *ep, struct usb_request *req)
1568 {
1569 	char response[FASTBOOT_RESPONSE_LEN];
1570 
1571 	printf("Starting upload of %d bytes\n", upload_size);
1572 
1573 	if (0 == upload_size) {
1574 		strcpy(response, "FAILdata invalid size");
1575 	} else {
1576 		start_upload = false;
1577 		sprintf(response, "DATA%08x", upload_size);
1578 		fastboot_func->in_req->complete = tx_handler_ul;
1579 	}
1580 
1581 	fastboot_tx_write_str(response);
1582 }
1583 
1584 static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
1585 {
1586 	char boot_addr_start[12];
1587 	char *bootm_args[] = { "bootm", boot_addr_start, NULL };
1588 
1589 	puts("Booting kernel..\n");
1590 
1591 	sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR);
1592 	do_bootm(NULL, 0, 2, bootm_args);
1593 
1594 	/* This only happens if image is somehow faulty so we start over */
1595 	do_reset(NULL, 0, 0, NULL);
1596 }
1597 
1598 static void cb_boot(struct usb_ep *ep, struct usb_request *req)
1599 {
1600 	fastboot_func->in_req->complete = do_bootm_on_complete;
1601 	fastboot_tx_write_str("OKAY");
1602 }
1603 
1604 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
1605 {
1606 	g_dnl_trigger_detach();
1607 }
1608 
1609 static void cb_continue(struct usb_ep *ep, struct usb_request *req)
1610 {
1611 	fastboot_func->in_req->complete = do_exit_on_complete;
1612 	fastboot_tx_write_str("OKAY");
1613 }
1614 
1615 static void cb_set_active(struct usb_ep *ep, struct usb_request *req)
1616 {
1617 	char *cmd = req->buf;
1618 
1619 	debug("%s: %s\n", __func__, cmd);
1620 
1621 	strsep(&cmd, ":");
1622 	if (!cmd) {
1623 		pr_err("missing slot name");
1624 		fastboot_tx_write_str("FAILmissing slot name");
1625 		return;
1626 	}
1627 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1628 	unsigned int slot_number;
1629 	if (strncmp("a", cmd, 1) == 0) {
1630 		slot_number = 0;
1631 		rk_avb_set_slot_active(&slot_number);
1632 	} else if (strncmp("b", cmd, 1) == 0) {
1633 		slot_number = 1;
1634 		rk_avb_set_slot_active(&slot_number);
1635 	} else {
1636 		fastboot_tx_write_str("FAILunkown slot name");
1637 		return;
1638 	}
1639 
1640 	fastboot_tx_write_str("OKAY");
1641 	return;
1642 #else
1643 	fastboot_tx_write_str("FAILnot implemented");
1644 	return;
1645 #endif
1646 }
1647 
1648 #ifdef CONFIG_FASTBOOT_FLASH
1649 static void cb_flash(struct usb_ep *ep, struct usb_request *req)
1650 {
1651 	char *cmd = req->buf;
1652 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1653 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1654 	uint8_t flash_lock_state;
1655 
1656 	if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
1657 		/* write the device flashing unlock when first read */
1658 		if (rk_avb_write_flash_lock_state(1)) {
1659 			fastboot_tx_write_str("FAILflash lock state write failure");
1660 			return;
1661 		}
1662 		if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
1663 			fastboot_tx_write_str("FAILflash lock state read failure");
1664 			return;
1665 		}
1666 	}
1667 
1668 	if (flash_lock_state == 0) {
1669 		fastboot_tx_write_str("FAILThe device is locked, can not flash!");
1670 		printf("The device is locked, can not flash!\n");
1671 		return;
1672 	}
1673 #endif
1674 	strsep(&cmd, ":");
1675 	if (!cmd) {
1676 		pr_err("missing partition name");
1677 		fastboot_tx_write_str("FAILmissing partition name");
1678 		return;
1679 	}
1680 
1681 	fastboot_fail("no flash device defined", response);
1682 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1683 	fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
1684 				download_bytes, response);
1685 #endif
1686 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
1687 	fb_nand_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
1688 				download_bytes, response);
1689 #endif
1690 	fastboot_tx_write_str(response);
1691 }
1692 
1693 static void cb_flashing(struct usb_ep *ep, struct usb_request *req)
1694 {
1695 	char *cmd = req->buf;
1696 
1697 	if (strncmp("lock", cmd + 9, 4) == 0) {
1698 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1699 		uint8_t flash_lock_state;
1700 		flash_lock_state = 0;
1701 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1702 			fastboot_tx_write_str("FAILflash lock state"
1703 					      " write failure");
1704 		else
1705 			fastboot_tx_write_str("OKAY");
1706 #else
1707 		fastboot_tx_write_str("FAILnot implemented");
1708 #endif
1709 	} else if (strncmp("unlock", cmd + 9, 6) == 0) {
1710 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1711 		uint8_t flash_lock_state;
1712 		flash_lock_state = 1;
1713 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1714 			fastboot_tx_write_str("FAILflash lock state"
1715 					      " write failure");
1716 		else
1717 			fastboot_tx_write_str("OKAY");
1718 #else
1719 		fastboot_tx_write_str("FAILnot implemented");
1720 #endif
1721 	} else if (strncmp("lock_critical", cmd + 9, 12) == 0) {
1722 		fastboot_tx_write_str("FAILnot implemented");
1723 	} else if (strncmp("unlock_critical", cmd + 9, 14) == 0) {
1724 		fastboot_tx_write_str("FAILnot implemented");
1725 	} else if (strncmp("get_unlock_ability", cmd + 9, 17) == 0) {
1726 		fastboot_tx_write_str("FAILnot implemented");
1727 	} else if (strncmp("get_unlock_bootloader_nonce", cmd + 4, 27) == 0) {
1728 		fastboot_tx_write_str("FAILnot implemented");
1729 	} else if (strncmp("unlock_bootloader", cmd + 9, 17) == 0) {
1730 		fastboot_tx_write_str("FAILnot implemented");
1731 	} else if (strncmp("lock_bootloader", cmd + 9, 15) == 0) {
1732 		fastboot_tx_write_str("FAILnot implemented");
1733 	} else {
1734 		fastboot_tx_write_str("FAILunknown flashing command");
1735 	}
1736 }
1737 #endif
1738 
1739 static void cb_oem_perm_attr(void)
1740 {
1741 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1742 	sha256_context ctx;
1743 	uint8_t digest[SHA256_SUM_LEN] = {0};
1744 	uint8_t digest_temp[SHA256_SUM_LEN] = {0};
1745 	uint8_t perm_attr_temp[PERM_ATTR_TOTAL_SIZE] = {0};
1746 	uint8_t flag = 0;
1747 
1748 	if (PERM_ATTR_TOTAL_SIZE != download_bytes) {
1749 		printf("Permanent attribute size is not equal!\n");
1750 		fastboot_tx_write_str("FAILincorrect perm attribute size");
1751 		return;
1752 	}
1753 
1754 	if (rk_avb_read_perm_attr_flag(&flag)) {
1755 		printf("rk_avb_read_perm_attr_flag error!\n");
1756 		fastboot_tx_write_str("FAILperm attr read failed");
1757 		return;
1758 	}
1759 
1760 	if (flag == PERM_ATTR_SUCCESS_FLAG) {
1761 		if (rk_avb_read_attribute_hash(digest_temp,
1762 					       SHA256_SUM_LEN)) {
1763 			printf("The efuse IO can not be used!\n");
1764 			fastboot_tx_write_str("FAILefuse IO can not be used");
1765 			return;
1766 		}
1767 
1768 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1769 			if (rk_avb_read_permanent_attributes(perm_attr_temp,
1770 							     PERM_ATTR_TOTAL_SIZE)) {
1771 				printf("rk_avb_write_permanent_attributes error!\n");
1772 				fastboot_tx_write_str("FAILread perm attr error");
1773 				return;
1774 			}
1775 
1776 			sha256_starts(&ctx);
1777 			sha256_update(&ctx,
1778 				      (const uint8_t *)perm_attr_temp,
1779 				      PERM_ATTR_TOTAL_SIZE);
1780 			sha256_finish(&ctx, digest);
1781 			if (memcmp(digest, digest_temp, SHA256_SUM_LEN) == 0) {
1782 				printf("The hash has been written!\n");
1783 				fastboot_tx_write_str("OKAY");
1784 				return;
1785 			}
1786 		}
1787 
1788 		if (rk_avb_write_perm_attr_flag(0)) {
1789 			fastboot_tx_write_str("FAILperm attr flag write failure");
1790 			return;
1791 		}
1792 	}
1793 
1794 	if (rk_avb_write_permanent_attributes((uint8_t *)
1795 					      CONFIG_FASTBOOT_BUF_ADDR,
1796 					      download_bytes)) {
1797 		if (rk_avb_write_perm_attr_flag(0)) {
1798 			fastboot_tx_write_str("FAILperm attr flag write failure");
1799 			return;
1800 		}
1801 		fastboot_tx_write_str("FAILperm attr write failed");
1802 		return;
1803 	}
1804 
1805 	memset(digest, 0, SHA256_SUM_LEN);
1806 	sha256_starts(&ctx);
1807 	sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1808 		      PERM_ATTR_TOTAL_SIZE);
1809 	sha256_finish(&ctx, digest);
1810 
1811 	if (rk_avb_write_attribute_hash((uint8_t *)digest,
1812 					SHA256_SUM_LEN)) {
1813 		if (rk_avb_read_attribute_hash(digest_temp,
1814 						SHA256_SUM_LEN)) {
1815 			printf("The efuse IO can not be used!\n");
1816 			fastboot_tx_write_str("FAILefuse IO can not be used");
1817 			return;
1818 		}
1819 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1820 			if (rk_avb_write_perm_attr_flag(0)) {
1821 				fastboot_tx_write_str("FAILperm attr flag write failure");
1822 				return;
1823 			}
1824 			printf("The hash has been written, but is different!\n");
1825 			fastboot_tx_write_str("FAILhash comparison failure");
1826 			return;
1827 		}
1828 	}
1829 
1830 	if (rk_avb_write_perm_attr_flag(PERM_ATTR_SUCCESS_FLAG)) {
1831 		fastboot_tx_write_str("FAILperm attr flag write failure");
1832 		return;
1833 	}
1834 
1835 	fastboot_tx_write_str("OKAY");
1836 #else
1837 	fastboot_tx_write_str("FAILnot implemented");
1838 #endif
1839 }
1840 
1841 static void cb_oem(struct usb_ep *ep, struct usb_request *req)
1842 {
1843 	char *cmd = req->buf;
1844 
1845 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1846 	if (strncmp("format", cmd + 4, 6) == 0) {
1847 		char cmdbuf[32];
1848 		sprintf(cmdbuf, "gpt write mmc %x $partitions",
1849 			CONFIG_FASTBOOT_FLASH_MMC_DEV);
1850 		if (run_command(cmdbuf, 0))
1851 			fastboot_tx_write_str("FAILmmc write failure");
1852 		else
1853 			fastboot_tx_write_str("OKAY");
1854 	} else
1855 #endif
1856 	if (strncmp("unlock", cmd + 4, 8) == 0) {
1857 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1858 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1859 		fastboot_tx_write_str("FAILnot implemented");
1860 		return;
1861 #else
1862 		uint8_t unlock = 0;
1863 		TEEC_Result result;
1864 		debug("oem unlock\n");
1865 		result = trusty_read_oem_unlock(&unlock);
1866 		if (result) {
1867 			printf("read oem unlock status with error : 0x%x\n", result);
1868 			fastboot_tx_write_str("FAILRead oem unlock status failed");
1869 			return;
1870 		}
1871 		if (unlock) {
1872 			printf("oem unlock ignored, device already unlocked\n");
1873 			fastboot_tx_write_str("FAILalready unlocked");
1874 			return;
1875 		}
1876 		printf("oem unlock requested:\n");
1877 		printf("\tUnlocking forces a factory reset and could\n");
1878 		printf("\topen your device up to a world of hurt.  If you\n");
1879 		printf("\tare sure you know what you're doing, then accept\n");
1880 		printf("\tvia 'fastboot oem unlock_accept'.\n");
1881 		env_set("unlock", "unlock");
1882 		fastboot_tx_write_str("OKAY");
1883 #endif
1884 #else
1885 		fastboot_tx_write_str("FAILnot implemented");
1886 		return;
1887 #endif
1888 	} else if (strncmp("unlock_accept", cmd + 4, 13) == 0) {
1889 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1890 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1891 		fastboot_tx_write_str("FAILnot implemented");
1892 		return;
1893 #else
1894 		char *unlock = env_get("unlock");
1895 		TEEC_Result result;
1896 		debug("oem unlock_accept\n");
1897 		if (unlock == NULL || strncmp("unlock", unlock, 6) != 0) {
1898 			printf("oem unlock_accept ignored, not pending\n");
1899 			fastboot_tx_write_str("FAILoem unlock not requested");
1900 			return;
1901 		}
1902 		env_set("unlock", "");
1903 		printf("Erasing userdata partition\n");
1904 		struct blk_desc *dev_desc;
1905 		disk_partition_t part_info;
1906 		dev_desc = rockchip_get_bootdev();
1907 		if (!dev_desc) {
1908 			printf("%s: dev_desc is NULL!\n", __func__);
1909 			return;
1910 		}
1911 		int ret = part_get_info_by_name(dev_desc, "userdata",
1912 				&part_info);
1913 		if (ret < 0) {
1914 			printf("not found userdata partition");
1915 			printf("Erase failed with error %d\n", ret);
1916 			fastboot_tx_write_str("FAILErasing userdata failed");
1917 			return;
1918 		}
1919 		ret = blk_derase(dev_desc, part_info.start, part_info.size);
1920 		if (ret != part_info.size) {
1921 			printf("Erase failed with error %d\n", ret);
1922 			fastboot_tx_write_str("FAILErasing userdata failed");
1923 			return;
1924 		}
1925 		printf("Erasing succeeded\n");
1926 
1927 		result = trusty_write_oem_unlock(1);
1928 		if (result) {
1929 			printf("write oem unlock status with error : 0x%x\n", result);
1930 			fastboot_tx_write_str("FAILWrite oem unlock status failed");
1931 			return;
1932 		}
1933 		fastboot_tx_write_str("OKAY");
1934 
1935 		/*
1936 		 * now reboot into recovery to do a format of the
1937 		 * userdata partition so it's ready to use on next boot
1938 		 */
1939 		board_run_recovery_wipe_data();
1940 #endif
1941 #else
1942 		fastboot_tx_write_str("FAILnot implemented");
1943 		return;
1944 #endif
1945 	} else if (strncmp("lock", cmd + 4, 8) == 0) {
1946 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1947 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1948 		fastboot_tx_write_str("FAILnot implemented");
1949 		return;
1950 #else
1951 		TEEC_Result result;
1952 		uint8_t unlock = 0;
1953 		trusty_read_oem_unlock(&unlock);
1954 		if (!unlock) {
1955 			printf("oem lock ignored, already locked\n");
1956 			fastboot_tx_write_str("FAILalready locked");
1957 			return;
1958 		}
1959 
1960 		result = trusty_write_oem_unlock(0);
1961 		if (result) {
1962 			printf("write oem unlock status with error : 0x%x\n", result);
1963 			fastboot_tx_write_str("FAILWrite oem unlock status failed");
1964 			return;
1965 		}
1966 		fastboot_tx_write_str("OKAY");
1967 #endif
1968 #else
1969 		fastboot_tx_write_str("FAILnot implemented");
1970 		return;
1971 #endif
1972 	} else if (strncmp("at-get-ca-request", cmd + 4, 17) == 0) {
1973 #ifdef CONFIG_OPTEE_CLIENT
1974 		uint8_t out[ATTEST_CA_OUT_SIZE];
1975 		uint32_t operation_size = download_bytes;
1976 		uint32_t out_len = ATTEST_CA_OUT_SIZE;
1977 		uint32_t res = 0;
1978 
1979 		res = trusty_attest_get_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1980 					   &operation_size, out, &out_len);
1981 		if (res) {
1982 			fastboot_tx_write_str("FAILtrusty_attest_get_ca failed");
1983 			return;
1984 		}
1985 		upload_size = out_len;
1986 		memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR, out, out_len);
1987 		fastboot_tx_write_str("OKAY");
1988 #else
1989 		fastboot_tx_write_str("FAILnot implemented");
1990 		return;
1991 #endif
1992 	} else if (strncmp("at-set-ca-response", cmd + 4, 18) == 0) {
1993 #ifdef CONFIG_OPTEE_CLIENT
1994 		uint32_t ca_response_size = download_bytes;
1995 		uint32_t res = 0;
1996 
1997 		res = trusty_attest_set_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1998 					   &ca_response_size);
1999 		if (res)
2000 			fastboot_tx_write_str("FAILtrusty_attest_set_ca failed");
2001 		else
2002 			fastboot_tx_write_str("OKAY");
2003 #else
2004 		fastboot_tx_write_str("FAILnot implemented");
2005 		return;
2006 #endif
2007 	} else if (strncmp("at-get-vboot-unlock-challenge", cmd + 4, 29) == 0) {
2008 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2009 		uint32_t challenge_len = 0;
2010 		int ret = 0;
2011 
2012 		ret = rk_generate_unlock_challenge((void *)CONFIG_FASTBOOT_BUF_ADDR, &challenge_len);
2013 		if (ret == 0) {
2014 			upload_size = challenge_len;
2015 			fastboot_tx_write_str("OKAY");
2016 		} else {
2017 			fastboot_tx_write_str("FAILgenerate unlock challenge fail!");
2018 		}
2019 #else
2020 		fastboot_tx_write_str("FAILnot implemented");
2021 		return;
2022 #endif
2023 	} else if (strncmp("at-lock-vboot", cmd + 4, 13) == 0) {
2024 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2025 		uint8_t lock_state;
2026 		lock_state = 0;
2027 		if (rk_avb_write_lock_state(lock_state))
2028 			fastboot_tx_write_str("FAILwrite lock state failed");
2029 		else
2030 			fastboot_tx_write_str("OKAY");
2031 #else
2032 		fastboot_tx_write_str("FAILnot implemented");
2033 #endif
2034 	} else if (strncmp("at-unlock-vboot", cmd + 4, 15) == 0) {
2035 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2036 		uint8_t lock_state;
2037 		bool out_is_trusted = true;
2038 
2039 		if (rk_avb_read_lock_state(&lock_state))
2040 			fastboot_tx_write_str("FAILlock sate read failure");
2041 		if (lock_state >> 1 == 1) {
2042 			fastboot_tx_write_str("FAILThe vboot is disable!");
2043 		} else {
2044 			lock_state = 1;
2045 #ifdef CONFIG_RK_AVB_LIBAVB_ENABLE_ATH_UNLOCK
2046 			if (rk_auth_unlock((void *)CONFIG_FASTBOOT_BUF_ADDR,
2047 					   &out_is_trusted)) {
2048 				printf("rk_auth_unlock ops error!\n");
2049 				fastboot_tx_write_str("FAILrk_auth_unlock ops error!");
2050 				return;
2051 			}
2052 #endif
2053 			if (out_is_trusted == true) {
2054 				if (rk_avb_write_lock_state(lock_state))
2055 					fastboot_tx_write_str("FAILwrite lock state failed");
2056 				else
2057 					fastboot_tx_write_str("OKAY");
2058 			} else {
2059 				fastboot_tx_write_str("FAILauthenticated unlock fail");
2060 			}
2061 		}
2062 #else
2063 		fastboot_tx_write_str("FAILnot implemented");
2064 #endif
2065 	} else if (strncmp("at-disable-unlock-vboot", cmd + 4, 23) == 0) {
2066 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2067 		uint8_t lock_state;
2068 		lock_state = 2;
2069 		if (rk_avb_write_lock_state(lock_state))
2070 			fastboot_tx_write_str("FAILwrite lock state failed");
2071 		else
2072 			fastboot_tx_write_str("OKAY");
2073 #else
2074 		fastboot_tx_write_str("FAILnot implemented");
2075 #endif
2076 	} else if (strncmp("fuse at-perm-attr", cmd + 4, 16) == 0) {
2077 		cb_oem_perm_attr();
2078 	} else if (strncmp("fuse at-bootloader-vboot-key", cmd + 4, 27) == 0) {
2079 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2080 		sha256_context ctx;
2081 		uint8_t digest[SHA256_SUM_LEN];
2082 
2083 		if (download_bytes != VBOOT_KEY_HASH_SIZE) {
2084 			fastboot_tx_write_str("FAILinvalid vboot key length");
2085 			printf("The vboot key size error!\n");
2086 			return;
2087 		}
2088 
2089 		sha256_starts(&ctx);
2090 		sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
2091 			      VBOOT_KEY_SIZE);
2092 		sha256_finish(&ctx, digest);
2093 
2094 		if (rk_avb_write_vbootkey_hash((uint8_t *)digest,
2095 					       SHA256_SUM_LEN)) {
2096 			fastboot_tx_write_str("FAILvbootkey hash write failure");
2097 			return;
2098 		}
2099 		fastboot_tx_write_str("OKAY");
2100 #else
2101 		fastboot_tx_write_str("FAILnot implemented");
2102 #endif
2103 	} else {
2104 		fastboot_tx_write_str("FAILunknown oem command");
2105 	}
2106 }
2107 
2108 #ifdef CONFIG_FASTBOOT_FLASH
2109 static void cb_erase(struct usb_ep *ep, struct usb_request *req)
2110 {
2111 	char *cmd = req->buf;
2112 	char response[FASTBOOT_RESPONSE_LEN];
2113 
2114 	strsep(&cmd, ":");
2115 	if (!cmd) {
2116 		pr_err("missing partition name");
2117 		fastboot_tx_write_str("FAILmissing partition name");
2118 		return;
2119 	}
2120 
2121 	fastboot_fail("no flash device defined", response);
2122 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
2123 	fb_mmc_erase(cmd, response);
2124 #endif
2125 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
2126 	fb_nand_erase(cmd, response);
2127 #endif
2128 	fastboot_tx_write_str(response);
2129 }
2130 #endif
2131 
2132 struct cmd_dispatch_info {
2133 	char *cmd;
2134 	void (*cb)(struct usb_ep *ep, struct usb_request *req);
2135 };
2136 
2137 static const struct cmd_dispatch_info cmd_dispatch_info[] = {
2138 	{
2139 		.cmd = "reboot",
2140 		.cb = cb_reboot,
2141 	}, {
2142 		.cmd = "getvar:",
2143 		.cb = cb_getvar,
2144 	}, {
2145 		.cmd = "download:",
2146 		.cb = cb_download,
2147 	}, {
2148 		.cmd = "upload",
2149 		.cb = cb_upload,
2150 	}, {
2151 		.cmd = "boot",
2152 		.cb = cb_boot,
2153 	}, {
2154 		.cmd = "continue",
2155 		.cb = cb_continue,
2156 	}, {
2157 		.cmd = "set_active",
2158 		.cb = cb_set_active,
2159 	},
2160 #ifdef CONFIG_FASTBOOT_FLASH
2161 	{
2162 		.cmd = "flashing",
2163 		.cb = cb_flashing,
2164 	},
2165 	{
2166 		.cmd = "flash",
2167 		.cb = cb_flash,
2168 	}, {
2169 		.cmd = "erase",
2170 		.cb = cb_erase,
2171 	},
2172 #endif
2173 	{
2174 		.cmd = "oem",
2175 		.cb = cb_oem,
2176 	},
2177 };
2178 
2179 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
2180 {
2181 	char *cmdbuf = req->buf;
2182 	void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
2183 	int i;
2184 
2185 	if (req->status != 0 || req->length == 0)
2186 		return;
2187 
2188 	for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
2189 		if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
2190 			func_cb = cmd_dispatch_info[i].cb;
2191 			break;
2192 		}
2193 	}
2194 
2195 	if (!func_cb) {
2196 		pr_err("unknown command: %.*s", req->actual, cmdbuf);
2197 		fastboot_tx_write_str("FAILunknown command");
2198 	} else {
2199 		if (req->actual < req->length) {
2200 			u8 *buf = (u8 *)req->buf;
2201 			buf[req->actual] = 0;
2202 			func_cb(ep, req);
2203 		} else {
2204 			pr_err("buffer overflow");
2205 			fastboot_tx_write_str("FAILbuffer overflow");
2206 		}
2207 	}
2208 
2209 	*cmdbuf = '\0';
2210 	req->actual = 0;
2211 	usb_ep_queue(ep, req, 0);
2212 }
2213