1 /***************************************************************************
2  *                                                                         *
3  *   Copyright (C) 2012 by Spencer Oliver                                  *
4  *   spen@spen-soft.co.uk                                                  *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
18  ***************************************************************************/
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 /* project specific includes */
25 #include <helper/binarybuffer.h>
26 #include <jtag/interface.h>
27 #include <jtag/hla/hla_layout.h>
28 #include <jtag/hla/hla_transport.h>
29 #include <jtag/hla/hla_interface.h>
30 #include <target/target.h>
31 
32 #include <target/cortex_m.h>
33 
34 #include "libusb_helper.h"
35 
36 #define ICDI_WRITE_ENDPOINT 0x02
37 #define ICDI_READ_ENDPOINT 0x83
38 
39 #define ICDI_WRITE_TIMEOUT 1000
40 #define ICDI_READ_TIMEOUT 1000
41 #define ICDI_PACKET_SIZE 2048
42 
43 #define PACKET_START "$"
44 #define PACKET_END "#"
45 
46 struct icdi_usb_handle_s {
47 	struct libusb_device_handle *usb_dev;
48 
49 	char *read_buffer;
50 	char *write_buffer;
51 	int max_packet;
52 	int read_count;
53 	uint32_t max_rw_packet; /* max X packet (read/write memory) transfers */
54 };
55 
56 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
57 		uint32_t count, uint8_t *buffer);
58 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
59 		uint32_t count, const uint8_t *buffer);
60 
remote_escape_output(const char * buffer,int len,char * out_buf,int * out_len,int out_maxlen)61 static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)
62 {
63 	int input_index, output_index;
64 
65 	output_index = 0;
66 
67 	for (input_index = 0; input_index < len; input_index++) {
68 
69 		char b = buffer[input_index];
70 
71 		if (b == '$' || b == '#' || b == '}' || b == '*') {
72 			/* These must be escaped.  */
73 			if (output_index + 2 > out_maxlen)
74 				break;
75 			out_buf[output_index++] = '}';
76 			out_buf[output_index++] = b ^ 0x20;
77 		} else {
78 			if (output_index + 1 > out_maxlen)
79 				break;
80 			out_buf[output_index++] = b;
81 		}
82 	}
83 
84 	*out_len = input_index;
85 	return output_index;
86 }
87 
remote_unescape_input(const char * buffer,int len,char * out_buf,int out_maxlen)88 static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)
89 {
90 	int input_index, output_index;
91 	int escaped;
92 
93 	output_index = 0;
94 	escaped = 0;
95 
96 	for (input_index = 0; input_index < len; input_index++) {
97 
98 		char b = buffer[input_index];
99 
100 		if (output_index + 1 > out_maxlen)
101 			LOG_ERROR("Received too much data from the target.");
102 
103 		if (escaped) {
104 			out_buf[output_index++] = b ^ 0x20;
105 			escaped = 0;
106 		} else if (b == '}')
107 			escaped = 1;
108 		else
109 			out_buf[output_index++] = b;
110 	}
111 
112 	if (escaped)
113 		LOG_ERROR("Unmatched escape character in target response.");
114 
115 	return output_index;
116 }
117 
icdi_send_packet(void * handle,int len)118 static int icdi_send_packet(void *handle, int len)
119 {
120 	unsigned char cksum = 0;
121 	struct icdi_usb_handle_s *h = handle;
122 	int result, retry = 0;
123 	int transferred = 0;
124 
125 	assert(handle != NULL);
126 
127 	/* check we have a large enough buffer for checksum "#00" */
128 	if (len + 3 > h->max_packet) {
129 		LOG_ERROR("packet buffer too small");
130 		return ERROR_FAIL;
131 	}
132 
133 	/* calculate checksum - offset start of packet */
134 	for (int i = 1; i < len; i++)
135 		cksum += h->write_buffer[i];
136 
137 	len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
138 
139 #ifdef _DEBUG_USB_COMMS_
140 	char buffer[50];
141 	char ch = h->write_buffer[1];
142 	if (ch == 'x' || ch == 'X')
143 		LOG_DEBUG("writing packet: <binary>");
144 	else {
145 		memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
146 		buffer[len] = 0;
147 		LOG_DEBUG("writing packet: %s", buffer);
148 	}
149 #endif
150 
151 	while (1) {
152 
153 		result = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len,
154 				&transferred, ICDI_WRITE_TIMEOUT);
155 		if (result != 0 || transferred != len) {
156 			LOG_DEBUG("Error TX Data %d", result);
157 			return ERROR_FAIL;
158 		}
159 
160 		/* check that the client got the message ok, or shall we resend */
161 		result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet,
162 					&transferred, ICDI_READ_TIMEOUT);
163 		if (result != 0 || transferred < 1) {
164 			LOG_DEBUG("Error RX Data %d", result);
165 			return ERROR_FAIL;
166 		}
167 
168 #ifdef _DEBUG_USB_COMMS_
169 		LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
170 #endif
171 
172 		if (h->read_buffer[0] == '-') {
173 			LOG_DEBUG("Resending packet %d", ++retry);
174 		} else {
175 			if (h->read_buffer[0] != '+')
176 				LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]);
177 			break;
178 		}
179 
180 		if (retry == 3) {
181 			LOG_DEBUG("maximum nack retries attempted");
182 			return ERROR_FAIL;
183 		}
184 	}
185 
186 	retry = 0;
187 	h->read_count = transferred;
188 
189 	while (1) {
190 
191 		/* read reply from icdi */
192 		result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,
193 				h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);
194 
195 #ifdef _DEBUG_USB_COMMS_
196 		LOG_DEBUG("received data: count %d", transferred);
197 #endif
198 
199 		/* check for errors but retry for timeout */
200 		if (result != 0) {
201 
202 			if (result == LIBUSB_ERROR_TIMEOUT) {
203 				LOG_DEBUG("Error RX timeout %d", result);
204 			} else {
205 				LOG_DEBUG("Error RX Data %d", result);
206 				return ERROR_FAIL;
207 			}
208 		}
209 
210 		h->read_count += transferred;
211 
212 		/* we need to make sure we have a full packet, including checksum */
213 		if (h->read_count > 5) {
214 
215 			/* check that we have received an packet delimiter
216 			 * we do not validate the checksum
217 			 * reply should contain $...#AA - so we check for # */
218 			if (h->read_buffer[h->read_count - 3] == '#')
219 				return ERROR_OK;
220 		}
221 
222 		if (retry++ == 3) {
223 			LOG_DEBUG("maximum data retries attempted");
224 			break;
225 		}
226 	}
227 
228 	return ERROR_FAIL;
229 }
230 
icdi_send_cmd(void * handle,const char * cmd)231 static int icdi_send_cmd(void *handle, const char *cmd)
232 {
233 	struct icdi_usb_handle_s *h = handle;
234 
235 	int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd);
236 	return icdi_send_packet(handle, cmd_len);
237 }
238 
icdi_send_remote_cmd(void * handle,const char * data)239 static int icdi_send_remote_cmd(void *handle, const char *data)
240 {
241 	struct icdi_usb_handle_s *h = handle;
242 
243 	size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
244 	cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data,
245 		strlen(data), h->max_packet - cmd_len);
246 
247 	return icdi_send_packet(handle, cmd_len);
248 }
249 
icdi_get_cmd_result(void * handle)250 static int icdi_get_cmd_result(void *handle)
251 {
252 	struct icdi_usb_handle_s *h = handle;
253 	int offset = 0;
254 	char ch;
255 
256 	assert(handle != NULL);
257 
258 	do {
259 		ch = h->read_buffer[offset++];
260 		if (offset > h->read_count)
261 			return ERROR_FAIL;
262 	} while (ch != '$');
263 
264 	if (memcmp("OK", h->read_buffer + offset, 2) == 0)
265 		return ERROR_OK;
266 
267 	if (h->read_buffer[offset] == 'E') {
268 		/* get error code */
269 		uint8_t result;
270 		if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
271 			return ERROR_FAIL;
272 		return result;
273 	}
274 
275 	/* for now we assume everything else is ok */
276 	return ERROR_OK;
277 }
278 
icdi_usb_idcode(void * handle,uint32_t * idcode)279 static int icdi_usb_idcode(void *handle, uint32_t *idcode)
280 {
281 	*idcode = 0;
282 	return ERROR_OK;
283 }
284 
icdi_usb_write_debug_reg(void * handle,uint32_t addr,uint32_t val)285 static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
286 {
287 	uint8_t buf[4];
288 	/* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32().
289 	 * I guess all supported chips are little-endian anyway. */
290 	h_u32_to_le(buf, val);
291 	return icdi_usb_write_mem(handle, addr, 4, 1, buf);
292 }
293 
icdi_usb_state(void * handle)294 static enum target_state icdi_usb_state(void *handle)
295 {
296 	int result;
297 	struct icdi_usb_handle_s *h = handle;
298 	uint32_t dhcsr;
299 	uint8_t buf[4];
300 
301 	result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf);
302 	if (result != ERROR_OK)
303 		return TARGET_UNKNOWN;
304 
305 	/* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().
306 	 * I guess all supported chips are little-endian anyway. */
307 	dhcsr = le_to_h_u32(buf);
308 	if (dhcsr & S_HALT)
309 		return TARGET_HALTED;
310 
311 	return TARGET_RUNNING;
312 }
313 
icdi_usb_version(void * handle)314 static int icdi_usb_version(void *handle)
315 {
316 	struct icdi_usb_handle_s *h = handle;
317 
318 	char version[20];
319 
320 	/* get info about icdi */
321 	int result = icdi_send_remote_cmd(handle, "version");
322 	if (result != ERROR_OK)
323 		return result;
324 
325 	if (h->read_count < 8) {
326 		LOG_ERROR("Invalid Reply Received");
327 		return ERROR_FAIL;
328 	}
329 
330 	/* convert reply */
331 	if (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) {
332 		LOG_WARNING("unable to get ICDI version");
333 		return ERROR_OK;
334 	}
335 
336 	/* null terminate and print info */
337 	version[4] = 0;
338 
339 	LOG_INFO("ICDI Firmware version: %s", version);
340 
341 	return ERROR_OK;
342 }
343 
icdi_usb_query(void * handle)344 static int icdi_usb_query(void *handle)
345 {
346 	int result;
347 
348 	struct icdi_usb_handle_s *h = handle;
349 
350 	result = icdi_send_cmd(handle, "qSupported");
351 	if (result != ERROR_OK)
352 		return result;
353 
354 	/* check result */
355 	result = icdi_get_cmd_result(handle);
356 	if (result != ERROR_OK) {
357 		LOG_ERROR("query supported failed: 0x%x", result);
358 		return ERROR_FAIL;
359 	}
360 
361 	/* from this we can get the max packet supported */
362 
363 	/* query packet buffer size */
364 	char *offset = strstr(h->read_buffer, "PacketSize");
365 	if (offset) {
366 		char *separator;
367 		int max_packet;
368 
369 		max_packet = strtol(offset + 11, &separator, 16);
370 		if (!max_packet)
371 			LOG_ERROR("invalid max packet, using defaults");
372 		else
373 			h->max_packet = max_packet;
374 		LOG_DEBUG("max packet supported : %i bytes", h->max_packet);
375 	}
376 
377 
378 	/* if required re allocate packet buffer */
379 	if (h->max_packet != ICDI_PACKET_SIZE) {
380 		h->read_buffer = realloc(h->read_buffer, h->max_packet);
381 		h->write_buffer = realloc(h->write_buffer, h->max_packet);
382 		if (h->read_buffer == 0 || h->write_buffer == 0) {
383 			LOG_ERROR("unable to reallocate memory");
384 			return ERROR_FAIL;
385 		}
386 	}
387 
388 	/* set extended mode */
389 	result = icdi_send_cmd(handle, "!");
390 	if (result != ERROR_OK)
391 		return result;
392 
393 	/* check result */
394 	result = icdi_get_cmd_result(handle);
395 	if (result != ERROR_OK) {
396 		LOG_ERROR("unable to enable extended mode: 0x%x", result);
397 		return ERROR_FAIL;
398 	}
399 
400 	return ERROR_OK;
401 }
402 
icdi_usb_reset(void * handle)403 static int icdi_usb_reset(void *handle)
404 {
405 	/* we do this in hla_target.c */
406 	return ERROR_OK;
407 }
408 
icdi_usb_assert_srst(void * handle,int srst)409 static int icdi_usb_assert_srst(void *handle, int srst)
410 {
411 	/* TODO not supported yet */
412 	return ERROR_COMMAND_NOTFOUND;
413 }
414 
icdi_usb_run(void * handle)415 static int icdi_usb_run(void *handle)
416 {
417 	int result;
418 
419 	/* resume target at current address */
420 	result = icdi_send_cmd(handle, "c");
421 	if (result != ERROR_OK)
422 		return result;
423 
424 	/* check result */
425 	result = icdi_get_cmd_result(handle);
426 	if (result != ERROR_OK) {
427 		LOG_ERROR("continue failed: 0x%x", result);
428 		return ERROR_FAIL;
429 	}
430 
431 	return result;
432 }
433 
icdi_usb_halt(void * handle)434 static int icdi_usb_halt(void *handle)
435 {
436 	int result;
437 
438 	/* this query halts the target ?? */
439 	result = icdi_send_cmd(handle, "?");
440 	if (result != ERROR_OK)
441 		return result;
442 
443 	/* check result */
444 	result = icdi_get_cmd_result(handle);
445 	if (result != ERROR_OK) {
446 		LOG_ERROR("halt failed: 0x%x", result);
447 		return ERROR_FAIL;
448 	}
449 
450 	return result;
451 }
452 
icdi_usb_step(void * handle)453 static int icdi_usb_step(void *handle)
454 {
455 	int result;
456 
457 	/* step target at current address */
458 	result = icdi_send_cmd(handle, "s");
459 	if (result != ERROR_OK)
460 		return result;
461 
462 	/* check result */
463 	result = icdi_get_cmd_result(handle);
464 	if (result != ERROR_OK) {
465 		LOG_ERROR("step failed: 0x%x", result);
466 		return ERROR_FAIL;
467 	}
468 
469 	return result;
470 }
471 
icdi_usb_read_regs(void * handle)472 static int icdi_usb_read_regs(void *handle)
473 {
474 	/* currently unsupported */
475 	return ERROR_OK;
476 }
477 
icdi_usb_read_reg(void * handle,unsigned int regsel,uint32_t * val)478 static int icdi_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)
479 {
480 	int result;
481 	struct icdi_usb_handle_s *h = handle;
482 	char cmd[10];
483 
484 	snprintf(cmd, sizeof(cmd), "p%x", regsel);
485 	result = icdi_send_cmd(handle, cmd);
486 	if (result != ERROR_OK)
487 		return result;
488 
489 	/* check result */
490 	result = icdi_get_cmd_result(handle);
491 	if (result != ERROR_OK) {
492 		LOG_ERROR("register read failed: 0x%x", result);
493 		return ERROR_FAIL;
494 	}
495 
496 	/* convert result */
497 	uint8_t buf[4];
498 	if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
499 		LOG_ERROR("failed to convert result");
500 		return ERROR_FAIL;
501 	}
502 	*val = le_to_h_u32(buf);
503 
504 	return result;
505 }
506 
icdi_usb_write_reg(void * handle,unsigned int regsel,uint32_t val)507 static int icdi_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)
508 {
509 	int result;
510 	char cmd[20];
511 	uint8_t buf[4];
512 	h_u32_to_le(buf, val);
513 
514 	int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", regsel);
515 	hexify(cmd + cmd_len, buf, 4, sizeof(cmd));
516 
517 	result = icdi_send_cmd(handle, cmd);
518 	if (result != ERROR_OK)
519 		return result;
520 
521 	/* check result */
522 	result = icdi_get_cmd_result(handle);
523 	if (result != ERROR_OK) {
524 		LOG_ERROR("register write failed: 0x%x", result);
525 		return ERROR_FAIL;
526 	}
527 
528 	return result;
529 }
530 
icdi_usb_read_mem_int(void * handle,uint32_t addr,uint32_t len,uint8_t * buffer)531 static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)
532 {
533 	int result;
534 	struct icdi_usb_handle_s *h = handle;
535 	char cmd[20];
536 
537 	snprintf(cmd, sizeof(cmd), "x%" PRIx32 ",%" PRIx32, addr, len);
538 	result = icdi_send_cmd(handle, cmd);
539 	if (result != ERROR_OK)
540 		return result;
541 
542 	/* check result */
543 	result = icdi_get_cmd_result(handle);
544 	if (result != ERROR_OK) {
545 		LOG_ERROR("memory read failed: 0x%x", result);
546 		return ERROR_FAIL;
547 	}
548 
549 	/* unescape input */
550 	int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);
551 	if (read_len != (int)len) {
552 		LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32, read_len, len);
553 		return ERROR_FAIL;
554 	}
555 
556 	return ERROR_OK;
557 }
558 
icdi_usb_write_mem_int(void * handle,uint32_t addr,uint32_t len,const uint8_t * buffer)559 static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)
560 {
561 	int result;
562 	struct icdi_usb_handle_s *h = handle;
563 
564 	size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%" PRIx32 ",%" PRIx32 ":", addr, len);
565 
566 	int out_len;
567 	cmd_len += remote_escape_output((const char *)buffer, len, h->write_buffer + cmd_len,
568 			&out_len, h->max_packet - cmd_len);
569 
570 	if (out_len < (int)len) {
571 		/* for now issue a error as we have no way of allocating a larger buffer */
572 		LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32, out_len, len);
573 		return ERROR_FAIL;
574 	}
575 
576 	result = icdi_send_packet(handle, cmd_len);
577 	if (result != ERROR_OK)
578 		return result;
579 
580 	/* check result */
581 	result = icdi_get_cmd_result(handle);
582 	if (result != ERROR_OK) {
583 		LOG_ERROR("memory write failed: 0x%x", result);
584 		return ERROR_FAIL;
585 	}
586 
587 	return ERROR_OK;
588 }
589 
icdi_usb_read_mem(void * handle,uint32_t addr,uint32_t size,uint32_t count,uint8_t * buffer)590 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
591 		uint32_t count, uint8_t *buffer)
592 {
593 	int retval = ERROR_OK;
594 	struct icdi_usb_handle_s *h = handle;
595 	uint32_t bytes_remaining;
596 
597 	/* calculate byte count */
598 	count *= size;
599 
600 	while (count) {
601 
602 		bytes_remaining = h->max_rw_packet;
603 		if (count < bytes_remaining)
604 			bytes_remaining = count;
605 
606 		retval = icdi_usb_read_mem_int(handle, addr, bytes_remaining, buffer);
607 		if (retval != ERROR_OK)
608 			return retval;
609 
610 		buffer += bytes_remaining;
611 		addr += bytes_remaining;
612 		count -= bytes_remaining;
613 	}
614 
615 	return retval;
616 }
617 
icdi_usb_write_mem(void * handle,uint32_t addr,uint32_t size,uint32_t count,const uint8_t * buffer)618 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
619 		uint32_t count, const uint8_t *buffer)
620 {
621 	int retval = ERROR_OK;
622 	struct icdi_usb_handle_s *h = handle;
623 	uint32_t bytes_remaining;
624 
625 	/* calculate byte count */
626 	count *= size;
627 
628 	while (count) {
629 
630 		bytes_remaining = h->max_rw_packet;
631 		if (count < bytes_remaining)
632 			bytes_remaining = count;
633 
634 		retval = icdi_usb_write_mem_int(handle, addr, bytes_remaining, buffer);
635 		if (retval != ERROR_OK)
636 			return retval;
637 
638 		buffer += bytes_remaining;
639 		addr += bytes_remaining;
640 		count -= bytes_remaining;
641 	}
642 
643 	return retval;
644 }
645 
icdi_usb_override_target(const char * targetname)646 static int icdi_usb_override_target(const char *targetname)
647 {
648 	return !strcmp(targetname, "cortex_m");
649 }
650 
icdi_usb_close(void * handle)651 static int icdi_usb_close(void *handle)
652 {
653 	struct icdi_usb_handle_s *h = handle;
654 
655 	if (!h)
656 		return ERROR_OK;
657 
658 	if (h->usb_dev)
659 		jtag_libusb_close(h->usb_dev);
660 
661 	free(h->read_buffer);
662 	free(h->write_buffer);
663 	free(handle);
664 	return ERROR_OK;
665 }
666 
icdi_usb_open(struct hl_interface_param_s * param,void ** fd)667 static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
668 {
669 	/* TODO: Convert remaining libusb_ calls to jtag_libusb_ */
670 	int retval;
671 	struct icdi_usb_handle_s *h;
672 
673 	LOG_DEBUG("icdi_usb_open");
674 
675 	h = calloc(1, sizeof(struct icdi_usb_handle_s));
676 
677 	if (h == 0) {
678 		LOG_ERROR("unable to allocate memory");
679 		return ERROR_FAIL;
680 	}
681 
682 	for (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i)
683 		LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport,
684 			param->vid[i], param->pid[i], param->serial ? param->serial : "");
685 
686 	/* TI (Stellaris) ICDI provides its serial number in the USB descriptor;
687 	   no need to provide a callback here. */
688 	jtag_libusb_open(param->vid, param->pid, param->serial, &h->usb_dev, NULL);
689 
690 	if (!h->usb_dev) {
691 		LOG_ERROR("open failed");
692 		goto error_open;
693 	}
694 
695 	if (libusb_claim_interface(h->usb_dev, 2)) {
696 		LOG_DEBUG("claim interface failed");
697 		goto error_open;
698 	}
699 
700 	/* check if mode is supported */
701 	retval = ERROR_OK;
702 
703 	switch (param->transport) {
704 #if 0
705 		/* TODO place holder as swd is not currently supported */
706 		case HL_TRANSPORT_SWD:
707 #endif
708 		case HL_TRANSPORT_JTAG:
709 			break;
710 		default:
711 			retval = ERROR_FAIL;
712 			break;
713 	}
714 
715 	if (retval != ERROR_OK) {
716 		LOG_ERROR("mode (transport) not supported by device");
717 		goto error_open;
718 	}
719 
720 	/* allocate buffer */
721 	h->read_buffer = malloc(ICDI_PACKET_SIZE);
722 	h->write_buffer = malloc(ICDI_PACKET_SIZE);
723 	h->max_packet = ICDI_PACKET_SIZE;
724 
725 	if (h->read_buffer == 0 || h->write_buffer == 0) {
726 		LOG_DEBUG("malloc failed");
727 		goto error_open;
728 	}
729 
730 	/* query icdi version etc */
731 	retval = icdi_usb_version(h);
732 	if (retval != ERROR_OK)
733 		goto error_open;
734 
735 	/* query icdi support */
736 	retval = icdi_usb_query(h);
737 	if (retval != ERROR_OK)
738 		goto error_open;
739 
740 	*fd = h;
741 
742 	/* set the max target read/write buffer in bytes
743 	 * as we are using gdb binary packets to transfer memory we have to
744 	 * reserve half the buffer for any possible escape chars plus
745 	 * at least 64 bytes for the gdb packet header */
746 	h->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2;
747 
748 	return ERROR_OK;
749 
750 error_open:
751 	icdi_usb_close(h);
752 
753 	return ERROR_FAIL;
754 }
755 
756 struct hl_layout_api_s icdi_usb_layout_api = {
757 	.open = icdi_usb_open,
758 	.close = icdi_usb_close,
759 	.idcode = icdi_usb_idcode,
760 	.state = icdi_usb_state,
761 	.reset = icdi_usb_reset,
762 	.assert_srst = icdi_usb_assert_srst,
763 	.run = icdi_usb_run,
764 	.halt = icdi_usb_halt,
765 	.step = icdi_usb_step,
766 	.read_regs = icdi_usb_read_regs,
767 	.read_reg = icdi_usb_read_reg,
768 	.write_reg = icdi_usb_write_reg,
769 	.read_mem = icdi_usb_read_mem,
770 	.write_mem = icdi_usb_write_mem,
771 	.write_debug_reg = icdi_usb_write_debug_reg,
772 	.override_target = icdi_usb_override_target,
773 	.custom_command = icdi_send_remote_cmd,
774 };
775