This is an automated email from Gerrit. Tarek BOCHKATI ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/5632
-- gerrit commit b2e5f0cd11c216ab098f8c1bff5a32560f27d587 Author: Tarek BOCHKATI <[email protected]> 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 <[email protected]> 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 <[email protected]> * + * * * 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 [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
