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