afk: Fix ringbuf space checks in afk_epic_tx

Redo the checks to make sure we never cause rptr==wptr, because that
signifies an empty buffer, not a full one.

Signed-off-by: Martin Povišer <povik@cutebit.org>
This commit is contained in:
Martin Povišer 2023-02-09 15:38:59 +01:00 committed by Hector Martin
parent 07ea5a92c3
commit 264e18169f

View file

@ -275,10 +275,16 @@ static int afk_epic_tx(afk_epic_ep_t *epic, u32 channel, u32 type, void *data, s
u32 rptr = rb->hdr->rptr;
u32 wptr = rb->hdr->wptr;
struct afk_qe *hdr = rb->buf + wptr;
size_t buf_advance = ALIGN_UP(sizeof(struct afk_qe) + size, 1 << BLOCK_SHIFT);
if (wptr < rptr && (wptr + sizeof(struct afk_qe) > rptr)) {
printf("EPIC: TX ring buffer is full\n");
return -1;
if (wptr < rptr && buf_advance >= rptr - wptr)
goto buffer_full;
if (wptr >= rptr) {
bool fits_above_wptr =
(buf_advance < rb->bufsz - wptr) || (buf_advance == rb->bufsz - wptr && rptr != 0);
if (!fits_above_wptr && buf_advance >= rptr)
goto buffer_full;
}
hdr->magic = QE_MAGIC;
@ -289,20 +295,11 @@ static int afk_epic_tx(afk_epic_ep_t *epic, u32 channel, u32 type, void *data, s
wptr += sizeof(struct afk_qe);
if (size > rb->bufsz - wptr) {
if (rptr < sizeof(struct afk_qe)) {
printf("EPIC: TX ring buffer is full\n");
return -1;
}
*(struct afk_qe *)rb->buf = *hdr;
hdr = rb->buf;
wptr = sizeof(struct afk_qe);
}
if (wptr < rptr && (wptr + size > rptr)) {
printf("EPIC: TX ring buffer is full\n");
return -1;
}
wptr += size;
wptr = ALIGN_UP(wptr, 1 << BLOCK_SHIFT);
@ -323,6 +320,10 @@ static int afk_epic_tx(afk_epic_ep_t *epic, u32 channel, u32 type, void *data, s
}
return 1;
buffer_full:
printf("EPIC: TX ring buffer is full\n");
return -1;
}
static void afk_epic_rx_ack(afk_epic_ep_t *epic)