aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/fastboot/fb_command.c10
-rw-r--r--drivers/usb/gadget/f_fastboot.c29
-rw-r--r--include/fastboot.h18
-rw-r--r--net/fastboot_udp.c29
4 files changed, 80 insertions, 6 deletions
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index 5fcadcd..ab72d8c 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -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
*
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 9f322c9..09e740c 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -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);
diff --git a/include/fastboot.h b/include/fastboot.h
index 296451f..59cbea6 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -14,6 +14,16 @@
#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_ */
diff --git a/net/fastboot_udp.c b/net/fastboot_udp.c
index d690787..6fee441 100644
--- a/net/fastboot_udp.c
+++ b/net/fastboot_udp.c
@@ -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