]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/dfu/dfu.c
Merge branch 'master' of git://git.denx.de/u-boot-usb
[karo-tx-uboot.git] / drivers / dfu / dfu.c
index b8d382d9b5dfefd453557ff122c2a3399b31d318..14cb366b014cb3e7fb9de8f9e316783c1be05f19 100644 (file)
 #include <linux/list.h>
 #include <linux/compiler.h>
 
-static bool dfu_reset_request;
+static bool dfu_detach_request;
 static LIST_HEAD(dfu_list);
 static int dfu_alt_num;
 static int alt_num_cnt;
 static struct hash_algo *dfu_hash_algo;
 
-bool dfu_reset(void)
+/*
+ * The purpose of the dfu_usb_get_reset() function is to
+ * provide information if after USB_DETACH request
+ * being sent the dfu-util performed reset of USB
+ * bus.
+ *
+ * Described behaviour is the only way to distinct if
+ * user has typed -e (detach) or -R (reset) when invoking
+ * dfu-util command.
+ *
+ */
+__weak bool dfu_usb_get_reset(void)
+{
+       return true;
+}
+
+bool dfu_detach(void)
+{
+       return dfu_detach_request;
+}
+
+void dfu_trigger_detach(void)
 {
-       return dfu_reset_request;
+       dfu_detach_request = true;
 }
 
-void dfu_trigger_reset()
+void dfu_clear_detach(void)
 {
-       dfu_reset_request = true;
+       dfu_detach_request = false;
 }
 
 static int dfu_find_alt_num(const char *s)
@@ -268,7 +289,7 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
        readn = 0;
        while (size > 0) {
                /* get chunk that can be read */
-               chunk = min(size, dfu->b_left);
+               chunk = min((long)size, dfu->b_left);
                /* consume */
                if (chunk > 0) {
                        memcpy(buf, dfu->i_buf, chunk);
@@ -332,7 +353,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                case DFU_RAM_ADDR:
                        break;
                default:
-                       if (dfu->r_left >= dfu_buf_size) {
+                       if (dfu->r_left > dfu_buf_size) {
                                printf("%s: File too big for buffer\n",
                                       __func__);
                                return -EOVERFLOW;
@@ -401,6 +422,7 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
 
        dfu->alt = alt;
        dfu->max_buf_size = 0;
+       dfu->free_entity = NULL;
 
        /* Specific for mmc device */
        if (strcmp(interface, "mmc") == 0) {
@@ -412,6 +434,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
        } else if (strcmp(interface, "ram") == 0) {
                if (dfu_fill_entity_ram(dfu, devstr, s))
                        return -1;
+       } else if (strcmp(interface, "sf") == 0) {
+               if (dfu_fill_entity_sf(dfu, devstr, s))
+                       return -1;
        } else {
                printf("%s: Device %s not (yet) supported!\n",
                       __func__,  interface);
@@ -427,6 +452,8 @@ void dfu_free_entities(void)
 
        list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) {
                list_del(&dfu->list);
+               if (dfu->free_entity)
+                       dfu->free_entity(dfu);
                t = dfu;
        }
        if (t)
@@ -517,10 +544,35 @@ struct dfu_entity *dfu_get_entity(int alt)
 int dfu_get_alt(char *name)
 {
        struct dfu_entity *dfu;
+       char *str;
 
        list_for_each_entry(dfu, &dfu_list, list) {
-               if (!strncmp(dfu->name, name, strlen(dfu->name)))
-                       return dfu->alt;
+               if (dfu->name[0] != '/') {
+                       if (!strncmp(dfu->name, name, strlen(dfu->name)))
+                               return dfu->alt;
+               } else {
+                       /*
+                        * One must also consider absolute path
+                        * (/boot/bin/uImage) available at dfu->name when
+                        * compared "plain" file name (uImage)
+                        *
+                        * It is the case for e.g. thor gadget where lthor SW
+                        * sends only the file name, so only the very last part
+                        * of path must be checked for equality
+                        */
+
+                       str = strstr(dfu->name, name);
+                       if (!str)
+                               continue;
+
+                       /*
+                        * Check if matching substring is the last element of
+                        * dfu->name (uImage)
+                        */
+                       if (strlen(dfu->name) ==
+                           ((str - dfu->name) + strlen(name)))
+                               return dfu->alt;
+               }
        }
 
        return -ENODEV;