#include <common.h>
#include <command.h>
+#include <console.h>
#include <env.h>
#include <fastboot.h>
#include <fastboot-internal.h>
return -1;
}
+void fastboot_multiresponse(int cmd, char *response)
+{
+ switch (cmd) {
+ default:
+ fastboot_fail("Unknown multiresponse command", response);
+ break;
+ }
+}
+
/**
* okay() - Send bare OKAY response
*
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
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);
#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)
*/
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_ */
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,
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);
static void fastboot_timed_send_info(const char *msg)
{
static ulong start;
+ char response[FASTBOOT_RESPONSE_LEN] = {0};
/* Initialize timer */
if (start == 0)
/* 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);
}
}
} 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