mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
use irq-safe version of llist operations between USB callback and main
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "req_ctx.h"
|
#include "req_ctx.h"
|
||||||
#include "linuxlist.h"
|
#include "linuxlist.h"
|
||||||
|
#include "llist_irqsafe.h"
|
||||||
|
|
||||||
static volatile uint32_t usbep_in_progress[BOARD_USB_NUMENDPOINTS];
|
static volatile uint32_t usbep_in_progress[BOARD_USB_NUMENDPOINTS];
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
}
|
}
|
||||||
rctx->tot_len = transferred;
|
rctx->tot_len = transferred;
|
||||||
req_ctx_set_state(rctx, RCTX_S_MAIN_PROCESSING);
|
req_ctx_set_state(rctx, RCTX_S_MAIN_PROCESSING);
|
||||||
llist_add_tail(&rctx->list, queue);
|
llist_add_tail_irqsafe(&rctx->list, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_refill_from_host(struct llist_head *queue, int ep)
|
int usb_refill_from_host(struct llist_head *queue, int ep)
|
||||||
|
|||||||
27
firmware/src_simtrace/llist_irqsafe.h
Normal file
27
firmware/src_simtrace/llist_irqsafe.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "linuxlist.h"
|
||||||
|
|
||||||
|
static inline void llist_add_tail_irqsafe(struct llist_head *_new,
|
||||||
|
struct llist_head *head)
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
llist_add_tail(_new, head);
|
||||||
|
__enable_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct llist_head *llist_head_dequeue_irqsafe(struct llist_head *head)
|
||||||
|
{
|
||||||
|
struct llist_head *lh;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
if (llist_empty(head)) {
|
||||||
|
lh = NULL;
|
||||||
|
} else {
|
||||||
|
lh = head->next;
|
||||||
|
llist_del(lh);
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
return lh;
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "iso7816_fidi.h"
|
#include "iso7816_fidi.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "linuxlist.h"
|
#include "linuxlist.h"
|
||||||
|
#include "llist_irqsafe.h"
|
||||||
#include "req_ctx.h"
|
#include "req_ctx.h"
|
||||||
#include "cardemu_prot.h"
|
#include "cardemu_prot.h"
|
||||||
|
|
||||||
@@ -326,12 +327,22 @@ static void dispatch_usb_command(struct req_ctx *rctx, struct cardem_inst *ci)
|
|||||||
|
|
||||||
/* iterate over the queue of incoming USB commands and dispatch/execute
|
/* iterate over the queue of incoming USB commands and dispatch/execute
|
||||||
* them */
|
* them */
|
||||||
static void process_any_usb_commands(struct llist_head *main_q, struct cardem_inst *ci)
|
static void process_any_usb_commands(struct llist_head *main_q,
|
||||||
|
struct cardem_inst *ci)
|
||||||
{
|
{
|
||||||
struct req_ctx *rctx, *tmp;
|
struct llist_head *lh;
|
||||||
|
struct req_ctx *rctx;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry_safe(rctx, tmp, main_q, list) {
|
/* limit the number of iterations to 10, to ensure we don't get
|
||||||
llist_del(&rctx->list);
|
* stuck here without returning to main loop processing */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
/* de-queue the list head in an irq-safe way */
|
||||||
|
lh = llist_head_dequeue_irqsafe(main_q);
|
||||||
|
if (!lh)
|
||||||
|
break;
|
||||||
|
rctx = llist_entry(lh, struct req_ctx, list);
|
||||||
|
/* dispatch the command with interrupts enabled */
|
||||||
dispatch_usb_command(rctx, ci);
|
dispatch_usb_command(rctx, ci);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user