f_thor: allow to download 4GB images
authorPrzemyslaw Marczak <p.marczak@samsung.com>
Tue, 10 Nov 2015 11:29:18 +0000 (12:29 +0100)
committerJaehoon Chung <jh80.chung@samsung.com>
Fri, 8 Apr 2016 02:17:34 +0000 (11:17 +0900)
This commit fixes 2GB file size limit for thor downloader.

The application on host side sends the downloaded file size as 32-bit
unsigned value. But the thor implementation on U-Boot side interpreted
this as signed value. This caused an error for files with size greater
than 2GB.

This commit fixes the data types in code, which allows to send file
of size 4GB.

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
drivers/usb/gadget/f_thor.c

index 342b1e79abedd4f2f3bc767646741e748295e975..27f3256a854847a66f5376fd2a5511c02da1c065 100644 (file)
@@ -37,7 +37,7 @@
 
 static void thor_tx_data(unsigned char *data, int len);
 static void thor_set_dma(void *addr, int len);
-static int thor_rx_data(void);
+static int thor_rx_data(size_t *received);
 
 static struct f_thor *thor_func;
 static inline struct f_thor *func_to_thor(struct usb_function *f)
@@ -54,7 +54,7 @@ DEFINE_CACHE_ALIGN_BUFFER(unsigned char, thor_rx_data_buf,
 /*         THOR protocol - transmission handling             */
 /* ********************************************************** */
 DEFINE_CACHE_ALIGN_BUFFER(char, f_name, F_NAME_BUF_SIZE);
-static unsigned long long int thor_file_size;
+static size_t thor_file_size;
 #ifdef CONFIG_TIZEN
 static unsigned long long int total_file_size;
 static unsigned long long int downloaded_file_size;
@@ -150,12 +150,12 @@ static int process_rqt_cmd(const struct rqt_box *rqt)
        return true;
 }
 
