Index: C:/msys/1.0/home/Administrator/openocd/trunk/src/jtag/vsllink.c
===================================================================
--- C:/msys/1.0/home/Administrator/openocd/trunk/src/jtag/vsllink.c	(revision 2562)
+++ C:/msys/1.0/home/Administrator/openocd/trunk/src/jtag/vsllink.c	(working copy)
@@ -42,9 +42,12 @@
 static uint8_t vsllink_usb_bulkout;
 static uint8_t vsllink_usb_bulkin;
 static uint8_t vsllink_usb_interface;
+static char *vsllink_usb_serialstring = NULL;
 static uint8_t vsllink_mode = VSLLINK_MODE_NORMAL;
 static int VSLLINK_USB_TIMEOUT = 10000;
 
+#define VSLLINK_USB_SERIAL_INDEX	3
+
 static int VSLLINK_BufferSize = 1024;
 
 /* Global USB buffers */
@@ -191,6 +194,7 @@
 static int vsllink_handle_usb_bulkin_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int vsllink_handle_usb_bulkout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int vsllink_handle_usb_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int vsllink_handle_usb_serialstring_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int vsllink_handle_mode_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
 /* Queue command functions */
@@ -594,6 +598,11 @@
 		free(vsllink_usb_out_buffer);
 		vsllink_usb_out_buffer = NULL;
 	}
+	if (vsllink_usb_serialstring != NULL)
+	{
+		free(vsllink_usb_serialstring);
+		vsllink_usb_serialstring = NULL;
+	}
 
 	return ERROR_OK;
 }
@@ -1369,6 +1378,8 @@
 					COMMAND_CONFIG, NULL);
 	register_command(cmd_ctx, NULL, "vsllink_usb_interface", vsllink_handle_usb_interface_command,
 					COMMAND_CONFIG, NULL);
+	register_command(cmd_ctx, NULL, "vsllink_usb_serialstring", vsllink_handle_usb_serialstring_command,
+					COMMAND_CONFIG, NULL);
 	register_command(cmd_ctx, NULL, "vsllink_mode", vsllink_handle_mode_command,
 					COMMAND_CONFIG, NULL);
 
@@ -1461,6 +1472,26 @@
 	return parse_u8(args[0], &vsllink_usb_interface);
 }
 
+static int vsllink_handle_usb_serialstring_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+	if (argc != 1)
+	{
+		LOG_ERROR("parameter error, should be one parameter for serial string");
+		return ERROR_OK;
+	}
+
+	vsllink_usb_serialstring = malloc(strlen(args[0]) + 1);
+	if (vsllink_usb_serialstring != NULL)
+	{
+		strcpy(vsllink_usb_serialstring, args[0]);
+		return ERROR_OK;
+	}
+	else
+	{
+		return ERROR_FAIL;
+	}
+}
+
 /***************************************************************************/
 /* VSLLink tap functions */
 
@@ -1756,11 +1787,16 @@
 	struct usb_bus *busses;
 	struct usb_bus *bus;
 	struct usb_device *dev;
-	int ret;
+	int ret, i;
 
 	vsllink_jtag_t *result;
 
 	result = (vsllink_jtag_t*) malloc(sizeof(vsllink_jtag_t));
+	if (NULL == result)
+	{
+		LOG_ERROR("not enough memory.");
+		return NULL;
+	}
 
 	usb_init();
 	usb_find_busses();
@@ -1780,31 +1816,60 @@
 				if (NULL == result->usb_handle)
 				{
 					LOG_ERROR("failed to open %04X:%04X, not enough permissions?", vsllink_usb_vid, vsllink_usb_pid);
-					exit(-1);
+					continue;
 				}
 
+				if (vsllink_usb_serialstring != NULL)
+				{
+					char buf[256];
+					int buflen;
+
+					buflen = usb_get_string_simple(result->usb_handle, VSLLINK_USB_SERIAL_INDEX, buf, sizeof(buf));
+					if ((buflen < 0) 
+						|| (buflen != ((int)strlen(vsllink_usb_serialstring) + 1)))
+					{
+						usb_close(result->usb_handle);
+						result->usb_handle = NULL;
+						continue;
+					}
+
+					for (i = 0; i < (buflen - 1); i++)
+					{
+						if (buf[i] != vsllink_usb_serialstring[i])
+						{
+							usb_close(result->usb_handle);
+							result->usb_handle = NULL;
+							break;
+						}
+					}
+					if (i != (buflen - 1))
+					{
+						continue;
+					}
+				}
+
 				/* usb_set_configuration required under win32 */
 				ret = usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
 				if (ret != 0)
 				{
 					LOG_ERROR("fail to set configuration to %d, %d returned, not enough permissions?", dev->config[0].bConfigurationValue, ret);
-					exit(-1);
+					usb_close(result->usb_handle);
+					result->usb_handle = NULL;
+					continue;
 				}
 				ret = usb_claim_interface(result->usb_handle, vsllink_usb_interface);
 				if (ret != 0)
 				{
 					LOG_ERROR("fail to claim interface %d, %d returned", vsllink_usb_interface, ret);
-					exit(-1);
+					usb_close(result->usb_handle);
+					result->usb_handle = NULL;
+					continue;
 				}
 
-#if 0
-				/*
-				 * This makes problems under Mac OS X. And is not needed
-				 * under Windows. Hopefully this will not break a linux build
-				 */
-				usb_set_altinterface(result->usb_handle, 0);
-#endif
-				return result;
+				if (result->usb_handle != NULL)
+				{
+					return result;
+				}
 			}
 		}
 	}
