fix bug: adjust all bulk queue head from ehci_data.device

This commit is contained in:
hathach 2013-03-22 21:21:00 +07:00
parent f6acca6664
commit 397d62db10
7 changed files with 70 additions and 51 deletions

View File

@ -127,7 +127,7 @@ void test_isr_disconnect_then_async_advance_control_pipe(void)
.wValue = 3 }, .wValue = 3 },
NULL); NULL);
ehci_qhd_t *p_qhd = &ehci_data.device[dev_addr].control.qhd; ehci_qhd_t *p_qhd = get_control_qhd(dev_addr);
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head; ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail; ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;
@ -162,7 +162,7 @@ void test_bulk_pipe_close(void)
hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 100); hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 100);
hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 50); hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 50);
ehci_qhd_t *p_qhd = &ehci_data.device[dev_addr].qhd[pipe_hdl.index]; ehci_qhd_t *p_qhd = &ehci_data.device[dev_addr-1].qhd[pipe_hdl.index];
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head; ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail; ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;

View File

@ -153,7 +153,7 @@ void test_open_bulk_qhd_data(void)
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr); TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl.xfer_type); TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl.xfer_type);
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr ].qhd[ pipe_hdl.index ]; p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
verify_bulk_open_qhd(p_qhd, desc_endpoint, TUSB_CLASS_MSC); verify_bulk_open_qhd(p_qhd, desc_endpoint, TUSB_CLASS_MSC);
//------------- async list check -------------// //------------- async list check -------------//
@ -169,7 +169,7 @@ void test_bulk_close(void)
{ {
tusb_descriptor_endpoint_t const * desc_endpoint = &desc_ept_bulk_in; tusb_descriptor_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
pipe_handle_t pipe_hdl = hcd_pipe_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC); pipe_handle_t pipe_hdl = hcd_pipe_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC);
ehci_qhd_t *p_qhd = &ehci_data.device[ pipe_hdl.dev_addr ].qhd[ pipe_hdl.index ]; ehci_qhd_t *p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
//------------- Code Under TEST -------------// //------------- Code Under TEST -------------//
hcd_pipe_close(pipe_hdl); hcd_pipe_close(pipe_hdl);

View File

@ -101,7 +101,7 @@ void setUp(void)
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_bulk.dev_addr); TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_bulk.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl_bulk.xfer_type); TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl_bulk.xfer_type);
p_qhd_bulk = &ehci_data.device[ dev_addr ].qhd[ pipe_hdl_bulk.index ]; p_qhd_bulk = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_bulk.index ];
} }
void tearDown(void) void tearDown(void)

View File

@ -98,9 +98,9 @@ void setUp(void)
async_head = get_async_head( hostid ); async_head = get_async_head( hostid );
p_setup = &ehci_data.device[dev_addr].control.qtd[0]; p_setup = &ehci_data.device[dev_addr-1].control.qtd[0];
p_data = &ehci_data.device[dev_addr].control.qtd[1]; p_data = &ehci_data.device[dev_addr-1].control.qtd[1];
p_status = &ehci_data.device[dev_addr].control.qtd[2]; p_status = &ehci_data.device[dev_addr-1].control.qtd[2];
} }
void tearDown(void) void tearDown(void)

View File

@ -148,7 +148,7 @@ void test_open_interrupt_qhd_hs(void)
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr); TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type); TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr ].qhd[ pipe_hdl.index ]; p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
verify_int_qhd(p_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID); verify_int_qhd(p_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);
@ -169,7 +169,7 @@ void test_open_interrupt_qhd_non_hs(void)
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr); TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type); TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr ].qhd[ pipe_hdl.index ]; p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
verify_int_qhd(p_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID); verify_int_qhd(p_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);

View File

