[prev in list] [next in list] [prev in thread] [next in thread]
List: openocd-development
Subject: [OpenOCD-devel] [PATCH]: b2e5f0c stlink: separate stlink core from USB functions [RFC]
From: gerrit () openocd ! org (gerrit)
Date: 2020-04-27 23:15:07
Message-ID: 20200427231507.5A46F4A2546 () mail ! openocd ! org
[Download RAW message or body]
This is an automated email from Gerrit.
Tarek BOCHKATI (tarek.bouchkati@gmail.com) just uploaded a new patch set to Gerrit, \
which you can find at http://openocd.zylin.com/5632
-- gerrit
commit b2e5f0cd11c216ab098f8c1bff5a32560f27d587
Author: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Date: Mon Apr 27 23:59:58 2020 +0100
stlink: separate stlink core from USB functions [RFC]
the introduced stlink_interface_s struct provides an API to separate USB
internals from stlink core.
this separation aims to ease:
- stlink-server integration [1]
- stlink driver split into modules:
- stlink_core
- stlink_usb
- stlink_server [1]
Change-Id: Iff6790942612ce1769ec4c75990914534e5e9e24
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index 062c87e..ec7be09 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -1,4 +1,7 @@
/***************************************************************************
+ * Copyright (C) 2020 by Tarek Bochkati *
+ * Tarek Bochkati <tarek.bouchkati@gmail.com> *
+ * *
* SWIM contributions by Ake Rehnman *
* Copyright (C) 2017 Ake Rehnman *
* ake.rehnman(at)gmail.com *
@@ -119,12 +122,30 @@ struct stlink_usb_version {
uint32_t flags;
};
-/** */
-struct stlink_usb_handle_s {
+struct stlink_usb_priv_s {
/** */
struct libusb_device_handle *fd;
/** */
struct libusb_transfer *trans;
+};
+
+struct stlink_interface_s {
+ /** */
+ void *priv;
+ /** */
+ int (*open)(void *handle, struct hl_interface_param_s *param);
+ /** */
+ int (*close)(void *handle);
+ /** */
+ int (*xfer)(void *handle, const uint8_t *buf, int size);
+ /** */
+ int (*read)(void *handle, const uint8_t *buf, int size);
+};
+
+/** */
+struct stlink_usb_handle_s {
+ /** */
+ struct stlink_interface_s *itf;
/** */
uint8_t rx_ep;
/** */
@@ -532,6 +553,7 @@ static int jtag_libusb_bulk_transfer_n(
static int stlink_usb_xfer_v1_get_status(void *handle)
{
struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
int tr, ret;
assert(handle != NULL);
@@ -539,7 +561,7 @@ static int stlink_usb_xfer_v1_get_status(void *handle)
/* read status */
memset(h->cmdbuf, 0, STLINK_SG_SIZE);
- ret = jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)h->cmdbuf, 13,
+ ret = jtag_libusb_bulk_read(itf_priv->fd, h->rx_ep, (char *)h->cmdbuf, 13,
STLINK_READ_TIMEOUT, &tr);
if (ret || tr != 13)
return ERROR_FAIL;
@@ -567,6 +589,7 @@ static int stlink_usb_xfer_v1_get_status(void *handle)
static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int \
size) {
struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
assert(handle != NULL);
@@ -596,7 +619,7 @@ static int stlink_usb_xfer_rw(void *handle, int cmdsize, const \
uint8_t *buf, int }
return jtag_libusb_bulk_transfer_n(
- h->fd,
+ itf_priv->fd,
transfers,
n_transfers,
STLINK_WRITE_TIMEOUT);
@@ -605,24 +628,25 @@ static int stlink_usb_xfer_rw(void *handle, int cmdsize, const \
uint8_t *buf, int static int stlink_usb_xfer_rw(void *handle, int cmdsize, const \
uint8_t *buf, int size) {
struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
int tr, ret;
assert(handle != NULL);
- ret = jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)h->cmdbuf,
+ ret = jtag_libusb_bulk_write(itf_priv->fd, h->tx_ep, (char *)h->cmdbuf,
cmdsize, STLINK_WRITE_TIMEOUT, &tr);
if (ret || tr != cmdsize)
return ERROR_FAIL;
if (h->direction == h->tx_ep && size) {
- ret = jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)buf,
+ ret = jtag_libusb_bulk_write(itf_priv->fd, h->tx_ep, (char *)buf,
size, STLINK_WRITE_TIMEOUT, &tr);
if (ret || tr != size) {
LOG_DEBUG("bulk write failed");
return ERROR_FAIL;
}
} else if (h->direction == h->rx_ep && size) {
- ret = jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)buf,
+ ret = jtag_libusb_bulk_read(itf_priv->fd, h->rx_ep, (char *)buf,
size, STLINK_READ_TIMEOUT, &tr);
if (ret || tr != size) {
LOG_DEBUG("bulk read failed");
@@ -661,6 +685,23 @@ static int stlink_usb_xfer_v1_get_sense(void *handle)
return ERROR_OK;
}
+/** */
+static int stlink_usb_bulk_read(void *handle, const uint8_t *buf, int size)
+{
+ struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
+ int tr, ret;
+
+ ret = jtag_libusb_bulk_read(itf_priv->fd, h->direction, (char *)buf, size,
+ STLINK_READ_TIMEOUT, &tr);
+ if (ret || tr != size) {
+ LOG_ERROR("bulk trace read failed");
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
/*
transfers block in cmdbuf
<size> indicates number of bytes in the following
@@ -795,10 +836,11 @@ static int stlink_usb_error_check(void *handle)
static int stlink_usb_xfer_errcheck(void *handle, const uint8_t *buf, int size)
{
int retval;
+ struct stlink_usb_handle_s *h = handle;
assert(size > 0);
- retval = stlink_usb_xfer_noerrcheck(handle, buf, size);
+ retval = h->itf->xfer(handle, buf, size);
if (retval != ERROR_OK)
return retval;
@@ -820,7 +862,7 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t \
*buf, int size)
while (1) {
if ((h->st_mode != STLINK_MODE_DEBUG_SWIM) || !retries) {
- res = stlink_usb_xfer_noerrcheck(handle, buf, size);
+ res = h->itf->xfer(handle, buf, size);
if (res != ERROR_OK)
return res;
}
@@ -846,20 +888,14 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t \
*buf, int size) static int stlink_usb_read_trace(void *handle, const uint8_t *buf, \
int size) {
struct stlink_usb_handle_s *h = handle;
- int tr, ret;
assert(handle != NULL);
assert(h->version.flags & STLINK_F_HAS_TRACE);
- ret = jtag_libusb_bulk_read(h->fd, h->trace_ep, (char *)buf, size,
- STLINK_READ_TIMEOUT, &tr);
- if (ret || tr != size) {
- LOG_ERROR("bulk trace read failed");
- return ERROR_FAIL;
- }
+ stlink_usb_init_buffer(h, h->trace_ep, 0);
- return ERROR_OK;
+ return h->itf->read(handle, buf, size);
}
/*
@@ -926,7 +962,7 @@ static int stlink_usb_version(void *handle)
h->cmdbuf[h->cmdidx++] = STLINK_GET_VERSION;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 6);
+ res = h->itf->xfer(handle, h->databuf, 6);
if (res != ERROR_OK)
return res;
@@ -967,7 +1003,7 @@ static int stlink_usb_version(void *handle)
h->cmdbuf[h->cmdidx++] = STLINK_APIV3_GET_VERSION_EX;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 12);
+ res = h->itf->xfer(handle, h->databuf, 12);
if (res != ERROR_OK)
return res;
@@ -1104,7 +1140,7 @@ static int stlink_usb_check_voltage(void *handle, float \
*target_voltage)
h->cmdbuf[h->cmdidx++] = STLINK_GET_TARGET_VOLTAGE;
- int result = stlink_usb_xfer_noerrcheck(handle, h->databuf, 8);
+ int result = h->itf->xfer(handle, h->databuf, 8);
if (result != ERROR_OK)
return result;
@@ -1183,7 +1219,7 @@ static int stlink_usb_current_mode(void *handle, uint8_t *mode)
h->cmdbuf[h->cmdidx++] = STLINK_GET_CURRENT_MODE;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);
+ res = h->itf->xfer(handle, h->databuf, 2);
if (res != ERROR_OK)
return res;
@@ -1231,7 +1267,7 @@ static int stlink_usb_mode_enter(void *handle, enum stlink_mode \
type) h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_ENTER;
/* swim enter does not return any response or status */
- return stlink_usb_xfer_noerrcheck(handle, h->databuf, 0);
+ return h->itf->xfer(handle, h->databuf, 0);
case STLINK_MODE_DFU:
case STLINK_MODE_MASS:
default:
@@ -1271,7 +1307,7 @@ static int stlink_usb_mode_leave(void *handle, enum stlink_mode \
type) return ERROR_FAIL;
}
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 0);
+ res = h->itf->xfer(handle, h->databuf, 0);
if (res != ERROR_OK)
return res;
@@ -1449,7 +1485,7 @@ static int stlink_swim_status(void *handle)
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_READSTATUS;
/* error is checked by the caller */
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);
+ res = h->itf->xfer(handle, h->databuf, 4);
if (res != ERROR_OK)
return res;
return ERROR_OK;
@@ -1469,7 +1505,7 @@ static int stlink_swim_cap(void *handle, uint8_t *cap)
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_READ_CAP;
h->cmdbuf[h->cmdidx++] = 0x01;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 8);
+ res = h->itf->xfer(handle, h->databuf, 8);
if (res != ERROR_OK)
return res;
memcpy(cap, h->databuf, 8);
@@ -1626,7 +1662,7 @@ static int stlink_swim_readbytes(void *handle, uint32_t addr, \
uint32_t len, uint stlink_usb_init_buffer(handle, h->rx_ep, len);
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_SWIM_READBUF;
- res = stlink_usb_xfer_noerrcheck(handle, data, len);
+ res = h->itf->xfer(handle, data, len);
if (res != ERROR_OK)
return res;
@@ -1653,7 +1689,7 @@ static int stlink_usb_idcode(void *handle, uint32_t *idcode)
if (h->version.jtag_api == STLINK_JTAG_API_V1) {
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READCOREID;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);
+ res = h->itf->xfer(handle, h->databuf, 4);
offset = 0;
} else {
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READ_IDCODES;
@@ -1730,7 +1766,7 @@ static int stlink_usb_trace_read(void *handle, uint8_t *buf, \
size_t *size) h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GET_TRACE_NB;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);
+ res = h->itf->xfer(handle, h->databuf, 2);
if (res != ERROR_OK)
return res;
@@ -1794,7 +1830,7 @@ static enum target_state stlink_usb_state(void *handle)
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_GETSTATUS;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);
+ res = h->itf->xfer(handle, h->databuf, 2);
if (res != ERROR_OK)
return TARGET_UNKNOWN;
@@ -1994,7 +2030,7 @@ static int stlink_usb_read_regs(void *handle)
if (h->version.jtag_api == STLINK_JTAG_API_V1) {
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READALLREGS;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 84);
+ res = h->itf->xfer(handle, h->databuf, 84);
/* regs data from offset 0 */
} else {
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READALLREGS;
@@ -2023,7 +2059,7 @@ static int stlink_usb_read_reg(void *handle, int num, uint32_t \
*val) h->cmdbuf[h->cmdidx++] = num;
if (h->version.jtag_api == STLINK_JTAG_API_V1) {
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);
+ res = h->itf->xfer(handle, h->databuf, 4);
if (res != ERROR_OK)
return res;
*val = le_to_h_u32(h->databuf);
@@ -2108,7 +2144,7 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, \
uint16_t len, if (read_len == 1)
read_len++;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, read_len);
+ res = h->itf->xfer(handle, h->databuf, read_len);
if (res != ERROR_OK)
return res;
@@ -2142,7 +2178,7 @@ static int stlink_usb_write_mem8(void *handle, uint32_t addr, \
uint16_t len, h_u16_to_le(h->cmdbuf+h->cmdidx, len);
h->cmdidx += 2;
- res = stlink_usb_xfer_noerrcheck(handle, buffer, len);
+ res = h->itf->xfer(handle, buffer, len);
if (res != ERROR_OK)
return res;
@@ -2177,7 +2213,7 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, \
uint16_t len, h_u16_to_le(h->cmdbuf+h->cmdidx, len);
h->cmdidx += 2;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len);
+ res = h->itf->xfer(handle, h->databuf, len);
if (res != ERROR_OK)
return res;
@@ -2214,7 +2250,7 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, \
uint16_t len, h_u16_to_le(h->cmdbuf+h->cmdidx, len);
h->cmdidx += 2;
- res = stlink_usb_xfer_noerrcheck(handle, buffer, len);
+ res = h->itf->xfer(handle, buffer, len);
if (res != ERROR_OK)
return res;
@@ -2246,7 +2282,7 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, \
uint16_t len, h_u16_to_le(h->cmdbuf+h->cmdidx, len);
h->cmdidx += 2;
- res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len);
+ res = h->itf->xfer(handle, h->databuf, len);
if (res != ERROR_OK)
return res;
@@ -2280,7 +2316,7 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, \
uint16_t len, h_u16_to_le(h->cmdbuf+h->cmdidx, len);
h->cmdidx += 2;
- res = stlink_usb_xfer_noerrcheck(handle, buffer, len);
+ res = h->itf->xfer(handle, buffer, len);
if (res != ERROR_OK)
return res;
@@ -2688,14 +2724,26 @@ static int stlink_speed(void *handle, int khz, bool query)
static int stlink_usb_close(void *handle)
{
struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
- if (h && h->fd) {
+ if (h && itf_priv->fd) {
stlink_usb_exit_mode(h);
/* do not check return code, it prevent
us from closing jtag_libusb */
- jtag_libusb_close(h->fd);
+ jtag_libusb_close(itf_priv->fd);
}
+ return ERROR_OK;
+}
+
+/** */
+static int stlink_close(void *handle)
+{
+ struct stlink_usb_handle_s *h = handle;
+
+ h->itf->close(handle);
+
+ free(h->itf->priv);
free(h);
return ERROR_OK;
@@ -2781,27 +2829,11 @@ char *stlink_usb_get_alternate_serial(libusb_device_handle \
*device, }
/** */
-static int stlink_usb_open(struct hl_interface_param_s *param, enum stlink_mode \
mode, void **fd) +static int stlink_usb_open(void *handle, struct \
hl_interface_param_s *param) {
+ struct stlink_usb_handle_s *h = handle;
+ struct stlink_usb_priv_s *itf_priv = h->itf->priv;
int err, retry_count = 1;
- struct stlink_usb_handle_s *h;
-
- LOG_DEBUG("stlink_usb_open");
-
- h = calloc(1, sizeof(struct stlink_usb_handle_s));
-
- if (h == 0) {
- LOG_DEBUG("malloc failed");
- return ERROR_FAIL;
- }
-
- h->st_mode = mode;
-
- for (unsigned i = 0; param->vid[i]; i++) {
- LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s",
- h->st_mode, param->vid[i], param->pid[i],
- param->serial ? param->serial : "");
- }
/*
On certain host USB configurations(e.g. MacBook Air)
@@ -2814,25 +2846,25 @@ static int stlink_usb_open(struct hl_interface_param_s \
*param, enum stlink_mode
*/
do {
if (jtag_libusb_open(param->vid, param->pid, param->serial,
- &h->fd, stlink_usb_get_alternate_serial) != ERROR_OK) {
+ &itf_priv->fd, stlink_usb_get_alternate_serial) != ERROR_OK) {
LOG_ERROR("open failed");
- goto error_open;
+ return ERROR_FAIL;
}
- jtag_libusb_set_configuration(h->fd, 0);
+ jtag_libusb_set_configuration(itf_priv->fd, 0);
- if (libusb_claim_interface(h->fd, 0) != ERROR_OK) {
+ if (libusb_claim_interface(itf_priv->fd, 0) != ERROR_OK) {
LOG_DEBUG("claim interface failed");
- goto error_open;
+ return ERROR_FAIL;
}
/* RX EP is common for all versions */
h->rx_ep = STLINK_RX_EP;
uint16_t pid;
- if (jtag_libusb_get_pid(libusb_get_device(h->fd), &pid) != ERROR_OK) {
+ if (jtag_libusb_get_pid(libusb_get_device(itf_priv->fd), &pid) != ERROR_OK) {
LOG_DEBUG("libusb_get_pid failed");
- goto error_open;
+ return ERROR_FAIL;
}
/* wrap version for first read */
@@ -2872,21 +2904,21 @@ static int stlink_usb_open(struct hl_interface_param_s \
*param, enum stlink_mode } else if (h->version.stlink == 1 ||
retry_count == 0) {
LOG_ERROR("read version failed");
- goto error_open;
+ return ERROR_FAIL;
} else {
- err = libusb_release_interface(h->fd, 0);
+ err = libusb_release_interface(itf_priv->fd, 0);
if (err != ERROR_OK) {
LOG_ERROR("release interface failed");
- goto error_open;
+ return ERROR_FAIL;
}
- err = libusb_reset_device(h->fd);
+ err = libusb_reset_device(itf_priv->fd);
if (err != ERROR_OK) {
LOG_ERROR("reset device failed");
- goto error_open;
+ return ERROR_FAIL;
}
- jtag_libusb_close(h->fd);
+ jtag_libusb_close(itf_priv->fd);
/*
Give the device one second to settle down and
reenumerate.
@@ -2896,8 +2928,45 @@ static int stlink_usb_open(struct hl_interface_param_s *param, \
enum stlink_mode }
} while (1);
+ return ERROR_OK;
+}
+
+static struct stlink_interface_s stlink_usb_itf = {
+ .open = stlink_usb_open,
+ .close = stlink_usb_close,
+ .xfer = stlink_usb_xfer_noerrcheck,
+ .read = stlink_usb_bulk_read,
+};
+
+static int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode, \
void **fd) +{
+ struct stlink_usb_handle_s *h;
+
+ LOG_DEBUG("stlink_usb_open");
+
+ h = calloc(1, sizeof(struct stlink_usb_handle_s));
+
+ if (h == 0) {
+ LOG_DEBUG("malloc failed");
+ return ERROR_FAIL;
+ }
+
+ h->st_mode = mode;
+
+ for (unsigned i = 0; param->vid[i]; i++) {
+ LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s",
+ h->st_mode, param->vid[i], param->pid[i],
+ param->serial ? param->serial : "");
+ }
+
+ h->itf = &stlink_usb_itf;
+ h->itf->priv = calloc(1, sizeof(struct stlink_usb_priv_s));
+
+ if (h->itf->priv == NULL || h->itf->open(h, param) != ERROR_OK)
+ goto error_open;
+
/* check if mode is supported */
- err = ERROR_OK;
+ int err = ERROR_OK;
switch (h->st_mode) {
case STLINK_MODE_DEBUG_SWD:
@@ -2963,14 +3032,13 @@ static int stlink_usb_open(struct hl_interface_param_s \
*param, enum stlink_mode return ERROR_OK;
error_open:
- stlink_usb_close(h);
-
+ stlink_close(h);
return ERROR_FAIL;
}
static int stlink_usb_hl_open(struct hl_interface_param_s *param, void **fd)
{
- return stlink_usb_open(param, stlink_get_mode(param->transport), fd);
+ return stlink_open(param, stlink_get_mode(param->transport), fd);
}
int stlink_config_trace(void *handle, bool enabled,
@@ -3680,7 +3748,7 @@ static int stlink_dap_init(void)
return ERROR_FAIL;
}
- retval = stlink_usb_open(&stlink_dap_param, mode, (void **)&stlink_dap_handle);
+ retval = stlink_open(&stlink_dap_param, mode, (void **)&stlink_dap_handle);
if (retval != ERROR_OK)
return retval;
--
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic