Home | History | Annotate | Download | only in gadget
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * f_dfu.c -- Device Firmware Update USB function
      4  *
      5  * Copyright (C) 2012 Samsung Electronics
      6  * authors: Andrzej Pietrasiewicz <andrzej.p (at) samsung.com>
      7  *          Lukasz Majewski <l.majewski (at) samsung.com>
      8  *
      9  * Based on OpenMoko u-boot: drivers/usb/usbdfu.c
     10  * (C) 2007 by OpenMoko, Inc.
     11  * Author: Harald Welte <laforge (at) openmoko.org>
     12  *
     13  * based on existing SAM7DFU code from OpenPCD:
     14  * (C) Copyright 2006 by Harald Welte <hwelte at hmw-consulting.de>
     15  */
     16 
     17 #include <errno.h>
     18 #include <common.h>
     19 #include <malloc.h>
     20 
     21 #include <linux/usb/ch9.h>
     22 #include <linux/usb/gadget.h>
     23 #include <linux/usb/composite.h>
     24 
     25 #include <dfu.h>
     26 #include <g_dnl.h>
     27 #include "f_dfu.h"
     28 
     29 struct f_dfu {
     30 	struct usb_function		usb_function;
     31 
     32 	struct usb_descriptor_header	**function;
     33 	struct usb_string		*strings;
     34 
     35 	/* when configured, we have one config */
     36 	u8				config;
     37 	u8				altsetting;
     38 	enum dfu_state			dfu_state;
     39 	unsigned int			dfu_status;
     40 
     41 	/* Send/received block number is handy for data integrity check */
     42 	int                             blk_seq_num;
     43 	unsigned int                    poll_timeout;
     44 };
     45 
     46 struct dfu_entity *dfu_defer_flush;
     47 
     48 typedef int (*dfu_state_fn) (struct f_dfu *,
     49 			     const struct usb_ctrlrequest *,
     50 			     struct usb_gadget *,
     51 			     struct usb_request *);
     52 
     53 static inline struct f_dfu *func_to_dfu(struct usb_function *f)
     54 {
     55 	return container_of(f, struct f_dfu, usb_function);
     56 }
     57 
     58 static const struct dfu_function_descriptor dfu_func = {
     59 	.bLength =		sizeof dfu_func,
     60 	.bDescriptorType =	DFU_DT_FUNC,
     61 	.bmAttributes =		DFU_BIT_WILL_DETACH |
     62 				DFU_BIT_MANIFESTATION_TOLERANT |
     63 				DFU_BIT_CAN_UPLOAD |
     64 				DFU_BIT_CAN_DNLOAD,
     65 	.wDetachTimeOut =	0,
     66 	.wTransferSize =	DFU_USB_BUFSIZ,
     67 	.bcdDFUVersion =	__constant_cpu_to_le16(0x0110),
     68 };
     69 
     70 static struct usb_interface_descriptor dfu_intf_runtime = {
     71 	.bLength =		sizeof dfu_intf_runtime,
     72 	.bDescriptorType =	USB_DT_INTERFACE,
     73 	.bNumEndpoints =	0,
     74 	.bInterfaceClass =	USB_CLASS_APP_SPEC,
     75 	.bInterfaceSubClass =	1,
     76 	.bInterfaceProtocol =	1,
     77 	/* .iInterface = DYNAMIC */
     78 };
     79 
     80 static struct usb_descriptor_header *dfu_runtime_descs[] = {
     81 	(struct usb_descriptor_header *) &dfu_intf_runtime,
     82 	NULL,
     83 };
     84 
     85 static const char dfu_name[] = "Device Firmware Upgrade";
     86 
     87 /*
     88  * static strings, in UTF-8
     89  *
     90  * dfu_generic configuration
     91  */
     92 static struct usb_string strings_dfu_generic[] = {
     93 	[0].s = dfu_name,
     94 	{  }			/* end of list */
     95 };
     96 
     97 static struct usb_gadget_strings stringtab_dfu_generic = {
     98 	.language	= 0x0409,	/* en-us */
     99 	.strings	= strings_dfu_generic,
    100 };
    101 
    102 static struct usb_gadget_strings *dfu_generic_strings[] = {
    103 	&stringtab_dfu_generic,
    104 	NULL,
    105 };
    106 
    107 /*
    108  * usb_function specific
    109  */
    110 static struct usb_gadget_strings stringtab_dfu = {
    111 	.language	= 0x0409,	/* en-us */
    112 	/*
    113 	 * .strings
    114 	 *
    115 	 * assigned during initialization,
    116 	 * depends on number of flash entities
    117 	 *
    118 	 */
    119 };
    120 
    121 static struct usb_gadget_strings *dfu_strings[] = {
    122 	&stringtab_dfu,
    123 	NULL,
    124 };
    125 
    126 static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms)
    127 {
    128 	/*
    129 	 * The bwPollTimeout DFU_GETSTATUS request payload provides information
    130 	 * about minimum time, in milliseconds, that the host should wait before
    131 	 * sending a subsequent DFU_GETSTATUS request
    132 	 *
    133 	 * This permits the device to vary the delay depending on its need to
    134 	 * erase or program the memory
    135 	 *
    136 	 */
    137 
    138 	unsigned char *p = (unsigned char *)&ms;
    139 
    140 	if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) {
    141 		dstat->bwPollTimeout[0] = 0;
    142 		dstat->bwPollTimeout[1] = 0;
    143 		dstat->bwPollTimeout[2] = 0;
    144 
    145 		return;
    146 	}
    147 
    148 	dstat->bwPollTimeout[0] = *p++;
    149 	dstat->bwPollTimeout[1] = *p++;
    150 	dstat->bwPollTimeout[2] = *p;
    151 }
    152 
    153 /*-------------------------------------------------------------------------*/
    154 
    155 static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req)
    156 {
    157 	struct f_dfu *f_dfu = req->context;
    158 	int ret;
    159 
    160 	ret = dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf,
    161 			req->actual, f_dfu->blk_seq_num);
    162 	if (ret) {
    163 		f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
    164 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    165 	}
    166 }
    167 
    168 static void dnload_request_flush(struct usb_ep *ep, struct usb_request *req)
    169 {
    170 	struct f_dfu *f_dfu = req->context;
    171 	dfu_set_defer_flush(dfu_get_entity(f_dfu->altsetting));
    172 }
    173 
    174 static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
    175 {
    176 	return dfu->poll_timeout ? dfu->poll_timeout(dfu) :
    177 		DFU_MANIFEST_POLL_TIMEOUT;
    178 }
    179 
    180 static int handle_getstatus(struct usb_request *req)
    181 {
    182 	struct dfu_status *dstat = (struct dfu_status *)req->buf;
    183 	struct f_dfu *f_dfu = req->context;
    184 	struct dfu_entity *dfu = dfu_get_entity(f_dfu->altsetting);
    185 
    186 	dfu_set_poll_timeout(dstat, 0);
    187 
    188 	switch (f_dfu->dfu_state) {
    189 	case DFU_STATE_dfuDNLOAD_SYNC:
    190 	case DFU_STATE_dfuDNBUSY:
    191 		f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_IDLE;
    192 		break;
    193 	case DFU_STATE_dfuMANIFEST_SYNC:
    194 		f_dfu->dfu_state = DFU_STATE_dfuMANIFEST;
    195 		break;
    196 	case DFU_STATE_dfuMANIFEST:
    197 		dfu_set_poll_timeout(dstat, dfu_get_manifest_timeout(dfu));
    198 		break;
    199 	default:
    200 		break;
    201 	}
    202 
    203 	if (f_dfu->poll_timeout)
    204 		if (!(f_dfu->blk_seq_num %
    205 		      (dfu_get_buf_size() / DFU_USB_BUFSIZ)))
    206 			dfu_set_poll_timeout(dstat, f_dfu->poll_timeout);
    207 
    208 	/* send status response */
    209 	dstat->bStatus = f_dfu->dfu_status;
    210 	dstat->bState = f_dfu->dfu_state;
    211 	dstat->iString = 0;
    212 
    213 	return sizeof(struct dfu_status);
    214 }
    215 
    216 static int handle_getstate(struct usb_request *req)
    217 {
    218 	struct f_dfu *f_dfu = req->context;
    219 
    220 	((u8 *)req->buf)[0] = f_dfu->dfu_state;
    221 	return sizeof(u8);
    222 }
    223 
    224 static inline void to_dfu_mode(struct f_dfu *f_dfu)
    225 {
    226 	f_dfu->usb_function.strings = dfu_strings;
    227 	f_dfu->usb_function.hs_descriptors = f_dfu->function;
    228 	f_dfu->usb_function.descriptors = f_dfu->function;
    229 	f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    230 }
    231 
    232 static inline void to_runtime_mode(struct f_dfu *f_dfu)
    233 {
    234 	f_dfu->usb_function.strings = NULL;
    235 	f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
    236 	f_dfu->usb_function.descriptors = dfu_runtime_descs;
    237 }
    238 
    239 static int handle_upload(struct usb_request *req, u16 len)
    240 {
    241 	struct f_dfu *f_dfu = req->context;
    242 
    243 	return dfu_read(dfu_get_entity(f_dfu->altsetting), req->buf,
    244 			req->length, f_dfu->blk_seq_num);
    245 }
    246 
    247 static int handle_dnload(struct usb_gadget *gadget, u16 len)
    248 {
    249 	struct usb_composite_dev *cdev = get_gadget_data(gadget);
    250 	struct usb_request *req = cdev->req;
    251 	struct f_dfu *f_dfu = req->context;
    252 
    253 	if (len == 0)
    254 		f_dfu->dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
    255 
    256 	req->complete = dnload_request_complete;
    257 
    258 	return len;
    259 }
    260 
    261 /*-------------------------------------------------------------------------*/
    262 /* DFU state machine  */
    263 static int state_app_idle(struct f_dfu *f_dfu,
    264 			  const struct usb_ctrlrequest *ctrl,
    265 			  struct usb_gadget *gadget,
    266 			  struct usb_request *req)
    267 {
    268 	int value = 0;
    269 
    270 	switch (ctrl->bRequest) {
    271 	case USB_REQ_DFU_GETSTATUS:
    272 		value = handle_getstatus(req);
    273 		break;
    274 	case USB_REQ_DFU_GETSTATE:
    275 		value = handle_getstate(req);
    276 		break;
    277 	case USB_REQ_DFU_DETACH:
    278 		f_dfu->dfu_state = DFU_STATE_appDETACH;
    279 		to_dfu_mode(f_dfu);
    280 		value = RET_ZLP;
    281 		break;
    282 	default:
    283 		value = RET_STALL;
    284 		break;
    285 	}
    286 
    287 	return value;
    288 }
    289 
    290 static int state_app_detach(struct f_dfu *f_dfu,
    291 			    const struct usb_ctrlrequest *ctrl,
    292 			    struct usb_gadget *gadget,
    293 			    struct usb_request *req)
    294 {
    295 	int value = 0;
    296 
    297 	switch (ctrl->bRequest) {
    298 	case USB_REQ_DFU_GETSTATUS:
    299 		value = handle_getstatus(req);
    300 		break;
    301 	case USB_REQ_DFU_GETSTATE:
    302 		value = handle_getstate(req);
    303 		break;
    304 	default:
    305 		f_dfu->dfu_state = DFU_STATE_appIDLE;
    306 		value = RET_STALL;
    307 		break;
    308 	}
    309 
    310 	return value;
    311 }
    312 
    313 static int state_dfu_idle(struct f_dfu *f_dfu,
    314 			  const struct usb_ctrlrequest *ctrl,
    315 			  struct usb_gadget *gadget,
    316 			  struct usb_request *req)
    317 {
    318 	u16 w_value = le16_to_cpu(ctrl->wValue);
    319 	u16 len = le16_to_cpu(ctrl->wLength);
    320 	int value = 0;
    321 
    322 	switch (ctrl->bRequest) {
    323 	case USB_REQ_DFU_DNLOAD:
    324 		if (len == 0) {
    325 			f_dfu->dfu_state = DFU_STATE_dfuERROR;
    326 			value = RET_STALL;
    327 			break;
    328 		}
    329 		f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
    330 		f_dfu->blk_seq_num = w_value;
    331 		value = handle_dnload(gadget, len);
    332 		break;
    333 	case USB_REQ_DFU_UPLOAD:
    334 		f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
    335 		f_dfu->blk_seq_num = 0;
    336 		value = handle_upload(req, len);
    337 		break;
    338 	case USB_REQ_DFU_ABORT:
    339 		/* no zlp? */
    340 		value = RET_ZLP;
    341 		break;
    342 	case USB_REQ_DFU_GETSTATUS:
    343 		value = handle_getstatus(req);
    344 		break;
    345 	case USB_REQ_DFU_GETSTATE:
    346 		value = handle_getstate(req);
    347 		break;
    348 	case USB_REQ_DFU_DETACH:
    349 		/*
    350 		 * Proprietary extension: 'detach' from idle mode and
    351 		 * get back to runtime mode in case of USB Reset.  As
    352 		 * much as I dislike this, we just can't use every USB
    353 		 * bus reset to switch back to runtime mode, since at
    354 		 * least the Linux USB stack likes to send a number of
    355 		 * resets in a row :(
    356 		 */
    357 		f_dfu->dfu_state =
    358 			DFU_STATE_dfuMANIFEST_WAIT_RST;
    359 		to_runtime_mode(f_dfu);
    360 		f_dfu->dfu_state = DFU_STATE_appIDLE;
    361 
    362 		g_dnl_trigger_detach();
    363 		break;
    364 	default:
    365 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    366 		value = RET_STALL;
    367 		break;
    368 	}
    369 
    370 	return value;
    371 }
    372 
    373 static int state_dfu_dnload_sync(struct f_dfu *f_dfu,
    374 				 const struct usb_ctrlrequest *ctrl,
    375 				 struct usb_gadget *gadget,
    376 				 struct usb_request *req)
    377 {
    378 	int value = 0;
    379 
    380 	switch (ctrl->bRequest) {
    381 	case USB_REQ_DFU_GETSTATUS:
    382 		value = handle_getstatus(req);
    383 		break;
    384 	case USB_REQ_DFU_GETSTATE:
    385 		value = handle_getstate(req);
    386 		break;
    387 	default:
    388 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    389 		value = RET_STALL;
    390 		break;
    391 	}
    392 
    393 	return value;
    394 }
    395 
    396 static int state_dfu_dnbusy(struct f_dfu *f_dfu,
    397 			    const struct usb_ctrlrequest *ctrl,
    398 			    struct usb_gadget *gadget,
    399 			    struct usb_request *req)
    400 {
    401 	int value = 0;
    402 
    403 	switch (ctrl->bRequest) {
    404 	case USB_REQ_DFU_GETSTATUS:
    405 		value = handle_getstatus(req);
    406 		break;
    407 	default:
    408 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    409 		value = RET_STALL;
    410 		break;
    411 	}
    412 
    413 	return value;
    414 }
    415 
    416 static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
    417 				 const struct usb_ctrlrequest *ctrl,
    418 				 struct usb_gadget *gadget,
    419 				 struct usb_request *req)
    420 {
    421 	u16 w_value = le16_to_cpu(ctrl->wValue);
    422 	u16 len = le16_to_cpu(ctrl->wLength);
    423 	int value = 0;
    424 
    425 	switch (ctrl->bRequest) {
    426 	case USB_REQ_DFU_DNLOAD:
    427 		f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
    428 		f_dfu->blk_seq_num = w_value;
    429 		value = handle_dnload(gadget, len);
    430 		break;
    431 	case USB_REQ_DFU_ABORT:
    432 		f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    433 		value = RET_ZLP;
    434 		break;
    435 	case USB_REQ_DFU_GETSTATUS:
    436 		value = handle_getstatus(req);
    437 		break;
    438 	case USB_REQ_DFU_GETSTATE:
    439 		value = handle_getstate(req);
    440 		break;
    441 	default:
    442 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    443 		value = RET_STALL;
    444 		break;
    445 	}
    446 
    447 	return value;
    448 }
    449 
    450 static int state_dfu_manifest_sync(struct f_dfu *f_dfu,
    451 				   const struct usb_ctrlrequest *ctrl,
    452 				   struct usb_gadget *gadget,
    453 				   struct usb_request *req)
    454 {
    455 	int value = 0;
    456 
    457 	switch (ctrl->bRequest) {
    458 	case USB_REQ_DFU_GETSTATUS:
    459 		/* We're MainfestationTolerant */
    460 		f_dfu->dfu_state = DFU_STATE_dfuMANIFEST;
    461 		value = handle_getstatus(req);
    462 		f_dfu->blk_seq_num = 0;
    463 		req->complete = dnload_request_flush;
    464 		break;
    465 	case USB_REQ_DFU_GETSTATE:
    466 		value = handle_getstate(req);
    467 		break;
    468 	default:
    469 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    470 		value = RET_STALL;
    471 		break;
    472 	}
    473 
    474 	return value;
    475 }
    476 
    477 static int state_dfu_manifest(struct f_dfu *f_dfu,
    478 			      const struct usb_ctrlrequest *ctrl,
    479 			      struct usb_gadget *gadget,
    480 			      struct usb_request *req)
    481 {
    482 	int value = 0;
    483 
    484 	switch (ctrl->bRequest) {
    485 	case USB_REQ_DFU_GETSTATUS:
    486 		/* We're MainfestationTolerant */
    487 		f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    488 		value = handle_getstatus(req);
    489 		f_dfu->blk_seq_num = 0;
    490 		puts("DOWNLOAD ... OK\nCtrl+C to exit ...\n");
    491 		break;
    492 	case USB_REQ_DFU_GETSTATE:
    493 		value = handle_getstate(req);
    494 		break;
    495 	default:
    496 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    497 		value = RET_STALL;
    498 		break;
    499 	}
    500 	return value;
    501 }
    502 
    503 static int state_dfu_upload_idle(struct f_dfu *f_dfu,
    504 				 const struct usb_ctrlrequest *ctrl,
    505 				 struct usb_gadget *gadget,
    506 				 struct usb_request *req)
    507 {
    508 	u16 w_value = le16_to_cpu(ctrl->wValue);
    509 	u16 len = le16_to_cpu(ctrl->wLength);
    510 	int value = 0;
    511 
    512 	switch (ctrl->bRequest) {
    513 	case USB_REQ_DFU_UPLOAD:
    514 		/* state transition if less data then requested */
    515 		f_dfu->blk_seq_num = w_value;
    516 		value = handle_upload(req, len);
    517 		if (value >= 0 && value < len)
    518 			f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    519 		break;
    520 	case USB_REQ_DFU_ABORT:
    521 		f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    522 		/* no zlp? */
    523 		value = RET_ZLP;
    524 		break;
    525 	case USB_REQ_DFU_GETSTATUS:
    526 		value = handle_getstatus(req);
    527 		break;
    528 	case USB_REQ_DFU_GETSTATE:
    529 		value = handle_getstate(req);
    530 		break;
    531 	default:
    532 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    533 		value = RET_STALL;
    534 		break;
    535 	}
    536 
    537 	return value;
    538 }
    539 
    540 static int state_dfu_error(struct f_dfu *f_dfu,
    541 				 const struct usb_ctrlrequest *ctrl,
    542 				 struct usb_gadget *gadget,
    543 				 struct usb_request *req)
    544 {
    545 	int value = 0;
    546 
    547 	switch (ctrl->bRequest) {
    548 	case USB_REQ_DFU_GETSTATUS:
    549 		value = handle_getstatus(req);
    550 		break;
    551 	case USB_REQ_DFU_GETSTATE:
    552 		value = handle_getstate(req);
    553 		break;
    554 	case USB_REQ_DFU_CLRSTATUS:
    555 		f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    556 		f_dfu->dfu_status = DFU_STATUS_OK;
    557 		/* no zlp? */
    558 		value = RET_ZLP;
    559 		break;
    560 	default:
    561 		f_dfu->dfu_state = DFU_STATE_dfuERROR;
    562 		value = RET_STALL;
    563 		break;
    564 	}
    565 
    566 	return value;
    567 }
    568 
    569 static dfu_state_fn dfu_state[] = {
    570 	state_app_idle,          /* DFU_STATE_appIDLE */
    571 	state_app_detach,        /* DFU_STATE_appDETACH */
    572 	state_dfu_idle,          /* DFU_STATE_dfuIDLE */
    573 	state_dfu_dnload_sync,   /* DFU_STATE_dfuDNLOAD_SYNC */
    574 	state_dfu_dnbusy,        /* DFU_STATE_dfuDNBUSY */
    575 	state_dfu_dnload_idle,   /* DFU_STATE_dfuDNLOAD_IDLE */
    576 	state_dfu_manifest_sync, /* DFU_STATE_dfuMANIFEST_SYNC */
    577 	state_dfu_manifest,	 /* DFU_STATE_dfuMANIFEST */
    578 	NULL,                    /* DFU_STATE_dfuMANIFEST_WAIT_RST */
    579 	state_dfu_upload_idle,   /* DFU_STATE_dfuUPLOAD_IDLE */
    580 	state_dfu_error          /* DFU_STATE_dfuERROR */
    581 };
    582 
    583 static int
    584 dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
    585 {
    586 	struct usb_gadget *gadget = f->config->cdev->gadget;
    587 	struct usb_request *req = f->config->cdev->req;
    588 	struct f_dfu *f_dfu = f->config->cdev->req->context;
    589 	u16 len = le16_to_cpu(ctrl->wLength);
    590 	u16 w_value = le16_to_cpu(ctrl->wValue);
    591 	int value = 0;
    592 	u8 req_type = ctrl->bRequestType & USB_TYPE_MASK;
    593 
    594 	debug("w_value: 0x%x len: 0x%x\n", w_value, len);
    595 	debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n",
    596 	       req_type, ctrl->bRequest, f_dfu->dfu_state);
    597 
    598 	if (req_type == USB_TYPE_STANDARD) {
    599 		if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR &&
    600 		    (w_value >> 8) == DFU_DT_FUNC) {
    601 			value = min(len, (u16) sizeof(dfu_func));
    602 			memcpy(req->buf, &dfu_func, value);
    603 		}
    604 	} else /* DFU specific request */
    605 		value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req);
    606 
    607 	if (value >= 0) {
    608 		req->length = value;
    609 		req->zero = value < len;
    610 		value = usb_ep_queue(gadget->ep0, req, 0);
    611 		if (value < 0) {
    612 			debug("ep_queue --> %d\n", value);
    613 			req->status = 0;
    614 		}
    615 	}
    616 
    617 	return value;
    618 }
    619 
    620 /*-------------------------------------------------------------------------*/
    621 
    622 static int
    623 dfu_prepare_strings(struct f_dfu *f_dfu, int n)
    624 {
    625 	struct dfu_entity *de = NULL;
    626 	int i = 0;
    627 
    628 	f_dfu->strings = calloc(sizeof(struct usb_string), n + 1);
    629 	if (!f_dfu->strings)
    630 		return -ENOMEM;
    631 
    632 	for (i = 0; i < n; ++i) {
    633 		de = dfu_get_entity(i);
    634 		f_dfu->strings[i].s = de->name;
    635 	}
    636 
    637 	f_dfu->strings[i].id = 0;
    638 	f_dfu->strings[i].s = NULL;
    639 
    640 	return 0;
    641 }
    642 
    643 static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
    644 {
    645 	struct usb_interface_descriptor *d;
    646 	int i = 0;
    647 
    648 	f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 2);
    649 	if (!f_dfu->function)
    650 		goto enomem;
    651 
    652 	for (i = 0; i < n; ++i) {
    653 		d = calloc(sizeof(*d), 1);
    654 		if (!d)
    655 			goto enomem;
    656 
    657 		d->bLength =		sizeof(*d);
    658 		d->bDescriptorType =	USB_DT_INTERFACE;
    659 		d->bAlternateSetting =	i;
    660 		d->bNumEndpoints =	0;
    661 		d->bInterfaceClass =	USB_CLASS_APP_SPEC;
    662 		d->bInterfaceSubClass =	1;
    663 		d->bInterfaceProtocol =	2;
    664 
    665 		f_dfu->function[i] = (struct usb_descriptor_header *)d;
    666 	}
    667 
    668 	/* add DFU Functional Descriptor */
    669 	f_dfu->function[i] = calloc(sizeof(dfu_func), 1);
    670 	if (!f_dfu->function[i])
    671 		goto enomem;
    672 	memcpy(f_dfu->function[i], &dfu_func, sizeof(dfu_func));
    673 
    674 	i++;
    675 	f_dfu->function[i] = NULL;
    676 
    677 	return 0;
    678 
    679 enomem:
    680 	while (i) {
    681 		free(f_dfu->function[--i]);
    682 		f_dfu->function[i] = NULL;
    683 	}
    684 	free(f_dfu->function);
    685 
    686 	return -ENOMEM;
    687 }
    688 
    689 static int dfu_bind(struct usb_configuration *c, struct usb_function *f)
    690 {
    691 	struct usb_composite_dev *cdev = c->cdev;
    692 	struct f_dfu *f_dfu = func_to_dfu(f);
    693 	const char *s;
    694 	int alt_num = dfu_get_alt_number();
    695 	int rv, id, i;
    696 
    697 	id = usb_interface_id(c, f);
    698 	if (id < 0)
    699 		return id;
    700 	dfu_intf_runtime.bInterfaceNumber = id;
    701 
    702 	f_dfu->dfu_state = DFU_STATE_appIDLE;
    703 	f_dfu->dfu_status = DFU_STATUS_OK;
    704 
    705 	rv = dfu_prepare_function(f_dfu, alt_num);
    706 	if (rv)
    707 		goto error;
    708 
    709 	rv = dfu_prepare_strings(f_dfu, alt_num);
    710 	if (rv)
    711 		goto error;
    712 	for (i = 0; i < alt_num; i++) {
    713 		id = usb_string_id(cdev);
    714 		if (id < 0)
    715 			return id;
    716 		f_dfu->strings[i].id = id;
    717 		((struct usb_interface_descriptor *)f_dfu->function[i])
    718 			->iInterface = id;
    719 	}
    720 
    721 	to_dfu_mode(f_dfu);
    722 
    723 	stringtab_dfu.strings = f_dfu->strings;
    724 
    725 	cdev->req->context = f_dfu;
    726 
    727 	s = env_get("serial#");
    728 	if (s)
    729 		g_dnl_set_serialnumber((char *)s);
    730 
    731 error:
    732 	return rv;
    733 }
    734 
    735 static void dfu_unbind(struct usb_configuration *c, struct usb_function *f)
    736 {
    737 	struct f_dfu *f_dfu = func_to_dfu(f);
    738 	int alt_num = dfu_get_alt_number();
    739 	int i;
    740 
    741 	if (f_dfu->strings) {
    742 		i = alt_num;
    743 		while (i)
    744 			f_dfu->strings[--i].s = NULL;
    745 
    746 		free(f_dfu->strings);
    747 	}
    748 
    749 	if (f_dfu->function) {
    750 		i = alt_num;
    751 		while (i) {
    752 			free(f_dfu->function[--i]);
    753 			f_dfu->function[i] = NULL;
    754 		}
    755 		free(f_dfu->function);
    756 	}
    757 
    758 	free(f_dfu);
    759 }
    760 
    761 static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
    762 {
    763 	struct f_dfu *f_dfu = func_to_dfu(f);
    764 
    765 	debug("%s: intf:%d alt:%d\n", __func__, intf, alt);
    766 
    767 	f_dfu->altsetting = alt;
    768 	f_dfu->dfu_state = DFU_STATE_dfuIDLE;
    769 	f_dfu->dfu_status = DFU_STATUS_OK;
    770 
    771 	return 0;
    772 }
    773 
    774 static int __dfu_get_alt(struct usb_function *f, unsigned intf)
    775 {
    776 	struct f_dfu *f_dfu = func_to_dfu(f);
    777 
    778 	return f_dfu->altsetting;
    779 }
    780 
    781 /* TODO: is this really what we need here? */
    782 static void dfu_disable(struct usb_function *f)
    783 {
    784 	struct f_dfu *f_dfu = func_to_dfu(f);
    785 	if (f_dfu->config == 0)
    786 		return;
    787 
    788 	debug("%s: reset config\n", __func__);
    789 
    790 	f_dfu->config = 0;
    791 }
    792 
    793 static int dfu_bind_config(struct usb_configuration *c)
    794 {
    795 	struct f_dfu *f_dfu;
    796 	int status;
    797 
    798 	f_dfu = calloc(sizeof(*f_dfu), 1);
    799 	if (!f_dfu)
    800 		return -ENOMEM;
    801 	f_dfu->usb_function.name = "dfu";
    802 	f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
    803 	f_dfu->usb_function.descriptors = dfu_runtime_descs;
    804 	f_dfu->usb_function.bind = dfu_bind;
    805 	f_dfu->usb_function.unbind = dfu_unbind;
    806 	f_dfu->usb_function.set_alt = dfu_set_alt;
    807 	f_dfu->usb_function.get_alt = __dfu_get_alt;
    808 	f_dfu->usb_function.disable = dfu_disable;
    809 	f_dfu->usb_function.strings = dfu_generic_strings;
    810 	f_dfu->usb_function.setup = dfu_handle;
    811 	f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
    812 
    813 	status = usb_add_function(c, &f_dfu->usb_function);
    814 	if (status)
    815 		free(f_dfu);
    816 
    817 	return status;
    818 }
    819 
    820 int dfu_add(struct usb_configuration *c)
    821 {
    822 	int id;
    823 
    824 	id = usb_string_id(c->cdev);
    825 	if (id < 0)
    826 		return id;
    827 	strings_dfu_generic[0].id = id;
    828 	dfu_intf_runtime.iInterface = id;
    829 
    830 	debug("%s: cdev: 0x%p gadget:0x%p gadget->ep0: 0x%p\n", __func__,
    831 	       c->cdev, c->cdev->gadget, c->cdev->gadget->ep0);
    832 
    833 	return dfu_bind_config(c);
    834 }
    835 
    836 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_dfu, dfu_add);
    837