@ -61,10 +61,12 @@ void ehci_controller_run(uint8_t hostid);
void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed); void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed);
void ehci_controller_device_unplug(uint8_t hostid); void ehci_controller_device_unplug(uint8_t hostid);
ehci_registers_t* const get_operational_register(uint8_t hostid); ehci_registers_t* get_operational_register(uint8_t hostid);
ehci_link_t* const get_period_frame_list(uint8_t list_idx); ehci_link_t* get_period_frame_list(uint8_t list_idx);
ehci_qhd_t* const get_async_head(uint8_t hostid); ehci_qhd_t* get_async_head(uint8_t hostid);
ehci_qhd_t* const get_period_head(uint8_t hostid); ehci_qhd_t* get_period_head(uint8_t hostid);
ehci_qhd_t* get_control_qhd(uint8_t dev_addr);
ehci_qtd_t* get_control_qtds(uint8_t dev_addr);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -111,6 +111,13 @@ STATIC_ INLINE_ ehci_qhd_t* get_period_head(uint8_t hostid)
return &ehci_data.period_head[ hostid_to_data_idx(hostid) ]; return &ehci_data.period_head[ hostid_to_data_idx(hostid) ];
} }
static inline uint8_t get_qhd_index(ehci_qhd_t * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE;
static inline uint8_t get_qhd_index(ehci_qhd_t * p_qhd)
{
return p_qhd - ehci_data.device[p_qhd->device_address-1].qhd;
}
tusb_error_t hcd_controller_init(uint8_t hostid) ATTR_WARN_UNUSED_RESULT; tusb_error_t hcd_controller_init(uint8_t hostid) ATTR_WARN_UNUSED_RESULT;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -159,12 +166,6 @@ bool hcd_port_connect_status(uint8_t hostid)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// EHCI Interrupt Handler // EHCI Interrupt Handler
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline uint8_t get_qhd_index(ehci_qhd_t * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE;
static inline uint8_t get_qhd_index(ehci_qhd_t * p_qhd)
{
return p_qhd - ehci_data.device[p_qhd->device_address].qhd;
}
void async_advance_isr(ehci_qhd_t * const async_head) void async_advance_isr(ehci_qhd_t * const async_head)
{ {
if(async_head->is_removing) // closing control pipe of addr0 if(async_head->is_removing) // closing control pipe of addr0
@ -419,8 +420,8 @@ tusb_error_t hcd_controller_reset(uint8_t hostid)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void init_qhd(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type); static void init_qhd(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type);
static inline ehci_qhd_t* get_control_qhd(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT; STATIC_ INLINE_ ehci_qhd_t* get_control_qhd(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT;
static inline ehci_qtd_t* get_control_qtds(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT; STATIC_ INLINE_ ehci_qtd_t* get_control_qtds(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// CONTROL PIPE API // CONTROL PIPE API
@ -569,22 +570,30 @@ tusb_error_t hcd_pipe_control_close(uint8_t dev_addr)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// BULK/INT/ISO PIPE API // BULK/INT/ISO PIPE API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline ehci_qhd_t* find_free_qhd (uint8_t dev_addr) ATTR_PURE ATTR_ALWAYS_INLINE;
static inline ehci_qhd_t* find_free_qhd (uint8_t dev_addr)
{
uint8_t relative_address = dev_addr-1;
uint8_t index=0;
while( index<EHCI_MAX_QHD && ehci_data.device[relative_address].qhd[index].used )
{
index++;
}
return (index < EHCI_MAX_QHD) ? &ehci_data.device[relative_address].qhd[index] : NULL;
}
pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * p_endpoint_desc, uint8_t class_code) pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * p_endpoint_desc, uint8_t class_code)
{ {
pipe_handle_t const null_handle = { .dev_addr = 0, .xfer_type = 0, .index = 0 }; pipe_handle_t const null_handle = { .dev_addr = 0, .xfer_type = 0, .index = 0 };
ASSERT(dev_addr > 0, null_handle);
if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
return null_handle; // TODO not support ISO yet return null_handle; // TODO not support ISO yet
//------------- find a free queue head -------------// ehci_qhd_t * const p_qhd = find_free_qhd(dev_addr);
uint8_t index=0; ASSERT_PTR(p_qhd, null_handle);
while( index<EHCI_MAX_QHD && ehci_data.device[dev_addr].qhd[index].used )
{
index++;
}
ASSERT( index < EHCI_MAX_QHD, null_handle);
ehci_qhd_t * const p_qhd = &ehci_data.device[dev_addr].qhd[index];
init_qhd(p_qhd, dev_addr, p_endpoint_desc->wMaxPacketSize, p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); init_qhd(p_qhd, dev_addr, p_endpoint_desc->wMaxPacketSize, p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer);
p_qhd->class_code = class_code; p_qhd->class_code = class_code;
@ -604,24 +613,36 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *
list_insert( (ehci_link_t*) list_head, list_insert( (ehci_link_t*) list_head,
(ehci_link_t*) p_qhd, EHCI_QUEUE_ELEMENT_QHD); (ehci_link_t*) p_qhd, EHCI_QUEUE_ELEMENT_QHD);
return (pipe_handle_t) { .dev_addr = dev_addr, .xfer_type = p_endpoint_desc->bmAttributes.xfer, .index = index}; return (pipe_handle_t) { .dev_addr = dev_addr, .xfer_type = p_endpoint_desc->bmAttributes.xfer, .index = get_qhd_index(p_qhd) };
}
static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE;
static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl)
{
return &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
}
STATIC_ INLINE_ ehci_qtd_t* find_free_qtd(uint8_t dev_addr) ATTR_PURE ATTR_ALWAYS_INLINE;
STATIC_ INLINE_ ehci_qtd_t* find_free_qtd(uint8_t dev_addr)
{
uint8_t index=0;
while( index<EHCI_MAX_QTD && ehci_data.device[dev_addr-1].qtd[index].used )
{
index++;
}
return (index < EHCI_MAX_QTD) ? &ehci_data.device[dev_addr-1].qtd[index] : NULL;
} }
tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete)
{ {
//------------- TODO pipe handle validate -------------// //------------- TODO pipe handle validate -------------//
//------------- find a free qtd -------------//
uint8_t index=0;
while( index<EHCI_MAX_QTD && ehci_data.device[pipe_hdl.dev_addr].qtd[index].used )
{
index++;
}
ASSERT( index < EHCI_MAX_QTD, TUSB_ERROR_EHCI_NOT_ENOUGH_QTD);
//------------- set up QTD -------------// //------------- set up QTD -------------//
ehci_qhd_t *p_qhd = &ehci_data.device[pipe_hdl.dev_addr].qhd[pipe_hdl.index]; ehci_qhd_t *p_qhd = get_qhd_from_pipe_handle(pipe_hdl);
ehci_qtd_t *p_qtd = &ehci_data.device[pipe_hdl.dev_addr].qtd[index]; ehci_qtd_t *p_qtd = find_free_qtd(pipe_hdl.dev_addr);
ASSERT_PTR(p_qtd, TUSB_ERROR_EHCI_NOT_ENOUGH_QTD);
init_qtd(p_qtd, (uint32_t) buffer, total_bytes); init_qtd(p_qtd, (uint32_t) buffer, total_bytes);
p_qtd->pid = p_qhd->pid_non_control; p_qtd->pid = p_qhd->pid_non_control;
@ -633,17 +654,14 @@ tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t t
return TUSB_ERROR_NONE; return TUSB_ERROR_NONE;
} }
static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE;
static inline ehci_qhd_t* get_qhd_from_pipe_handle(pipe_handle_t pipe_hdl)
{
return &ehci_data.device[ pipe_hdl.dev_addr ].qhd[ pipe_hdl.index ];
}
tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl)
{ {
ASSERT(pipe_hdl.dev_addr > 0, TUSB_ERROR_INVALID_PARA);
ASSERT(pipe_hdl.xfer_type != TUSB_XFER_ISOCHRONOUS, TUSB_ERROR_INVALID_PARA); ASSERT(pipe_hdl.xfer_type != TUSB_XFER_ISOCHRONOUS, TUSB_ERROR_INVALID_PARA);
ehci_qhd_t *p_qhd = get_qhd_from_pipe_handle( pipe_hdl ); ehci_qhd_t *p_qhd = get_qhd_from_pipe_handle( pipe_hdl );
p_qhd->is_removing = 1; p_qhd->is_removing = 1;
if ( pipe_hdl.xfer_type == TUSB_XFER_BULK ) if ( pipe_hdl.xfer_type == TUSB_XFER_BULK )
@ -662,17 +680,17 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// HELPER // HELPER
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline ehci_qhd_t* get_control_qhd(uint8_t dev_addr) STATIC_ INLINE_ ehci_qhd_t* get_control_qhd(uint8_t dev_addr)
{ {
return (dev_addr == 0) ? return (dev_addr == 0) ?
get_async_head( usbh_device_info_pool[dev_addr].core_id ) : get_async_head( usbh_device_info_pool[dev_addr].core_id ) :
&ehci_data.device[dev_addr-1].control.qhd; &ehci_data.device[dev_addr-1].control.qhd;
} }
static inline ehci_qtd_t* get_control_qtds(uint8_t dev_addr) STATIC_ INLINE_ ehci_qtd_t* get_control_qtds(uint8_t dev_addr)
{ {
return (dev_addr == 0) ? return (dev_addr == 0) ?
ehci_data.addr0_qtd : ehci_data.addr0_qtd :
ehci_data.device[ dev_addr ].control.qtd; ehci_data.device[ dev_addr-1 ].control.qtd;
} }
@ -724,5 +742,4 @@ static void init_qhd(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_si
} }
#endif #endif