e39a4d627902baa0bc71af4bd60bcd698e5f788f
[fw/openocd] / src / jtag / drivers / vsllink.c
1 /***************************************************************************
2  *   Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com>       *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19
20 /* Versaloon is a programming tool for multiple MCUs.
21  * It's distributed under GPLv3.
22  * You can find it at http://www.Versaloon.com/.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include "usb_common.h"
32
33 #include "versaloon/versaloon_include.h"
34 #include "versaloon/versaloon.h"
35
36 static int vsllink_tms_offset;
37
38 struct pending_scan_result {
39         int src_offset;
40         int dest_offset;
41         int length; /* Number of bits to read */
42         struct scan_command *command; /* Corresponding scan command */
43         uint8_t *ack;
44         uint8_t *buffer;
45         bool last; /* indicate the last scan pending */
46 };
47
48 #define MAX_PENDING_SCAN_RESULTS 256
49
50 static int pending_scan_results_length;
51 static struct pending_scan_result
52                 pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
53
54 /* Queue command functions */
55 static void vsllink_end_state(tap_state_t state);
56 static void vsllink_state_move(void);
57 static void vsllink_path_move(int num_states, tap_state_t *path);
58 static void vsllink_tms(int num_bits, const uint8_t *bits);
59 static void vsllink_runtest(int num_cycles);
60 static void vsllink_stableclocks(int num_cycles, int tms);
61 static void vsllink_scan(bool ir_scan, enum scan_type type,
62         uint8_t *buffer, int scan_size, struct scan_command *command);
63 static void vsllink_reset(int trst, int srst);
64
65 /* VSLLink tap buffer functions */
66 static void vsllink_tap_append_step(int tms, int tdi);
67 static void vsllink_tap_init(void);
68 static int  vsllink_tap_execute(void);
69 static void vsllink_tap_ensure_pending(int scans);
70 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
71                 struct scan_command *command);
72
73 /* VSLLink lowlevel functions */
74 struct vsllink {
75         struct usb_dev_handle *usb_handle;
76 };
77
78 static struct vsllink *vsllink_usb_open(void);
79 static void vsllink_usb_close(struct vsllink *vsllink);
80
81 #if defined _DEBUG_JTAG_IO_
82 static void vsllink_debug_buffer(uint8_t *buffer, int length);
83 #endif
84
85 static int tap_length;
86 static int tap_buffer_size;
87 static uint8_t *tms_buffer;
88 static uint8_t *tdi_buffer;
89 static uint8_t *tdo_buffer;
90
91 struct vsllink *vsllink_handle;
92
93 static int vsllink_execute_queue(void)
94 {
95         struct jtag_command *cmd = jtag_command_queue;
96         int scan_size;
97         enum scan_type type;
98         uint8_t *buffer;
99
100         DEBUG_JTAG_IO("-------------------------------------"
101                 " vsllink "
102                 "-------------------------------------");
103
104         while (cmd != NULL) {
105                 switch (cmd->type) {
106                         case JTAG_RUNTEST:
107                                 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
108                                         cmd->cmd.runtest->num_cycles,
109                                         tap_state_name(cmd->cmd.runtest
110                                                         ->end_state));
111
112                                 vsllink_end_state(cmd->cmd.runtest->end_state);
113                                 vsllink_runtest(cmd->cmd.runtest->num_cycles);
114                                 break;
115
116                         case JTAG_TLR_RESET:
117                                 DEBUG_JTAG_IO("statemove end in %s",
118                                         tap_state_name(cmd->cmd.statemove
119                                                         ->end_state));
120
121                                 vsllink_end_state(cmd->cmd.statemove
122                                                         ->end_state);
123                                 vsllink_state_move();
124                                 break;
125
126                         case JTAG_PATHMOVE:
127                                 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
128                                         cmd->cmd.pathmove->num_states,
129                                         tap_state_name(cmd->cmd.pathmove
130                                                 ->path[cmd->cmd.pathmove
131                                                         ->num_states - 1]));
132
133                                 vsllink_path_move(
134                                         cmd->cmd.pathmove->num_states,
135                                         cmd->cmd.pathmove->path);
136                                 break;
137
138                         case JTAG_SCAN:
139                                 DEBUG_JTAG_IO("JTAG Scan...");
140
141                                 vsllink_end_state(cmd->cmd.scan->end_state);
142
143                                 scan_size = jtag_build_buffer(
144                                         cmd->cmd.scan, &buffer);
145
146                                 if (cmd->cmd.scan->ir_scan)
147                                         DEBUG_JTAG_IO(
148                                                 "JTAG Scan write IR(%d bits), "
149                                                 "end in %s:",
150                                                 scan_size,
151                                                 tap_state_name(cmd->cmd.scan
152                                                                 ->end_state));
153
154                                 else
155                                         DEBUG_JTAG_IO(
156                                                 "JTAG Scan write DR(%d bits), "
157                                                 "end in %s:",
158                                                 scan_size,
159                                                 tap_state_name(cmd->cmd.scan
160                                                         ->end_state));
161
162 #ifdef _DEBUG_JTAG_IO_
163                                 vsllink_debug_buffer(buffer,
164                                         DIV_ROUND_UP(scan_size, 8));
165 #endif
166
167                                 type = jtag_scan_type(cmd->cmd.scan);
168
169                                 vsllink_scan(cmd->cmd.scan->ir_scan,
170                                                 type, buffer, scan_size,
171                                                 cmd->cmd.scan);
172                                 break;
173
174                         case JTAG_RESET:
175                                 DEBUG_JTAG_IO("reset trst: %i srst %i",
176                                                 cmd->cmd.reset->trst,
177                                                 cmd->cmd.reset->srst);
178
179                                 vsllink_tap_execute();
180
181                                 if (cmd->cmd.reset->trst == 1)
182                                         tap_set_state(TAP_RESET);
183
184                                 vsllink_reset(cmd->cmd.reset->trst,
185                                                 cmd->cmd.reset->srst);
186                                 break;
187
188                         case JTAG_SLEEP:
189                                 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
190                                 vsllink_tap_execute();
191                                 jtag_sleep(cmd->cmd.sleep->us);
192                                 break;
193
194                         case JTAG_STABLECLOCKS:
195                                 DEBUG_JTAG_IO("add %d clocks",
196                                         cmd->cmd.stableclocks->num_cycles);
197
198                                 switch (tap_get_state()) {
199                                 case TAP_RESET:
200                                         /* tms must be '1' to stay
201                                          * n TAP_RESET mode
202                                          */
203                                         scan_size = 1;
204                                         break;
205                                 case TAP_DRSHIFT:
206                                 case TAP_IDLE:
207                                 case TAP_DRPAUSE:
208                                 case TAP_IRSHIFT:
209                                 case TAP_IRPAUSE:
210                                         /* else, tms should be '0' */
211                                         scan_size = 0;
212                                         break;
213                                         /* above stable states are OK */
214                                 default:
215                                          LOG_ERROR("jtag_add_clocks() "
216                                                 "in non-stable state \"%s\"",
217                                                 tap_state_name(tap_get_state())
218                                                 );
219                                  exit(-1);
220                                 }
221                                 vsllink_stableclocks(cmd->cmd.stableclocks
222                                                 ->num_cycles, scan_size);
223                                 break;
224
225                         case JTAG_TMS:
226                                 DEBUG_JTAG_IO("add %d jtag tms",
227                                                 cmd->cmd.tms->num_bits);
228
229                                 vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
230                                 break;
231
232                         default:
233                                 LOG_ERROR("BUG: unknown JTAG command type "
234                                         "encountered: %d", cmd->type);
235                                 exit(-1);
236                 }
237                 cmd = cmd->next;
238         }
239
240         return vsllink_tap_execute();
241 }
242
243 static int vsllink_speed(int speed)
244 {
245         versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);
246         return versaloon_interface.adaptors.peripheral_commit();
247 }
248
249 static int vsllink_khz(int khz, int *jtag_speed)
250 {
251         *jtag_speed = khz;
252
253         return ERROR_OK;
254 }
255
256 static int vsllink_speed_div(int jtag_speed, int *khz)
257 {
258         *khz = jtag_speed;
259
260         return ERROR_OK;
261 }
262
263 static void vsllink_free_buffer(void)
264 {
265         if (tdi_buffer != NULL)
266         {
267                 free(tdi_buffer);
268                 tdi_buffer = NULL;
269         }
270         if (tdo_buffer != NULL)
271         {
272                 free(tdo_buffer);
273                 tdo_buffer = NULL;
274         }
275         if (tms_buffer != NULL)
276         {
277                 free(tms_buffer);
278                 tms_buffer = NULL;
279         }
280 }
281
282 static int vsllink_quit(void)
283 {
284         versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
285                 0, 0, GPIO_SRST | GPIO_TRST);
286         versaloon_interface.adaptors.gpio.fini(0);
287         versaloon_interface.adaptors.jtag_raw.fini(0);
288         versaloon_interface.adaptors.peripheral_commit();
289         versaloon_interface.fini();
290
291         vsllink_free_buffer();
292         vsllink_usb_close(vsllink_handle);
293
294         return ERROR_OK;
295 }
296
297 static int vsllink_init(void)
298 {
299         vsllink_handle = vsllink_usb_open();
300         if (vsllink_handle == 0) {
301                 LOG_ERROR("Can't find USB JTAG Interface!"\
302                                 "Please check connection and permissions.");
303                 return ERROR_JTAG_INIT_FAILED;
304         }
305         LOG_DEBUG("vsllink found on %04X:%04X",
306                         versaloon_interface.usb_setting.vid,
307                         versaloon_interface.usb_setting.pid);
308         versaloon_usb_device_handle = vsllink_handle->usb_handle;
309
310         if (ERROR_OK != versaloon_interface.init())
311         {
312                 return ERROR_FAIL;
313         }
314         if (versaloon_interface.usb_setting.buf_size < 32)
315         {
316                 versaloon_interface.fini();
317                 return ERROR_FAIL;
318         }
319
320         // malloc buffer size for tap
321         tap_buffer_size = versaloon_interface.usb_setting.buf_size - 32;
322         vsllink_free_buffer();
323         tdi_buffer = (uint8_t *)malloc(tap_buffer_size);
324         tdo_buffer = (uint8_t *)malloc(tap_buffer_size);
325         tms_buffer = (uint8_t *)malloc(tap_buffer_size);
326         if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer))
327         {
328                 vsllink_quit();
329                 return ERROR_FAIL;
330         }
331
332         versaloon_interface.adaptors.jtag_raw.init(0);
333         versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz());
334         versaloon_interface.adaptors.gpio.init(0);
335         versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
336                                 GPIO_TRST, GPIO_SRST, GPIO_SRST);
337         if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit())
338         {
339                 return ERROR_FAIL;
340         }
341
342         vsllink_reset(0, 0);
343         vsllink_tap_init();
344         return ERROR_OK;
345 }
346
347 /***************************************************************************/
348 /* Queue command implementations */
349
350 static void vsllink_end_state(tap_state_t state)
351 {
352         if (tap_is_state_stable(state))
353                 tap_set_end_state(state);
354         else {
355                 LOG_ERROR("BUG: %i is not a valid end state", state);
356                 exit(-1);
357         }
358 }
359
360 /* Goes to the end state. */
361 static void vsllink_state_move(void)
362 {
363         int i;
364         uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
365                                         tap_get_end_state());
366         uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
367                                         tap_get_end_state());
368
369         for (i = 0; i < tms_scan_bits; i++)
370                 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
371
372         tap_set_state(tap_get_end_state());
373 }
374
375 static void vsllink_path_move(int num_states, tap_state_t *path)
376 {
377         for (int i = 0; i < num_states; i++) {
378                 if (path[i] == tap_state_transition(tap_get_state(), false))
379                         vsllink_tap_append_step(0, 0);
380                 else if (path[i] == tap_state_transition(tap_get_state(), true))
381                         vsllink_tap_append_step(1, 0);
382                 else {
383                         LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
384                                                 tap_state_name(tap_get_state()),
385                                                 tap_state_name(path[i]));
386                         exit(-1);
387                 }
388
389                 tap_set_state(path[i]);
390         }
391
392         tap_set_end_state(tap_get_state());
393 }
394
395 static void vsllink_tms(int num_bits, const uint8_t *bits)
396 {
397         for (int i = 0; i < num_bits; i++) {
398                 vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
399         }
400 }
401
402 static void vsllink_stableclocks(int num_cycles, int tms)
403 {
404         while (num_cycles > 0) {
405                 vsllink_tap_append_step(tms, 0);
406                 num_cycles--;
407         }
408 }
409
410 static void vsllink_runtest(int num_cycles)
411 {
412         tap_state_t saved_end_state = tap_get_end_state();
413
414         if (tap_get_state() != TAP_IDLE) {
415                 /* enter IDLE state */
416                 vsllink_end_state(TAP_IDLE);
417                 vsllink_state_move();
418         }
419
420         vsllink_stableclocks(num_cycles, 0);
421
422         // post-process
423         // set end_state
424         vsllink_end_state(saved_end_state);
425         if (tap_get_end_state() != tap_get_end_state())
426                 vsllink_state_move();
427 }
428
429 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
430                                 int scan_size, struct scan_command *command)
431 {
432         tap_state_t saved_end_state;
433
434         saved_end_state = tap_get_end_state();
435
436         /* Move to appropriate scan state */
437         vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
438
439         if (tap_get_state() != tap_get_end_state())
440                 vsllink_state_move();
441         vsllink_end_state(saved_end_state);
442
443         /* Scan */
444         vsllink_tap_append_scan(scan_size, buffer, command);
445
446         /* Goto Pause and record position to insert tms:0 */
447         vsllink_tap_append_step(0, 0);
448         vsllink_tms_offset = tap_length;
449
450         tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
451
452         if (tap_get_state() != tap_get_end_state())
453                 vsllink_state_move();
454 }
455
456 static void vsllink_reset(int trst, int srst)
457 {
458         LOG_DEBUG("trst: %i, srst: %i", trst, srst);
459
460         if (!srst)
461                 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
462         else
463                 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
464
465         if (!trst)
466                 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
467         else
468                 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
469         versaloon_interface.adaptors.peripheral_commit();
470 }
471
472 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
473 {
474         if (CMD_ARGC != 1) {
475                 LOG_ERROR("parameter error, "
476                                         "should be one parameter for VID");
477                 return ERROR_OK;
478         }
479
480         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
481                 versaloon_interface.usb_setting.vid);
482         return ERROR_OK;
483 }
484
485 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
486 {
487         if (CMD_ARGC != 1) {
488                 LOG_ERROR("parameter error, "
489                                         "should be one parameter for PID");
490                 return ERROR_OK;
491         }
492         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
493                 versaloon_interface.usb_setting.pid);
494         return ERROR_OK;
495 }
496
497 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
498 {
499         if (CMD_ARGC != 1) {
500                 LOG_ERROR("parameter error, "
501                         "should be one parameter for BULKIN endpoint");
502                 return ERROR_OK;
503         }
504
505         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
506                 versaloon_interface.usb_setting.ep_in);
507
508         versaloon_interface.usb_setting.ep_in |= 0x80;
509
510         return ERROR_OK;
511 }
512
513 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
514 {
515         if (CMD_ARGC != 1) {
516                 LOG_ERROR("parameter error, "
517                         "should be one parameter for BULKOUT endpoint");
518                 return ERROR_OK;
519         }
520
521         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
522                 versaloon_interface.usb_setting.ep_out);
523
524         versaloon_interface.usb_setting.ep_out &= ~0x80;
525
526         return ERROR_OK;
527 }
528
529 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
530 {
531         if (CMD_ARGC != 1) {
532                 LOG_ERROR("parameter error, "
533                         "should be one parameter for interface number");
534                 return ERROR_OK;
535         }
536
537         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
538                 versaloon_interface.usb_setting.interface);
539         return ERROR_OK;
540 }
541
542 /***************************************************************************/
543 /* VSLLink tap functions */
544
545 static void vsllink_tap_init(void)
546 {
547         tap_length = 0;
548         pending_scan_results_length = 0;
549         vsllink_tms_offset = 0;
550 }
551
552 static void vsllink_tap_ensure_pending(int scans)
553 {
554         int available_scans =
555                         MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
556
557         if (scans > available_scans)
558                 vsllink_tap_execute();
559 }
560
561 static void vsllink_tap_append_step(int tms, int tdi)
562 {
563         int index_var = tap_length / 8;
564
565         int bit_index = tap_length % 8;
566         uint8_t bit = 1 << bit_index;
567
568         if (tms)
569                 tms_buffer[index_var] |= bit;
570         else
571                 tms_buffer[index_var] &= ~bit;
572
573         if (tdi)
574                 tdi_buffer[index_var] |= bit;
575         else
576                 tdi_buffer[index_var] &= ~bit;
577
578         tap_length++;
579
580         if (tap_buffer_size * 8 <= tap_length)
581                 vsllink_tap_execute();
582 }
583
584 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
585                 struct scan_command *command)
586 {
587         struct pending_scan_result *pending_scan_result;
588         int len_tmp, len_all, i;
589
590         len_all = 0;
591         while (len_all < length) {
592                 vsllink_tap_ensure_pending(1);
593                 pending_scan_result =
594                                 &pending_scan_results_buffer[
595                                         pending_scan_results_length];
596
597                 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
598                         /* Use all memory available
599                            vsllink_tap_append_step will commit automatically */
600                         len_tmp = tap_buffer_size * 8 - tap_length;
601                         pending_scan_result->last = false;
602                 } else {
603                         len_tmp = length - len_all;
604                         pending_scan_result->last = true;
605                 }
606                 pending_scan_result->src_offset = tap_length;
607                 pending_scan_result->dest_offset = len_all;
608                 pending_scan_result->length = len_tmp;
609                 pending_scan_result->command = command;
610                 pending_scan_result->buffer = buffer;
611                 pending_scan_results_length++;
612
613                 for (i = 0; i < len_tmp; i++) {
614                         vsllink_tap_append_step(((len_all + i) < length-1
615                                                 ? 0 : 1),
616                                         (buffer[(len_all + i)/8]
617                                                 >> ((len_all + i)%8)) & 1);
618                 }
619
620                 len_all += len_tmp;
621         }
622 }
623
624 static int vsllink_jtag_execute(void)
625 {
626         int i;
627         int result;
628
629         if (tap_length <= 0)
630                 return ERROR_OK;
631
632         versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer, 
633                 tdo_buffer, tap_length);
634
635         result = versaloon_interface.adaptors.peripheral_commit();
636
637         if (result == ERROR_OK) {
638                 for (i = 0; i < pending_scan_results_length; i++) {
639                         struct pending_scan_result *pending_scan_result =
640                                 &pending_scan_results_buffer[i];
641                         uint8_t *buffer = pending_scan_result->buffer;
642                         int length = pending_scan_result->length;
643                         int src_first = pending_scan_result->src_offset;
644                         int dest_first = pending_scan_result->dest_offset;
645                         bool last = pending_scan_result->last;
646
647                         struct scan_command *command;
648
649                         command = pending_scan_result->command;
650                         buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
651
652 #ifdef _DEBUG_JTAG_IO_
653                         DEBUG_JTAG_IO(
654                                 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
655                                 length, src_first, dest_first);
656                         vsllink_debug_buffer(buffer + dest_first / 8,
657                                         DIV_ROUND_UP(length, 7));
658 #endif
659
660                         if (last) {
661                                 if (jtag_read_buffer(buffer, command)
662                                                 != ERROR_OK) {
663                                         vsllink_tap_init();
664                                         return ERROR_JTAG_QUEUE_FAILED;
665                                 }
666
667                                 if (pending_scan_result->buffer != NULL)
668                                         free(pending_scan_result->buffer);
669                         }
670                 }
671         } else {
672                 LOG_ERROR("vsllink_jtag_execute failure");
673                 return ERROR_JTAG_QUEUE_FAILED;
674         }
675
676         vsllink_tap_init();
677
678         return ERROR_OK;
679 }
680
681 static int vsllink_tap_execute(void)
682 {
683         return vsllink_jtag_execute();
684 }
685
686 /*****************************************************************************/
687 /* VSLLink USB low-level functions */
688
689 static uint8_t usb_check_string(usb_dev_handle *usb, uint8_t stringidx,
690                                                                 char * string, char * buff, uint16_t buf_size)
691 {
692         int len;
693         uint8_t alloced = 0;
694         uint8_t ret = 1;
695
696         if (NULL == buff)
697         {
698                 buf_size = 256;
699                 buff = (char*)malloc(buf_size);
700                 if (NULL == buff)
701                 {
702                         ret = 0;
703                         goto free_and_return;
704                 }
705                 alloced = 1;
706         }
707
708         strcpy(buff, "");
709         len = usb_get_string_simple(usb, stringidx, (char *)buff, buf_size);
710         if ((len < 0) || (len != ((int)strlen((const char *)buff))))
711         {
712                 ret = 0;
713                 goto free_and_return;
714         }
715
716         buff[len] = '\0';
717         if ((string != NULL) && strcmp((const char *)buff, string))
718         {
719                 ret = 0;
720                 goto free_and_return;
721         }
722
723 free_and_return:
724         if (alloced && (buff != NULL))
725         {
726                 free(buff);
727                 buff = NULL;
728         }
729         return ret;
730 }
731
732 static usb_dev_handle* find_usb_device(uint16_t VID, uint16_t PID,
733                 uint8_t interface, int8_t serialindex, char *serialstring,
734                 int8_t productindex, char *productstring)
735 {
736         usb_dev_handle *dev_handle = NULL;
737         struct usb_bus *busses;
738         struct usb_bus *bus;
739         struct usb_device *dev;
740
741         usb_init();
742         usb_find_busses();
743         usb_find_devices();
744         busses = usb_get_busses();
745
746         for (bus = busses; bus; bus = bus->next)
747         {
748                 for (dev = bus->devices; dev; dev = dev->next)
749                 {
750                         if ((dev->descriptor.idVendor == VID)
751                                 && (dev->descriptor.idProduct == PID))
752                         {
753                                 dev_handle = usb_open(dev);
754                                 if (NULL == dev_handle)
755                                 {
756                                         LOG_ERROR("failed to open %04X:%04X, %s", VID, PID,
757                                                                 usb_strerror());
758                                         continue;
759                                 }
760
761                                 // check description string
762                                 if (((productstring != NULL) && (productindex >= 0)
763                                                 && !usb_check_string(dev_handle, productindex,
764                                                                                                 productstring, NULL, 0))
765                                         || ((serialstring != NULL) && (serialindex >= 0)
766                                                 && !usb_check_string(dev_handle, serialindex,
767                                                                                                 serialstring, NULL, 0)))
768                                 {
769                                         usb_close(dev_handle);
770                                         dev_handle = NULL;
771                                         continue;
772                                 }
773
774                                 if (usb_claim_interface(dev_handle, interface) != 0)
775                                 {
776                                         LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE,
777                                                                 "claim interface", usb_strerror());
778                                         usb_close(dev_handle);
779                                         dev_handle = NULL;
780                                         continue;
781                                 }
782
783                                 if (dev_handle != NULL)
784                                 {
785                                         return dev_handle;
786                                 }
787                         }
788                 }
789         }
790
791         return dev_handle;
792 }
793
794 static struct vsllink *vsllink_usb_open(void)
795 {
796         usb_init();
797
798         struct usb_dev_handle *dev;
799
800         dev = find_usb_device(versaloon_interface.usb_setting.vid,
801                                                         versaloon_interface.usb_setting.pid,
802                                                         versaloon_interface.usb_setting.interface,
803                                                         0, NULL, 2, "Versaloon");
804         if (NULL == dev)
805                 return NULL;
806
807         struct vsllink *result = malloc(sizeof(struct vsllink));
808         result->usb_handle = dev;
809         return result;
810 }
811
812 static void vsllink_usb_close(struct vsllink *vsllink)
813 {
814         int ret;
815
816         ret = usb_release_interface(vsllink->usb_handle,
817                         versaloon_interface.usb_setting.interface);
818         if (ret != 0) {
819                 LOG_ERROR("fail to release interface %d, %d returned",
820                                         versaloon_interface.usb_setting.interface, ret);
821                 exit(-1);
822         }
823
824         ret = usb_close(vsllink->usb_handle);
825         if (ret != 0) {
826                 LOG_ERROR("fail to close usb, %d returned", ret);
827                 exit(-1);
828         }
829
830         free(vsllink);
831 }
832
833 #define BYTES_PER_LINE  16
834
835 #if defined _DEBUG_JTAG_IO_
836 static void vsllink_debug_buffer(uint8_t *buffer, int length)
837 {
838         char line[81];
839         char s[4];
840         int i;
841         int j;
842
843         for (i = 0; i < length; i += BYTES_PER_LINE) {
844                 snprintf(line, 5, "%04x", i);
845                 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
846                         snprintf(s, 4, " %02x", buffer[j]);
847                         strcat(line, s);
848                 }
849                 LOG_DEBUG("%s", line);
850         }
851 }
852 #endif /* _DEBUG_JTAG_IO_ */
853
854 static const struct command_registration vsllink_command_handlers[] = {
855         {
856                 .name = "vsllink_usb_vid",
857                 .handler = &vsllink_handle_usb_vid_command,
858                 .mode = COMMAND_CONFIG,
859         },
860         {
861                 .name = "vsllink_usb_pid",
862                 .handler = &vsllink_handle_usb_pid_command,
863                 .mode = COMMAND_CONFIG,
864         },
865         {
866                 .name = "vsllink_usb_bulkin",
867                 .handler = &vsllink_handle_usb_bulkin_command,
868                 .mode = COMMAND_CONFIG,
869         },
870         {
871                 .name = "vsllink_usb_bulkout",
872                 .handler = &vsllink_handle_usb_bulkout_command,
873                 .mode = COMMAND_CONFIG,
874         },
875         {
876                 .name = "vsllink_usb_interface",
877                 .handler = &vsllink_handle_usb_interface_command,
878                 .mode = COMMAND_CONFIG,
879         },
880         COMMAND_REGISTRATION_DONE
881 };
882
883 static const char *vsllink_transports[] = {"jtag", "swd", NULL};
884
885 struct jtag_interface vsllink_interface = {
886         .name = "vsllink",
887         .supported = DEBUG_CAP_TMS_SEQ,
888         .commands = vsllink_command_handlers,
889         .transports = vsllink_transports,
890
891         .init = vsllink_init,
892         .quit = vsllink_quit,
893         .khz = vsllink_khz,
894         .speed = vsllink_speed,
895         .speed_div = vsllink_speed_div,
896         .execute_queue = vsllink_execute_queue,
897 };