summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyzee119 <[email protected]>2024-01-07 08:30:33 +1030
committerRyzee119 <[email protected]>2024-01-10 16:03:43 +1030
commite7e19f562765999ed76b25b93649e80d9652b088 (patch)
treecb104c9f28a8910aa698a699bbbfb43c987ac432 /src
parentae364b1460b91153cd94b4b0303eeda6419ff1d1 (diff)
[OHCI] Allow more than 16 devices
Diffstat (limited to 'src')
-rw-r--r--src/portable/ohci/ohci.c16
-rw-r--r--src/portable/ohci/ohci.h16
2 files changed, 26 insertions, 6 deletions
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index f978b0965..c7f4c04ad 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -157,6 +157,7 @@ static ohci_ed_t * const p_ed_head[] =
static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed);
static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
+static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd);
//--------------------------------------------------------------------+
// USBH-HCD API
@@ -345,7 +346,7 @@ static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes)
tu_memclr(p_td, sizeof(ohci_gtd_t));
p_td->used = 1;
- p_td->expected_bytes = total_bytes;
+ gtd_get_extra_data(p_td)->expected_bytes = total_bytes;
p_td->buffer_rounding = 1; // less than queued length is not a error
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
@@ -610,6 +611,16 @@ static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd)
}
}
+static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd) {
+ if ( gtd_is_control(gtd) )
+ {
+ return &ohci_data.control[((intptr_t)gtd - (intptr_t)&ohci_data.control->gtd) / sizeof(ohci_data.control[0])].gtd_data;
+ }else
+ {
+ return &ohci_data.gtd_data[gtd - ohci_data.gtd_pool];
+ }
+}
+
static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer)
{
// 5.2.9 OHCI sample code
@@ -641,8 +652,7 @@ static void done_queue_isr(uint8_t hostid)
if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) )
{
ohci_ed_t * const ed = gtd_get_ed(qtd);
-
- uint32_t const xferred_bytes = qtd->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
+ uint32_t const xferred_bytes = gtd_get_extra_data(qtd)->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
// NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs.
// When there is a error resulting this ED is halted, and this EP still has other queued TD
diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h
index 2081ffabb..cb23396bc 100644
--- a/src/portable/ohci/ohci.h
+++ b/src/portable/ohci/ohci.h
@@ -45,6 +45,9 @@ enum {
#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
#define GTD_MAX ED_MAX
+// 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");
+
//--------------------------------------------------------------------+
// OHCI Data Structure
//--------------------------------------------------------------------+
@@ -70,9 +73,8 @@ typedef struct TU_ATTR_ALIGNED(16)
{
// Word 0
uint32_t used : 1;
- uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer
- uint32_t expected_bytes : 13; // TODO available for hcd
-
+ 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;
uint32_t pid : 2;
uint32_t delay_interrupt : 3;
@@ -152,6 +154,12 @@ typedef struct TU_ATTR_ALIGNED(32)
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
+typedef struct
+{
+ uint16_t expected_bytes : 13; // can be up to 8192 bytes long so use 13 bits
+ uint16_t : 3; // can be used
+} gtd_extra_data_t;
+
// structure with member alignment required from large to small
typedef struct TU_ATTR_ALIGNED(256)
{
@@ -164,11 +172,13 @@ typedef struct TU_ATTR_ALIGNED(256)
struct {
ohci_ed_t ed;
ohci_gtd_t gtd;
+ gtd_extra_data_t gtd_data;
}control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1];
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
ohci_ed_t ed_pool[ED_MAX];
ohci_gtd_t gtd_pool[GTD_MAX];
+ gtd_extra_data_t gtd_data[GTD_MAX]; // extra data needed by TDs that can't fit in the TD struct
volatile uint16_t frame_number_hi;