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