+/* Sends a packet with content determined by the printf format string
+ FORMAT and the remaining arguments, then gets the reply. Returns
+ whether the packet was a success, a failure, or unknown. */
+
+enum packet_result
+remote_send_printf (const char *format, ...)
+{
+ struct remote_state *rs = get_remote_state ();
+ int max_size = get_remote_packet_size ();
+
+ va_list ap;
+ va_start (ap, format);
+
+ rs->buf[0] = '\0';
+ if (vsnprintf (rs->buf, max_size, format, ap) >= max_size)
+ internal_error (__FILE__, __LINE__, "Too long remote packet.");
+
+ if (putpkt (rs->buf) < 0)
+ error (_("Communication problem with target."));
+
+ rs->buf[0] = '\0';
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ return packet_check_result (rs->buf);
+}
+
+static void
+restore_remote_timeout (void *p)
+{
+ int value = *(int *)p;
+ remote_timeout = value;
+}
+
+/* Flash writing can take quite some time. We'll set
+ effectively infinite timeout for flash operations.
+ In future, we'll need to decide on a better approach. */
+static const int remote_flash_timeout = 1000;
+
+static void
+remote_flash_erase (struct target_ops *ops,
+ ULONGEST address, LONGEST length)
+{
+ int saved_remote_timeout = remote_timeout;
+ enum packet_result ret;
+
+ struct cleanup *back_to = make_cleanup (restore_remote_timeout,
+ &saved_remote_timeout);
+ remote_timeout = remote_flash_timeout;
+
+ ret = remote_send_printf ("vFlashErase:%s,%s",
+ paddr (address),
+ phex (length, 4));
+ switch (ret)
+ {
+ case PACKET_UNKNOWN:
+ error (_("Remote target does not support flash erase"));
+ case PACKET_ERROR:
+ error (_("Error erasing flash with vFlashErase packet"));
+ default:
+ break;
+ }
+
+ do_cleanups (back_to);
+}
+
+static LONGEST
+remote_flash_write (struct target_ops *ops,
+ ULONGEST address, LONGEST length,
+ const gdb_byte *data)
+{
+ int saved_remote_timeout = remote_timeout;
+ int ret;
+ struct cleanup *back_to = make_cleanup (restore_remote_timeout,
+ &saved_remote_timeout);
+
+ remote_timeout = remote_flash_timeout;
+ ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, 'X', 0);
+ do_cleanups (back_to);
+
+ return ret;
+}
+
+static void
+remote_flash_done (struct target_ops *ops)
+{
+ int saved_remote_timeout = remote_timeout;
+ int ret;
+ struct cleanup *back_to = make_cleanup (restore_remote_timeout,
+ &saved_remote_timeout);
+
+ remote_timeout = remote_flash_timeout;
+ ret = remote_send_printf ("vFlashDone");
+ do_cleanups (back_to);
+
+ switch (ret)
+ {
+ case PACKET_UNKNOWN:
+ error (_("Remote target does not support vFlashDone"));
+ case PACKET_ERROR:
+ error (_("Error finishing flash operation"));
+ default:
+ break;
+ }
+}
+