- jlink_queue_data_out(NULL, dap->memaccess_tck);
-}
-
-/*****************************************************************************/
-/* JLink USB low-level functions */
-
-static struct jlink *jlink_usb_open()
-{
- struct jtag_libusb_device_handle *devh;
- if (jtag_libusb_open(vids, pids, jlink_serial, &devh) != ERROR_OK)
- return NULL;
-
- /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
- * AREA!!!!!!!!!!! The behavior of libusb is not completely
- * consistent across Windows, Linux, and Mac OS X platforms.
- * The actions taken in the following compiler conditionals may
- * not agree with published documentation for libusb, but were
- * found to be necessary through trials and tribulations. Even
- * little tweaks can break one or more platforms, so if you do
- * make changes test them carefully on all platforms before
- * committing them!
- */
-
-/* This entire block can probably be removed. It was a workaround for
- * libusb0.1 and old JLink firmware. It has already be removed for
- * windows and causing problems (LPC Link-2 with JLink firmware) on
- * Linux with libusb1.0.
- *
- * However, for now the behavior will be left unchanged for non-windows
- * platforms using libusb0.1 due to lack of testing.
- */
-#if IS_WIN32 == 0 && HAVE_LIBUSB1 == 0
-
- jtag_libusb_reset_device(devh);
-
-#if IS_DARWIN == 0
-
- int timeout = 5;
- /* reopen jlink after usb_reset
- * on win32 this may take a second or two to re-enumerate */
- int retval;
- while ((retval = jtag_libusb_open(vids, pids, jlink_serial, &devh)) != ERROR_OK) {
- usleep(1000);
- timeout--;
- if (!timeout)
- break;
- }
- if (ERROR_OK != retval)
- return NULL;
-#endif
-
-#endif
-
- /* usb_set_configuration is only required under win32
- * with libusb 0.1 and libusb0.sys. For libusb 1.0 it is a no-op
- * since the configuration is already set. */
- jtag_libusb_set_configuration(devh, 0);
-
- jtag_libusb_choose_interface(devh, &jlink_read_ep, &jlink_write_ep,
- JLINK_USB_INTERFACE_CLASS,
- JLINK_USB_INTERFACE_SUBCLASS,
- JLINK_USB_INTERFACE_PROTOCOL);
-
- struct jlink *result = malloc(sizeof(struct jlink));
- result->usb_handle = devh;
- return result;
-}
-
-static void jlink_usb_close(struct jlink *jlink)
-{
- jtag_libusb_close(jlink->usb_handle);
- free(jlink);
-}
-
-/* Send a message and receive the reply. */
-static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
-{
- int result;
-
- result = jlink_usb_write(jlink, out_length);
- if (result != out_length) {
- LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
- out_length, result);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- result = jlink_usb_read(jlink, in_length);
- if (result != in_length) {
- LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
- in_length, result);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- return ERROR_OK;
-}
-
-/* calls the given usb_bulk_* function, allowing for the data to
- * trickle in with some timeouts */
-static int usb_bulk_with_retries(
- int (*f)(jtag_libusb_device_handle *, int, char *, int, int),
- jtag_libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
-{
- int tries = 3, count = 0;
-
- while (tries && (count < size)) {
- int result = f(dev, ep, bytes + count, size - count, timeout);
- if (result > 0)
- count += result;
- else if ((-ETIMEDOUT != result) || !--tries)
- return result;
- }
- return count;
-}
-
-static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep,
- char *buff, int size, int timeout)
-{
- /* usb_bulk_write() takes const char *buff */
- return jtag_libusb_bulk_write(dev, ep, buff, size, timeout);
-}
-
-static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
-{
- return usb_bulk_with_retries(&wrap_usb_bulk_write,
- dev, ep, bytes, size, timeout);
-}
-
-static inline int usb_bulk_read_ex(jtag_libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
-{
- return usb_bulk_with_retries(&jtag_libusb_bulk_read,
- dev, ep, bytes, size, timeout);
-}
-
-/* Write data from out_buffer to USB. */
-static int jlink_usb_write(struct jlink *jlink, int out_length)
-{
- int result;
-
- if (out_length > JLINK_OUT_BUFFER_SIZE) {
- LOG_ERROR("jlink_write illegal out_length=%d (max=%d)",
- out_length, JLINK_OUT_BUFFER_SIZE);
- return -1;
- }
-
- result = usb_bulk_write_ex(jlink->usb_handle, jlink_write_ep,
- (char *)usb_out_buffer, out_length, JLINK_USB_TIMEOUT);
-
- DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d",
- out_length, result);
-
- jlink_debug_buffer(usb_out_buffer, out_length);
- return result;
-}
-
-/* Read data from USB into in_buffer. */
-static int jlink_usb_read(struct jlink *jlink, int expected_size)
-{
- int result = usb_bulk_read_ex(jlink->usb_handle, jlink_read_ep,
- (char *)usb_in_buffer, expected_size, JLINK_USB_TIMEOUT);
-
- DEBUG_JTAG_IO("jlink_usb_read, result = %d", result);
-
- jlink_debug_buffer(usb_in_buffer, result);
- return result;
-}
-
-/*
- * Send a message and receive the reply - simple messages.
- *
- * @param jlink pointer to driver data
- * @param out_length data length in @c usb_out_buffer
- * @param in_length data length to be read to @c usb_in_buffer
- */
-static int jlink_usb_io(struct jlink *jlink, int out_length, int in_length)
-{
- int result;
-
- result = jlink_usb_write(jlink, out_length);
- if (result != out_length) {
- LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
- out_length, result);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- result = jlink_usb_read(jlink, in_length);
- if (result != in_length) {
- LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
- in_length, result);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- /*
- * Section 4.2.4 IN-transaction:
- * read dummy 0-byte packet if transaction size is
- * multiple of 64 bytes but not max. size of 0x8000
- */
- if ((in_length % 64) == 0 && in_length != 0x8000) {
- char dummy_buffer;
- result = usb_bulk_read_ex(jlink->usb_handle, jlink_read_ep,
- &dummy_buffer, 1, JLINK_USB_TIMEOUT);
- if (result != 0) {
- LOG_ERROR("dummy byte read failed");
- return ERROR_JTAG_DEVICE_ERROR;
- }
- }
- return ERROR_OK;