diff options
author | Vinayak Pane <vpane@nvidia.com> | 2014-06-26 19:38:03 -0700 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2014-07-10 02:05:19 -0700 |
commit | 630e52e4a8c9cfece1acf289b5d02f4ede7dc358 (patch) | |
tree | a482d8ddcef007c00af93cb38ab3c5a1143b135f | |
parent | 108d084bf6c4d25ee076f5b48fcac5f3a3e26d03 (diff) |
staging: ozwpan: set port changed flag at disconnect
Set port changed flag at every hub disconnect control message.
USB hub status should know correct port status always.
Also contains ugly WAR to recover from network failure cases.
After 3 port reset retries reset the net interface.
Bug 1522708
Change-Id: I1aa5baa837f60668cfb4a23dd7fa820be27151e7
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/431926
(cherry picked from commit bf3790755af42b0d6d2497061b7880078829e9c7)
Reviewed-on: http://git-master/r/435721
GVS: Gerrit_Virtual_Submit
Reviewed-by: Anshul Jain (SW) <anshulj@nvidia.com>
Tested-by: Anshul Jain (SW) <anshulj@nvidia.com>
-rw-r--r-- | drivers/staging/ozwpan/ozhcd.c | 33 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozpd.c | 1 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozpd.h | 1 |
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 42c8a0880740..f43d50f060b2 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -34,6 +34,9 @@ #include "oztrace.h" #include "ozurbparanoia.h" #include "ozhcd.h" +#include "ozpd.h" +#include "ozproto.h" +#include "ozusbsvc.h" #define OZ_HUB_DEBOUNCE_TIMEOUT 1500 @@ -756,6 +759,7 @@ void oz_hcd_pd_departed(void *hport) struct oz_port *port = (struct oz_port *)hport; struct oz_hcd *ozhcd; void *hpd; + struct usb_hcd *hcd; struct oz_endpoint *ep = NULL; oz_trace("%s:\n", __func__); @@ -798,6 +802,8 @@ void oz_hcd_pd_departed(void *hport) spin_unlock_bh(&port->port_lock); if (ep) oz_ep_free(port, ep); + hcd = ozhcd->hcd; + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); oz_trace_msg(H, "usb_hcd_poll_rh_status()\n"); usb_hcd_poll_rh_status(ozhcd->hcd); oz_usb_put(hpd); @@ -1995,6 +2001,29 @@ static int oz_set_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) ozhcd->ports[port_id-1].bus_addr = 0; hpd = oz_claim_hpd(&ozhcd->ports[port_id-1]); if (hpd != NULL) { + struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_pd *pd = (struct oz_pd *)usb_ctx->pd; + + /* FIXME: Hack to reset network interface + * Unrecoverable situation occured. + */ + if (pd && ((++pd->reset_retry > 2) || + (!(pd->state & OZ_PD_S_CONNECTED)))) { + char *_net_dev = ""; + + pr_info("OZ: tear down network interface\n"); + spin_lock_bh(&port->port_lock); + port->flags |= OZ_PORT_F_CHANGED; + spin_unlock_bh(&port->port_lock); + oz_usb_put(hpd); + + oz_pd_stop(pd); + msleep(10); + oz_protocol_term(); + msleep(100); + oz_protocol_init(_net_dev); + break; + } oz_usb_reset_device(hpd); oz_usb_put(hpd); } @@ -2083,6 +2112,10 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) case USB_PORT_FEAT_C_CONNECTION: oz_trace("USB_PORT_FEAT_C_CONNECTION\n"); clear_bits = (USB_PORT_STAT_C_CONNECTION << 16); + spin_lock_bh(&port->port_lock); + port->flags |= OZ_PORT_F_CHANGED; + spin_unlock_bh(&port->port_lock); + break; case USB_PORT_FEAT_C_ENABLE: oz_trace("USB_PORT_FEAT_C_ENABLE\n"); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index bc488433856d..24db6ded553c 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -202,6 +202,7 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr) hrtimer_init(&pd->timeout, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pd->heartbeat.function = oz_pd_heartbeat_event; pd->timeout.function = oz_pd_timeout_event; + pd->reset_retry = 0; atomic_set(&pd->pd_destroy_scheduled, 0); memset(&pd->workitem, 0, sizeof(pd->workitem)); INIT_WORK(&pd->workitem, oz_pd_free); diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index f21c830db564..a19ad5712626 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -111,6 +111,7 @@ struct oz_pd { struct work_struct workitem; struct work_struct uevent_workitem; atomic_t pd_destroy_scheduled; + unsigned int reset_retry; u8 up_audio_buf; }; |