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