diff options
| author | hathach <[email protected]> | 2013-09-24 15:05:11 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-09-24 15:21:16 +0700 |
| commit | 63b776f7cf3bb7fe64c2f3b3e383a90b2c50683f (patch) | |
| tree | 1df33c2d8b80310eb7da613e56830181b0cf2fca /tinyusb/host | |
| parent | c4fef827b1f6cb33b9cc336687bd4ff791f8eec9 (diff) | |
add some tests support for msc host
refractor msch buffer for getting inital scsi like inquiry, read capacity
adding support for resovling stall on control pipe
Diffstat (limited to 'tinyusb/host')
| -rw-r--r-- | tinyusb/host/ehci/ehci.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index b2948e0db..40c59616e 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -446,6 +446,7 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); // async list needs async advance handshake to make sure host controller has released cached data + // non-control does not use async advance, it will eventually free by control pipe close // period list queue element is guarantee to be free in the next frame (1 ms) p_qhd->is_removing = 1; // TODO redundant, only apply to control queue head @@ -620,29 +621,47 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) p_qhd->qtd_overlay.buffer_err ||p_qhd->qtd_overlay.babble_err || p_qhd->qtd_overlay.xact_err ) //p_qhd->qtd_overlay.non_hs_period_missed_uframe || p_qhd->qtd_overlay.pingstate_err TODO split transaction error { // current qhd has error in transaction - uint16_t total_xferred_bytes; tusb_xfer_type_t const xfer_type = qhd_get_xfer_type(p_qhd); tusb_event_t error_event; - // TODO allow stall with control pipe // no error bits are set, endpoint is halted due to STALL error_event = ( !(p_qhd->qtd_overlay.buffer_err || p_qhd->qtd_overlay.babble_err || p_qhd->qtd_overlay.xact_err) ) ? TUSB_EVENT_XFER_STALLED : TUSB_EVENT_XFER_ERROR; p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes; - hal_debugger_breakpoint(); + // TODO skip unplugged device + if ( TUSB_EVENT_XFER_ERROR == error_event ) hal_debugger_breakpoint(); p_qhd->p_qtd_list_head->used = 0; // free QTD qtd_remove_1st_from_qhd(p_qhd); - // subtract setup size if it is control xfer - total_xferred_bytes = p_qhd->total_xferred_bytes - (xfer_type == TUSB_XFER_CONTROL ? min8_of(8, p_qhd->total_xferred_bytes) : 0); + if ( TUSB_XFER_CONTROL == xfer_type ) + { + p_qhd->total_xferred_bytes -= min8_of(8, p_qhd->total_xferred_bytes); // subtract setup size + + // control cannot be halted --> clear all qtd list + p_qhd->p_qtd_list_head = NULL; + p_qhd->p_qtd_list_tail = NULL; + + p_qhd->qtd_overlay.next.terminate = 1; + p_qhd->qtd_overlay.alternate.terminate = 1; + p_qhd->qtd_overlay.halted = 0; + + #if 0 // no need to mark control qtds as not used + ehci_qtd_t *p_setup = get_control_qtds(dev_addr); + ehci_qtd_t *p_data = p_setup + 1; + ehci_qtd_t *p_status = p_setup + 2; + + p_setup->used = p_data->used = p_status = 0; + #endif + } // call USBH callback usbh_xfer_isr( qhd_create_pipe_handle(p_qhd, xfer_type), p_qhd->class_code, error_event, - total_xferred_bytes); + p_qhd->total_xferred_bytes); + p_qhd->total_xferred_bytes = 0; } } |
