diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c
index 9af57dd1b60a797d118a8da8634c772d7fe4055d..67167c78b167c9adb51b299081c5a10822f7e363 100644
--- a/src/jtag/ft2232.c
+++ b/src/jtag/ft2232.c
@@ -108,6 +108,7 @@ ft2232_layout_t ft2232_layouts[] =
 	{"usbjtag", usbjtag_init, usbjtag_reset, NULL},
 	{"jtagkey", jtagkey_init, jtagkey_reset, NULL},
 	{"jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL},
+	{"oocdlink", jtagkey_init, jtagkey_reset, NULL},
 	{"signalyzer", usbjtag_init, usbjtag_reset, NULL},
 	{"evb_lm3s811", usbjtag_init, usbjtag_reset, NULL},
 	{"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink},
@@ -1260,7 +1261,8 @@ int jtagkey_init(void)
 		nSRST = 0x02;
 		nSRSTnOE = 0x08;
 	}
-	else if (strcmp(layout->name, "jtagkey_prototype_v1") == 0)
+	else if ((strcmp(layout->name, "jtagkey_prototype_v1") == 0) ||
+		(strcmp(layout->name, "oocdlink") == 0))
 	{
 		nTRST = 0x02;
 		nTRSTnOE = 0x1;
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 7bf042a91e03e29701b3bf32a3ad95838ac7391e..cd7e7fe187910ed1c2bae14455fbb7be5aab345a 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -253,7 +253,7 @@ int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 	return ERROR_OK;
 }
 
-int arm7_9_add_breakpoint(struct target_s *target, u32 address, u32 length, enum breakpoint_type type)
+int arm7_9_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 {
 	armv4_5_common_t *armv4_5 = target->arch_info;
 	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
@@ -266,28 +266,29 @@ int arm7_9_add_breakpoint(struct target_s *target, u32 address, u32 length, enum
 	
 	if (arm7_9->force_hw_bkpts)
 	{
-		type = BKPT_HARD;
+		DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
+		breakpoint->type = BKPT_HARD;
 	}
 	
-	if ((type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
+	if ((breakpoint->type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
 	{
 		INFO("sw breakpoint requested, but software breakpoints not enabled");
 		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 	}
 	
-	if ((type == BKPT_HARD) && (arm7_9->wp_available < 1))
+	if ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1))
 	{
 		INFO("no watchpoint unit available for hardware breakpoint");
 		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 	}
 	
-	if ((length != 2) && (length != 4))
+	if ((breakpoint->length != 2) && (breakpoint->length != 4))
 	{
 		INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
 		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 	}
 	
-	if (type == BKPT_HARD)
+	if (breakpoint->type == BKPT_HARD)
 		arm7_9->wp_available--;
 	
 	return ERROR_OK;
@@ -406,7 +407,7 @@ int arm7_9_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
 	return ERROR_OK;
 }
 
-int arm7_9_add_watchpoint(struct target_s *target, u32 address, u32 length, enum watchpoint_rw rw)
+int arm7_9_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
 {
 	armv4_5_common_t *armv4_5 = target->arch_info;
 	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
@@ -422,7 +423,7 @@ int arm7_9_add_watchpoint(struct target_s *target, u32 address, u32 length, enum
 		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 	}
 	
-	if ((length != 1) && (length != 2) && (length != 4))
+	if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
 	{
 		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 	}
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index 08468907e8297d63fe87b6bb9c33ba69c4d29df5..fc90c05912ba7cb77073b77ec7f6c82847624e78 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -114,9 +114,9 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
 
 int arm7_9_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_prams, reg_param_t *reg_param, u32 entry_point, void *arch_info);
 
-int arm7_9_add_breakpoint(struct target_s *target, u32 address, u32 length, enum breakpoint_type type);
+int arm7_9_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
 int arm7_9_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
-int arm7_9_add_watchpoint(struct target_s *target, u32 address, u32 length, enum watchpoint_rw rw);
+int arm7_9_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
 int arm7_9_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
 
 void arm7_9_enable_eice_step(target_t *target);
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index a30d67a4cac7600758ba6c344ce66348e069d9fc..8b140b3e98ea4176d8dd1dfba83be985512234f9 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -56,17 +56,29 @@ int breakpoint_add(target_t *target, u32 address, u32 length, enum breakpoint_ty
 		breakpoint_p = &breakpoint->next;
 		breakpoint = breakpoint->next;
 	}
+		
+	(*breakpoint_p) = malloc(sizeof(breakpoint_t));
+	(*breakpoint_p)->address = address;
+	(*breakpoint_p)->length = length;
+	(*breakpoint_p)->type = type;
+	(*breakpoint_p)->set = 0;
+	(*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
+	(*breakpoint_p)->next = NULL;
 	
-	if ((retval = target->type->add_breakpoint(target, address, length, type)) != ERROR_OK)
+	if ((retval = target->type->add_breakpoint(target, *breakpoint_p)) != ERROR_OK)
 	{
 		switch (retval)
 		{
 			case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
-				INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[type]);
+				INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[(*breakpoint_p)->type]);
+				free (*breakpoint_p);
+				*breakpoint_p = NULL;
 				return retval;
 				break;
 			case ERROR_TARGET_NOT_HALTED:
 				INFO("can't add breakpoint while target is running");
+				free (*breakpoint_p);
+				*breakpoint_p = NULL;
 				return retval;
 				break;
 			default:
@@ -76,15 +88,9 @@ int breakpoint_add(target_t *target, u32 address, u32 length, enum breakpoint_ty
 		}
 	}
 	
-	(*breakpoint_p) = malloc(sizeof(breakpoint_t));
-	(*breakpoint_p)->address = address;
-	(*breakpoint_p)->length = length;
-	(*breakpoint_p)->type = type;
-	(*breakpoint_p)->set = 0;
-	(*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
-	(*breakpoint_p)->next = NULL;
-	
-	DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", breakpoint_type_strings[type], address, length);
+	DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", 
+		breakpoint_type_strings[(*breakpoint_p)->type],
+		(*breakpoint_p)->address, (*breakpoint_p)->length);
 	
 	return ERROR_OK;
 }
@@ -159,16 +165,29 @@ int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw
 		watchpoint = watchpoint->next;
 	}
 	
-	if ((retval = target->type->add_watchpoint(target, address, length, rw)) != ERROR_OK)
+	(*watchpoint_p) = malloc(sizeof(watchpoint_t));
+	(*watchpoint_p)->address = address;
+	(*watchpoint_p)->length = length;
+	(*watchpoint_p)->value = value;
+	(*watchpoint_p)->mask = mask;
+	(*watchpoint_p)->rw = rw;
+	(*watchpoint_p)->set = 0;
+	(*watchpoint_p)->next = NULL;
+		
+	if ((retval = target->type->add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
 	{
 		switch (retval)
 		{
 			case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
-				INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[rw]);
+				INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[(*watchpoint_p)->rw]);
+				free (*watchpoint_p);
+				*watchpoint_p = NULL;
 				return retval;
 				break;
 			case ERROR_TARGET_NOT_HALTED:
 				INFO("can't add watchpoint while target is running");
+				free (*watchpoint_p);
+				*watchpoint_p = NULL;
 				return retval;
 				break;
 			default:
@@ -178,16 +197,9 @@ int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw
 		}
 	}
 	
-	(*watchpoint_p) = malloc(sizeof(watchpoint_t));
-	(*watchpoint_p)->address = address;
-	(*watchpoint_p)->length = length;
-	(*watchpoint_p)->value = value;
-	(*watchpoint_p)->mask = mask;
-	(*watchpoint_p)->rw = rw;
-	(*watchpoint_p)->set = 0;
-	(*watchpoint_p)->next = NULL;
-	
-	DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x", watchpoint_rw_strings[rw], address, length);
+	DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x",
+		watchpoint_rw_strings[(*watchpoint_p)->rw],
+		(*watchpoint_p)->address, (*watchpoint_p)->length);
 	
 	return ERROR_OK;
 }
diff --git a/src/target/target.h b/src/target/target.h
index 7201867169bd7d0ed15bc7ccd8fde07144be0cbf..04157fde1e22139feecd155ebc52e72a709be18f 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -125,9 +125,9 @@ typedef struct target_type_s
 	/* target break-/watchpoint control 
 	* rw: 0 = write, 1 = read, 2 = access
 	*/
-	int (*add_breakpoint)(struct target_s *target, u32 address, u32 length, enum breakpoint_type type);
+	int (*add_breakpoint)(struct target_s *target, breakpoint_t *breakpoint);
 	int (*remove_breakpoint)(struct target_s *target, breakpoint_t *breakpoint);
-	int (*add_watchpoint)(struct target_s *target, u32 address, u32 length, enum watchpoint_rw rw);
+	int (*add_watchpoint)(struct target_s *target, watchpoint_t *watchpoint);
 	int (*remove_watchpoint)(struct target_s *target, watchpoint_t *watchpoint);
 
 	/* target algorithm support */