Change return value on error.
[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                 return ERROR_COMMAND_SYNTAX_ERROR;
476         }
477
478         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
479                 versaloon_interface.usb_setting.vid);
480         return ERROR_OK;
481 }
482
483 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
484 {
485         if (CMD_ARGC != 1) {
486                 return ERROR_COMMAND_SYNTAX_ERROR;
487         }
488         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
489                 versaloon_interface.usb_setting.pid);
490         return ERROR_OK;
491 }
492
493 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
494 {
495         if (CMD_ARGC != 1) {
496                 return ERROR_COMMAND_SYNTAX_ERROR;
497         }
498
499         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
500                 versaloon_interface.usb_setting.ep_in);
501
502         versaloon_interface.usb_setting.ep_in |= 0x80;
503
504         return ERROR_OK;
505 }
506
507 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
508 {
509         if (CMD_ARGC != 1) {
510                 return ERROR_COMMAND_SYNTAX_ERROR;
511         }
512
513         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
514                 versaloon_interface.usb_setting.ep_out);
515
516         versaloon_interface.usb_setting.ep_out &= ~0x80;
517
518         return ERROR_OK;
519 }
520
521 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
522 {
523         if (CMD_ARGC != 1) {
524                 return ERROR_COMMAND_SYNTAX_ERROR;
525         }
526
527         COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
528                 versaloon_interface.usb_setting.interface);
529         return ERROR_OK;
530 }
531
532 /***************************************************************************/
533 /* VSLLink tap functions */
534
535 static void vsllink_tap_init(void)
536 {
537         tap_length = 0;
538         pending_scan_results_length = 0;
539         vsllink_tms_offset = 0;
540 }
541
542 static void vsllink_tap_ensure_pending(int scans)
543 {
544         int available_scans =
545                         MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
546
547         if (scans > available_scans)
548                 vsllink_tap_execute();
549 }
550
551 static void vsllink_tap_append_step(int tms, int tdi)
552 {
553         int index_var = tap_length / 8;
554
555         int bit_index = tap_length % 8;
556         uint8_t bit = 1 << bit_index;
557
558         if (tms)
559                 tms_buffer[index_var] |= bit;
560         else
561                 tms_buffer[index_var] &= ~bit;
562
563         if (tdi)
564                 tdi_buffer[index_var] |= bit;
565         else
566                 tdi_buffer[index_var] &= ~bit;
567
568         tap_length++;
569
570         if (tap_buffer_size * 8 <= tap_length)
571                 vsllink_tap_execute();
572 }
573
574 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
575                 struct scan_command *command)
576 {
577         struct pending_scan_result *pending_scan_result;
578         int len_tmp, len_all, i;
579
580         len_all = 0;
581         while (len_all < length) {
582                 vsllink_tap_ensure_pending(1);
583                 pending_scan_result =
584                                 &pending_scan_results_buffer[
585                                         pending_scan_results_length];
586
587                 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
588                         /* Use all memory available
589                            vsllink_tap_append_step will commit automatically */
590                         len_tmp = tap_buffer_size * 8 - tap_length;
591                         pending_scan_result->last = false;
592                 } else {
593                         len_tmp = length - len_all;
594                         pending_scan_result->last = true;
595                 }
596                 pending_scan_result->src_offset = tap_length;
597                 pending_scan_result->dest_offset = len_all;
598                 pending_scan_result->length = len_tmp;
599                 pending_scan_result->command = command;
600                 pending_scan_result->buffer = buffer;
601                 pending_scan_results_length++;
602
603                 for (i = 0; i < len_tmp; i++) {
604                         vsllink_tap_append_step(((len_all + i) < length-1
605                                                 ? 0 : 1),
606                                         (buffer[(len_all + i)/8]
607                                                 >> ((len_all + i)%8)) & 1);
608                 }
609
610                 len_all += len_tmp;
611         }
612 }
613
614 static int vsllink_jtag_execute(void)
615 {
616         int i;
617         int result;
618
619         if (tap_length <= 0)
620                 return ERROR_OK;
621
622         versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer, 
623                 tdo_buffer, tap_length);
624
625         result = versaloon_interface.adaptors.peripheral_commit();
626
627         if (result == ERROR_OK) {
628                 for (i = 0; i < pending_scan_results_length; i++) {
629                         struct pending_scan_result *pending_scan_result =
630                                 &pending_scan_results_buffer[i];
631                         uint8_t *buffer = pending_scan_result->buffer;
632                         int length = pending_scan_result->length;
633                         int src_first = pending_scan_result->src_offset;
634                         int dest_first = pending_scan_result->dest_offset;
635                         bool last = pending_scan_result->last;
636
637                         struct scan_command *command;
638
639                         command = pending_scan_result->command;
640                         buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
641
642 #ifdef _DEBUG_JTAG_IO_
643                         DEBUG_JTAG_IO(
644                                 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
645                                 length, src_first, dest_first);
646                         vsllink_debug_buffer(buffer + dest_first / 8,
647                                         DIV_ROUND_UP(length, 7));
648 #endif
649
650                         if (last) {
651                                 if (jtag_read_buffer(buffer, command)
652                                                 != ERROR_OK) {
653                                         vsllink_tap_init();
654                                         return ERROR_JTAG_QUEUE_FAILED;
655                                 }
656
657                                 if (pending_scan_result->buffer != NULL)
658                                         free(pending_scan_result->buffer);
659                         }
660                 }
661         } else {
662                 LOG_ERROR("vsllink_jtag_execute failure");
663                 return ERROR_JTAG_QUEUE_FAILED;
664         }
665
666         vsllink_tap_init();
667
668         return ERROR_OK;
669 }
670
671 static int vsllink_tap_execute(void)
672 {
673         return vsllink_jtag_execute();
674 }
675
676 /*****************************************************************************/
677 /* VSLLink USB low-level functions */
678
679 static uint8_t usb_check_string(usb_dev_handle *usb, uint8_t stringidx,
680                                                                 char * string, char * buff, uint16_t buf_size)
681 {
682         int len;
683         uint8_t alloced = 0;
684         uint8_t ret = 1;
685
686         if (NULL == buff)
687         {
688                 buf_size = 256;
689                 buff = (char*)malloc(buf_size);
690                 if (NULL == buff)
691                 {
692                         ret = 0;
693                         goto free_and_return;
694                 }
695                 alloced = 1;
696         }
697
698         strcpy(buff, "");
699         len = usb_get_string_simple(usb, stringidx, (char *)buff, buf_size);
700         if ((len < 0) || (len != ((int)strlen((const char *)buff))))
701         {
702                 ret = 0;
703                 goto free_and_return;
704         }
705
706         buff[len] = '\0';
707         if ((string != NULL) && strcmp((const char *)buff, string))
708         {
709                 ret = 0;
710                 goto free_and_return;
711         }
712
713 free_and_return:
714         if (alloced && (buff != NULL))
715         {
716                 free(buff);
717                 buff = NULL;
718         }
719         return ret;
720 }
721
722 static usb_dev_handle* find_usb_device(uint16_t VID, uint16_t PID,
723                 uint8_t interface, int8_t serialindex, char *serialstring,
724                 int8_t productindex, char *productstring)
725 {
726         usb_dev_handle *dev_handle = NULL;
727         struct usb_bus *busses;
728         struct usb_bus *bus;
729         struct usb_device *dev;
730
731         usb_init();
732         usb_find_busses();
733         usb_find_devices();
734         busses = usb_get_busses();
735
736         for (bus = busses; bus; bus = bus->next)
737         {
738                 for (dev = bus->devices; dev; dev = dev->next)
739                 {
740                         if ((dev->descriptor.idVendor == VID)
741                                 && (dev->descriptor.idProduct == PID))
742                         {
743                                 dev_handle = usb_open(dev);
744                                 if (NULL == dev_handle)
745                                 {
746                                         LOG_ERROR("failed to open %04X:%04X, %s", VID, PID,
747                                                                 usb_strerror());
748                                         continue;
749                                 }
750
751                                 // check description string
752                                 if (((productstring != NULL) && (productindex >= 0)
753                                                 && !usb_check_string(dev_handle, productindex,
754                                                                                                 productstring, NULL, 0))
755                                         || ((serialstring != NULL) && (serialindex >= 0)
756                                                 && !usb_check_string(dev_handle, serialindex,
757                                                                                                 serialstring, NULL, 0)))
758                                 {
759                                         usb_close(dev_handle);
760                                         dev_handle = NULL;
761                                         continue;
762                                 }
763
764                                 if (usb_claim_interface(dev_handle, interface) != 0)
765                                 {
766                                         LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE,
767                                                                 "claim interface", usb_strerror());
768                                         usb_close(dev_handle);
769                                         dev_handle = NULL;
770                                         continue;
771                                 }
772
773                                 if (dev_handle != NULL)
774                                 {
775                                         return dev_handle;
776                                 }
777                         }
778                 }
779         }
780
781         return dev_handle;
782 }
783
784 static struct vsllink *vsllink_usb_open(void)
785 {
786         usb_init();
787
788         struct usb_dev_handle *dev;
789
790         dev = find_usb_device(versaloon_interface.usb_setting.vid,
791                                                         versaloon_interface.usb_setting.pid,
792                                                         versaloon_interface.usb_setting.interface,
793                                                         0, NULL, 2, "Versaloon");
794         if (NULL == dev)
795                 return NULL;
796
797         struct vsllink *result = malloc(sizeof(struct vsllink));
798         result->usb_handle = dev;
799         return result;
800 }
801
802 static void vsllink_usb_close(struct vsllink *vsllink)
803 {
804         int ret;
805
806         ret = usb_release_interface(vsllink->usb_handle,
807                         versaloon_interface.usb_setting.interface);
808         if (ret != 0) {
809                 LOG_ERROR("fail to release interface %d, %d returned",
810                                         versaloon_interface.usb_setting.interface, ret);
811                 exit(-1);
812         }
813
814         ret = usb_close(vsllink->usb_handle);
815         if (ret != 0) {
816                 LOG_ERROR("fail to close usb, %d returned", ret);
817                 exit(-1);
818         }
819
820         free(vsllink);
821 }
822
823 #define BYTES_PER_LINE  16
824
825 #if defined _DEBUG_JTAG_IO_
826 static void vsllink_debug_buffer(uint8_t *buffer, int length)
827 {
828         char line[81];
829         char s[4];
830         int i;
831         int j;
832
833         for (i = 0; i < length; i += BYTES_PER_LINE) {
834                 snprintf(line, 5, "%04x", i);
835                 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
836                         snprintf(s, 4, " %02x", buffer[j]);
837                         strcat(line, s);
838                 }
839                 LOG_DEBUG("%s", line);
840         }
841 }
842 #endif /* _DEBUG_JTAG_IO_ */
843
844 static const struct command_registration vsllink_command_handlers[] = {
845         {
846                 .name = "vsllink_usb_vid",
847                 .handler = &vsllink_handle_usb_vid_command,
848                 .mode = COMMAND_CONFIG,
849         },
850         {
851                 .name = "vsllink_usb_pid",
852                 .handler = &vsllink_handle_usb_pid_command,
853                 .mode = COMMAND_CONFIG,
854         },
855         {
856                 .name = "vsllink_usb_bulkin",
857                 .handler = &vsllink_handle_usb_bulkin_command,
858                 .mode = COMMAND_CONFIG,
859         },
860         {
861                 .name = "vsllink_usb_bulkout",
862                 .handler = &vsllink_handle_usb_bulkout_command,
863                 .mode = COMMAND_CONFIG,
864         },
865         {
866                 .name = "vsllink_usb_interface",
867                 .handler = &vsllink_handle_usb_interface_command,
868                 .mode = COMMAND_CONFIG,
869         },
870         COMMAND_REGISTRATION_DONE
871 };
872
873 static const char *vsllink_transports[] = {"jtag", "swd", NULL};
874
875 struct jtag_interface vsllink_interface = {
876         .name = "vsllink",
877         .supported = DEBUG_CAP_TMS_SEQ,
878         .commands = vsllink_command_handlers,
879         .transports = vsllink_transports,
880
881         .init = vsllink_init,
882         .quit = vsllink_quit,
883         .khz = vsllink_khz,
884         .speed = vsllink_speed,
885         .speed_div = vsllink_speed_div,
886         .execute_queue = vsllink_execute_queue,
887 };