diff --git a/doc/openocd.texi b/doc/openocd.texi
index fa17cfe44f247a705c075d2f89de896dd67b8fe7..c55ae482b839dea1c90077b5c67e6c91a4e50334 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2397,8 +2397,9 @@ and underscores are OK; while others (including dots!) are not.
 In older code, JTAG TAPs were numbered from 0..N.
 This feature is still present.
 However its use is highly discouraged, and
-should not be counted upon.
-Update all of your scripts to use TAP names rather than numbers.
+should not be relied on; it will be removed by mid-2010.
+Update all of your scripts to use TAP names rather than numbers,
+by paying attention to the runtime warnings they trigger.
 Using TAP numbers in target configuration scripts prevents
 reusing those scripts on boards with multiple targets.
 @end quotation
diff --git a/src/flash/str9xpec.c b/src/flash/str9xpec.c
index c1021ba026e7d7f9598cab129cd8c623292f28d6..bca3b88fc6ff769b1dc0c3a1131716094c7678fb 100644
--- a/src/flash/str9xpec.c
+++ b/src/flash/str9xpec.c
@@ -318,14 +318,14 @@ static int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *
 	str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
 	bank->driver_priv = str9xpec_info;
 
-	/* find out jtag position of flash controller
-	 * it is always after the arm966 core */
-
+	/* REVISIT verify that the jtag position of flash controller is
+	 * right after *THIS* core, which must be a STR9xx core ...
+	 */
 	armv4_5 = bank->target->arch_info;
 	arm7_9 = armv4_5->arch_info;
 	jtag_info = &arm7_9->jtag_info;
 
-	str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
+	str9xpec_info->tap = bank->target->tap;
 	str9xpec_info->isc_enable = 0;
 
 	str9xpec_build_block_list(bank);
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 651e654594d94c4f8037f860f6d47825c61dff66..c721b91b038efeca372167aa4b02a0b308e24800 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -162,10 +162,22 @@ void jtag_tap_add(struct jtag_tap_s *t)
 	*tap = t;
 }
 
+/* returns a pointer to the n-th device in the scan chain */
+static inline jtag_tap_t *jtag_tap_by_position(unsigned n)
+{
+	jtag_tap_t *t = jtag_all_taps();
+
+	while (t && n-- > 0)
+		t = t->next_tap;
+
+	return t;
+}
+
 jtag_tap_t *jtag_tap_by_string(const char *s)
 {
 	/* try by name first */
 	jtag_tap_t *t = jtag_all_taps();
+
 	while (t)
 	{
 		if (0 == strcmp(t->dotted_name, s))
@@ -178,7 +190,16 @@ jtag_tap_t *jtag_tap_by_string(const char *s)
 	if (parse_uint(s, &n) != ERROR_OK)
 		return NULL;
 
-	return jtag_tap_by_position(n);
+	/* FIXME remove this numeric fallback code late June 2010, along
+	 * with all info in the User's Guide that TAPs have numeric IDs.
+	 * Also update "scan_chain" output to not display the numbers.
+	 */
+	t = jtag_tap_by_position(n);
+	if (t)
+		LOG_WARNING("Specify TAP '%s' by name, not number %u",
+			t->dotted_name, n);
+
+	return t;
 }
 
 jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
@@ -192,17 +213,6 @@ jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
 	return t;
 }
 
-/* returns a pointer to the n-th device in the scan chain */
-jtag_tap_t *jtag_tap_by_position(unsigned n)
-{
-	jtag_tap_t *t = jtag_all_taps();
-
-	while (t && n-- > 0)
-		t = t->next_tap;
-
-	return t;
-}
-
 jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p)
 {
 	p = p ? p->next_tap : jtag_all_taps();
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 1564ca650c2bdab372170291e8a430337c7f0ba3..7cdaa51ff9971c3bebd0b2aff9e8293325429b49 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -185,7 +185,6 @@ extern jtag_tap_t* jtag_all_taps(void);
 extern const char *jtag_tap_name(const jtag_tap_t *tap);
 extern jtag_tap_t* jtag_tap_by_string(const char* dotted_name);
 extern jtag_tap_t* jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj* obj);
-extern jtag_tap_t* jtag_tap_by_position(unsigned abs_position);
 extern jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p);
 extern unsigned jtag_tap_count_enabled(void);
 extern unsigned jtag_tap_count(void);