-static long long int download_head(unsigned long long total,
+static int download_head(unsigned long long total,
                                   unsigned int packet_size,
-                                  long long int *left,
+                                  size_t *left,
                                   int *cnt)
 {
-       long long int rcv_cnt = 0, left_to_rcv, ret_rcv;
+       size_t rcv_cnt = 0, left_to_rcv, ret_rcv;
        struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
        void *transfer_buffer = dfu_get_buf(dfu_entity);
        void *buf = transfer_buffer;
@@ -171,11 +171,11 @@ static long long int download_head(unsigned long long total,
        while (total - rcv_cnt >= packet_size) {
                thor_set_dma(buf, packet_size);
                buf += packet_size;
-               ret_rcv = thor_rx_data();
-               if (ret_rcv < 0)
-                       return ret_rcv;
+               ret = thor_rx_data(&ret_rcv);
+               if (ret < 0)
+                       return ret;
                rcv_cnt += ret_rcv;
-               debug("%d: RCV data count: %llu cnt: %d\n", usb_pkt_cnt,
+               debug("%d: RCV data count: %u cnt: %d\n", usb_pkt_cnt,
                      rcv_cnt, *cnt);
 
                if ((rcv_cnt % THOR_STORE_UNIT_SIZE) == 0) {
@@ -200,21 +200,21 @@ static long long int download_head(unsigned long long total,
         * on the medium (they are smaller than THOR_STORE_UNIT_SIZE)
         */
        *left = left_to_rcv + buf - transfer_buffer;
-       debug("%s: left: %llu left_to_rcv: %llu buf: 0x%p\n", __func__,
+       debug("%s: left: %u left_to_rcv: %u buf: 0x%p\n", __func__,
              *left, left_to_rcv, buf);
 
        if (left_to_rcv) {
                thor_set_dma(buf, packet_size);
-               ret_rcv = thor_rx_data();
-               if (ret_rcv < 0)
-                       return ret_rcv;
+               ret = thor_rx_data(&ret_rcv);
+               if (ret < 0)
+                       return ret;
                rcv_cnt += ret_rcv;
                send_data_rsp(0, ++usb_pkt_cnt);
        }
 
-       debug("%s: %llu total: %llu cnt: %d\n", __func__, rcv_cnt, total, *cnt);
+       debug("%s: %u total: %llu cnt: %d\n", __func__, rcv_cnt, total, *cnt);
 
-       return rcv_cnt;
+       return 0;
 }
 
 static int download_tail(long long int left, int cnt)
@@ -267,11 +267,11 @@ static int download_tail(long long int left, int cnt)
        return ret;
 }
 
-static long long int process_rqt_download(const struct rqt_box *rqt)
+static int process_rqt_download(const struct rqt_box *rqt)
 {
        ALLOC_CACHE_ALIGN_BUFFER(struct rsp_box, rsp, sizeof(struct rsp_box));
-       static long long int left, ret_head;
-       int file_type, ret = 0;
+       int ret_head, file_type, ret = 0;
+       static size_t left;
        static int cnt;
 
        memset(rsp, 0, sizeof(struct rsp_box));
@@ -280,12 +280,12 @@ static long long int process_rqt_download(const struct rqt_box *rqt)
 
        switch (rqt->rqt_data) {
        case RQT_DL_INIT:
-               thor_file_size = rqt->int_data[0];
+               thor_file_size = (size_t)rqt->int_data[0];
 #ifdef CONFIG_TIZEN
                total_file_size = thor_file_size;
                downloaded_file_size = 0;
 #endif
-               debug("INIT: total %d bytes\n", rqt->int_data[0]);
+               debug("INIT: total %u bytes\n", (size_t)rqt->int_data[0]);
                break;
        case RQT_DL_FILE_INFO:
                file_type = rqt->int_data[0];
@@ -296,10 +296,10 @@ static long long int process_rqt_download(const struct rqt_box *rqt)
                        break;
                }
 
-               thor_file_size = rqt->int_data[1];
+               thor_file_size = (size_t)rqt->int_data[1];
                memcpy(f_name, rqt->str_data[0], F_NAME_BUF_SIZE);
 
-               debug("INFO: name(%s, %d), size(%llu), type(%d)\n",
+               debug("INFO: name(%s, %d), size(%u), type(%d)\n",
                      f_name, 0, thor_file_size, file_type);
 
                rsp->int_data[0] = THOR_PACKET_SIZE;
@@ -357,7 +357,7 @@ static int process_data(void)
                ret = process_rqt_cmd(rqt);
                break;
        case RQT_DL:
-               ret = (int) process_rqt_download(rqt);
+               ret = process_rqt_download(rqt);
                break;
        case RQT_UL:
                puts("RQT: UPLOAD not supported!\n");
@@ -548,13 +548,14 @@ static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
        return req;
 }
 
-static int thor_rx_data(void)
+static int thor_rx_data(size_t *received)
 {
        struct thor_dev *dev = thor_func->dev;
-       int data_to_rx, tmp, status;
+       size_t data_to_rx;
+       int status;
 
        data_to_rx = dev->out_req->length;
-       tmp = data_to_rx;
+       *received = data_to_rx;
        do {
                dev->out_req->length = data_to_rx;
                debug("dev->out_req->length:%d dev->rxdata:%d\n",
@@ -588,7 +589,7 @@ static int thor_rx_data(void)
 #endif
        } while (data_to_rx);
 
-       return tmp;
+       return 0;
 }
 
 static void thor_tx_data(unsigned char *data, int len)
@@ -728,6 +729,7 @@ int thor_init(void)
 {
        struct thor_dev *dev = thor_func->dev;
        int power_key_cnt = 0;
+       size_t received;
 
 #ifdef CONFIG_TIZEN
 #ifdef CONFIG_OF_MULTI
@@ -761,7 +763,7 @@ int thor_init(void)
 #endif
        thor_set_dma(thor_rx_data_buf, strlen("THOR"));
        /* detect the download request from Host PC */
-       if (thor_rx_data() < 0) {
+       if (thor_rx_data(&received) < 0) {
                printf("%s: Data not received!\n", __func__);
                return -1;
        }
@@ -782,14 +784,14 @@ int thor_init(void)
 
 int thor_handle(void)
 {
+       size_t received;
        int ret;
 
        /* receive the data from Host PC */
        while (1) {
                thor_set_dma(thor_rx_data_buf, sizeof(struct rqt_box));
-               ret = thor_rx_data();
-
-               if (ret > 0) {
+               ret = thor_rx_data(&received);
+               if (!ret) {
                        ret = process_data();
 #ifdef CONFIG_THOR_RESET_OFF
                        if (ret == RESET_DONE)