]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - drivers/usb/gadget/f_mass_storage.c
usb: f_mass_storage: sleep_thread: retrigger watchdog
[karo-tx-uboot.git] / drivers / usb / gadget / f_mass_storage.c
index be6b418d4e82fffe03e8041912e03100cb848335..f30b4f812e6d4b8495e8b08fc0c59bb84e9ce851 100644 (file)
 #include <config.h>
 #include <malloc.h>
 #include <common.h>
+#include <g_dnl.h>
+#include <watchdog.h>
 
 #include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/composite.h>
 #include <usb/lin_gadget_compat.h>
+#include <g_dnl.h>
 
 /*------------------------------------------------------------------------*/
 
@@ -669,13 +672,27 @@ static int sleep_thread(struct fsg_common *common)
                if (common->thread_wakeup_needed)
                        break;
 
-               if (++i == 50000) {
+               if (++i == 20000) {
                        busy_indicator();
                        i = 0;
                        k++;
                }
 
-               usb_gadget_handle_interrupts();
+               if (k == 10) {
+                       /* Handle CTRL+C */
+                       if (ctrlc())
+                               return -EPIPE;
+
+                       WATCHDOG_RESET();
+
+                       /* Check cable connection */
+                       if (!g_dnl_board_usb_cable_connected())
+                               return -EIO;
+
+                       k = 0;
+               }
+
+               usb_gadget_handle_interrupts(0);
        }
        common->thread_wakeup_needed = 0;
        return rc;
@@ -959,7 +976,7 @@ static int do_write(struct fsg_common *common)
 
                        /* If an error occurred, report it and its position */
                        if (nwritten < amount) {
-                               printf("nwritten:%d amount:%d\n", nwritten,
+                               printf("nwritten:%zd amount:%u\n", nwritten,
                                       amount);
                                curlun->sense_data = SS_WRITE_ERROR;
                                curlun->info_valid = 1;
@@ -1096,6 +1113,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
 
        memset(buf, 0, 8);
        buf[0] = TYPE_DISK;
+       buf[1] = curlun->removable ? 0x80 : 0;
        buf[2] = 2;             /* ANSI SCSI level 2 */
        buf[3] = 2;             /* SCSI-2 INQUIRY data format */
        buf[4] = 31;            /* Additional length */
@@ -2387,6 +2405,7 @@ static void handle_exception(struct fsg_common *common)
 
 int fsg_main_thread(void *common_)
 {
+       int ret;
        struct fsg_common       *common = the_fsg_common;
        /* The main loop */
        do {
@@ -2396,12 +2415,16 @@ int fsg_main_thread(void *common_)
                }
 
                if (!common->running) {
-                       sleep_thread(common);
+                       ret = sleep_thread(common);
+                       if (ret)
+                               return ret;
+
                        continue;
                }
 
-               if (get_next_command(common))
-                       continue;
+               ret = get_next_command(common);
+               if (ret)
+                       return ret;
 
                if (!exception_in_progress(common))
                        common->state = FSG_STATE_DATA_PHASE;
@@ -2443,12 +2466,12 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
 
        /* Allocate? */
        if (!common) {
-               common = calloc(sizeof *common, 1);
+               common = calloc(sizeof(*common), 1);
                if (!common)
                        return ERR_PTR(-ENOMEM);
                common->free_storage_on_release = 1;
        } else {
-               memset(common, 0, sizeof common);
+               memset(common, 0, sizeof(*common));
                common->free_storage_on_release = 0;
        }
 
@@ -2497,7 +2520,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
 buffhds_first_it:
                bh->inreq_busy = 0;
                bh->outreq_busy = 0;
-               bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+               bh->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, FSG_BUFLEN);
                if (unlikely(!bh->buf)) {
                        rc = -ENOMEM;
                        goto error_release;
@@ -2604,7 +2627,7 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
                bytes += (*tmp)->bLength;
        bytes += (n_desc + 1) * sizeof(*tmp);
 
-       mem = kmalloc(bytes, GFP_KERNEL);
+       mem = memalign(CONFIG_SYS_CACHELINE_SIZE, bytes);
        if (!mem)
                return NULL;
 
@@ -2760,3 +2783,5 @@ int fsg_init(struct ums *ums_dev)
 
        return 0;
 }
+
+DECLARE_GADGET_BIND_CALLBACK(usb_dnl_ums, fsg_add);