Merge branch 'master' of git://git.denx.de/u-boot-socfpga
[oweals/u-boot.git] / drivers / usb / gadget / f_thor.c
1 /*
2  * f_thor.c -- USB TIZEN THOR Downloader gadget function
3  *
4  * Copyright (C) 2013 Samsung Electronics
5  * Lukasz Majewski <l.majewski@samsung.com>
6  *
7  * Based on code from:
8  * git://review.tizen.org/kernel/u-boot
9  *
10  * Developed by:
11  * Copyright (C) 2009 Samsung Electronics
12  * Minkyu Kang <mk7.kang@samsung.com>
13  * Sanghee Kim <sh0130.kim@samsung.com>
14  *
15  * SPDX-License-Identifier:     GPL-2.0+
16  */
17
18 #include <errno.h>
19 #include <common.h>
20 #include <malloc.h>
21 #include <version.h>
22 #include <linux/usb/ch9.h>
23 #include <linux/usb/gadget.h>
24 #include <linux/usb/composite.h>
25 #include <linux/usb/cdc.h>
26 #include <g_dnl.h>
27 #include <dfu.h>
28
29 #include "f_thor.h"
30
31 static void thor_tx_data(unsigned char *data, int len);
32 static void thor_set_dma(void *addr, int len);
33 static int thor_rx_data(void);
34
35 static struct f_thor *thor_func;
36 static inline struct f_thor *func_to_thor(struct usb_function *f)
37 {
38         return container_of(f, struct f_thor, usb_function);
39 }
40
41 DEFINE_CACHE_ALIGN_BUFFER(unsigned char, thor_tx_data_buf,
42                           sizeof(struct rsp_box));
43 DEFINE_CACHE_ALIGN_BUFFER(unsigned char, thor_rx_data_buf,
44                           sizeof(struct rqt_box));
45
46 /* ********************************************************** */
47 /*         THOR protocol - transmission handling              */
48 /* ********************************************************** */
49 DEFINE_CACHE_ALIGN_BUFFER(char, f_name, F_NAME_BUF_SIZE);
50 static unsigned long long int thor_file_size;
51 static int alt_setting_num;
52
53 static void send_rsp(const struct rsp_box *rsp)
54 {
55         memcpy(thor_tx_data_buf, rsp, sizeof(struct rsp_box));
56         thor_tx_data(thor_tx_data_buf, sizeof(struct rsp_box));
57
58         debug("-RSP: %d, %d\n", rsp->rsp, rsp->rsp_data);
59 }
60
61 static void send_data_rsp(s32 ack, s32 count)
62 {
63         ALLOC_CACHE_ALIGN_BUFFER(struct data_rsp_box, rsp,
64                                  sizeof(struct data_rsp_box));
65
66         rsp->ack = ack;
67         rsp->count = count;
68
69         memcpy(thor_tx_data_buf, rsp, sizeof(struct data_rsp_box));
70         thor_tx_data(thor_tx_data_buf, sizeof(struct data_rsp_box));
71
72         debug("-DATA RSP: %d, %d\n", ack, count);
73 }
74
75 static int process_rqt_info(const struct rqt_box *rqt)
76 {
77         ALLOC_CACHE_ALIGN_BUFFER(struct rsp_box, rsp, sizeof(struct rsp_box));
78         memset(rsp, 0, sizeof(struct rsp_box));
79
80         rsp->rsp = rqt->rqt;
81         rsp->rsp_data = rqt->rqt_data;
82
83         switch (rqt->rqt_data) {
84         case RQT_INFO_VER_PROTOCOL:
85                 rsp->int_data[0] = VER_PROTOCOL_MAJOR;
86                 rsp->int_data[1] = VER_PROTOCOL_MINOR;
87                 break;
88         case RQT_INIT_VER_HW:
89                 snprintf(rsp->str_data[0], sizeof(rsp->str_data[0]),
90                          "%x", checkboard());
91                 break;
92         case RQT_INIT_VER_BOOT:
93                 sprintf(rsp->str_data[0], "%s", U_BOOT_VERSION);
94                 break;
95         case RQT_INIT_VER_KERNEL:
96                 sprintf(rsp->str_data[0], "%s", "k unknown");
97                 break;
98         case RQT_INIT_VER_PLATFORM:
99                 sprintf(rsp->str_data[0], "%s", "p unknown");
100                 break;
101         case RQT_INIT_VER_CSC:
102                 sprintf(rsp->str_data[0], "%s", "c unknown");
103                 break;
104         default:
105                 return -EINVAL;
106         }
107
108         send_rsp(rsp);
109         return true;
110 }
111
112 static int process_rqt_cmd(const struct rqt_box *rqt)
113 {
114         ALLOC_CACHE_ALIGN_BUFFER(struct rsp_box, rsp, sizeof(struct rsp_box));
115         memset(rsp, 0, sizeof(struct rsp_box));
116
117         rsp->rsp = rqt->rqt;
118         rsp->rsp_data = rqt->rqt_data;
119
120         switch (rqt->rqt_data) {
121         case RQT_CMD_REBOOT:
122                 debug("TARGET RESET\n");
123                 send_rsp(rsp);
124                 g_dnl_unregister();
125                 dfu_free_entities();
126                 run_command("reset", 0);
127                 break;
128         case RQT_CMD_POWEROFF:
129         case RQT_CMD_EFSCLEAR:
130                 send_rsp(rsp);
131         default:
132                 printf("Command not supported -> cmd: %d\n", rqt->rqt_data);
133                 return -EINVAL;
134         }
135
136         return true;
137 }
138
139 static long long int download_head(unsigned long long total,
140                                    unsigned int packet_size,
141                                    long long int *left,
142                                    int *cnt)
143 {
144         long long int rcv_cnt = 0, left_to_rcv, ret_rcv;
145         struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
146         void *transfer_buffer = dfu_get_buf(dfu_entity);
147         void *buf = transfer_buffer;
148         int usb_pkt_cnt = 0, ret;
149
150         /*
151          * Files smaller than THOR_STORE_UNIT_SIZE (now 32 MiB) are stored on
152          * the medium.
153          * The packet response is sent on the purpose after successful data
154          * chunk write. There is a room for improvement when asynchronous write
155          * is performed.
156          */
157         while (total - rcv_cnt >= packet_size) {
158                 thor_set_dma(buf, packet_size);
159                 buf += packet_size;
160                 ret_rcv = thor_rx_data();
161                 if (ret_rcv < 0)
162                         return ret_rcv;
163                 rcv_cnt += ret_rcv;
164                 debug("%d: RCV data count: %llu cnt: %d\n", usb_pkt_cnt,
165                       rcv_cnt, *cnt);
166
167                 if ((rcv_cnt % THOR_STORE_UNIT_SIZE) == 0) {
168                         ret = dfu_write(dfu_get_entity(alt_setting_num),
169                                         transfer_buffer, THOR_STORE_UNIT_SIZE,
170                                         (*cnt)++);
171                         if (ret) {
172                                 error("DFU write failed [%d] cnt: %d",
173                                       ret, *cnt);
174                                 return ret;
175                         }
176                         buf = transfer_buffer;
177                 }
178                 send_data_rsp(0, ++usb_pkt_cnt);
179         }
180
181         /* Calculate the amount of data to arrive from PC (in bytes) */
182         left_to_rcv = total - rcv_cnt;
183
184         /*
185          * Calculate number of data already received. but not yet stored
186          * on the medium (they are smaller than THOR_STORE_UNIT_SIZE)
187          */
188         *left = left_to_rcv + buf - transfer_buffer;
189         debug("%s: left: %llu left_to_rcv: %llu buf: 0x%p\n", __func__,
190               *left, left_to_rcv, buf);
191
192         if (left_to_rcv) {
193                 thor_set_dma(buf, packet_size);
194                 ret_rcv = thor_rx_data();
195                 if (ret_rcv < 0)
196                         return ret_rcv;
197                 rcv_cnt += ret_rcv;
198                 send_data_rsp(0, ++usb_pkt_cnt);
199         }
200
201         debug("%s: %llu total: %llu cnt: %d\n", __func__, rcv_cnt, total, *cnt);
202
203         return rcv_cnt;
204 }
205
206 static int download_tail(long long int left, int cnt)
207 {
208         struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
209         void *transfer_buffer = dfu_get_buf(dfu_entity);
210         int ret;
211
212         debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
213
214         if (left) {
215                 ret = dfu_write(dfu_entity, transfer_buffer, left, cnt++);
216                 if (ret) {
217                         error("DFU write failed [%d]: left: %llu", ret, left);
218                         return ret;
219                 }
220         }
221
222         /*
223          * To store last "packet" or write file from buffer to filesystem
224          * DFU storage backend requires dfu_flush
225          *
226          * This also frees memory malloc'ed by dfu_get_buf(), so no explicit
227          * need fo call dfu_free_buf() is needed.
228          */
229         ret = dfu_flush(dfu_entity, transfer_buffer, 0, cnt);
230         if (ret)
231                 error("DFU flush failed!");
232
233         return ret;
234 }
235
236 static long long int process_rqt_download(const struct rqt_box *rqt)
237 {
238         ALLOC_CACHE_ALIGN_BUFFER(struct rsp_box, rsp, sizeof(struct rsp_box));
239         static long long int left, ret_head;
240         int file_type, ret = 0;
241         static int cnt;
242
243         memset(rsp, 0, sizeof(struct rsp_box));
244         rsp->rsp = rqt->rqt;
245         rsp->rsp_data = rqt->rqt_data;
246
247         switch (rqt->rqt_data) {
248         case RQT_DL_INIT:
249                 thor_file_size = rqt->int_data[0];
250                 debug("INIT: total %d bytes\n", rqt->int_data[0]);
251                 break;
252         case RQT_DL_FILE_INFO:
253                 file_type = rqt->int_data[0];
254                 if (file_type == FILE_TYPE_PIT) {
255                         puts("PIT table file - not supported\n");
256                         rsp->ack = -ENOTSUPP;
257                         ret = rsp->ack;
258                         break;
259                 }
260
261                 thor_file_size = rqt->int_data[1];
262                 memcpy(f_name, rqt->str_data[0], F_NAME_BUF_SIZE);
263
264                 debug("INFO: name(%s, %d), size(%llu), type(%d)\n",
265                       f_name, 0, thor_file_size, file_type);
266
267                 rsp->int_data[0] = THOR_PACKET_SIZE;
268
269                 alt_setting_num = dfu_get_alt(f_name);
270                 if (alt_setting_num < 0) {
271                         error("Alt setting [%d] to write not found!",
272                               alt_setting_num);
273                         rsp->ack = -ENODEV;
274                         ret = rsp->ack;
275                 }
276                 break;
277         case RQT_DL_FILE_START:
278                 send_rsp(rsp);
279                 ret_head = download_head(thor_file_size, THOR_PACKET_SIZE,
280                                          &left, &cnt);
281                 if (ret_head < 0) {
282                         left = 0;
283                         cnt = 0;
284                 }
285                 return ret_head;
286         case RQT_DL_FILE_END:
287                 debug("DL FILE_END\n");
288                 rsp->ack = download_tail(left, cnt);
289                 ret = rsp->ack;
290                 left = 0;
291                 cnt = 0;
292                 break;
293         case RQT_DL_EXIT:
294                 debug("DL EXIT\n");
295                 break;
296         default:
297                 error("Operation not supported: %d", rqt->rqt_data);
298                 ret = -ENOTSUPP;
299         }
300
301         send_rsp(rsp);
302         return ret;
303 }
304
305 static int process_data(void)
306 {
307         ALLOC_CACHE_ALIGN_BUFFER(struct rqt_box, rqt, sizeof(struct rqt_box));
308         int ret = -EINVAL;
309
310         memcpy(rqt, thor_rx_data_buf, sizeof(struct rqt_box));
311
312         debug("+RQT: %d, %d\n", rqt->rqt, rqt->rqt_data);
313
314         switch (rqt->rqt) {
315         case RQT_INFO:
316                 ret = process_rqt_info(rqt);
317                 break;
318         case RQT_CMD:
319                 ret = process_rqt_cmd(rqt);
320                 break;
321         case RQT_DL:
322                 ret = (int) process_rqt_download(rqt);
323                 break;
324         case RQT_UL:
325                 puts("RQT: UPLOAD not supported!\n");
326                 break;
327         default:
328                 error("unknown request (%d)", rqt->rqt);
329         }
330
331         return ret;
332 }
333
334 /* ********************************************************** */
335 /*         THOR USB Function                                  */
336 /* ********************************************************** */
337
338 static inline struct usb_endpoint_descriptor *
339 ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
340         struct usb_endpoint_descriptor *fs)
341 {
342         if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
343                 return hs;
344         return fs;
345 }
346
347 static struct usb_interface_descriptor thor_downloader_intf_data = {
348         .bLength =              sizeof(thor_downloader_intf_data),
349         .bDescriptorType =      USB_DT_INTERFACE,
350
351         .bNumEndpoints =        2,
352         .bInterfaceClass =      USB_CLASS_CDC_DATA,
353 };
354
355 static struct usb_endpoint_descriptor fs_in_desc = {
356         .bLength =              USB_DT_ENDPOINT_SIZE,
357         .bDescriptorType =      USB_DT_ENDPOINT,
358
359         .bEndpointAddress =     USB_DIR_IN,
360         .bmAttributes = USB_ENDPOINT_XFER_BULK,
361 };
362
363 static struct usb_endpoint_descriptor fs_out_desc = {
364         .bLength =              USB_DT_ENDPOINT_SIZE,
365         .bDescriptorType =      USB_DT_ENDPOINT,
366
367         .bEndpointAddress =     USB_DIR_OUT,
368         .bmAttributes = USB_ENDPOINT_XFER_BULK,
369 };
370
371 /* CDC configuration */
372 static struct usb_interface_descriptor thor_downloader_intf_int = {
373         .bLength =              sizeof(thor_downloader_intf_int),
374         .bDescriptorType =      USB_DT_INTERFACE,
375
376         .bNumEndpoints =        1,
377         .bInterfaceClass =      USB_CLASS_COMM,
378          /* 0x02 Abstract Line Control Model */
379         .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
380         /* 0x01 Common AT commands */
381         .bInterfaceProtocol =   USB_CDC_ACM_PROTO_AT_V25TER,
382 };
383
384 static struct usb_cdc_header_desc thor_downloader_cdc_header = {
385         .bLength         =    sizeof(thor_downloader_cdc_header),
386         .bDescriptorType =    0x24, /* CS_INTERFACE */
387         .bDescriptorSubType = 0x00,
388         .bcdCDC =             0x0110,
389 };
390
391 static struct usb_cdc_call_mgmt_descriptor thor_downloader_cdc_call = {
392         .bLength         =    sizeof(thor_downloader_cdc_call),
393         .bDescriptorType =    0x24, /* CS_INTERFACE */
394         .bDescriptorSubType = 0x01,
395         .bmCapabilities =     0x00,
396         .bDataInterface =     0x01,
397 };
398
399 static struct usb_cdc_acm_descriptor thor_downloader_cdc_abstract = {
400         .bLength         =    sizeof(thor_downloader_cdc_abstract),
401         .bDescriptorType =    0x24, /* CS_INTERFACE */
402         .bDescriptorSubType = 0x02,
403         .bmCapabilities =     0x00,
404 };
405
406 static struct usb_cdc_union_desc thor_downloader_cdc_union = {
407         .bLength         =     sizeof(thor_downloader_cdc_union),
408         .bDescriptorType =     0x24, /* CS_INTERFACE */
409         .bDescriptorSubType =  USB_CDC_UNION_TYPE,
410 };
411
412 static struct usb_endpoint_descriptor fs_int_desc = {
413         .bLength = USB_DT_ENDPOINT_SIZE,
414         .bDescriptorType = USB_DT_ENDPOINT,
415
416         .bEndpointAddress = 3 | USB_DIR_IN,
417         .bmAttributes = USB_ENDPOINT_XFER_INT,
418         .wMaxPacketSize = __constant_cpu_to_le16(16),
419
420         .bInterval = 0x9,
421 };
422
423 static struct usb_interface_assoc_descriptor
424 thor_iad_descriptor = {
425         .bLength =              sizeof(thor_iad_descriptor),
426         .bDescriptorType =      USB_DT_INTERFACE_ASSOCIATION,
427
428         .bFirstInterface =      0,
429         .bInterfaceCount =      2,      /* control + data */
430         .bFunctionClass =       USB_CLASS_COMM,
431         .bFunctionSubClass =    USB_CDC_SUBCLASS_ACM,
432         .bFunctionProtocol =    USB_CDC_PROTO_NONE,
433 };
434
435 static struct usb_endpoint_descriptor hs_in_desc = {
436         .bLength =              USB_DT_ENDPOINT_SIZE,
437         .bDescriptorType =      USB_DT_ENDPOINT,
438
439         .bmAttributes = USB_ENDPOINT_XFER_BULK,
440         .wMaxPacketSize =       __constant_cpu_to_le16(512),
441 };
442
443 static struct usb_endpoint_descriptor hs_out_desc = {
444         .bLength =              USB_DT_ENDPOINT_SIZE,
445         .bDescriptorType =      USB_DT_ENDPOINT,
446
447         .bmAttributes = USB_ENDPOINT_XFER_BULK,
448         .wMaxPacketSize =       __constant_cpu_to_le16(512),
449 };
450
451 static struct usb_endpoint_descriptor hs_int_desc = {
452         .bLength = USB_DT_ENDPOINT_SIZE,
453         .bDescriptorType = USB_DT_ENDPOINT,
454
455         .bmAttributes = USB_ENDPOINT_XFER_INT,
456         .wMaxPacketSize = __constant_cpu_to_le16(16),
457
458         .bInterval = 0x9,
459 };
460
461 /*
462  * This attribute vendor descriptor is necessary for correct operation with
463  * Windows version of THOR download program
464  *
465  * It prevents windows driver from sending zero lenght packet (ZLP) after
466  * each THOR_PACKET_SIZE. This assures consistent behaviour with libusb
467  */
468 static struct usb_cdc_attribute_vendor_descriptor thor_downloader_cdc_av = {
469         .bLength =              sizeof(thor_downloader_cdc_av),
470         .bDescriptorType =      0x24,
471         .bDescriptorSubType =   0x80,
472         .DAUType =              0x0002,
473         .DAULength =            0x0001,
474         .DAUValue =             0x00,
475 };
476
477 static const struct usb_descriptor_header *hs_thor_downloader_function[] = {
478         (struct usb_descriptor_header *)&thor_iad_descriptor,
479
480         (struct usb_descriptor_header *)&thor_downloader_intf_int,
481         (struct usb_descriptor_header *)&thor_downloader_cdc_header,
482         (struct usb_descriptor_header *)&thor_downloader_cdc_call,
483         (struct usb_descriptor_header *)&thor_downloader_cdc_abstract,
484         (struct usb_descriptor_header *)&thor_downloader_cdc_union,
485         (struct usb_descriptor_header *)&hs_int_desc,
486
487         (struct usb_descriptor_header *)&thor_downloader_intf_data,
488         (struct usb_descriptor_header *)&thor_downloader_cdc_av,
489         (struct usb_descriptor_header *)&hs_in_desc,
490         (struct usb_descriptor_header *)&hs_out_desc,
491         NULL,
492 };
493
494 /*-------------------------------------------------------------------------*/
495 static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
496 {
497         struct usb_request *req;
498
499         req = usb_ep_alloc_request(ep, 0);
500         if (!req)
501                 return req;
502
503         req->length = length;
504         req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, length);
505         if (!req->buf) {
506                 usb_ep_free_request(ep, req);
507                 req = NULL;
508         }
509
510         return req;
511 }
512
513 static int thor_rx_data(void)
514 {
515         struct thor_dev *dev = thor_func->dev;
516         int data_to_rx, tmp, status;
517
518         data_to_rx = dev->out_req->length;
519         tmp = data_to_rx;
520         do {
521                 dev->out_req->length = data_to_rx;
522                 debug("dev->out_req->length:%d dev->rxdata:%d\n",
523                       dev->out_req->length, dev->rxdata);
524
525                 status = usb_ep_queue(dev->out_ep, dev->out_req, 0);
526                 if (status) {
527                         error("kill %s:  resubmit %d bytes --> %d",
528                               dev->out_ep->name, dev->out_req->length, status);
529                         usb_ep_set_halt(dev->out_ep);
530                         return -EAGAIN;
531                 }
532
533                 while (!dev->rxdata) {
534                         usb_gadget_handle_interrupts();
535                         if (ctrlc())
536                                 return -1;
537                 }
538                 dev->rxdata = 0;
539                 data_to_rx -= dev->out_req->actual;
540         } while (data_to_rx);
541
542         return tmp;
543 }
544
545 static void thor_tx_data(unsigned char *data, int len)
546 {
547         struct thor_dev *dev = thor_func->dev;
548         unsigned char *ptr = dev->in_req->buf;
549         int status;
550
551         memset(ptr, 0, len);
552         memcpy(ptr, data, len);
553
554         dev->in_req->length = len;
555
556         debug("%s: dev->in_req->length:%d to_cpy:%d\n", __func__,
557               dev->in_req->length, sizeof(data));
558
559         status = usb_ep_queue(dev->in_ep, dev->in_req, 0);
560         if (status) {
561                 error("kill %s:  resubmit %d bytes --> %d",
562                       dev->in_ep->name, dev->in_req->length, status);
563                 usb_ep_set_halt(dev->in_ep);
564         }
565
566         /* Wait until tx interrupt received */
567         while (!dev->txdata)
568                 usb_gadget_handle_interrupts();
569
570         dev->txdata = 0;
571 }
572
573 static void thor_rx_tx_complete(struct usb_ep *ep, struct usb_request *req)
574 {
575         struct thor_dev *dev = thor_func->dev;
576         int status = req->status;
577
578         debug("%s: ep_ptr:%p, req_ptr:%p\n", __func__, ep, req);
579         switch (status) {
580         case 0:
581                 if (ep == dev->out_ep)
582                         dev->rxdata = 1;
583                 else
584                         dev->txdata = 1;
585
586                 break;
587
588         /* this endpoint is normally active while we're configured */
589         case -ECONNABORTED:             /* hardware forced ep reset */
590         case -ECONNRESET:               /* request dequeued */
591         case -ESHUTDOWN:                /* disconnect from host */
592         case -EREMOTEIO:                /* short read */
593         case -EOVERFLOW:
594                 error("ERROR:%d", status);
595                 break;
596         }
597
598         debug("%s complete --> %d, %d/%d\n", ep->name,
599               status, req->actual, req->length);
600 }
601
602 static struct usb_request *thor_start_ep(struct usb_ep *ep)
603 {
604         struct usb_request *req;
605
606         req = alloc_ep_req(ep, THOR_PACKET_SIZE);
607         debug("%s: ep:%p req:%p\n", __func__, ep, req);
608
609         if (!req)
610                 return NULL;
611
612         memset(req->buf, 0, req->length);
613         req->complete = thor_rx_tx_complete;
614
615         return req;
616 }
617
618 static void thor_setup_complete(struct usb_ep *ep, struct usb_request *req)
619 {
620         if (req->status || req->actual != req->length)
621                 debug("setup complete --> %d, %d/%d\n",
622                       req->status, req->actual, req->length);
623 }
624
625 static int
626 thor_func_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
627 {
628         struct thor_dev *dev = thor_func->dev;
629         struct usb_request *req = dev->req;
630         struct usb_gadget *gadget = dev->gadget;
631         int value = 0;
632
633         u16 len = le16_to_cpu(ctrl->wLength);
634
635         debug("Req_Type: 0x%x Req: 0x%x wValue: 0x%x wIndex: 0x%x wLen: 0x%x\n",
636               ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex,
637               ctrl->wLength);
638
639         switch (ctrl->bRequest) {
640         case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
641                 value = 0;
642                 break;
643         case USB_CDC_REQ_SET_LINE_CODING:
644                 value = len;
645                 /* Line Coding set done = configuration done */
646                 thor_func->dev->configuration_done = 1;
647                 break;
648
649         default:
650                 error("thor_setup: unknown request: %d", ctrl->bRequest);
651         }
652
653         if (value >= 0) {
654                 req->length = value;
655                 req->zero = value < len;
656                 value = usb_ep_queue(gadget->ep0, req, 0);
657                 if (value < 0) {
658                         debug("%s: ep_queue: %d\n", __func__, value);
659                         req->status = 0;
660                 }
661         }
662
663         return value;
664 }
665
666 /* Specific to the THOR protocol */
667 static void thor_set_dma(void *addr, int len)
668 {
669         struct thor_dev *dev = thor_func->dev;
670
671         debug("in_req:%p, out_req:%p\n", dev->in_req, dev->out_req);
672         debug("addr:%p, len:%d\n", addr, len);
673
674         dev->out_req->buf = addr;
675         dev->out_req->length = len;
676 }
677
678 int thor_init(void)
679 {
680         struct thor_dev *dev = thor_func->dev;
681
682         /* Wait for a device enumeration and configuration settings */
683         debug("THOR enumeration/configuration setting....\n");
684         while (!dev->configuration_done)
685                 usb_gadget_handle_interrupts();
686
687         thor_set_dma(thor_rx_data_buf, strlen("THOR"));
688         /* detect the download request from Host PC */
689         if (thor_rx_data() < 0) {
690                 printf("%s: Data not received!\n", __func__);
691                 return -1;
692         }
693
694         if (!strncmp((char *)thor_rx_data_buf, "THOR", strlen("THOR"))) {
695                 puts("Download request from the Host PC\n");
696                 udelay(30 * 1000); /* 30 ms */
697
698                 strcpy((char *)thor_tx_data_buf, "ROHT");
699                 thor_tx_data(thor_tx_data_buf, strlen("ROHT"));
700         } else {
701                 puts("Wrong reply information\n");
702                 return -1;
703         }
704
705         return 0;
706 }
707
708 int thor_handle(void)
709 {
710         int ret;
711
712         /* receive the data from Host PC */
713         while (1) {
714                 thor_set_dma(thor_rx_data_buf, sizeof(struct rqt_box));
715                 ret = thor_rx_data();
716
717                 if (ret > 0) {
718                         ret = process_data();
719                         if (ret < 0)
720                                 return ret;
721                 } else {
722                         printf("%s: No data received!\n", __func__);
723                         break;
724                 }
725         }
726
727         return 0;
728 }
729
730 static int thor_func_bind(struct usb_configuration *c, struct usb_function *f)
731 {
732         struct usb_gadget *gadget = c->cdev->gadget;
733         struct f_thor *f_thor = func_to_thor(f);
734         struct thor_dev *dev;
735         struct usb_ep *ep;
736         int status;
737
738         thor_func = f_thor;
739         dev = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*dev));
740         if (!dev)
741                 return -ENOMEM;
742
743         memset(dev, 0, sizeof(*dev));
744         dev->gadget = gadget;
745         f_thor->dev = dev;
746
747         debug("%s: usb_configuration: 0x%p usb_function: 0x%p\n",
748               __func__, c, f);
749         debug("f_thor: 0x%p thor: 0x%p\n", f_thor, dev);
750
751         /* EP0  */
752         /* preallocate control response and buffer */
753         dev->req = usb_ep_alloc_request(gadget->ep0, 0);
754         if (!dev->req) {
755                 status = -ENOMEM;
756                 goto fail;
757         }
758         dev->req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
759                                  gadget->ep0->maxpacket);
760         if (!dev->req->buf) {
761                 status = -ENOMEM;
762                 goto fail;
763         }
764
765         dev->req->complete = thor_setup_complete;
766
767         /* DYNAMIC interface numbers assignments */
768         status = usb_interface_id(c, f);
769
770         if (status < 0)
771                 goto fail;
772
773         thor_downloader_intf_int.bInterfaceNumber = status;
774         thor_downloader_cdc_union.bMasterInterface0 = status;
775
776         status = usb_interface_id(c, f);
777
778         if (status < 0)
779                 goto fail;
780
781         thor_downloader_intf_data.bInterfaceNumber = status;
782         thor_downloader_cdc_union.bSlaveInterface0 = status;
783
784         /* allocate instance-specific endpoints */
785         ep = usb_ep_autoconfig(gadget, &fs_in_desc);
786         if (!ep) {
787                 status = -ENODEV;
788                 goto fail;
789         }
790
791         if (gadget_is_dualspeed(gadget)) {
792                 hs_in_desc.bEndpointAddress =
793                                 fs_in_desc.bEndpointAddress;
794         }
795
796         dev->in_ep = ep; /* Store IN EP for enabling @ setup */
797
798         ep = usb_ep_autoconfig(gadget, &fs_out_desc);
799         if (!ep) {
800                 status = -ENODEV;
801                 goto fail;
802         }
803
804         if (gadget_is_dualspeed(gadget))
805                 hs_out_desc.bEndpointAddress =
806                                 fs_out_desc.bEndpointAddress;
807
808         dev->out_ep = ep; /* Store OUT EP for enabling @ setup */
809
810         ep = usb_ep_autoconfig(gadget, &fs_int_desc);
811         if (!ep) {
812                 status = -ENODEV;
813                 goto fail;
814         }
815
816         dev->int_ep = ep;
817
818         if (gadget_is_dualspeed(gadget)) {
819                 hs_int_desc.bEndpointAddress =
820                                 fs_int_desc.bEndpointAddress;
821
822                 f->hs_descriptors = (struct usb_descriptor_header **)
823                         &hs_thor_downloader_function;
824
825                 if (!f->hs_descriptors)
826                         goto fail;
827         }
828
829         debug("%s: out_ep:%p out_req:%p\n", __func__,
830               dev->out_ep, dev->out_req);
831
832         return 0;
833
834  fail:
835         free(dev);
836         return status;
837 }
838
839 static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
840 {
841         free(req->buf);
842         usb_ep_free_request(ep, req);
843 }
844
845 static void thor_unbind(struct usb_configuration *c, struct usb_function *f)
846 {
847         struct f_thor *f_thor = func_to_thor(f);
848         struct thor_dev *dev = f_thor->dev;
849
850         free(dev);
851         memset(thor_func, 0, sizeof(*thor_func));
852         thor_func = NULL;
853 }
854
855 static void thor_func_disable(struct usb_function *f)
856 {
857         struct f_thor *f_thor = func_to_thor(f);
858         struct thor_dev *dev = f_thor->dev;
859
860         debug("%s:\n", __func__);
861
862         /* Avoid freeing memory when ep is still claimed */
863         if (dev->in_ep->driver_data) {
864                 free_ep_req(dev->in_ep, dev->in_req);
865                 usb_ep_disable(dev->in_ep);
866                 dev->in_ep->driver_data = NULL;
867         }
868
869         if (dev->out_ep->driver_data) {
870                 dev->out_req->buf = NULL;
871                 usb_ep_free_request(dev->out_ep, dev->out_req);
872                 usb_ep_disable(dev->out_ep);
873                 dev->out_ep->driver_data = NULL;
874         }
875
876         if (dev->int_ep->driver_data) {
877                 usb_ep_disable(dev->int_ep);
878                 dev->int_ep->driver_data = NULL;
879         }
880 }
881
882 static int thor_eps_setup(struct usb_function *f)
883 {
884         struct usb_composite_dev *cdev = f->config->cdev;
885         struct usb_gadget *gadget = cdev->gadget;
886         struct thor_dev *dev = thor_func->dev;
887         struct usb_endpoint_descriptor *d;
888         struct usb_request *req;
889         struct usb_ep *ep;
890         int result;
891
892         ep = dev->in_ep;
893         d = ep_desc(gadget, &hs_in_desc, &fs_in_desc);
894         debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
895
896         result = usb_ep_enable(ep, d);
897         if (result)
898                 goto exit;
899
900         ep->driver_data = cdev; /* claim */
901         req = thor_start_ep(ep);
902         if (!req) {
903                 usb_ep_disable(ep);
904                 result = -EIO;
905                 goto exit;
906         }
907
908         dev->in_req = req;
909         ep = dev->out_ep;
910         d = ep_desc(gadget, &hs_out_desc, &fs_out_desc);
911         debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
912
913         result = usb_ep_enable(ep, d);
914         if (result)
915                 goto exit;
916
917         ep->driver_data = cdev; /* claim */
918         req = thor_start_ep(ep);
919         if (!req) {
920                 usb_ep_disable(ep);
921                 result = -EIO;
922                 goto exit;
923         }
924
925         dev->out_req = req;
926         /* ACM control EP */
927         ep = dev->int_ep;
928         ep->driver_data = cdev; /* claim */
929
930  exit:
931         return result;
932 }
933
934 static int thor_func_set_alt(struct usb_function *f,
935                              unsigned intf, unsigned alt)
936 {
937         struct thor_dev *dev = thor_func->dev;
938         int result;
939
940         debug("%s: func: %s intf: %d alt: %d\n",
941               __func__, f->name, intf, alt);
942
943         switch (intf) {
944         case 0:
945                 debug("ACM INTR interface\n");
946                 break;
947         case 1:
948                 debug("Communication Data interface\n");
949                 result = thor_eps_setup(f);
950                 if (result)
951                         error("%s: EPs setup failed!", __func__);
952                 dev->configuration_done = 1;
953                 break;
954         }
955
956         return 0;
957 }
958
959 static int thor_func_init(struct usb_configuration *c)
960 {
961         struct f_thor *f_thor;
962         int status;
963
964         debug("%s: cdev: 0x%p\n", __func__, c->cdev);
965
966         f_thor = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_thor));
967         if (!f_thor)
968                 return -ENOMEM;
969
970         memset(f_thor, 0, sizeof(*f_thor));
971
972         f_thor->usb_function.name = "f_thor";
973         f_thor->usb_function.bind = thor_func_bind;
974         f_thor->usb_function.unbind = thor_unbind;
975         f_thor->usb_function.setup = thor_func_setup;
976         f_thor->usb_function.set_alt = thor_func_set_alt;
977         f_thor->usb_function.disable = thor_func_disable;
978
979         status = usb_add_function(c, &f_thor->usb_function);
980         if (status)
981                 free(f_thor);
982
983         return status;
984 }
985
986 int thor_add(struct usb_configuration *c)
987 {
988         debug("%s:\n", __func__);
989         return thor_func_init(c);
990 }
991
992 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_thor, thor_add);