diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index ee85f1b6a..ee89555a3 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -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; diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index ac5d2881b..a6f31c7a5 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -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