Merge branch '2020-05-08-assorted-fixes'
[oweals/u-boot.git] / drivers / usb / gadget / f_sdp.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * f_sdp.c -- USB HID Serial Download Protocol
4  *
5  * Copyright (C) 2017 Toradex
6  * Author: Stefan Agner <stefan.agner@toradex.com>
7  *
8  * This file implements the Serial Download Protocol (SDP) as specified in
9  * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
10  * allows to download images directly to memory. The implementation
11  * works with the imx_loader (imx_usb) USB client software on host side.
12  *
13  * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
14  * SKIP_DCD_HEADER are only stubs.
15  *
16  * Parts of the implementation are based on f_dfu and f_thor.
17  */
18
19 #include <errno.h>
20 #include <common.h>
21 #include <console.h>
22 #include <env.h>
23 #include <malloc.h>
24
25 #include <linux/usb/ch9.h>
26 #include <linux/usb/gadget.h>
27 #include <linux/usb/composite.h>
28
29 #include <asm/io.h>
30 #include <g_dnl.h>
31 #include <sdp.h>
32 #include <spl.h>
33 #include <image.h>
34 #include <imximage.h>
35 #include <watchdog.h>
36
37 #define HID_REPORT_ID_MASK      0x000000ff
38
39 /*
40  * HID class requests
41  */
42 #define HID_REQ_GET_REPORT              0x01
43 #define HID_REQ_GET_IDLE                0x02
44 #define HID_REQ_GET_PROTOCOL            0x03
45 #define HID_REQ_SET_REPORT              0x09
46 #define HID_REQ_SET_IDLE                0x0A
47 #define HID_REQ_SET_PROTOCOL            0x0B
48
49 #define HID_USAGE_PAGE_LEN              76
50
51 struct hid_report {
52         u8 usage_page[HID_USAGE_PAGE_LEN];
53 } __packed;
54
55 #define SDP_READ_REGISTER       0x0101
56 #define SDP_WRITE_REGISTER      0x0202
57 #define SDP_WRITE_FILE          0x0404
58 #define SDP_ERROR_STATUS        0x0505
59 #define SDP_DCD_WRITE           0x0a0a
60 #define SDP_JUMP_ADDRESS        0x0b0b
61 #define SDP_SKIP_DCD_HEADER     0x0c0c
62
63 #define SDP_SECURITY_CLOSED             0x12343412
64 #define SDP_SECURITY_OPEN               0x56787856
65
66 #define SDP_WRITE_FILE_COMPLETE         0x88888888
67 #define SDP_WRITE_REGISTER_COMPLETE     0x128A8A12
68 #define SDP_SKIP_DCD_HEADER_COMPLETE    0x900DD009
69 #define SDP_ERROR_IMXHEADER             0x000a0533
70
71 #define SDP_COMMAND_LEN         16
72
73 struct sdp_command {
74         u16 cmd;
75         u32 addr;
76         u8 format;
77         u32 cnt;
78         u32 data;
79         u8 rsvd;
80 } __packed;
81
82 enum sdp_state {
83         SDP_STATE_IDLE,
84         SDP_STATE_RX_DCD_DATA,
85         SDP_STATE_RX_FILE_DATA,
86         SDP_STATE_TX_SEC_CONF,
87         SDP_STATE_TX_SEC_CONF_BUSY,
88         SDP_STATE_TX_REGISTER,
89         SDP_STATE_TX_REGISTER_BUSY,
90         SDP_STATE_TX_STATUS,
91         SDP_STATE_TX_STATUS_BUSY,
92         SDP_STATE_JUMP,
93 };
94
95 struct f_sdp {
96         struct usb_function             usb_function;
97
98         struct usb_descriptor_header    **function;
99
100         u8                              altsetting;
101         enum sdp_state                  state;
102         enum sdp_state                  next_state;
103         u32                             dnl_address;
104         u32                             dnl_bytes;
105         u32                             dnl_bytes_remaining;
106         u32                             jmp_address;
107         bool                            always_send_status;
108         u32                             error_status;
109
110         /* EP0 request */
111         struct usb_request              *req;
112
113         /* EP1 IN */
114         struct usb_ep                   *in_ep;
115         struct usb_request              *in_req;
116
117         bool                            configuration_done;
118 };
119
120 static struct f_sdp *sdp_func;
121
122 static inline struct f_sdp *func_to_sdp(struct usb_function *f)
123 {
124         return container_of(f, struct f_sdp, usb_function);
125 }
126
127 static struct usb_interface_descriptor sdp_intf_runtime = {
128         .bLength =              sizeof(sdp_intf_runtime),
129         .bDescriptorType =      USB_DT_INTERFACE,
130         .bAlternateSetting =    0,
131         .bNumEndpoints =        1,
132         .bInterfaceClass =      USB_CLASS_HID,
133         .bInterfaceSubClass =   0,
134         .bInterfaceProtocol =   0,
135         /* .iInterface = DYNAMIC */
136 };
137
138 /* HID configuration */
139 static struct usb_class_hid_descriptor sdp_hid_desc = {
140         .bLength =              sizeof(sdp_hid_desc),
141         .bDescriptorType =      USB_DT_CS_DEVICE,
142
143         .bcdCDC =               __constant_cpu_to_le16(0x0110),
144         .bCountryCode =         0,
145         .bNumDescriptors =      1,
146
147         .bDescriptorType0       = USB_DT_HID_REPORT,
148         .wDescriptorLength0     = HID_USAGE_PAGE_LEN,
149 };
150
151 static struct usb_endpoint_descriptor in_desc = {
152         .bLength =              USB_DT_ENDPOINT_SIZE,
153         .bDescriptorType =      USB_DT_ENDPOINT, /*USB_DT_CS_ENDPOINT*/
154
155         .bEndpointAddress =     1 | USB_DIR_IN,
156         .bmAttributes = USB_ENDPOINT_XFER_INT,
157         .wMaxPacketSize =       64,
158         .bInterval =            1,
159 };
160
161 static struct usb_descriptor_header *sdp_runtime_descs[] = {
162         (struct usb_descriptor_header *)&sdp_intf_runtime,
163         (struct usb_descriptor_header *)&sdp_hid_desc,
164         (struct usb_descriptor_header *)&in_desc,
165         NULL,
166 };
167
168 /* This is synchronized with what the SoC implementation reports */
169 static struct hid_report sdp_hid_report = {
170         .usage_page = {
171                 0x06, 0x00, 0xff, /* Usage Page */
172                 0x09, 0x01, /* Usage (Pointer?) */
173                 0xa1, 0x01, /* Collection */
174
175                 0x85, 0x01, /* Report ID */
176                 0x19, 0x01, /* Usage Minimum */
177                 0x29, 0x01, /* Usage Maximum */
178                 0x15, 0x00, /* Local Minimum */
179                 0x26, 0xFF, 0x00, /* Local Maximum? */
180                 0x75, 0x08, /* Report Size */
181                 0x95, 0x10, /* Report Count */
182                 0x91, 0x02, /* Output Data */
183
184                 0x85, 0x02, /* Report ID */
185                 0x19, 0x01, /* Usage Minimum */
186                 0x29, 0x01, /* Usage Maximum */
187                 0x15, 0x00, /* Local Minimum */
188                 0x26, 0xFF, 0x00, /* Local Maximum? */
189                 0x75, 0x80, /* Report Size 128 */
190                 0x95, 0x40, /* Report Count */
191                 0x91, 0x02, /* Output Data */
192
193                 0x85, 0x03, /* Report ID */
194                 0x19, 0x01, /* Usage Minimum */
195                 0x29, 0x01, /* Usage Maximum */
196                 0x15, 0x00, /* Local Minimum */
197                 0x26, 0xFF, 0x00, /* Local Maximum? */
198                 0x75, 0x08, /* Report Size 8 */
199                 0x95, 0x04, /* Report Count */
200                 0x81, 0x02, /* Input Data */
201
202                 0x85, 0x04, /* Report ID */
203                 0x19, 0x01, /* Usage Minimum */
204                 0x29, 0x01, /* Usage Maximum */
205                 0x15, 0x00, /* Local Minimum */
206                 0x26, 0xFF, 0x00, /* Local Maximum? */
207                 0x75, 0x08, /* Report Size 8 */
208                 0x95, 0x40, /* Report Count */
209                 0x81, 0x02, /* Input Data */
210                 0xc0
211         },
212 };
213
214 static const char sdp_name[] = "Serial Downloader Protocol";
215
216 /*
217  * static strings, in UTF-8
218  */
219 static struct usb_string strings_sdp_generic[] = {
220         [0].s = sdp_name,
221         {  }                    /* end of list */
222 };
223
224 static struct usb_gadget_strings stringtab_sdp_generic = {
225         .language       = 0x0409,       /* en-us */
226         .strings        = strings_sdp_generic,
227 };
228
229 static struct usb_gadget_strings *sdp_generic_strings[] = {
230         &stringtab_sdp_generic,
231         NULL,
232 };
233
234 static inline void *sdp_ptr(u32 val)
235 {
236         return (void *)(uintptr_t)val;
237 }
238
239 static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req)
240 {
241         struct f_sdp *sdp = req->context;
242         int status = req->status;
243         u8 *data = req->buf;
244         u8 report = data[0];
245
246         if (status != 0) {
247                 pr_err("Status: %d\n", status);
248                 return;
249         }
250
251         if (report != 1) {
252                 pr_err("Unexpected report %d\n", report);
253                 return;
254         }
255
256         struct sdp_command *cmd = req->buf + 1;
257
258         debug("%s: command: %04x, addr: %08x, cnt: %u\n",
259               __func__, be16_to_cpu(cmd->cmd),
260               be32_to_cpu(cmd->addr), be32_to_cpu(cmd->cnt));
261
262         switch (be16_to_cpu(cmd->cmd)) {
263         case SDP_READ_REGISTER:
264                 sdp->always_send_status = false;
265                 sdp->error_status = 0x0;
266
267                 sdp->state = SDP_STATE_TX_SEC_CONF;
268                 sdp->dnl_address = be32_to_cpu(cmd->addr);
269                 sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt);
270                 sdp->next_state = SDP_STATE_TX_REGISTER;
271                 printf("Reading %d registers at 0x%08x... ",
272                        sdp->dnl_bytes_remaining, sdp->dnl_address);
273                 break;
274         case SDP_WRITE_FILE:
275                 sdp->always_send_status = true;
276                 sdp->error_status = SDP_WRITE_FILE_COMPLETE;
277
278                 sdp->state = SDP_STATE_RX_FILE_DATA;
279                 sdp->dnl_address = be32_to_cpu(cmd->addr);
280                 sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt);
281                 sdp->dnl_bytes = sdp->dnl_bytes_remaining;
282                 sdp->next_state = SDP_STATE_IDLE;
283
284                 printf("Downloading file of size %d to 0x%08x... ",
285                        sdp->dnl_bytes_remaining, sdp->dnl_address);
286
287                 break;
288         case SDP_ERROR_STATUS:
289                 sdp->always_send_status = true;
290                 sdp->error_status = 0;
291
292                 sdp->state = SDP_STATE_TX_SEC_CONF;
293                 sdp->next_state = SDP_STATE_IDLE;
294                 break;
295         case SDP_DCD_WRITE:
296                 sdp->always_send_status = true;
297                 sdp->error_status = SDP_WRITE_REGISTER_COMPLETE;
298
299                 sdp->state = SDP_STATE_RX_DCD_DATA;
300                 sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt);
301                 sdp->next_state = SDP_STATE_IDLE;
302                 break;
303         case SDP_JUMP_ADDRESS:
304                 sdp->always_send_status = false;
305                 sdp->error_status = 0;
306
307                 sdp->jmp_address = be32_to_cpu(cmd->addr);
308                 sdp->state = SDP_STATE_TX_SEC_CONF;
309                 sdp->next_state = SDP_STATE_JUMP;
310                 break;
311         case SDP_SKIP_DCD_HEADER:
312                 sdp->always_send_status = true;
313                 sdp->error_status = SDP_SKIP_DCD_HEADER_COMPLETE;
314
315                 /* Ignore command, DCD not supported anyway */
316                 sdp->state = SDP_STATE_TX_SEC_CONF;
317                 sdp->next_state = SDP_STATE_IDLE;
318                 break;
319         default:
320                 pr_err("Unknown command: %04x\n", be16_to_cpu(cmd->cmd));
321         }
322 }
323
324 static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request *req)
325 {
326         struct f_sdp *sdp = req->context;
327         int status = req->status;
328         u8 *data = req->buf;
329         u8 report = data[0];
330         int datalen = req->length - 1;
331
332         if (status != 0) {
333                 pr_err("Status: %d\n", status);
334                 return;
335         }
336
337         if (report != 2) {
338                 pr_err("Unexpected report %d\n", report);
339                 return;
340         }
341
342         if (sdp->dnl_bytes_remaining < datalen) {
343                 /*
344                  * Some USB stacks require to send a complete buffer as
345                  * specified in the HID descriptor. This leads to longer
346                  * transfers than the file length, no problem for us.
347                  */
348                 sdp->dnl_bytes_remaining = 0;
349         } else {
350                 sdp->dnl_bytes_remaining -= datalen;
351         }
352
353         if (sdp->state == SDP_STATE_RX_FILE_DATA) {
354                 memcpy(sdp_ptr(sdp->dnl_address), req->buf + 1, datalen);
355                 sdp->dnl_address += datalen;
356         }
357
358         if (sdp->dnl_bytes_remaining)
359                 return;
360
361 #ifndef CONFIG_SPL_BUILD
362         env_set_hex("filesize", sdp->dnl_bytes);
363 #endif
364         printf("done\n");
365
366         switch (sdp->state) {
367         case SDP_STATE_RX_FILE_DATA:
368                 sdp->state = SDP_STATE_TX_SEC_CONF;
369                 break;
370         case SDP_STATE_RX_DCD_DATA:
371                 sdp->state = SDP_STATE_TX_SEC_CONF;
372                 break;
373         default:
374                 pr_err("Invalid state: %d\n", sdp->state);
375         }
376 }
377
378 static void sdp_tx_complete(struct usb_ep *ep, struct usb_request *req)
379 {
380         struct f_sdp *sdp = req->context;
381         int status = req->status;
382
383         if (status != 0) {
384                 pr_err("Status: %d\n", status);
385                 return;
386         }
387
388         switch (sdp->state) {
389         case SDP_STATE_TX_SEC_CONF_BUSY:
390                 /* Not all commands require status report */
391                 if (sdp->always_send_status || sdp->error_status)
392                         sdp->state = SDP_STATE_TX_STATUS;
393                 else
394                         sdp->state = sdp->next_state;
395
396                 break;
397         case SDP_STATE_TX_STATUS_BUSY:
398                 sdp->state = sdp->next_state;
399                 break;
400         case SDP_STATE_TX_REGISTER_BUSY:
401                 if (sdp->dnl_bytes_remaining)
402                         sdp->state = SDP_STATE_TX_REGISTER;
403                 else
404                         sdp->state = SDP_STATE_IDLE;
405                 break;
406         default:
407                 pr_err("Wrong State: %d\n", sdp->state);
408                 sdp->state = SDP_STATE_IDLE;
409                 break;
410         }
411         debug("%s complete --> %d, %d/%d\n", ep->name,
412               status, req->actual, req->length);
413 }
414
415 static int sdp_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
416 {
417         struct usb_gadget *gadget = f->config->cdev->gadget;
418         struct usb_request *req = f->config->cdev->req;
419         struct f_sdp *sdp = f->config->cdev->req->context;
420         u16 len = le16_to_cpu(ctrl->wLength);
421         u16 w_value = le16_to_cpu(ctrl->wValue);
422         int value = 0;
423         u8 req_type = ctrl->bRequestType & USB_TYPE_MASK;
424
425         debug("w_value: 0x%04x len: 0x%04x\n", w_value, len);
426         debug("req_type: 0x%02x ctrl->bRequest: 0x%02x sdp->state: %d\n",
427               req_type, ctrl->bRequest, sdp->state);
428
429         if (req_type == USB_TYPE_STANDARD) {
430                 if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR) {
431                         /* Send HID report descriptor */
432                         value = min(len, (u16) sizeof(sdp_hid_report));
433                         memcpy(req->buf, &sdp_hid_report, value);
434                         sdp->configuration_done = true;
435                 }
436         }
437
438         if (req_type == USB_TYPE_CLASS) {
439                 int report = w_value & HID_REPORT_ID_MASK;
440
441                 /* HID (SDP) request */
442                 switch (ctrl->bRequest) {
443                 case HID_REQ_SET_REPORT:
444                         switch (report) {
445                         case 1:
446                                 value = SDP_COMMAND_LEN + 1;
447                                 req->complete = sdp_rx_command_complete;
448                                 break;
449                         case 2:
450                                 value = len;
451                                 req->complete = sdp_rx_data_complete;
452                                 break;
453                         }
454                 }
455         }
456
457         if (value >= 0) {
458                 req->length = value;
459                 req->zero = value < len;
460                 value = usb_ep_queue(gadget->ep0, req, 0);
461                 if (value < 0) {
462                         debug("ep_queue --> %d\n", value);
463                         req->status = 0;
464                 }
465         }
466
467         return value;
468 }
469
470 static int sdp_bind(struct usb_configuration *c, struct usb_function *f)
471 {
472         struct usb_gadget *gadget = c->cdev->gadget;
473         struct usb_composite_dev *cdev = c->cdev;
474         struct f_sdp *sdp = func_to_sdp(f);
475         int rv = 0, id;
476
477         id = usb_interface_id(c, f);
478         if (id < 0)
479                 return id;
480         sdp_intf_runtime.bInterfaceNumber = id;
481
482         struct usb_ep *ep;
483
484         /* allocate instance-specific endpoints */
485         ep = usb_ep_autoconfig(gadget, &in_desc);
486         if (!ep) {
487                 rv = -ENODEV;
488                 goto error;
489         }
490
491         sdp->in_ep = ep; /* Store IN EP for enabling @ setup */
492
493         cdev->req->context = sdp;
494
495 error:
496         return rv;
497 }
498
499 static void sdp_unbind(struct usb_configuration *c, struct usb_function *f)
500 {
501         free(sdp_func);
502         sdp_func = NULL;
503 }
504
505 static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
506 {
507         struct usb_request *req;
508
509         req = usb_ep_alloc_request(ep, 0);
510         if (!req)
511                 return req;
512
513         req->length = length;
514         req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, length);
515         if (!req->buf) {
516                 usb_ep_free_request(ep, req);
517                 req = NULL;
518         }
519
520         return req;
521 }
522
523
524 static struct usb_request *sdp_start_ep(struct usb_ep *ep)
525 {
526         struct usb_request *req;
527
528         req = alloc_ep_req(ep, 64);
529         debug("%s: ep:%p req:%p\n", __func__, ep, req);
530
531         if (!req)
532                 return NULL;
533
534         memset(req->buf, 0, req->length);
535         req->complete = sdp_tx_complete;
536
537         return req;
538 }
539 static int sdp_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
540 {
541         struct f_sdp *sdp = func_to_sdp(f);
542         struct usb_composite_dev *cdev = f->config->cdev;
543         int result;
544
545         debug("%s: intf: %d alt: %d\n", __func__, intf, alt);
546
547         result = usb_ep_enable(sdp->in_ep, &in_desc);
548         if (result)
549                 return result;
550         sdp->in_req = sdp_start_ep(sdp->in_ep);
551         sdp->in_req->context = sdp;
552
553         sdp->in_ep->driver_data = cdev; /* claim */
554
555         sdp->altsetting = alt;
556         sdp->state = SDP_STATE_IDLE;
557
558         return 0;
559 }
560
561 static int sdp_get_alt(struct usb_function *f, unsigned intf)
562 {
563         struct f_sdp *sdp = func_to_sdp(f);
564
565         return sdp->altsetting;
566 }
567
568 static void sdp_disable(struct usb_function *f)
569 {
570         struct f_sdp *sdp = func_to_sdp(f);
571
572         usb_ep_disable(sdp->in_ep);
573
574         if (sdp->in_req) {
575                 free(sdp->in_req);
576                 sdp->in_req = NULL;
577         }
578 }
579
580 static int sdp_bind_config(struct usb_configuration *c)
581 {
582         int status;
583
584         if (!sdp_func) {
585                 sdp_func = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*sdp_func));
586                 if (!sdp_func)
587                         return -ENOMEM;
588         }
589
590         memset(sdp_func, 0, sizeof(*sdp_func));
591
592         sdp_func->usb_function.name = "sdp";
593         sdp_func->usb_function.hs_descriptors = sdp_runtime_descs;
594         sdp_func->usb_function.descriptors = sdp_runtime_descs;
595         sdp_func->usb_function.bind = sdp_bind;
596         sdp_func->usb_function.unbind = sdp_unbind;
597         sdp_func->usb_function.set_alt = sdp_set_alt;
598         sdp_func->usb_function.get_alt = sdp_get_alt;
599         sdp_func->usb_function.disable = sdp_disable;
600         sdp_func->usb_function.strings = sdp_generic_strings;
601         sdp_func->usb_function.setup = sdp_setup;
602
603         status = usb_add_function(c, &sdp_func->usb_function);
604
605         return status;
606 }
607
608 int sdp_init(int controller_index)
609 {
610         printf("SDP: initialize...\n");
611         while (!sdp_func->configuration_done) {
612                 if (ctrlc()) {
613                         puts("\rCTRL+C - Operation aborted.\n");
614                         return 1;
615                 }
616
617                 WATCHDOG_RESET();
618                 usb_gadget_handle_interrupts(controller_index);
619         }
620
621         return 0;
622 }
623
624 static u32 sdp_jump_imxheader(void *address)
625 {
626         flash_header_v2_t *headerv2 = address;
627         ulong (*entry)(void);
628
629         if (headerv2->header.tag != IVT_HEADER_TAG) {
630                 printf("Header Tag is not an IMX image\n");
631                 return SDP_ERROR_IMXHEADER;
632         }
633
634         printf("Jumping to 0x%08x\n", headerv2->entry);
635         entry = sdp_ptr(headerv2->entry);
636         entry();
637
638         /* The image probably never returns hence we won't reach that point */
639         return 0;
640 }
641
642 #ifdef CONFIG_SPL_BUILD
643 #ifdef CONFIG_SPL_LOAD_FIT
644 static ulong sdp_fit_read(struct spl_load_info *load, ulong sector,
645                           ulong count, void *buf)
646 {
647         debug("%s: sector %lx, count %lx, buf %lx\n",
648               __func__, sector, count, (ulong)buf);
649         memcpy(buf, (void *)(load->dev + sector), count);
650         return count;
651 }
652 #endif
653 #endif
654
655 static void sdp_handle_in_ep(struct spl_image_info *spl_image)
656 {
657         u8 *data = sdp_func->in_req->buf;
658         u32 status;
659         int datalen;
660
661         switch (sdp_func->state) {
662         case SDP_STATE_TX_SEC_CONF:
663                 debug("Report 3: HAB security\n");
664                 data[0] = 3;
665
666                 status = SDP_SECURITY_OPEN;
667                 memcpy(&data[1], &status, 4);
668                 sdp_func->in_req->length = 5;
669                 usb_ep_queue(sdp_func->in_ep, sdp_func->in_req, 0);
670                 sdp_func->state = SDP_STATE_TX_SEC_CONF_BUSY;
671                 break;
672
673         case SDP_STATE_TX_STATUS:
674                 debug("Report 4: Status\n");
675                 data[0] = 4;
676
677                 memcpy(&data[1], &sdp_func->error_status, 4);
678                 sdp_func->in_req->length = 65;
679                 usb_ep_queue(sdp_func->in_ep, sdp_func->in_req, 0);
680                 sdp_func->state = SDP_STATE_TX_STATUS_BUSY;
681                 break;
682         case SDP_STATE_TX_REGISTER:
683                 debug("Report 4: Register Values\n");
684                 data[0] = 4;
685
686                 datalen = sdp_func->dnl_bytes_remaining;
687
688                 if (datalen > 64)
689                         datalen = 64;
690
691                 memcpy(&data[1], sdp_ptr(sdp_func->dnl_address), datalen);
692                 sdp_func->in_req->length = 65;
693
694                 sdp_func->dnl_bytes_remaining -= datalen;
695                 sdp_func->dnl_address += datalen;
696
697                 usb_ep_queue(sdp_func->in_ep, sdp_func->in_req, 0);
698                 sdp_func->state = SDP_STATE_TX_REGISTER_BUSY;
699                 break;
700         case SDP_STATE_JUMP:
701                 printf("Jumping to header at 0x%08x\n", sdp_func->jmp_address);
702                 status = sdp_jump_imxheader(sdp_ptr(sdp_func->jmp_address));
703
704                 /* If imx header fails, try some U-Boot specific headers */
705                 if (status) {
706 #ifdef CONFIG_SPL_BUILD
707                         image_header_t *header =
708                                 sdp_ptr(sdp_func->jmp_address);
709 #ifdef CONFIG_SPL_LOAD_FIT
710                         if (image_get_magic(header) == FDT_MAGIC) {
711                                 struct spl_load_info load;
712
713                                 debug("Found FIT\n");
714                                 load.dev = header;
715                                 load.bl_len = 1;
716                                 load.read = sdp_fit_read;
717                                 spl_load_simple_fit(spl_image, &load, 0,
718                                                     header);
719
720                                 return;
721                         }
722 #endif
723                         /* In SPL, allow jumps to U-Boot images */
724                         struct spl_image_info spl_image = {};
725                         spl_parse_image_header(&spl_image, header);
726                         jump_to_image_no_args(&spl_image);
727 #else
728                         /* In U-Boot, allow jumps to scripts */
729                         image_source_script(sdp_func->jmp_address, "script@1");
730 #endif
731                 }
732
733                 sdp_func->next_state = SDP_STATE_IDLE;
734                 sdp_func->error_status = status;
735
736                 /* Only send Report 4 if there was an error */
737                 if (status)
738                         sdp_func->state = SDP_STATE_TX_STATUS;
739                 else
740                         sdp_func->state = SDP_STATE_IDLE;
741                 break;
742         default:
743                 break;
744         };
745 }
746
747 #ifndef CONFIG_SPL_BUILD
748 int sdp_handle(int controller_index)
749 #else
750 int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image)
751 #endif
752 {
753         printf("SDP: handle requests...\n");
754         while (1) {
755                 if (ctrlc()) {
756                         puts("\rCTRL+C - Operation aborted.\n");
757                         return -EINVAL;
758                 }
759
760 #ifdef CONFIG_SPL_BUILD
761                 if (spl_image->flags & SPL_FIT_FOUND)
762                         return 0;
763 #endif
764
765                 WATCHDOG_RESET();
766                 usb_gadget_handle_interrupts(controller_index);
767
768 #ifdef CONFIG_SPL_BUILD
769                 sdp_handle_in_ep(spl_image);
770 #else
771                 sdp_handle_in_ep(NULL);
772 #endif
773         }
774 }
775
776 int sdp_add(struct usb_configuration *c)
777 {
778         int id;
779
780         id = usb_string_id(c->cdev);
781         if (id < 0)
782                 return id;
783         strings_sdp_generic[0].id = id;
784         sdp_intf_runtime.iInterface = id;
785
786         debug("%s: cdev: %p gadget: %p gadget->ep0: %p\n", __func__,
787               c->cdev, c->cdev->gadget, c->cdev->gadget->ep0);
788
789         return sdp_bind_config(c);
790 }
791
792 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_sdp, sdp_add);