1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3 * Description: LiteOS USB Driver DFU Protocol
4 * Author: huangjieliang
5 * Create: 2017-12-25
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29 * Notice of Export Control Law
30 * ===============================================
31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34 * applicable export control laws and regulations.
35 * --------------------------------------------------------------------------- */
36
37 #include <hisoc/uart.h>
38 #include "gadget/f_dfu.h"
39 #include "gadget/composite.h"
40
41 #ifdef __cplusplus
42 #if __cplusplus
43 extern "C" {
44 #endif /* __cplusplus */
45 #endif /* __cplusplus */
46
47 int usbdev_dfu_initialize(struct module *mod, int n, void *arg);
48
49 /* device driver structure definition */
50
51 static const driver_t g_dfu_driver =
52 {
53 .name = "fdfu",
54 .methods = NULL,
55 .size = 0
56 };
57
58 /* private device class information */
59
60 static devclass_t g_dfu_devclass;
61 DRIVER_MODULE(fdfu, simple, g_dfu_driver, g_dfu_devclass, usbdev_dfu_initialize, 0);
62
63 static struct usb_dfu_dev *g_dfu_dev = NULL;
64 static struct usb_dfu_entity *g_dfu_entity = NULL;
65 static struct pthread_mutex g_dfu_mtx = PTHREAD_MUTEX_INITIALIZER;
66
67 static struct string_des g_manufacturer_str;
68 static struct string_des g_serial_number_str;
69 static struct string_des g_product_str;
70
71 volatile uint8_t g_flash_upgrade_state = DFU_FLASH_STATE_UPGRADING;
72
73 /* define descriptor */
74
75 #define DEVICE_VENDOR_ID 0x0955
76 #define DEVICE_PRODUCT_ID 0x701A
77 #define DEVICE_VERSION 0x0110
78
79 #define DFU_STRING_LEN_BYTE 0
80 #define DFU_STRING_DATA_BYTE 2
81 #define DFU_STRING_HEAD_LEN 2
82 #define DFU_MANU_STRING_LEN 28
83 #define DFU_PRODUCT_STRING_LEN 48
84 #define DFU_SERIAL_STRING_LEN 22
85 #define DFU_STRING_ID_LEN 4
86
87 static const struct usb_device_descriptor g_dfu_device_desc =
88 {
89 .bLength = sizeof(struct usb_device_descriptor),
90 .bDescriptorType = UDESC_DEVICE,
91 HSETW(.bcdUSB, 0x0200),
92 .bDeviceClass = 0x02,
93 .bDeviceSubClass = 0x02, /* CDC-modem */
94 .bDeviceProtocol = 0x01, /* Interface Association Descriptor */
95 .bMaxPacketSize = 64, /* Control Endpoint packet size */
96 HSETW(.idVendor, DEVICE_VENDOR_ID),
97 HSETW(.idProduct, DEVICE_PRODUCT_ID),
98 HSETW(.bcdDevice, DEVICE_VERSION),
99 .iManufacturer = 1, /* Manufacturer name, string index */
100 .iProduct = 2,
101 .iSerialNumber = 3,
102 .bNumConfigurations = 1,
103 };
104
105 struct usb_config_descriptor g_dfu_config_desc =
106 {
107 .bLength = USB_CONFIG_DESC_SIZE,
108 .bDescriptorType = UDESC_CONFIG,
109
110 /* HSETW(.wTotalLength, USB_CONFIG_DESC_SIZE + sizeof(usb_dfu_func) + sizeof(usb_dfu_intf_desc)), */
111
112 HSETW(.wTotalLength, 0), /* Modify according to the actual length */
113 .bNumInterface = 1,
114 .bConfigurationValue = 1,
115 .iConfiguration = 0,
116 .bmAttributes = UC_SELF_POWERED | UC_BUS_POWERED, /* 0xc0 */
117 .bMaxPower = 1 /* max power */
118 };
119
120 /* HUAWEI LiteOS */
121
122 static char g_dfu_manufacturer[DFU_MANU_STRING_LEN] =
123 {
124 DFU_MANU_STRING_LEN,
125 UDESC_STRING,
126 'H', 0, 'U', 0, 'A', 0, 'W', 0, 'E', 0, 'I', 0, ' ', 0,
127 'L', 0, 'i', 0, 't', 0, 'e', 0, 'O', 0, 'S', 0
128 };
129
130 /* USB download gadget */
131
132 static char g_dfu_product[DFU_PRODUCT_STRING_LEN] =
133 {
134 DFU_PRODUCT_STRING_LEN,
135 UDESC_STRING,
136 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'd', 0, 'o', 0, 'w', 0, 'n', 0, 'l', 0, 'o', 0,
137 'w', 0, 'n', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, ' ', 0, 'g', 0, 'a', 0, 'd', 0,
138 'g', 0, 'e', 0, 't', 0
139 };
140
141 static char g_dfu_serial[DFU_SERIAL_STRING_LEN] =
142 {
143 DFU_SERIAL_STRING_LEN,
144 UDESC_STRING,
145 '1', 0, '2', 0, '3', 0, '4', 0, '5', 0,
146 '6', 0, '7', 0, '8', 0, '9', 0, '0', 0
147 };
148
149 static const char g_dfu_string_id[DFU_STRING_ID_LEN] =
150 {
151 DFU_STRING_ID_LEN,
152 UDESC_STRING,
153 0x09, 0x04
154 };
155
156 static struct usbd_string g_dfu_string_defs[] =
157 {
158 { 0, g_dfu_string_id },
159 { 1, g_dfu_manufacturer },
160 { 2, g_dfu_product },
161 { 3, g_dfu_serial },
162 { 4, g_dfu_product },
163 USBD_DEVICE_STRINGS_END /* end of list */
164 };
165
set_manufacturer_string(struct string_des * des)166 void set_manufacturer_string(struct string_des *des)
167 {
168 char *buf;
169 struct string_des *str_des;
170 int len;
171
172 if (des == NULL)
173 {
174 usb_err("%s failed\n", __FUNCTION__);
175 return;
176 }
177
178 if (des->str == NULL || des->len <= 0)
179 {
180 usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
181 return;
182 }
183
184 str_des = des;
185 len = str_des->len + DFU_STRING_HEAD_LEN;
186
187 buf = (char *)malloc(len);
188 if (buf == NULL)
189 {
190 usb_err("%s malloc failed\n", __FUNCTION__);
191 return;
192 }
193
194 g_manufacturer_str.str = buf;
195 g_manufacturer_str.len = len;
196
197 *buf = len;
198 *(buf + 1) = UDESC_STRING;
199 (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
200 }
201
set_serial_number_string(struct string_des * des)202 void set_serial_number_string(struct string_des *des)
203 {
204 char *buf;
205 struct string_des *str_des;
206 int len;
207
208 if (des == NULL)
209 {
210 usb_err("%s failed\n", __FUNCTION__);
211 return;
212 }
213
214 if (des->str == NULL || des->len <= 0)
215 {
216 usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
217 return;
218 }
219
220 str_des = des;
221 len = str_des->len + DFU_STRING_HEAD_LEN;
222
223 buf = (char *)malloc(len);
224 if (buf == NULL)
225 {
226 usb_err("%s malloc failed\n", __FUNCTION__);
227 return;
228 }
229
230 g_serial_number_str.str = buf;
231 g_serial_number_str.len = len;
232
233 *buf = len;
234 *(buf + 1) = UDESC_STRING;
235 (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
236 }
237
set_product_string(struct string_des * des)238 void set_product_string(struct string_des *des)
239 {
240 char *buf;
241 struct string_des *str_des;
242 int len;
243
244 if (des == NULL)
245 {
246 usb_err("%s failed\n", __FUNCTION__);
247 return;
248 }
249
250 if (des->str == NULL || des->len <= 0)
251 {
252 usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
253 return;
254 }
255
256 str_des = des;
257 len = str_des->len + DFU_STRING_HEAD_LEN;
258
259 buf = (char *)malloc(len);
260 if (buf == NULL)
261 {
262 usb_err("%s malloc failed\n", __FUNCTION__);
263 return;
264 }
265
266 g_product_str.str = buf;
267 g_product_str.len = len;
268
269 *buf = len;
270 *(buf + 1) = UDESC_STRING;
271 (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
272 }
273
set_flash_state(volatile uint8_t flash_state)274 void set_flash_state(volatile uint8_t flash_state)
275 {
276 if (flash_state != DFU_FLASH_STATE_UPGRADING &&
277 flash_state != DFU_FLASH_STATE_UPGRADED &&
278 flash_state != DFU_FLASH_STATE_ERROR)
279 {
280 PRINT_ERR("The state of flash upgrade is set failed!\n");
281 return;
282 }
283
284 g_flash_upgrade_state = flash_state;
285 }
286
get_flash_state(struct usbdev_req_s * req)287 void get_flash_state(struct usbdev_req_s *req)
288 {
289 uint8_t *buf = req->buf;
290
291 buf[0] = g_flash_upgrade_state; /* The 0 bit is valid */
292 }
293
usb_dfu_running(void)294 bool usb_dfu_running(void)
295 {
296 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
297
298 if (entity == NULL)
299 {
300 return false;
301 }
302
303 return (entity->trans_complete || entity->trans_size) ? true: false;
304 }
305
usb_dfu_update_status(void)306 uint32_t usb_dfu_update_status(void)
307 {
308 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
309
310 if (entity == NULL)
311 {
312 return 0;
313 }
314
315 return entity->trans_complete;
316 }
317
usb_dfu_update_size_get(void)318 uint64_t *usb_dfu_update_size_get(void)
319 {
320 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
321
322 if (entity == NULL)
323 {
324 return NULL;
325 }
326
327 return &entity->trans_size;
328 }
329
dfu_ram_read(uint8_t * buf,uint32_t len)330 static int dfu_ram_read(uint8_t *buf, uint32_t len)
331 {
332 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
333 uint32_t offset;
334 errno_t ret;
335
336 if (buf == NULL || entity == NULL)
337 {
338 return -1;
339 }
340
341 offset = entity->offset;
342 if (offset > entity->ram_size)
343 {
344 return -1;
345 }
346
347 len = min(len, (entity->ram_size - offset));
348
349 ret = memcpy_s(buf, len, (const void *)((uint8_t *)entity->ram_addr + offset), len);
350 if (ret != EOK)
351 {
352 usb_err("memcpy failed!\n");
353 return -1;
354 }
355 entity->offset += len;
356
357 (void)uart_putc('#');
358
359 return (int)len;
360 }
361
dfu_ram_write(const uint8_t * buf,uint32_t len)362 static int dfu_ram_write(const uint8_t *buf, uint32_t len)
363 {
364 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
365 uint32_t offset;
366 errno_t ret;
367
368 if (buf == NULL || entity == NULL)
369 {
370 return -1;
371 }
372
373 offset = entity->offset;
374 if (offset > entity->ram_size)
375 {
376 return -1;
377 }
378
379 len = min(len, (entity->ram_size - offset));
380
381 ret = memcpy_s((void *)((uint8_t *)entity->ram_addr + offset), entity->ram_size - offset, buf, len);
382 if (ret != EOK)
383 {
384 usb_err("memcpy failed!\n");
385 return -1;
386 }
387 entity->offset += len;
388 entity->trans_size += len;
389
390 (void)uart_putc('#');
391
392 return 0;
393 }
394
usbdev_dfu_dev_init(void)395 void usbdev_dfu_dev_init(void)
396 {
397 struct usb_dfu_dev *dev;
398 struct string_des str;
399
400 dev = malloc(sizeof(struct usb_dfu_dev));
401 if (dev == NULL)
402 {
403 return;
404 }
405 (void)memset_s(dev, sizeof(struct usb_dfu_dev), 0, sizeof(struct usb_dfu_dev));
406
407 g_dfu_dev = dev;
408
409 str.str = &g_dfu_manufacturer[DFU_STRING_DATA_BYTE];
410 str.len = g_dfu_manufacturer[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
411 set_manufacturer_string(&str);
412 str.str = &g_dfu_serial[DFU_STRING_DATA_BYTE];
413 str.len = g_dfu_serial[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
414 set_serial_number_string(&str);
415 str.str = &g_dfu_product[DFU_STRING_DATA_BYTE];
416 str.len = g_dfu_product[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
417 set_product_string(&str);
418 }
419
usbdev_dfu_dev_deinit(void)420 void usbdev_dfu_dev_deinit(void)
421 {
422 if (g_dfu_dev != NULL)
423 {
424 free(g_dfu_dev);
425 g_dfu_dev = NULL;
426 }
427
428 if (g_manufacturer_str.str != NULL)
429 {
430 free((void *)g_manufacturer_str.str);
431 g_manufacturer_str.str = NULL;
432 }
433
434 if (g_product_str.str != NULL)
435 {
436 free((void *)g_product_str.str);
437 g_product_str.str = NULL;
438 }
439
440 if (g_serial_number_str.str != NULL)
441 {
442 free((void *)g_serial_number_str.str);
443 g_serial_number_str.str = NULL;
444 }
445 }
446
usb_dfu_get_dev(void)447 static struct usb_dfu_dev *usb_dfu_get_dev(void)
448 {
449 return g_dfu_dev;
450 }
451
dfu_set_state(int new_state)452 static inline void dfu_set_state(int new_state)
453 {
454 struct usb_dfu_dev *dev = usb_dfu_get_dev();
455 dev->dfu_state = new_state;
456 }
457
dfu_get_state(void)458 static inline int dfu_get_state(void)
459 {
460 struct usb_dfu_dev *dev = usb_dfu_get_dev();
461 return dev->dfu_state;
462 }
463
dfu_dnload_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)464 static void dfu_dnload_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
465 {
466 struct usb_dfu_dev *dev = usb_dfu_get_dev();
467 int ret;
468
469 (void)ep;
470
471 ret = usb_dfu_write(usb_dfu_get_entity(0), req->buf, (int)req->len, dev->seq_num);
472 if (ret < 0)
473 {
474 dev->dfu_status.status = USB_DFU_ERR_UNKNOWN;
475 dev->dfu_state = USB_DFU_ERROR;
476 }
477 }
478
usbdev_dfu_set_config(void)479 void usbdev_dfu_set_config(void)
480 {
481 struct usb_dfu_dev *dev = usb_dfu_get_dev();
482
483 if (dev->dfu_state == USB_DFU_APP_DETACH)
484 {
485 dev->dfu_state = USB_DFU_IDLE;
486 }
487
488 dev->dfu_status.status = USB_DFU_STATUS_OK;
489 }
490
usbdev_dfu_transaction_cleanup(void)491 void usbdev_dfu_transaction_cleanup(void)
492 {
493 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
494
495 if (entity == NULL)
496 {
497 return;
498 }
499
500 entity->trans_size = 0;
501 entity->trans_complete = 0;
502 entity->seq_num = 0;
503 entity->offset = 0;
504 }
505
usbdev_dfu_init(void)506 void usbdev_dfu_init(void)
507 {
508 struct usb_dfu_dev *dev = usb_dfu_get_dev();
509
510 if (dev == NULL)
511 {
512 return;
513 }
514
515 /* When the host confirm that the dfu "bInterfaceProtocol" is the "Runtime mode"
516 * it will send a "DFU_DETACH" request to the device. When unload device, the device
517 * mode should change from "DFU mode" to "Runtime mode", so that next upgrade action
518 * can be performed smoothly.
519 *
520 * bInterfaceProtocol value: 0x1 --- Runtime protocol.
521 * bInterfaceProtocol value: 0x2 --- DFU mode protocol.
522 *
523 * More information, please refer to DFU_1.1.pdf
524 */
525
526 to_runtime_mode();
527 dev->dfu_state = USB_DFU_APP_IDLE;
528 (void)memset_s(&dev->dfu_status, sizeof(struct dfu_getstatus_response_s),
529 0, sizeof(struct dfu_getstatus_response_s));
530 dev->dfu_status.poll_timeout[0] = USB_DFU_POLLTIMEOUT;
531
532 usbdev_dfu_transaction_cleanup();
533 }
534
dfu_get_status_for_req(struct usbdev_req_s * ctrlreq)535 static int dfu_get_status_for_req(struct usbdev_req_s *ctrlreq)
536 {
537 struct dfu_getstatus_response_s *status = (struct dfu_getstatus_response_s *)ctrlreq->buf;
538 struct usb_dfu_dev *dev = usb_dfu_get_dev();
539 int dfu_state = dev->dfu_state;
540
541 if (dfu_state == USB_DFU_DNLOAD_SYNC)
542 {
543 dev->dfu_state = USB_DFU_DNLOAD_IDLE;
544 }
545 else if (dfu_state == USB_DFU_DNBUSY)
546 {
547 dev->dfu_state = USB_DFU_DNLOAD_SYNC;
548 }
549 else if (dfu_state == USB_DFU_MANIFEST_SYNC)
550 {
551 dev->dfu_state = USB_DFU_MANIFEST;
552 }
553 else if (dfu_state == USB_DFU_MANIFEST)
554 {
555 dev->dfu_state = USB_DFU_IDLE;
556 }
557
558 *status = dev->dfu_status;
559 status->state = (uint8_t)dev->dfu_state;
560
561 return USB_DFU_RET_STATUS_LEN;
562 }
563
dfu_get_state_for_req(struct usbdev_req_s * ctrlreq)564 static int dfu_get_state_for_req(struct usbdev_req_s *ctrlreq)
565 {
566 uint8_t *state = ctrlreq->buf;
567
568 *state = (uint8_t)dfu_get_state();
569
570 return USB_DFU_RET_STATE_LEN;
571 }
572
dfu_dnload(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)573 static int dfu_dnload(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
574 {
575 struct usb_dfu_dev *dev = usb_dfu_get_dev();
576 int len = UGETW(ctrl->wLength);
577 uint16_t value = UGETW(ctrl->wValue);
578
579 dev->dfu_state = USB_DFU_DNLOAD_SYNC;
580 dev->seq_num = value;
581
582 if (len == 0)
583 {
584 if (dev->dfu_state == USB_DFU_IDLE)
585 {
586 dev->dfu_state = USB_DFU_ERROR;
587 return USB_DFU_RET_ERR;
588 }
589 else
590 {
591 dev->dfu_state = USB_DFU_MANIFEST_SYNC;
592 }
593 }
594
595 ctrlreq->callback = dfu_dnload_complete;
596
597 return len;
598 }
599
dfu_upload(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)600 static int dfu_upload(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
601 {
602 struct usb_dfu_dev *dev = usb_dfu_get_dev();
603 uint16_t value = UGETW(ctrl->wValue);
604
605 if (dev->dfu_state == USB_DFU_IDLE)
606 {
607 dev->dfu_state = USB_DFU_UPLOAD_IDLE;
608 dev->seq_num = 0;
609 usbdev_dfu_transaction_cleanup();
610 }
611 else if (dev->dfu_state == USB_DFU_UPLOAD_IDLE)
612 {
613 dev->seq_num = value;
614 }
615
616 return usb_dfu_read(usb_dfu_get_entity(0), ctrlreq->buf, (int)ctrlreq->len, dev->seq_num);
617 }
618
dfu_app_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)619 static int dfu_app_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
620 {
621 int ret = USB_DFU_RET_OK;
622
623 switch (ctrl->bRequest)
624 {
625 case USB_DFU_DETACH:
626 {
627 to_dfu_mode();
628 dfu_set_state(USB_DFU_APP_DETACH);
629 }
630 break;
631
632 case USB_DFU_GET_STATUS:
633 ret = dfu_get_status_for_req(ctrlreq);
634 break;
635
636 case USB_DFU_GET_STATE:
637 ret = dfu_get_state_for_req(ctrlreq);
638 break;
639
640 default:
641 {
642 ret = USB_DFU_RET_ERR;
643 dfu_set_state(USB_DFU_APP_IDLE);
644 }
645 break;
646 }
647
648 return ret;
649 }
650
dfu_app_detach_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)651 static int dfu_app_detach_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
652 {
653 int ret;
654
655 switch (ctrl->bRequest)
656 {
657 case USB_DFU_GET_STATUS:
658 ret = dfu_get_status_for_req(ctrlreq);
659 break;
660
661 case USB_DFU_GET_STATE:
662 ret = dfu_get_state_for_req(ctrlreq);
663 break;
664
665 default:
666 {
667 ret = USB_DFU_RET_ERR;
668 dfu_set_state(USB_DFU_APP_IDLE);
669 }
670 break;
671 }
672
673 return ret;
674 }
675
dfu_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)676 static int dfu_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
677 {
678 int ret = USB_DFU_RET_OK;
679
680 switch (ctrl->bRequest)
681 {
682 case USB_DFU_GET_STATUS:
683 ret = dfu_get_status_for_req(ctrlreq);
684 break;
685
686 case USB_DFU_GET_STATE:
687 ret = dfu_get_state_for_req(ctrlreq);
688 break;
689
690 case USB_DFU_DNLOAD:
691 ret = dfu_dnload(ctrl, ctrlreq);
692 break;
693
694 case USB_DFU_UPLOAD:
695 ret = dfu_upload(ctrl, ctrlreq);
696 break;
697
698 case USB_DFU_ABORT:
699 dfu_set_state(USB_DFU_IDLE);
700 break;
701
702 case USB_DFU_FLASH_STATE:
703 {
704 get_flash_state(ctrlreq);
705 ret = 1;
706 }
707 break;
708
709 default:
710 {
711 ret = USB_DFU_RET_ERR;
712 dfu_set_state(USB_DFU_ERROR);
713 }
714 break;
715 }
716
717 return ret;
718 }
719
dfu_dnload_sync_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)720 static int dfu_dnload_sync_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
721 {
722 int ret;
723
724 switch (ctrl->bRequest)
725 {
726 case USB_DFU_GET_STATUS:
727 ret = dfu_get_status_for_req(ctrlreq);
728 break;
729
730 case USB_DFU_GET_STATE:
731 ret = dfu_get_state_for_req(ctrlreq);
732 break;
733
734 default:
735 {
736 ret = USB_DFU_RET_ERR;
737 dfu_set_state(USB_DFU_ERROR);
738 }
739 break;
740 }
741
742 return ret;
743 }
744
dfu_dnbusy_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)745 static int dfu_dnbusy_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
746 {
747 int ret;
748
749 switch (ctrl->bRequest)
750 {
751 case USB_DFU_GET_STATUS:
752 ret = dfu_get_status_for_req(ctrlreq);
753 break;
754
755 default:
756 {
757 ret = USB_DFU_RET_ERR;
758 dfu_set_state(USB_DFU_ERROR);
759 }
760 break;
761 }
762
763 return ret;
764 }
765
dfu_dnload_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)766 static int dfu_dnload_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
767 {
768 int ret = USB_DFU_RET_OK;
769
770 switch (ctrl->bRequest)
771 {
772 case USB_DFU_GET_STATUS:
773 ret = dfu_get_status_for_req(ctrlreq);
774 break;
775
776 case USB_DFU_GET_STATE:
777 ret = dfu_get_state_for_req(ctrlreq);
778 break;
779
780 case USB_DFU_DNLOAD:
781 ret = dfu_dnload(ctrl, ctrlreq);
782 break;
783
784 case USB_DFU_ABORT:
785 dfu_set_state(USB_DFU_IDLE);
786 break;
787
788 default:
789 {
790 ret = USB_DFU_RET_ERR;
791 dfu_set_state(USB_DFU_ERROR);
792 }
793 break;
794 }
795
796 return ret;
797 }
798
dfu_manifest_sync_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)799 static int dfu_manifest_sync_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
800 {
801 struct usb_dfu_dev *dev = usb_dfu_get_dev();
802 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
803 int ret;
804
805 switch (ctrl->bRequest)
806 {
807 case USB_DFU_GET_STATUS:
808 {
809 dev->seq_num = 0;
810 ret = dfu_get_status_for_req(ctrlreq);
811 if (entity != NULL)
812 {
813 entity->seq_num = 0;
814 entity->offset = 0;
815 }
816 }
817 break;
818
819 case USB_DFU_GET_STATE:
820 ret = dfu_get_state_for_req(ctrlreq);
821 break;
822
823 default:
824 {
825 ret = USB_DFU_RET_ERR;
826 dfu_set_state(USB_DFU_ERROR);
827 }
828 break;
829 }
830
831 return ret;
832 }
833
dfu_manifest_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)834 static int dfu_manifest_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
835 {
836 struct usb_dfu_dev *dev = usb_dfu_get_dev();
837 struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
838 int ret;
839
840 switch (ctrl->bRequest)
841 {
842 case USB_DFU_GET_STATUS:
843 {
844 ret = dfu_get_status_for_req(ctrlreq);
845 dev->seq_num = 0;
846 if (entity != NULL)
847 {
848 entity->trans_complete = 1;
849 }
850 dprintf("\nDOWNLOAD ... OK\n");
851 }
852 break;
853
854 case USB_DFU_GET_STATE:
855 ret = dfu_get_state_for_req(ctrlreq);
856 break;
857
858 default:
859 {
860 ret = USB_DFU_RET_ERR;
861 dfu_set_state(USB_DFU_ERROR);
862 }
863 break;
864 }
865
866 return ret;
867 }
868
dfu_manifest_wait_reset(const struct usb_device_request * ctrl,const struct usbdev_req_s * ctrlreq)869 static int dfu_manifest_wait_reset(const struct usb_device_request *ctrl, const struct usbdev_req_s *ctrlreq)
870 {
871 (void)ctrl;
872 (void)ctrlreq;
873 dprintf("Do nothing!\n");
874 return 0;
875 }
876
dfu_upload_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)877 static int dfu_upload_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
878 {
879 int ret = USB_DFU_RET_OK;
880 int len = UGETW(ctrl->wLength);
881
882 switch (ctrl->bRequest)
883 {
884 case USB_DFU_GET_STATUS:
885 ret = dfu_get_status_for_req(ctrlreq);
886 break;
887
888 case USB_DFU_GET_STATE:
889 ret = dfu_get_state_for_req(ctrlreq);
890 break;
891
892 case USB_DFU_UPLOAD:
893 {
894 ret = dfu_upload(ctrl, ctrlreq);
895 if (ret >= 0 && ret < len)
896 {
897 dfu_set_state(USB_DFU_IDLE);
898 }
899 }
900 break;
901
902 case USB_DFU_ABORT:
903 dfu_set_state(USB_DFU_IDLE);
904 break;
905
906 default:
907 {
908 ret = USB_DFU_RET_ERR;
909 dfu_set_state(USB_DFU_ERROR);
910 }
911 break;
912 }
913
914 return ret;
915 }
916
dfu_error_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)917 static int dfu_error_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
918 {
919 struct usb_dfu_dev *dev = usb_dfu_get_dev();
920 int ret = USB_DFU_RET_OK;
921
922 switch (ctrl->bRequest)
923 {
924 case USB_DFU_GET_STATUS:
925 ret = dfu_get_status_for_req(ctrlreq);
926 break;
927
928 case USB_DFU_GET_STATE:
929 ret = dfu_get_state_for_req(ctrlreq);
930 break;
931
932 case USB_DFU_CLR_STATUS:
933 {
934 dev->dfu_status.status = USB_DFU_STATUS_OK;
935 dfu_set_state(USB_DFU_IDLE);
936 }
937 break;
938
939 default:
940 {
941 ret = USB_DFU_RET_ERR;
942 dfu_set_state(USB_DFU_ERROR);
943 }
944 break;
945 }
946
947 return ret;
948 }
949
usbdev_dfu_class_requests(const struct usbdev_s * dev,const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)950 int usbdev_dfu_class_requests(const struct usbdev_s *dev,
951 const struct usb_device_request *ctrl,
952 struct usbdev_req_s *ctrlreq)
953 {
954 int ret = -EOPNOTSUPP;
955
956 (void)dev;
957
958 switch (dfu_get_state())
959 {
960 case USB_DFU_APP_IDLE:
961 ret = dfu_app_idle_request(ctrl, ctrlreq);
962 break;
963
964 case USB_DFU_APP_DETACH:
965 ret = dfu_app_detach_request(ctrl, ctrlreq);
966 break;
967
968 case USB_DFU_IDLE:
969 ret = dfu_idle_request(ctrl, ctrlreq);
970 break;
971
972 case USB_DFU_DNLOAD_SYNC:
973 ret = dfu_dnload_sync_request(ctrl, ctrlreq);
974 break;
975
976 case USB_DFU_DNBUSY:
977 ret = dfu_dnbusy_request(ctrl, ctrlreq);
978 break;
979
980 case USB_DFU_DNLOAD_IDLE:
981 ret = dfu_dnload_idle_request(ctrl, ctrlreq);
982 break;
983
984 case USB_DFU_MANIFEST_SYNC:
985 ret = dfu_manifest_sync_request(ctrl, ctrlreq);
986 break;
987
988 case USB_DFU_MANIFEST:
989 ret = dfu_manifest_request(ctrl, ctrlreq);
990 break;
991
992 case USB_DFU_MANIFEST_WAIT_RESET:
993 ret = dfu_manifest_wait_reset(ctrl, ctrlreq);
994 break;
995
996 case USB_DFU_UPLOAD_IDLE:
997 ret = dfu_upload_idle_request(ctrl, ctrlreq);
998 break;
999
1000 case USB_DFU_ERROR:
1001 ret = dfu_error_request(ctrl, ctrlreq);
1002 break;
1003
1004 default:
1005 usb_err("The state = %d of dfu is not support!\n", dfu_get_state());
1006 break;
1007 }
1008
1009 return ret;
1010 }
1011
dfu_ram_init_env(struct usb_dfu_entity * entity,char * envstr)1012 static int dfu_ram_init_env(struct usb_dfu_entity *entity, char *envstr)
1013 {
1014 char *st;
1015 int ret;
1016
1017 st = strsep(&envstr, " ");
1018 if (st == NULL)
1019 {
1020 return -1;
1021 }
1022 ret = strncpy_s(entity->dfu_name, DFU_NAME_MAX_LEN, st, strlen(st) + 1);
1023 if (ret != EOK)
1024 {
1025 return -1;
1026 }
1027
1028 st = strsep(&envstr, " ");
1029 if (strcmp(st, "ram"))
1030 {
1031 return -1;
1032 }
1033
1034 st = strsep(&envstr, " ");
1035 if (st == NULL)
1036 {
1037 return -1;
1038 }
1039 entity->ram_addr = (void *)strtoul(st, &st, 16);
1040
1041 st = strsep(&envstr, " ");
1042 if (st == NULL)
1043 {
1044 return -1;
1045 }
1046 entity->ram_size = strtoul(st, &st, 16);
1047
1048 entity->dfu_write = dfu_ram_write;
1049 entity->dfu_read = dfu_ram_read;
1050
1051 return 0;
1052 }
1053
usb_dfu_init_env_entities(char * type,char * envstr,char * devstr)1054 int usb_dfu_init_env_entities(char *type, char *envstr, char *devstr)
1055 {
1056 struct usb_dfu_entity *entity;
1057 int ret;
1058
1059 (void)devstr;
1060
1061 if (type == NULL || envstr == NULL)
1062 {
1063 return -1;
1064 }
1065
1066 mtx_lock(&g_dfu_mtx);
1067 if (g_dfu_entity != NULL)
1068 {
1069 goto err;
1070 }
1071
1072 entity = malloc(sizeof(struct usb_dfu_entity));
1073 if (entity == NULL)
1074 {
1075 goto err;
1076 }
1077 (void)memset_s(entity, sizeof(struct usb_dfu_entity), 0, sizeof(struct usb_dfu_entity));
1078
1079 if (!strcmp(type, "ram"))
1080 {
1081 ret = dfu_ram_init_env(entity, envstr);
1082 if (ret < 0)
1083 {
1084 free(entity);
1085 goto err;
1086 }
1087 }
1088 else
1089 {
1090 free(entity);
1091 usb_err("Device %s not (yet) supported!\n", type);
1092 goto err;
1093 }
1094
1095 g_dfu_entity = entity;
1096 usbdev_dfu_transaction_cleanup();
1097 mtx_unlock(&g_dfu_mtx);
1098
1099 return 0;
1100 err:
1101 mtx_unlock(&g_dfu_mtx);
1102 return -1;
1103 }
1104
usb_dfu_free_entities(void)1105 void usb_dfu_free_entities(void)
1106 {
1107 mtx_lock(&g_dfu_mtx);
1108 if (g_dfu_entity == NULL)
1109 {
1110 mtx_unlock(&g_dfu_mtx);
1111 return;
1112 }
1113 free(g_dfu_entity);
1114 g_dfu_entity = NULL;
1115 mtx_unlock(&g_dfu_mtx);
1116 }
1117
usb_dfu_get_entity(int alter)1118 struct usb_dfu_entity *usb_dfu_get_entity(int alter)
1119 {
1120 (void)alter;
1121 return g_dfu_entity;
1122 }
1123
usb_dfu_read(struct usb_dfu_entity * dfu,void * buf,int size,uint32_t blk_seq_num)1124 int usb_dfu_read(struct usb_dfu_entity *dfu, void *buf, int size, uint32_t blk_seq_num)
1125 {
1126 int ret;
1127
1128 if (dfu == NULL || buf == NULL)
1129 {
1130 return -1;
1131 }
1132
1133 if (dfu->seq_num != blk_seq_num)
1134 {
1135 return -1;
1136 }
1137 dfu->seq_num++;
1138
1139 ret = dfu->dfu_read(buf, size);
1140 if (ret < 0)
1141 {
1142 return -1;
1143 }
1144
1145 if (dfu->offset >= dfu->trans_size)
1146 {
1147 dprintf("\nUPLOAD ... done\n");
1148 usbdev_dfu_transaction_cleanup();
1149 }
1150
1151 return ret;
1152 }
1153
usb_dfu_write(struct usb_dfu_entity * dfu,void * buf,int size,uint32_t blk_seq_num)1154 int usb_dfu_write(struct usb_dfu_entity *dfu, void *buf, int size, uint32_t blk_seq_num)
1155 {
1156 int ret;
1157
1158 if (dfu == NULL || buf == NULL)
1159 {
1160 return -1;
1161 }
1162
1163 if (dfu->seq_num != blk_seq_num)
1164 {
1165 usbdev_dfu_transaction_cleanup();
1166 return -1;
1167 }
1168 dfu->seq_num++;
1169
1170 ret = dfu->dfu_write(buf, size);
1171 if (ret < 0)
1172 {
1173 usbdev_dfu_transaction_cleanup();
1174 return -1;
1175 }
1176
1177 return 0;
1178 }
1179
usbdev_dfu_mkdevdesc(uint8_t * buf)1180 void usbdev_dfu_mkdevdesc(uint8_t *buf)
1181 {
1182 errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_dfu_device_desc, sizeof(g_dfu_device_desc));
1183 if (ret != EOK)
1184 {
1185 usb_err("memcpy_s fail!, ret:%d\n", ret);
1186 return;
1187 }
1188 }
1189
usbdev_dfu_mkstrdesc(uint8_t id,uint8_t * buf)1190 int usbdev_dfu_mkstrdesc(uint8_t id, uint8_t *buf)
1191 {
1192 errno_t ret;
1193 const char *str;
1194 int i;
1195
1196 for (i = 0; g_dfu_string_defs[i].s != NULL; i++)
1197 {
1198 str = g_dfu_string_defs[i].s;
1199 if (g_dfu_string_defs[i].id == id)
1200 {
1201 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]);
1202 if (ret != EOK)
1203 {
1204 usb_err("memcpy_s failed, ret = %d\n", ret);
1205 return -1;
1206 }
1207 return str[0];
1208 }
1209 }
1210 usb_err("Can not find the id = %u of string\n", id);
1211
1212 return -1;
1213 }
1214
usbdev_dfu_initialize_sub(struct composite_devdesc_s * dev,int ifnobase,int minor)1215 static void usbdev_dfu_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor)
1216 {
1217 usbdev_dfu_get_composite_devdesc(dev);
1218
1219 /* Interfaces */
1220
1221 dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */
1222 dev->minor = minor; /* The minor interface number */
1223
1224 /* Strings */
1225
1226 dev->devinfo.strbase = 0; /* Offset to String Numbers */
1227 }
1228
usbdev_dfu_initialize(struct module * mod,int n,void * arg)1229 int usbdev_dfu_initialize(struct module *mod, int n, void *arg)
1230 {
1231 struct composite_softc *com_s = (struct composite_softc *)arg;
1232 struct composite_devdesc_s dev;
1233 int ret;
1234
1235 /* ignore compilation warnings */
1236
1237 (void)mod;
1238 (void)n;
1239
1240 if (com_s == NULL)
1241 {
1242 return -1;
1243 }
1244
1245 usbdev_dfu_initialize_sub(&dev, 0, DEV_DFU);
1246
1247 ret = composite_initialize(com_s, 1, &dev);
1248 if (ret < 0)
1249 {
1250 return -1;
1251 }
1252
1253 PRINTK("** DFU device initialized successfully! **\n");
1254 return 0;
1255 }
1256
1257 #ifdef __cplusplus
1258 #if __cplusplus
1259 }
1260 #endif /* __cplusplus */
1261 #endif /* __cplusplus */