1beacf11bSopenharmony_ci/**************************************************************************** 2beacf11bSopenharmony_ci * drivers/usbdev/dfu.c 3beacf11bSopenharmony_ci * 4beacf11bSopenharmony_ci * Copyright (C) 2011-2018 Gregory Nutt. All rights reserved. 5beacf11bSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. 6beacf11bSopenharmony_ci * 7beacf11bSopenharmony_ci * Authors: Petteri Aimonen <jpa@git.mail.kapsi.fi> 8beacf11bSopenharmony_ci * 9beacf11bSopenharmony_ci * Redistribution and use in source and binary forms, with or without 10beacf11bSopenharmony_ci * modification, are permitted provided that the following conditions 11beacf11bSopenharmony_ci * are met: 12beacf11bSopenharmony_ci * 13beacf11bSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 14beacf11bSopenharmony_ci * notice, this list of conditions and the following disclaimer. 15beacf11bSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 16beacf11bSopenharmony_ci * notice, this list of conditions and the following disclaimer in 17beacf11bSopenharmony_ci * the documentation and/or other materials provided with the 18beacf11bSopenharmony_ci * distribution. 19beacf11bSopenharmony_ci * 3. Neither the name NuttX nor the names of its contributors may be 20beacf11bSopenharmony_ci * used to endorse or promote products derived from this software 21beacf11bSopenharmony_ci * without specific prior written permission. 22beacf11bSopenharmony_ci * 23beacf11bSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24beacf11bSopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25beacf11bSopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26beacf11bSopenharmony_ci * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27beacf11bSopenharmony_ci * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28beacf11bSopenharmony_ci * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29beacf11bSopenharmony_ci * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30beacf11bSopenharmony_ci * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31beacf11bSopenharmony_ci * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32beacf11bSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33beacf11bSopenharmony_ci * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34beacf11bSopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 35beacf11bSopenharmony_ci * 36beacf11bSopenharmony_ci ****************************************************************************/ 37beacf11bSopenharmony_ci/**************************************************************************** 38beacf11bSopenharmony_ci * Notice of Export Control Law 39beacf11bSopenharmony_ci * =============================================== 40beacf11bSopenharmony_ci * Huawei LiteOS may be subject to applicable export control laws and regulations, 41beacf11bSopenharmony_ci * which might include those applicable to Huawei LiteOS of U.S. and the country in 42beacf11bSopenharmony_ci * which you are located. 43beacf11bSopenharmony_ci * Import, export and usage of Huawei LiteOS in any manner by you shall be in 44beacf11bSopenharmony_ci * compliance with such applicable export control laws and regulations. 45beacf11bSopenharmony_ci ****************************************************************************/ 46beacf11bSopenharmony_ci 47beacf11bSopenharmony_ci/* This is a driver for the USB Device Firmware Upgrade protocol v1.1. 48beacf11bSopenharmony_ci * Currently it supports the app-side ("Run-Time") part of the protocol: 49beacf11bSopenharmony_ci * a sequence of DFU_DETACH and USB reset commands, which will reboot into 50beacf11bSopenharmony_ci * a separate USB DFU bootloader. 51beacf11bSopenharmony_ci * 52beacf11bSopenharmony_ci * The bootloader is provided by board-specific logic, or STM32's 53beacf11bSopenharmony_ci * built-in ROM bootloader can be used. 54beacf11bSopenharmony_ci * 55beacf11bSopenharmony_ci * https://www.usb.org/sites/default/files/DFU_1.1.pdf 56beacf11bSopenharmony_ci */ 57beacf11bSopenharmony_ci 58beacf11bSopenharmony_ci/**************************************************************************** 59beacf11bSopenharmony_ci * Included Files 60beacf11bSopenharmony_ci ****************************************************************************/ 61beacf11bSopenharmony_ci 62beacf11bSopenharmony_ci#include <errno.h> 63beacf11bSopenharmony_ci#include <string.h> 64beacf11bSopenharmony_ci#include <stdlib.h> 65beacf11bSopenharmony_ci#include <stdio.h> 66beacf11bSopenharmony_ci#include "gadget/composite.h" 67beacf11bSopenharmony_ci#include "gadget/f_dfu.h" 68beacf11bSopenharmony_ci 69beacf11bSopenharmony_ci/**************************************************************************** 70beacf11bSopenharmony_ci * Pre-processor definitions 71beacf11bSopenharmony_ci ****************************************************************************/ 72beacf11bSopenharmony_ci 73beacf11bSopenharmony_ci#define DFU_MAX_TIMEOUT 255 74beacf11bSopenharmony_ci#define DFU_MAX_TRANSFER 4096 75beacf11bSopenharmony_ci#define DFU_VERSION 0x0110 76beacf11bSopenharmony_ci 77beacf11bSopenharmony_ci/* All 16-bit values must be little-endian */ 78beacf11bSopenharmony_ci 79beacf11bSopenharmony_ci#define MSBYTE(u16) ((u16) >> 8) /* Get MS byte from uint16_t */ 80beacf11bSopenharmony_ci#define LSBYTE(u16) ((u16) & 0xff) /* Get LS byte from uint16_t */ 81beacf11bSopenharmony_ci 82beacf11bSopenharmony_ci/**************************************************************************** 83beacf11bSopenharmony_ci * Private Types 84beacf11bSopenharmony_ci ****************************************************************************/ 85beacf11bSopenharmony_ci 86beacf11bSopenharmony_ci/* DFU functional descriptor */ 87beacf11bSopenharmony_ci 88beacf11bSopenharmony_cistruct dfu_funcdesc_s 89beacf11bSopenharmony_ci{ 90beacf11bSopenharmony_ci uint8_t len; /* Descriptor length */ 91beacf11bSopenharmony_ci uint8_t type; /* 0x21 = DFU FUNCTIONAL */ 92beacf11bSopenharmony_ci uint8_t attributes; /* Bit mask of supported features */ 93beacf11bSopenharmony_ci uint8_t detach_timeout[2]; /* Maximum time in milliseconds between DFU_DETACH and USB reset */ 94beacf11bSopenharmony_ci uint8_t transfer_size[2]; /* Maximum number of bytes in control writes */ 95beacf11bSopenharmony_ci uint8_t dfu_version[2]; /* Version of DFU specification supported */ 96beacf11bSopenharmony_ci}; 97beacf11bSopenharmony_ci 98beacf11bSopenharmony_ci/* USB configuration descriptor */ 99beacf11bSopenharmony_ci 100beacf11bSopenharmony_cistruct dfu_cfgdesc_s 101beacf11bSopenharmony_ci{ 102beacf11bSopenharmony_ci struct usb_interface_descriptor ifdesc; /* DFU interface descriptor */ 103beacf11bSopenharmony_ci struct dfu_funcdesc_s funcdesc; /* DFU functional descriptor */ 104beacf11bSopenharmony_ci}; 105beacf11bSopenharmony_ci 106beacf11bSopenharmony_cistruct dfu_driver_s 107beacf11bSopenharmony_ci{ 108beacf11bSopenharmony_ci struct usbdevclass_driver_s drvr; 109beacf11bSopenharmony_ci FAR struct usbdev_req_s *ctrlreq; /* Pointer to preallocated control request */ 110beacf11bSopenharmony_ci}; 111beacf11bSopenharmony_ci 112beacf11bSopenharmony_ci/**************************************************************************** 113beacf11bSopenharmony_ci * Private Function Prototypes 114beacf11bSopenharmony_ci ****************************************************************************/ 115beacf11bSopenharmony_ci 116beacf11bSopenharmony_ci/* usbclass callbacks */ 117beacf11bSopenharmony_ci 118beacf11bSopenharmony_cistatic int usbclass_setup(FAR struct usbdevclass_driver_s *driver, 119beacf11bSopenharmony_ci FAR struct usbdev_s *dev, 120beacf11bSopenharmony_ci FAR const struct usb_device_request *ctrl, 121beacf11bSopenharmony_ci FAR uint8_t *dataout, size_t outlen); 122beacf11bSopenharmony_cistatic int usbclass_bind(FAR struct usbdevclass_driver_s *driver, 123beacf11bSopenharmony_ci FAR struct usbdev_s *dev); 124beacf11bSopenharmony_cistatic int usbclass_unbind(FAR struct usbdevclass_driver_s *driver, 125beacf11bSopenharmony_ci FAR struct usbdev_s *dev); 126beacf11bSopenharmony_cistatic void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, 127beacf11bSopenharmony_ci FAR struct usbdev_s *dev); 128beacf11bSopenharmony_ci 129beacf11bSopenharmony_ci/**************************************************************************** 130beacf11bSopenharmony_ci * Private Data 131beacf11bSopenharmony_ci ****************************************************************************/ 132beacf11bSopenharmony_ci 133beacf11bSopenharmony_ci/* USB driver operations */ 134beacf11bSopenharmony_ci 135beacf11bSopenharmony_ciconst static struct usbdevclass_driverops_s g_dfu_driverops = 136beacf11bSopenharmony_ci{ 137beacf11bSopenharmony_ci &usbclass_bind, 138beacf11bSopenharmony_ci &usbclass_unbind, 139beacf11bSopenharmony_ci &usbclass_setup, 140beacf11bSopenharmony_ci &usbclass_disconnect, 141beacf11bSopenharmony_ci NULL, 142beacf11bSopenharmony_ci NULL 143beacf11bSopenharmony_ci}; 144beacf11bSopenharmony_ci 145beacf11bSopenharmony_cistatic struct dfu_cfgdesc_s g_dfu_cfgdesc = 146beacf11bSopenharmony_ci{ 147beacf11bSopenharmony_ci { 148beacf11bSopenharmony_ci .bLength = sizeof(struct usb_interface_descriptor), 149beacf11bSopenharmony_ci .bDescriptorType = UDESC_INTERFACE, 150beacf11bSopenharmony_ci .bInterfaceNumber = 0, 151beacf11bSopenharmony_ci .bAlternateSetting = 0, 152beacf11bSopenharmony_ci .bNumEndpoints = 0, 153beacf11bSopenharmony_ci .bInterfaceClass = 0xFE, 154beacf11bSopenharmony_ci .bInterfaceSubClass = 0x01, 155beacf11bSopenharmony_ci .bInterfaceProtocol = 0x01, /* DFU runtime protocol */ 156beacf11bSopenharmony_ci .iInterface = 0x01 157beacf11bSopenharmony_ci }, 158beacf11bSopenharmony_ci { 159beacf11bSopenharmony_ci .len = sizeof(struct dfu_funcdesc_s), 160beacf11bSopenharmony_ci .type = 0x21, 161beacf11bSopenharmony_ci .attributes = 0x0F, 162beacf11bSopenharmony_ci .detach_timeout = { LSBYTE(DFU_MAX_TIMEOUT), MSBYTE(DFU_MAX_TIMEOUT) }, 163beacf11bSopenharmony_ci .transfer_size = { LSBYTE(DFU_MAX_TRANSFER), MSBYTE(DFU_MAX_TRANSFER) }, 164beacf11bSopenharmony_ci .dfu_version = { LSBYTE(DFU_VERSION), MSBYTE(DFU_VERSION) } 165beacf11bSopenharmony_ci } 166beacf11bSopenharmony_ci}; 167beacf11bSopenharmony_ci 168beacf11bSopenharmony_civoid to_runtime_mode(void) 169beacf11bSopenharmony_ci{ 170beacf11bSopenharmony_ci g_dfu_cfgdesc.ifdesc.bInterfaceProtocol = 0x01; /* The runtime mode */ 171beacf11bSopenharmony_ci} 172beacf11bSopenharmony_ci 173beacf11bSopenharmony_civoid to_dfu_mode(void) 174beacf11bSopenharmony_ci{ 175beacf11bSopenharmony_ci g_dfu_cfgdesc.ifdesc.bInterfaceProtocol = 0x02; /* The DFU mode */ 176beacf11bSopenharmony_ci} 177beacf11bSopenharmony_ci 178beacf11bSopenharmony_ci/**************************************************************************** 179beacf11bSopenharmony_ci * Private Functions 180beacf11bSopenharmony_ci ****************************************************************************/ 181beacf11bSopenharmony_ci 182beacf11bSopenharmony_cistatic void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep, 183beacf11bSopenharmony_ci FAR struct usbdev_req_s *req) 184beacf11bSopenharmony_ci{ 185beacf11bSopenharmony_ci (void)ep; 186beacf11bSopenharmony_ci (void)req; 187beacf11bSopenharmony_ci} 188beacf11bSopenharmony_ci 189beacf11bSopenharmony_cistatic void usbclass_mkdevdesc(uint8_t *buf) 190beacf11bSopenharmony_ci{ 191beacf11bSopenharmony_ci usbdev_dfu_mkdevdesc(buf); 192beacf11bSopenharmony_ci} 193beacf11bSopenharmony_ci 194beacf11bSopenharmony_cistatic int16_t usbclass_mkcfgdesc(FAR uint8_t *buf, 195beacf11bSopenharmony_ci FAR struct usbdev_devinfo_s *devinfo) 196beacf11bSopenharmony_ci{ 197beacf11bSopenharmony_ci int16_t total_len = 0; 198beacf11bSopenharmony_ci int16_t len = USB_CONFIG_DESC_SIZE; 199beacf11bSopenharmony_ci int ret; 200beacf11bSopenharmony_ci 201beacf11bSopenharmony_ci /* Modify according to the actual length. */ 202beacf11bSopenharmony_ci 203beacf11bSopenharmony_ci USETW(g_dfu_config_desc.wTotalLength, (USB_CONFIG_DESC_SIZE + sizeof(g_dfu_cfgdesc))); 204beacf11bSopenharmony_ci 205beacf11bSopenharmony_ci /* Copy DFU device configure descriptor. */ 206beacf11bSopenharmony_ci 207beacf11bSopenharmony_ci ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_dfu_config_desc, (uint16_t)len); 208beacf11bSopenharmony_ci if (ret != EOK) 209beacf11bSopenharmony_ci { 210beacf11bSopenharmony_ci usb_err("memcpy_s fail, ret:%d\n", ret); 211beacf11bSopenharmony_ci return -1; 212beacf11bSopenharmony_ci } 213beacf11bSopenharmony_ci total_len += len; 214beacf11bSopenharmony_ci 215beacf11bSopenharmony_ci /* Copy DFU device function descriptor. */ 216beacf11bSopenharmony_ci 217beacf11bSopenharmony_ci buf += USB_CONFIG_DESC_SIZE; 218beacf11bSopenharmony_ci len = sizeof(g_dfu_cfgdesc); 219beacf11bSopenharmony_ci ret = memcpy_s(buf, (size_t)(USB_COMP_EP0_BUFSIZ - total_len), &g_dfu_cfgdesc, (uint16_t)len); 220beacf11bSopenharmony_ci if (ret != EOK) 221beacf11bSopenharmony_ci { 222beacf11bSopenharmony_ci usb_err("memcpy_s fail, ret:%d\n", ret); 223beacf11bSopenharmony_ci return -1; 224beacf11bSopenharmony_ci } 225beacf11bSopenharmony_ci total_len += len; 226beacf11bSopenharmony_ci 227beacf11bSopenharmony_ci return total_len; 228beacf11bSopenharmony_ci} 229beacf11bSopenharmony_ci 230beacf11bSopenharmony_cistatic int usbclass_mkstrdesc(uint8_t id, uint8_t *buf) 231beacf11bSopenharmony_ci{ 232beacf11bSopenharmony_ci return usbdev_dfu_mkstrdesc(id, buf); 233beacf11bSopenharmony_ci} 234beacf11bSopenharmony_ci 235beacf11bSopenharmony_cistatic int usbclass_setup(FAR struct usbdevclass_driver_s *driver, 236beacf11bSopenharmony_ci FAR struct usbdev_s *dev, 237beacf11bSopenharmony_ci FAR const struct usb_device_request *ctrl, 238beacf11bSopenharmony_ci FAR uint8_t *dataout, size_t outlen) 239beacf11bSopenharmony_ci{ 240beacf11bSopenharmony_ci FAR struct dfu_driver_s *priv = (FAR struct dfu_driver_s *)driver; 241beacf11bSopenharmony_ci FAR struct usbdev_req_s *ctrlreq = priv->ctrlreq; 242beacf11bSopenharmony_ci uint16_t value; 243beacf11bSopenharmony_ci uint16_t len; 244beacf11bSopenharmony_ci int ret = -EOPNOTSUPP; 245beacf11bSopenharmony_ci 246beacf11bSopenharmony_ci (void)dataout; 247beacf11bSopenharmony_ci (void)outlen; 248beacf11bSopenharmony_ci 249beacf11bSopenharmony_ci value = UGETW(ctrl->wValue); 250beacf11bSopenharmony_ci len = UGETW(ctrl->wLength); 251beacf11bSopenharmony_ci 252beacf11bSopenharmony_ci if ((ctrl->bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) 253beacf11bSopenharmony_ci { 254beacf11bSopenharmony_ci if (ctrl->bRequest == USB_REQ_SET_CONFIGURATION) 255beacf11bSopenharmony_ci { 256beacf11bSopenharmony_ci usbdev_dfu_set_config(); 257beacf11bSopenharmony_ci return 0; /* Composite driver will send the reply */ 258beacf11bSopenharmony_ci } 259beacf11bSopenharmony_ci else if (ctrl->bRequest == USB_REQ_SET_INTERFACE) 260beacf11bSopenharmony_ci { 261beacf11bSopenharmony_ci /* Only one alternate setting (0) is supported */ 262beacf11bSopenharmony_ci 263beacf11bSopenharmony_ci if (value == 0) 264beacf11bSopenharmony_ci { 265beacf11bSopenharmony_ci ret = 0; 266beacf11bSopenharmony_ci } 267beacf11bSopenharmony_ci } 268beacf11bSopenharmony_ci else if (ctrl->bRequest == USB_REQ_GET_INTERFACE) 269beacf11bSopenharmony_ci { 270beacf11bSopenharmony_ci *(FAR uint8_t *)ctrlreq->buf = 0; 271beacf11bSopenharmony_ci ret = 1; 272beacf11bSopenharmony_ci } 273beacf11bSopenharmony_ci } 274beacf11bSopenharmony_ci else if ((ctrl->bmRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) 275beacf11bSopenharmony_ci { 276beacf11bSopenharmony_ci ret = usbdev_dfu_class_requests(dev, ctrl, ctrlreq); 277beacf11bSopenharmony_ci } 278beacf11bSopenharmony_ci 279beacf11bSopenharmony_ci /* Respond to the setup command if data was returned. On an error return 280beacf11bSopenharmony_ci * value (ret < 0), the USB driver will stall. 281beacf11bSopenharmony_ci */ 282beacf11bSopenharmony_ci 283beacf11bSopenharmony_ci if (ret >= 0) 284beacf11bSopenharmony_ci { 285beacf11bSopenharmony_ci ctrlreq->len = (len < ret) ? len : (uint32_t)ret; 286beacf11bSopenharmony_ci ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT; 287beacf11bSopenharmony_ci ret = EP_SUBMIT(dev->ep0, ctrlreq); 288beacf11bSopenharmony_ci if (ret < 0) 289beacf11bSopenharmony_ci { 290beacf11bSopenharmony_ci usb_err("req submit failed!\r\n"); 291beacf11bSopenharmony_ci ctrlreq->result = OK; 292beacf11bSopenharmony_ci } 293beacf11bSopenharmony_ci } 294beacf11bSopenharmony_ci 295beacf11bSopenharmony_ci return ret; 296beacf11bSopenharmony_ci} 297beacf11bSopenharmony_ci 298beacf11bSopenharmony_cistatic int usbclass_bind(FAR struct usbdevclass_driver_s *driver, 299beacf11bSopenharmony_ci FAR struct usbdev_s *dev) 300beacf11bSopenharmony_ci{ 301beacf11bSopenharmony_ci FAR struct dfu_driver_s *priv = (FAR struct dfu_driver_s *)driver; 302beacf11bSopenharmony_ci struct composite_dev_s *cdev = dev->ep0->priv; 303beacf11bSopenharmony_ci 304beacf11bSopenharmony_ci priv->ctrlreq = cdev->ctrlreq; 305beacf11bSopenharmony_ci if (priv->ctrlreq == NULL) 306beacf11bSopenharmony_ci { 307beacf11bSopenharmony_ci usb_err("Ctrlreq is NULL!\r\n"); 308beacf11bSopenharmony_ci return -ENOMEM; 309beacf11bSopenharmony_ci } 310beacf11bSopenharmony_ci 311beacf11bSopenharmony_ci priv->ctrlreq->callback = usbclass_ep0incomplete; 312beacf11bSopenharmony_ci 313beacf11bSopenharmony_ci return OK; 314beacf11bSopenharmony_ci} 315beacf11bSopenharmony_ci 316beacf11bSopenharmony_cistatic int usbclass_unbind(FAR struct usbdevclass_driver_s *driver, 317beacf11bSopenharmony_ci FAR struct usbdev_s *dev) 318beacf11bSopenharmony_ci{ 319beacf11bSopenharmony_ci FAR struct dfu_driver_s *priv = (FAR struct dfu_driver_s *)driver; 320beacf11bSopenharmony_ci 321beacf11bSopenharmony_ci (void)dev; 322beacf11bSopenharmony_ci 323beacf11bSopenharmony_ci if (usb_dfu_running()) 324beacf11bSopenharmony_ci { 325beacf11bSopenharmony_ci PRINT_ERR("%s fail, dfu busy\n", __FUNCTION__); 326beacf11bSopenharmony_ci return -1; 327beacf11bSopenharmony_ci } 328beacf11bSopenharmony_ci 329beacf11bSopenharmony_ci if (priv->ctrlreq != NULL) 330beacf11bSopenharmony_ci { 331beacf11bSopenharmony_ci priv->ctrlreq = NULL; 332beacf11bSopenharmony_ci } 333beacf11bSopenharmony_ci usbdev_dfu_init(); 334beacf11bSopenharmony_ci 335beacf11bSopenharmony_ci return 0; 336beacf11bSopenharmony_ci} 337beacf11bSopenharmony_ci 338beacf11bSopenharmony_cistatic void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, 339beacf11bSopenharmony_ci FAR struct usbdev_s *dev) 340beacf11bSopenharmony_ci{ 341beacf11bSopenharmony_ci (void)driver; 342beacf11bSopenharmony_ci (void)dev; 343beacf11bSopenharmony_ci 344beacf11bSopenharmony_ci usbdev_dfu_transaction_cleanup(); 345beacf11bSopenharmony_ci dprintf("reset config\n"); 346beacf11bSopenharmony_ci} 347beacf11bSopenharmony_ci 348beacf11bSopenharmony_ci/**************************************************************************** 349beacf11bSopenharmony_ci * Name: usbclass_classobject 350beacf11bSopenharmony_ci * 351beacf11bSopenharmony_ci * Description: 352beacf11bSopenharmony_ci * Allocate memory for the RNDIS driver class object 353beacf11bSopenharmony_ci * 354beacf11bSopenharmony_ci * Returned Value: 355beacf11bSopenharmony_ci * 0 on success, negative error code on failure. 356beacf11bSopenharmony_ci * 357beacf11bSopenharmony_ci ****************************************************************************/ 358beacf11bSopenharmony_ci 359beacf11bSopenharmony_cistatic int usbclass_classobject(int minor, 360beacf11bSopenharmony_ci FAR struct usbdev_devinfo_s *devinfo, 361beacf11bSopenharmony_ci FAR struct usbdevclass_driver_s **classdev) 362beacf11bSopenharmony_ci{ 363beacf11bSopenharmony_ci FAR struct dfu_driver_s *alloc; 364beacf11bSopenharmony_ci 365beacf11bSopenharmony_ci (void)minor; 366beacf11bSopenharmony_ci (void)devinfo; 367beacf11bSopenharmony_ci 368beacf11bSopenharmony_ci alloc = malloc(sizeof(struct dfu_driver_s)); 369beacf11bSopenharmony_ci if (alloc == NULL) 370beacf11bSopenharmony_ci { 371beacf11bSopenharmony_ci return -ENOMEM; 372beacf11bSopenharmony_ci } 373beacf11bSopenharmony_ci 374beacf11bSopenharmony_ci *classdev = &alloc->drvr; 375beacf11bSopenharmony_ci 376beacf11bSopenharmony_ci alloc->drvr.speed = USB_SPEED_FULL; 377beacf11bSopenharmony_ci alloc->drvr.ops = &g_dfu_driverops; 378beacf11bSopenharmony_ci 379beacf11bSopenharmony_ci usbdev_dfu_dev_init(); 380beacf11bSopenharmony_ci 381beacf11bSopenharmony_ci return OK; 382beacf11bSopenharmony_ci} 383beacf11bSopenharmony_ci 384beacf11bSopenharmony_ci/**************************************************************************** 385beacf11bSopenharmony_ci * Name: usbclass_uninitialize 386beacf11bSopenharmony_ci * 387beacf11bSopenharmony_ci * Description: 388beacf11bSopenharmony_ci * Free allocated memory 389beacf11bSopenharmony_ci * 390beacf11bSopenharmony_ci * Returned Value: 391beacf11bSopenharmony_ci * 0 on success, negative error code on failure. 392beacf11bSopenharmony_ci * 393beacf11bSopenharmony_ci ****************************************************************************/ 394beacf11bSopenharmony_ci 395beacf11bSopenharmony_cistatic void usbclass_uninitialize(FAR struct usbdevclass_driver_s *classdev) 396beacf11bSopenharmony_ci{ 397beacf11bSopenharmony_ci usbdev_dfu_dev_deinit(); 398beacf11bSopenharmony_ci free(classdev); 399beacf11bSopenharmony_ci} 400beacf11bSopenharmony_ci 401beacf11bSopenharmony_ci/**************************************************************************** 402beacf11bSopenharmony_ci * Public Functions 403beacf11bSopenharmony_ci ****************************************************************************/ 404beacf11bSopenharmony_ci 405beacf11bSopenharmony_civoid usbdev_dfu_get_composite_devdesc(struct composite_devdesc_s *dev) 406beacf11bSopenharmony_ci{ 407beacf11bSopenharmony_ci (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0, sizeof(struct composite_devdesc_s)); 408beacf11bSopenharmony_ci 409beacf11bSopenharmony_ci dev->mkdevdesc = usbclass_mkdevdesc; 410beacf11bSopenharmony_ci dev->mkconfdesc = usbclass_mkcfgdesc; 411beacf11bSopenharmony_ci dev->mkstrdesc = usbclass_mkstrdesc; 412beacf11bSopenharmony_ci dev->classobject = usbclass_classobject; 413beacf11bSopenharmony_ci dev->uninitialize = usbclass_uninitialize; 414beacf11bSopenharmony_ci dev->nconfigs = 1; 415beacf11bSopenharmony_ci dev->configid = 0; 416beacf11bSopenharmony_ci dev->cfgdescsize = (int)sizeof(g_dfu_cfgdesc); 417beacf11bSopenharmony_ci dev->devinfo.ninterfaces = 1; 418beacf11bSopenharmony_ci dev->devinfo.nstrings = 1; 419beacf11bSopenharmony_ci dev->devinfo.nendpoints = 0; 420beacf11bSopenharmony_ci} 421