diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c
index 8b088660ff111554e37d5ea245a02c414c177d5f..2bb8ddb95dd0bb3791ef2bed00a5f16e6475f6fb 100644
--- a/stmhal/usbd_cdc_interface.c
+++ b/stmhal/usbd_cdc_interface.c
@@ -42,6 +42,7 @@
 #include "pendsv.h"
 
 #include "py/obj.h"
+#include "irq.h"
 #include "timer.h"
 #include "usb.h"
 
@@ -417,6 +418,10 @@ int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout) {
                 // timeout
                 return i;
             }
+            if (query_irq() == IRQ_STATE_DISABLED) {
+                // IRQs disabled so buffer will never be drained; return immediately
+                return i;
+            }
             __WFI(); // enter sleep mode, waiting for interrupt
         }
 
@@ -444,6 +449,10 @@ void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len) {
             // (wraparound of tick is taken care of by 2's complement arithmetic).
             uint32_t start = HAL_GetTick();
             while (((UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1)) == UserTxBufPtrOut && HAL_GetTick() - start <= 500) {
+                if (query_irq() == IRQ_STATE_DISABLED) {
+                    // IRQs disabled so buffer will never be drained; exit loop
+                    break;
+                }
                 __WFI(); // enter sleep mode, waiting for interrupt
             }
 
@@ -489,6 +498,10 @@ int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
                 // timeout
                 return i;
             }
+            if (query_irq() == IRQ_STATE_DISABLED) {
+                // IRQs disabled so buffer will never be filled; return immediately
+                return i;
+            }
             __WFI(); // enter sleep mode, waiting for interrupt
         }