diff -urN openocd/src/target/adi_v5_jtag.c openocd_swd/src/target/adi_v5_jtag.c
--- openocd/src/target/adi_v5_jtag.c	2010-08-09 22:00:28 +0800
+++ openocd_swd/src/target/adi_v5_jtag.c	2010-08-09 22:02:01 +0800
@@ -437,6 +437,7 @@
 	.queue_ap_read =	jtag_ap_q_read,
 	.queue_ap_write =	jtag_ap_q_write,
 	.queue_ap_abort =	jtag_ap_q_abort,
+	.queue_dp_scan = adi_jtag_dp_scan,
 	.run =			jtag_dp_run,
 };
 
diff -urN openocd/src/target/adi_v5_swd.c openocd_swd/src/target/adi_v5_swd.c
--- openocd/src/target/adi_v5_swd.c	2010-08-09 22:00:28 +0800
+++ openocd_swd/src/target/adi_v5_swd.c	2010-08-09 22:06:02 +0800
@@ -32,6 +32,340 @@
 #include "arm_adi_v5.h"
 #include <helper/time_support.h>
 
+/***************************************************************************
+ *
+ * DPACC and APACC scanchain access through JTAG-DP (or SWJ-DP)
+ *
+***************************************************************************/
+
+/**
+ * Scan DPACC or APACC using target ordered uint8_t buffers.  No endianness
+ * conversions are performed.  See section 4.4.3 of the ADIv5 spec, which
+ * discusses operations which access these registers.
+ *
+ * Note that only one scan is performed.  If RnW is set, a separate scan
+ * will be needed to collect the data which was read; the "invalue" collects
+ * the posted result of a preceding operation, not the current one.
+ *
+ * @param dap the DAP
+ * @param instr SWD_DP_APACC (AP access) or SWD_DP_DPACC (DP access)
+ * @param reg_addr two significant bits; A[3:2]; for APACC access, the
+ *	SELECT register has more addressing bits.
+ * @param RnW false iff outvalue will be written to the DP or AP
+ * @param outvalue points to a 32-bit (little-endian) integer
+ * @param invalue NULL, or points to a 32-bit (little-endian) integer
+ * @param ack points to where the three bit SWD_ACK_* code will be stored
+ */
+
+/* FIXME don't export ... this is a temporary workaround for the
+ * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
+ */
+int adi_swd_dp_scan(struct adiv5_dap *dap,
+		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+		uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
+{
+	if (RnW == DPAP_READ)
+	{
+		swd_add_transact_in(instr, 1, reg_addr, (uint32_t *)invalue, ack);
+	}
+	else
+	{
+		swd_add_transact_out(instr, 0, reg_addr, *(uint32_t *)outvalue, ack);
+	}
+
+	return ERROR_OK;
+}
+
+/**
+ * Scan DPACC or APACC out and in from host ordered uint32_t buffers.
+ * This is exactly like adi_swd_dp_scan(), except that endianness
+ * conversions are performed (so the types of invalue and outvalue
+ * must be different).
+ */
+static int adi_swd_dp_scan_u32(struct adiv5_dap *dap,
+		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+		uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
+{
+	if (RnW == DPAP_READ)
+	{
+		swd_add_transact_in(instr, 1, reg_addr, invalue, ack);
+	}
+	else
+	{
+		swd_add_transact_out(instr, 0, reg_addr, outvalue, ack);
+	}
+
+	return ERROR_OK;
+}
+
+/**
+ * Utility to write AP registers.
+ */
+static inline int adi_swd_ap_write_check(struct adiv5_dap *dap,
+		uint8_t reg_addr, uint8_t *outvalue)
+{
+	return adi_swd_dp_scan(dap, SWD_DP_APACC, reg_addr, DPAP_WRITE,
+			outvalue, NULL, NULL);
+}
+
+static int adi_swd_scan_inout_check_u32(struct adiv5_dap *dap,
+		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+		uint32_t outvalue, uint32_t *invalue)
+{
+	int retval;
+
+	/* Issue the read or write */
+	retval = adi_swd_dp_scan_u32(dap, instr, reg_addr,
+			RnW, outvalue, invalue, NULL);
+	if (retval != ERROR_OK)
+		return retval;
+
+	/* For reads,  collect posted value; RDBUFF has no other effect.
+	 * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
+	 */
+	if ((RnW == DPAP_READ) && (invalue != NULL) && (instr == SWD_DP_APACC))
+		retval = adi_swd_dp_scan_u32(dap, SWD_DP_DPACC,
+				DP_RDBUFF, DPAP_READ, 0, invalue, &dap->ack);
+	return retval;
+}
+
+static int swddp_transaction_endcheck(struct adiv5_dap *dap)
+{
+	int retval;
+	uint32_t ctrlstat;
+
+	/* too expensive to call keep_alive() here */
+
+#if 0
+	/* Danger!!!! BROKEN!!!! */
+	adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+	/* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here????
+	R956 introduced the check on return value here and now Michael Schwingen reports
+	that this code no longer works....
+
+	https://lists.berlios.de/pipermail/openocd-development/2008-September/003107.html
+	*/
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+	{
+		LOG_ERROR("BUG: Why does this fail the first time????");
+	}
+	/* Why??? second time it works??? */
+#endif
+
+	/* Post CTRL/STAT read; discard any previous posted read value
+	 * but collect its ACK status.
+	 */
+	retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+	if (retval != ERROR_OK)
+		return retval;
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+		return retval;
+
+	dap->ack = dap->ack & 0x7;
+
+	/* common code path avoids calling timeval_ms() */
+	if (dap->ack != SWD_ACK_OK)
+	{
+		long long then = timeval_ms();
+
+		while (dap->ack != SWD_ACK_OK)
+		{
+			if (dap->ack == SWD_ACK_WAIT)
+			{
+				if ((timeval_ms()-then) > 1000)
+				{
+					LOG_WARNING("Timeout (1000ms) waiting "
+						"for ACK=OK/FAULT "
+						"in swd-DP transaction");
+					return ERROR_JTAG_DEVICE_ERROR;
+				}
+			}
+			else
+			{
+				LOG_WARNING("Invalid ACK %#x "
+						"in swd-DP transaction",
+						dap->ack);
+				return ERROR_JTAG_DEVICE_ERROR;
+			}
+
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+			if (retval != ERROR_OK)
+				return retval;
+			if ((retval = dap_run(dap)) != ERROR_OK)
+				return retval;
+			dap->ack = dap->ack & 0x7;
+		}
+	}
+
+	/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
+
+	/* Check for STICKYERR and STICKYORUN */
+	if (ctrlstat & (SSTICKYORUN | SSTICKYERR))
+	{
+		LOG_DEBUG("swd-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
+		/* Check power to debug regions */
+		if ((ctrlstat & 0xf0000000) != 0xf0000000)
+		{
+			retval = ahbap_debugport_init(dap);
+			if (retval != ERROR_OK)
+				return retval;
+		}
+		else
+		{
+			uint32_t mem_ap_csw, mem_ap_tar;
+
+			/* Maybe print information about last intended
+			 * MEM-AP access; but not if autoincrementing.
+			 * *Real* CSW and TAR values are always shown.
+			 */
+			if (dap->ap_tar_value != (uint32_t) -1)
+				LOG_DEBUG("MEM-AP Cached values: "
+					"ap_bank 0x%" PRIx32
+					", ap_csw 0x%" PRIx32
+					", ap_tar 0x%" PRIx32,
+					dap->ap_bank_value,
+					dap->ap_csw_value,
+					dap->ap_tar_value);
+
+			if (ctrlstat & SSTICKYORUN)
+				LOG_ERROR("SWD-DP OVERRUN - check clock, "
+					"memaccess, or reduce swd speed");
+
+			if (ctrlstat & SSTICKYERR)
+				LOG_ERROR("SWD-DP STICKY ERROR");
+
+			/* Clear Sticky Error Bits */
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+					DP_ABORT, DPAP_WRITE,
+					dap->dp_ctrl_stat | ORUNERRCLR
+						| STKERRCLR, NULL);
+			if (retval != ERROR_OK)
+				return retval;
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+			if (retval != ERROR_OK)
+				return retval;
+			if ((retval = dap_run(dap)) != ERROR_OK)
+				return retval;
+
+			LOG_DEBUG("swd-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
+
+			retval = dap_queue_ap_read(dap,
+					AP_REG_CSW, &mem_ap_csw);
+			if (retval != ERROR_OK)
+				return retval;
+
+			retval = dap_queue_ap_read(dap,
+					AP_REG_TAR, &mem_ap_tar);
+			if (retval != ERROR_OK)
+				return retval;
+
+			if ((retval = dap_run(dap)) != ERROR_OK)
+				return retval;
+			LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
+					PRIx32, mem_ap_csw, mem_ap_tar);
+
+		}
+		if ((retval = dap_run(dap)) != ERROR_OK)
+			return retval;
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	return ERROR_OK;
+}
+
+/*--------------------------------------------------------------------------*/
+
+static int swd_idcode_q_read(struct adiv5_dap *dap,
+		uint8_t *ack, uint32_t *data)
+{
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			DP_IDCODE, DPAP_READ, 0, data);
+}
+
+static int swd_dp_q_read(struct adiv5_dap *dap, unsigned reg,
+		uint32_t *data)
+{
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			reg, DPAP_READ, 0, data);
+}
+
+static int swd_dp_q_write(struct adiv5_dap *dap, unsigned reg,
+		uint32_t data)
+{
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			reg, DPAP_WRITE, data, NULL);
+}
+
+/** Select the AP register bank matching bits 7:4 of reg. */
+static int swd_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg)
+{
+	uint32_t select_ap_bank = reg & 0x000000F0;
+
+	if (select_ap_bank == dap->ap_bank_value)
+		return ERROR_OK;
+	dap->ap_bank_value = select_ap_bank;
+
+	select_ap_bank |= dap->apsel;
+
+	return swd_dp_q_write(dap, DP_SELECT, select_ap_bank);
+}
+
+static int swd_ap_q_read(struct adiv5_dap *dap, unsigned reg,
+		uint32_t *data)
+{
+	int retval = swd_ap_q_bankselect(dap, reg);
+
+	if (retval != ERROR_OK)
+		return retval;
+
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_APACC, reg,
+			DPAP_READ, 0, data);
+}
+
+static int swd_ap_q_write(struct adiv5_dap *dap, unsigned reg,
+		uint32_t data)
+{
+	uint8_t out_value_buf[4];
+
+	int retval = swd_ap_q_bankselect(dap, reg);
+	if (retval != ERROR_OK)
+		return retval;
+
+	buf_set_u32(out_value_buf, 0, 32, data);
+
+	return adi_swd_ap_write_check(dap, reg, out_value_buf);
+}
+
+static int swd_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
+{
+	return ERROR_OK;
+}
+
+static int swd_dp_run(struct adiv5_dap *dap)
+{
+	dap->ack = SWD_ACK_OK;
+	return swddp_transaction_endcheck(dap);
+}
+
+/* FIXME don't export ... just initialize as
+ * part of DAP setup
+*/
+const struct dap_ops swd_dp_ops = {
+	.queue_idcode_read =	swd_idcode_q_read,
+	.queue_dp_read =	swd_dp_q_read,
+	.queue_dp_write =	swd_dp_q_write,
+	.queue_ap_read =	swd_ap_q_read,
+	.queue_ap_write =	swd_ap_q_write,
+	.queue_ap_abort =	swd_ap_q_abort,
+	.queue_dp_scan = adi_swd_dp_scan,
+	.run =			swd_dp_run,
+};
+
+
 /*
  * This represents the bits which must be sent out on TMS/SWDIO to
  * switch a DAP implemented using an SWJ-DP module into SWD mode.
@@ -54,7 +388,7 @@
 	/* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
 	 * putting both JTAG and SWD logic into reset state.
 	 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
 };
 
 /**
@@ -76,14 +410,8 @@
 
 	LOG_DEBUG("Enter SWD mode");
 
-	/* REVISIT it's nasty to need to make calls to a "jtag"
-	 * subsystem if the link isn't in JTAG mode...
-	 */
-
-	retval =  jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq),
-			jtag2swd_bitseq, TAP_INVALID);
-	if (retval == ERROR_OK)
-		retval = jtag_execute_queue();
+	swd_add_sequence((uint8_t*)jtag2swd_bitseq, sizeof(jtag2swd_bitseq) * 8);
+	retval = jtag_execute_queue();
 
 	/* REVISIT set up the DAP's ops vector for SWD mode. */
 
