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