+ stlink_usb_init_buffer(handle, STLINK_RX_EP, 16);
+
+ h->cmdbuf[h->cmdidx++] = REQUEST_SENSE;
+ h->cmdbuf[h->cmdidx++] = 0;
+ h->cmdbuf[h->cmdidx++] = 0;
+ h->cmdbuf[h->cmdidx++] = 0;
+ h->cmdbuf[h->cmdidx++] = REQUEST_SENSE_LENGTH;
+
+ res = stlink_usb_xfer_rw(handle, REQUEST_SENSE_LENGTH, h->databuf, 16);
+
+ if (res != ERROR_OK)
+ return res;
+
+ if (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK)
+ return ERROR_FAIL;
+
+ return ERROR_OK;
+}
+
+/** */
+static int stlink_usb_xfer(void *handle, const uint8_t *buf, int size)
+{
+ int err, cmdsize = STLINK_CMD_SIZE_V2;
+ struct stlink_usb_handle_s *h;
+
+ assert(handle != NULL);
+
+ h = (struct stlink_usb_handle_s *)handle;
+
+ if (h->version.stlink == 1)
+ cmdsize = STLINK_SG_SIZE;
+
+ err = stlink_usb_xfer_rw(handle, cmdsize, buf, size);
+
+ if (err != ERROR_OK)
+ return err;
+
+ if (h->version.stlink == 1) {
+ if (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK) {
+ /* check csw status */
+ if (h->cmdbuf[12] == 1) {
+ LOG_DEBUG("get sense");
+ if (stlink_usb_xfer_v1_get_sense(handle) != ERROR_OK)
+ return ERROR_FAIL;
+ }
+ return ERROR_FAIL;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+/** */
+static void stlink_usb_xfer_v1_create_cmd(void *handle, uint8_t direction, uint32_t size)
+{
+ struct stlink_usb_handle_s *h;
+
+ h = (struct stlink_usb_handle_s *)handle;
+
+ /* fill the send buffer */
+ strcpy((char *)h->cmdbuf, "USBC");
+ h->cmdidx += 4;
+ /* csw tag not used */
+ h->cmdidx += 4;
+ buf_set_u32(h->cmdbuf+h->cmdidx, 0, 32, size);
+ h->cmdidx += 4;
+ h->cmdbuf[h->cmdidx++] = (direction == STLINK_RX_EP ? ENDPOINT_IN : ENDPOINT_OUT);
+ h->cmdbuf[h->cmdidx++] = 0; /* lun */
+ h->cmdbuf[h->cmdidx++] = STLINK_CMD_SIZE_V1;
+}
+
+/** */
+static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size)
+{
+ struct stlink_usb_handle_s *h;
+
+ h = (struct stlink_usb_handle_s *)handle;
+
+ h->direction = direction;
+
+ h->cmdidx = 0;
+
+ memset(h->cmdbuf, 0, STLINK_SG_SIZE);
+ memset(h->databuf, 0, STLINK_DATA_SIZE);
+
+ if (h->version.stlink == 1)
+ stlink_usb_xfer_v1_create_cmd(handle, direction, size);
+}
+
+static const char * const stlink_usb_error_msg[] = {
+ "unknown"
+};
+
+/** */
+static int stlink_usb_error_check(void *handle)
+{
+ int res;
+ const char *err_msg = 0;
+ struct stlink_usb_handle_s *h;
+
+ assert(handle != NULL);
+
+ h = (struct stlink_usb_handle_s *)handle;
+
+ /* TODO: no error checking yet on api V1 */
+ if (h->jtag_api == STLINK_JTAG_API_V1)
+ h->databuf[0] = STLINK_DEBUG_ERR_OK;
+
+ switch (h->databuf[0]) {
+ case STLINK_DEBUG_ERR_OK:
+ res = ERROR_OK;
+ break;
+ case STLINK_DEBUG_ERR_FAULT:
+ default:
+ err_msg = stlink_usb_error_msg[0];
+ res = ERROR_FAIL;
+ break;
+ }
+
+ if (res != ERROR_OK)
+ LOG_DEBUG("status error: %d ('%s')", h->databuf[0], err_msg);
+
+ return res;