-
-struct trans_ctx {
-#define TRANS_FLAGS_IS_DONE (1 << 0)
-#define TRANS_FLAGS_HAS_ERROR (1 << 1)
- volatile unsigned long flags;
-};
-
-#ifndef LIBUSB_CALL
-# define LIBUSB_CALL
-#endif
-
-static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) {
- struct trans_ctx * const ctx = trans->user_data;
-
- if (trans->status != LIBUSB_TRANSFER_COMPLETED)
- ctx->flags |= TRANS_FLAGS_HAS_ERROR;
-
- ctx->flags |= TRANS_FLAGS_IS_DONE;
-}
-
-int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) {
- struct timeval start;
- struct timeval now;
- struct timeval diff;
- struct trans_ctx trans_ctx;
- enum libusb_error error;
-
- trans_ctx.flags = 0;
-
- /* brief intrusion inside the libusb interface */
- trans->callback = on_trans_done;
- trans->user_data = &trans_ctx;
-
- if ((error = libusb_submit_transfer(trans))) {
- printf("libusb_submit_transfer(%d)\n", error);
- return -1;
- }
-
- gettimeofday(&start, NULL);
-
- while (trans_ctx.flags == 0) {
- struct timeval timeout;
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
- if (libusb_handle_events_timeout(slu->libusb_ctx, &timeout)) {
- printf("libusb_handle_events()\n");
- return -1;
- }
-
- gettimeofday(&now, NULL);
- timersub(&now, &start, &diff);
- if (diff.tv_sec >= 3) {
- printf("libusb_handle_events() timeout\n");
- return -1;
- }
- }
-
- if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
- printf("libusb_handle_events() | has_error\n");
- return -1;
- }
-
- return 0;
-}
-