summaryrefslogtreecommitdiff
path: root/tinyusb/host
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-09-24 18:23:34 +0700
committerhathach <[email protected]>2013-09-24 18:23:34 +0700
commitbbfa85aa08d19f57f6e1c8bb0040839e38d9a01c (patch)
treeb79eac25722edca6eca467ae62b2506add73f7d7 /tinyusb/host
parent63b776f7cf3bb7fe64c2f3b3e383a90b2c50683f (diff)
allow a limited model to deal with stalled pipe/transaction
added stall clear & able to mount the stupid toshiba thumb drive add HCD pipe API - bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl); - bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl); - uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl); - tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl); remove tusbh_device_mount_failed_cb (not neccessary for user)
Diffstat (limited to 'tinyusb/host')
-rw-r--r--tinyusb/host/ehci/ehci.c41
-rw-r--r--tinyusb/host/hcd.h5
-rw-r--r--tinyusb/host/usbh.c10
3 files changed, 48 insertions, 8 deletions
diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c
index 40c59616e..684051917 100644
--- a/tinyusb/host/ehci/ehci.c
+++ b/tinyusb/host/ehci/ehci.c
@@ -100,6 +100,13 @@ static inline ehci_qhd_t* qhd_find_free (uint8_t dev_addr) ATTR_PURE ATTR_ALW
static inline tusb_xfer_type_t qhd_get_xfer_type(ehci_qhd_t const * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE;
STATIC_ INLINE_ ehci_qhd_t* qhd_get_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE;
static inline pipe_handle_t qhd_create_pipe_handle(ehci_qhd_t const * p_qhd, tusb_xfer_type_t xfer_type) ATTR_PURE ATTR_ALWAYS_INLINE;
+// determine if a queue head has bus-related error
+static inline bool qhd_has_xact_error(ehci_qhd_t * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE;
+static inline bool qhd_has_xact_error(ehci_qhd_t * p_qhd)
+{
+ return ( 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
+}
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type, uint8_t interval);
@@ -468,12 +475,38 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl)
return TUSB_ERROR_NONE;
}
+bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl)
+{
+ ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
+ return !p_qhd->qtd_overlay.halted && (p_qhd->p_qtd_list_head != NULL);
+}
+
bool hcd_pipe_is_idle(pipe_handle_t pipe_hdl)
{
ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
return (p_qhd->p_qtd_list_head == NULL);
}
+bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl)
+{
+ ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
+ return p_qhd->qtd_overlay.halted && !qhd_has_xact_error(p_qhd);
+}
+
+uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl)
+{
+ ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
+ return p_qhd->endpoint_number + ( (p_qhd->pid_non_control == EHCI_PID_IN) ? 0x80 : 0);
+}
+
+tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl)
+{
+ ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
+ p_qhd->qtd_overlay.halted = 0;
+
+ return TUSB_ERROR_NONE;
+}
+
//--------------------------------------------------------------------+
// EHCI Interrupt Handler
//--------------------------------------------------------------------+
@@ -617,16 +650,14 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint8_t interval_ms)
static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
{
- if ( (p_qhd->device_address != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL
- 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
+ if ( (p_qhd->device_address != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL
+ qhd_has_xact_error(p_qhd) )
{ // current qhd has error in transaction
tusb_xfer_type_t const xfer_type = qhd_get_xfer_type(p_qhd);
tusb_event_t error_event;
// 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;
+ error_event = qhd_has_xact_error(p_qhd) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_STALLED;
p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes;
diff --git a/tinyusb/host/hcd.h b/tinyusb/host/hcd.h
index 61642d95b..6383015a8 100644
--- a/tinyusb/host/hcd.h
+++ b/tinyusb/host/hcd.h
@@ -98,7 +98,12 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *
tusb_error_t hcd_pipe_queue_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes) ATTR_WARN_UNUSED_RESULT; // only queue, not transferring yet
tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) ATTR_WARN_UNUSED_RESULT;
tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) /*ATTR_WARN_UNUSED_RESULT*/;
+
+bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl);
+bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl);
bool hcd_pipe_is_idle(pipe_handle_t pipe_hdl);
+uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl);
+tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl);
#if 0
tusb_error_t hcd_pipe_cancel()ATTR_WARN_UNUSED_RESULT;
diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c
index 67cc8f96c..65efe8768 100644
--- a/tinyusb/host/usbh.c
+++ b/tinyusb/host/usbh.c
@@ -216,9 +216,13 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType,
osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl);
// TODO make handler for this function general purpose
- SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error &&
- TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status,
- tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
+ if (TUSB_ERROR_NONE != error) SUBTASK_EXIT(error);
+ if (TUSB_EVENT_XFER_STALLED == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_STALLED);
+ if (TUSB_EVENT_XFER_ERROR == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_FAILED);
+
+// SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error &&
+// TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status,
+// tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
OSAL_SUBTASK_END
}