fix todo size in list_reverse()

This commit is contained in:
hathach
2025-10-09 18:50:04 +07:00
parent d4374bb0db
commit cc82e088b5
2 changed files with 38 additions and 39 deletions

View File

@ -571,20 +571,18 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
//--------------------------------------------------------------------+
// OHCI Interrupt Handler
//--------------------------------------------------------------------+
static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head)
{
ohci_td_item_t* td_reverse_head = NULL;
TU_ATTR_ALWAYS_INLINE static inline bool is_itd(ohci_td_item_t* item) {
(void) item;
return false; // ISO not supported yet
}
while(td_head != NULL)
{
static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head) {
ohci_td_item_t* td_reverse_head = NULL;
while(td_head != NULL) {
td_head = _virt_addr(td_head);
// FIXME: This is not the correct object size.
// However, because we have hardcoded the assumption that
// a cache line is at least 32 bytes (in ohci.h), and
// because both types of TD structs are <= 32 bytes, this
// nonetheless still works without error.
hcd_dcache_invalidate(td_head, sizeof(ohci_td_item_t));
uint32_t next = td_head->next;
const uint32_t item_size = is_itd(td_head) ? sizeof(ohci_itd_t) : sizeof(ohci_gtd_t);
hcd_dcache_invalidate(td_head, item_size);
const uint32_t next = td_head->next;
// make current's item become reverse's first item
td_head->next = (uint32_t) td_reverse_head;

View File

@ -48,6 +48,10 @@ enum {
// tinyUSB's OHCI implementation caps number of EDs to 8 bits
TU_VERIFY_STATIC (ED_MAX <= 256, "Reduce CFG_TUH_DEVICE_MAX or CFG_TUH_ENDPOINT_MAX");
#define GTD_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16)
#define ED_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16)
#define ITD_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 32)
//--------------------------------------------------------------------+
// OHCI Data Structure
//--------------------------------------------------------------------+
@ -81,17 +85,15 @@ TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" );
// This ends up being impossible to guarantee, so we choose a design which avoids the situation entirely.
// common link item for gtd and itd for list travel
// use as pointer only
typedef struct TU_ATTR_ALIGNED(16) {
uint32_t reserved[2];
volatile uint32_t next;
uint32_t reserved2;
}ohci_td_item_t;
typedef struct TU_ATTR_ALIGNED(TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16))
{
// Word 0
uint32_t used : 1;
typedef struct TU_ATTR_ALIGNED(GTD_ALIGN_SIZE) {
// Word 0
uint32_t used : 1;
uint32_t index : 8; // endpoint index the gtd belongs to, or device address in case of control xfer
uint32_t : 9; // can be used
uint32_t buffer_rounding : 1;
@ -101,16 +103,16 @@ typedef struct TU_ATTR_ALIGNED(TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16))
volatile uint32_t error_count : 2;
volatile uint32_t condition_code : 4;
// Word 1
uint8_t* volatile current_buffer_pointer;
// Word 1
uint8_t* volatile current_buffer_pointer;
// Word 2 : next TD
volatile uint32_t next;
// Word 2 : next TD
volatile uint32_t next;
// Word 3
uint8_t* buffer_end;
// Word 3
uint8_t* buffer_end;
} ohci_gtd_t;
TU_VERIFY_STATIC(sizeof(ohci_gtd_t) == TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE,16), "size is not correct" );
TU_VERIFY_STATIC(sizeof(ohci_gtd_t) == GTD_ALIGN_SIZE, "size is not correct" );
typedef union {
struct {
@ -140,17 +142,16 @@ typedef union {
} ohci_ed_word2_t;
TU_VERIFY_STATIC(sizeof(ohci_ed_word2_t) == 4, "size is not correct" );
typedef struct TU_ATTR_ALIGNED(TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16)) {
typedef struct TU_ATTR_ALIGNED(ED_ALIGN_SIZE) {
ohci_ed_word0_t w0; // Word 0
uint32_t td_tail; // Word 1
volatile ohci_ed_word2_t td_head; // Word 2
uint32_t next; // Word 3
} ohci_ed_t;
TU_VERIFY_STATIC(sizeof(ohci_ed_t) == TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16), "size is not correct" );
TU_VERIFY_STATIC(sizeof(ohci_ed_t) == ED_ALIGN_SIZE, "size is not correct" );
typedef struct TU_ATTR_ALIGNED(TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 32))
{
/*---------- Word 1 ----------*/
typedef struct TU_ATTR_ALIGNED(ITD_ALIGN_SIZE) {
/*---------- Word 1 ----------*/
uint32_t starting_frame : 16;
uint32_t : 5; // can be used
uint32_t delay_interrupt : 3;
@ -158,20 +159,20 @@ typedef struct TU_ATTR_ALIGNED(TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 32))
uint32_t : 1; // can be used
volatile uint32_t condition_code : 4;
/*---------- Word 2 ----------*/
uint32_t buffer_page0; // 12 lsb bits can be used
/*---------- Word 3 ----------*/
volatile uint32_t next;
/*---------- Word 2 ----------*/
uint32_t buffer_page0; // 12 lsb bits can be used
/*---------- Word 4 ----------*/
uint32_t buffer_end;
/*---------- Word 3 ----------*/
volatile uint32_t next;
/*---------- Word 5-8 ----------*/
volatile uint16_t offset_packetstatus[8];
} ochi_itd_t;
/*---------- Word 4 ----------*/
uint32_t buffer_end;
TU_VERIFY_STATIC(sizeof(ochi_itd_t) == TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 32), "size is not correct" );
/*---------- Word 5-8 ----------*/
volatile uint16_t offset_packetstatus[8];
} ohci_itd_t;
TU_VERIFY_STATIC(sizeof(ohci_itd_t) == ITD_ALIGN_SIZE, "size is not correct" );
typedef struct {
uint16_t expected_bytes; // up to 8192 bytes so max is 13 bits