diff -urN openocd/src/target/arm_adi_v5.c openocd_swd/src/target/arm_adi_v5.c
--- openocd/src/target/arm_adi_v5.c	2010-08-09 22:00:28 +0800
+++ openocd_swd/src/target/arm_adi_v5.c	2010-08-09 22:02:01 +0800
@@ -73,6 +73,7 @@
 #include "arm_adi_v5.h"
 #include <helper/time_support.h>
 
+extern int swd_mode;
 
 /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement  */
 
@@ -561,13 +562,6 @@
 	return retval;
 }
 
-/* FIXME don't import ... this is a temporary workaround for the
- * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
- */
-extern int adi_jtag_dp_scan(struct adiv5_dap *dap,
-		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
-		uint8_t *outvalue, uint8_t *invalue, uint8_t *ack);
-
 /**
  * Synchronously read a block of 32-bit words into a buffer
  * @param dap The DAP connected to the MEM-AP.
@@ -606,15 +600,8 @@
 		if (retval != ERROR_OK)
 			return retval;
 
-		/* FIXME remove these three calls to adi_jtag_dp_scan(),
-		 * so this routine becomes transport-neutral.  Be careful
-		 * not to cause performance problems with JTAG; would it
-		 * suffice to loop over dap_queue_ap_read(), or would that
-		 * be slower when JTAG is the chosen transport?
-		 */
-
 		/* Scan out first read */
