]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
fastboot: multiresponse support
authorIon Agorria <ion@agorria.com>
Fri, 5 Jan 2024 07:22:06 +0000 (09:22 +0200)
committerMattijs Korpershoek <mkorpershoek@baylibre.com>
Tue, 9 Jan 2024 13:58:33 +0000 (14:58 +0100)
Currently u-boot fastboot can only send one message back to host,
so if there is a need to print more than one line messages must be
kept sending until all the required data is obtained. This behavior
can be adjusted using multiresponce ability (getting multiple lines
of response) proposed in this patch.

Signed-off-by: Ion Agorria <ion@agorria.com>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Link: https://lore.kernel.org/r/20240105072212.6615-2-clamor95@gmail.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
drivers/fastboot/fb_command.c
drivers/usb/gadget/f_fastboot.c
include/fastboot.h
net/fastboot_udp.c

index 5fcadcdf503d98f2f2b622ea0b124b03497af556..ab72d8c7810fcb48ee33f5cc14e24a180cb8be90 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <console.h>
 #include <env.h>
 #include <fastboot.h>
 #include <fastboot-internal.h>
@@ -152,6 +153,15 @@ int fastboot_handle_command(char *cmd_string, char *response)
        return -1;
 }
 
+void fastboot_multiresponse(int cmd, char *response)
+{
+       switch (cmd) {
+       default:
+               fastboot_fail("Unknown multiresponse command", response);
+               break;
+       }
+}
+
 /**
  * okay() - Send bare OKAY response
  *
index 9f322c955086da849d3d43b7cc9b10291b7d5d8e..09e740cc96224f75cb6c11e78af36d799c0f66dd 100644 (file)
@@ -497,6 +497,25 @@ static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
        do_exit_on_complete(ep, req);
 }
 
+static int multiresponse_cmd = -1;
+static void multiresponse_on_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       char response[FASTBOOT_RESPONSE_LEN] = {0};
+
+       if (multiresponse_cmd == -1)
+               return;
+
+       /* Call handler to obtain next response */
+       fastboot_multiresponse(multiresponse_cmd, response);
+       fastboot_tx_write_str(response);
+
+       /* If response is final OKAY/FAIL response disconnect this handler and unset cmd */
+       if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4)) {
+               multiresponse_cmd = -1;
+               fastboot_func->in_req->complete = fastboot_complete;
+       }
+}
+
 static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
 {
        /* When usb dequeue complete will be called
@@ -524,6 +543,16 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
                fastboot_fail("buffer overflow", response);
        }
 
+       if (!strncmp(FASTBOOT_MULTIRESPONSE_START, response, 4)) {
+               multiresponse_cmd = cmd;
+               fastboot_multiresponse(multiresponse_cmd, response);
+
+               /* Only add complete callback if first is not a final OKAY/FAIL response */
+               if (strncmp("OKAY", response, 4) && strncmp("FAIL", response, 4)) {
+                       fastboot_func->in_req->complete = multiresponse_on_complete;
+               }
+       }
+
        if (!strncmp("DATA", response, 4)) {
                req->complete = rx_handler_dl_image;
                req->length = rx_bytes_expected(ep);
index 296451f89d44dc25ac8ecdb8a3446681f93e14f0..59cbea61ecab553e459e54a776b086931c020faa 100644 (file)
 
 #define FASTBOOT_VERSION       "0.4"
 
+/*
+ * Signals u-boot fastboot code to send multiple responses by
+ * calling response generating function repeatedly until a OKAY/FAIL
+ * is generated as final response.
+ *
+ * This status code is only used internally to signal, must NOT
+ * be sent to host.
+ */
+#define FASTBOOT_MULTIRESPONSE_START   ("MORE")
+
 /* The 64 defined bytes plus \0 */
 #define FASTBOOT_COMMAND_LEN   (64 + 1)
 #define FASTBOOT_RESPONSE_LEN  (64 + 1)
@@ -172,5 +182,13 @@ void fastboot_data_download(const void *fastboot_data,
  */
 void fastboot_data_complete(char *response);
 
+/**
+ * fastboot_handle_multiresponse() - Called for each response to send
+ *
+ * @cmd: Command id that requested multiresponse
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_multiresponse(int cmd, char *response);
+
 void fastboot_acmd_complete(void);
 #endif /* _FASTBOOT_H_ */
index d6907874787e3482e463066de170fe3d8c354712..6fee441ab3b6e6476911a210bf28edc64bdc55da 100644 (file)
@@ -42,16 +42,15 @@ static int fastboot_remote_port;
 static int fastboot_our_port;
 
 /**
- * fastboot_udp_send_info() - Send an INFO packet during long commands.
+ * fastboot_udp_send_response() - Send an response into UDP
  *
- * @msg: String describing the reason for waiting
+ * @response: Response to send
  */
-static void fastboot_udp_send_info(const char *msg)
+static void fastboot_udp_send_response(const char *response)
 {
        uchar *packet;
        uchar *packet_base;
        int len = 0;
-       char response[FASTBOOT_RESPONSE_LEN] = {0};
 
        struct fastboot_header response_header = {
                .id = FASTBOOT_FASTBOOT,
@@ -66,7 +65,6 @@ static void fastboot_udp_send_info(const char *msg)
        memcpy(packet, &response_header, sizeof(response_header));
        packet += sizeof(response_header);
        /* Write response */
-       fastboot_response("INFO", response, "%s", msg);
        memcpy(packet, response, strlen(response));
        packet += strlen(response);
 
@@ -91,6 +89,7 @@ static void fastboot_udp_send_info(const char *msg)
 static void fastboot_timed_send_info(const char *msg)
 {
        static ulong start;
+       char response[FASTBOOT_RESPONSE_LEN] = {0};
 
        /* Initialize timer */
        if (start == 0)
@@ -99,7 +98,8 @@ static void fastboot_timed_send_info(const char *msg)
        /* Send INFO packet to host every 30 seconds */
        if (time >= 30000) {
                start = get_timer(0);
-               fastboot_udp_send_info(msg);
+               fastboot_response("INFO", response, "%s", msg);
+               fastboot_udp_send_response(response);
        }
 }
 
@@ -180,6 +180,23 @@ static void fastboot_send(struct fastboot_header header, char *fastboot_data,
                } else {
                        cmd = fastboot_handle_command(command, response);
                        pending_command = false;
+
+                       if (!strncmp(FASTBOOT_MULTIRESPONSE_START, response, 4)) {
+                               while (1) {
+                                       /* Call handler to obtain next response */
+                                       fastboot_multiresponse(cmd, response);
+
+                                       /*
+                                        * Send more responses or break to send
+                                        * final OKAY/FAIL response
+                                        */
+                                       if (strncmp("OKAY", response, 4) &&
+                                           strncmp("FAIL", response, 4))
+                                               fastboot_udp_send_response(response);
+                                       else
+                                               break;
+                               }
+                       }
                }
                /*
                 * Sent some INFO packets, need to update sequence number in