-		retval = adi_jtag_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
+		retval = dap_queue_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
 				DPAP_READ, 0, NULL, NULL);
 		if (retval != ERROR_OK)
 			return retval;
@@ -624,7 +611,7 @@
 			 * previous one.  Assumes read is acked "OK/FAULT",
 			 * and CTRL_STAT says that meant "OK".
 			 */
-			retval = adi_jtag_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
+			retval = dap_queue_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
 					DPAP_READ, 0, buffer + 4 * readcount,
 					&dap->ack);
 			if (retval != ERROR_OK)
@@ -634,7 +621,7 @@
 		/* Scan in last posted value; RDBUFF has no other effect,
 		 * assuming ack is OK/FAULT and CTRL_STAT says "OK".
 		 */
-		retval = adi_jtag_dp_scan(dap, JTAG_DP_DPACC, DP_RDBUFF,
+		retval = dap_queue_dp_scan(dap, JTAG_DP_DPACC, DP_RDBUFF,
 				DPAP_READ, 0, buffer + 4 * readcount,
 				&dap->ack);
 		if (retval != ERROR_OK)
@@ -889,6 +876,7 @@
  * part of DAP transport setup
 */
 extern const struct dap_ops jtag_dp_ops;
+extern const struct dap_ops swd_dp_ops;
 
 /*--------------------------------------------------------------------------*/
 
@@ -914,7 +902,17 @@
 	LOG_DEBUG(" ");
 
 	/* JTAG-DP or SWJ-DP, in JTAG mode */
-	dap->ops = &jtag_dp_ops;
+	if (swd_mode)
+	{
+		dap->ops = &swd_dp_ops;
+
+		dap_to_swd(NULL);
+		dap_queue_idcode_read(dap, NULL, &dummy);
+	}
+	else
+	{
+		dap->ops = &jtag_dp_ops;
+	}
 
 	/* Default MEM-AP setup.
 	 *
@@ -931,9 +929,18 @@
 	if (retval != ERROR_OK)
 		return retval;
 
-	retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
-	if (retval != ERROR_OK)
-		return retval;
+	if (swd_mode)
+	{
+		retval = dap_queue_dp_write(dap, DP_ABORT, DAPABORT | STKERRCLR | WDERRCLR | ORUNERRCLR);
+		if (retval != ERROR_OK)
+			return retval;
+	}
+	else
+	{
+		retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
+		if (retval != ERROR_OK)
+			return retval;
+	}
 
 	retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &dummy);
 	if (retval != ERROR_OK)
diff -urN openocd/src/target/arm_adi_v5.h openocd_swd/src/target/arm_adi_v5.h
--- openocd/src/target/arm_adi_v5.h	2010-08-09 22:00:28 +0800
+++ openocd_swd/src/target/arm_adi_v5.h	2010-08-09 22:02:01 +0800
@@ -38,10 +38,13 @@
 #define JTAG_DP_DPACC		0xA
 #define JTAG_DP_APACC		0xB
 
+#define SWD_DP_DPACC		0
+#define SWD_DP_APACC		1
+
 /* three-bit ACK values for SWD access (sent LSB first) */
-#define SWD_ACK_OK		0x4
+#define SWD_ACK_OK		0x1
 #define SWD_ACK_WAIT		0x2
-#define SWD_ACK_FAULT		0x1
+#define SWD_ACK_FAULT		0x4
 
 #define DPAP_WRITE		0
 #define DPAP_READ		1
@@ -214,6 +217,11 @@
 	/** AP operation abort. */
 	int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack);
 
+	/** low level DP Scan */
+	int (*queue_dp_scan)(struct adiv5_dap *dap,
+			uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+			uint8_t *outvalue, uint8_t *invalue, uint8_t *ack);
+
 	/** Executes all queued DAP operations. */
 	int (*run)(struct adiv5_dap *dap);
 };
@@ -324,6 +332,28 @@
 }
 
 /**
+ * Queue an DP scan operation.  It's ONLY needed in mem_ap_read_buf_u32.
+ *
+ * @param dap The DAP used for writing.
+ * @param instr The DAP instruction.
+ * @param reg_addr The address of target memory.
+ * @param RnW Control bit used to indicate read or write operation.
+ * @param outvalue Pointer to the output buffer.
+ * @param invalue Pointer to the input buffer.
+ * @param ack Pointer to where transaction status will be stored.
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_dp_scan(struct adiv5_dap *dap,
+			uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+			uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
+{
+	assert(dap->ops != NULL);
+	return dap->ops->queue_dp_scan(dap, instr, reg_addr, RnW, 
+			outvalue, invalue, ack);
+}
+
+/**
  * Perform all queued DAP operations, and clear any errors posted in the
  * CTRL_STAT register when they are done.  Note that if more than one AP
  * operation will be queued, one of the first operations in the queue
