[V2][PATCH net] tipc: fix the big/little endian issue in tipc_dest

2018-08-26 Thread Haiqing Bai
In function tipc_dest_push, the 32bit variables 'node' and 'port'
are stored separately in uppper and lower part of 64bit 'value'.
Then this value is assigned to dst->value which is a union like:
union
{
  struct {
u32 port;
u32 node;
  };
  u64 value;
}
This works on little-endian machines like x86 but fails on big-endian
machines.

The fix remove the 'value' stack parameter and even the 'value'
member of the union in tipc_dest, assign the 'node' and 'port' member
directly with the input parameter to avoid the endian issue.

Fixes: a80ae5306a73 ("tipc: improve destination linked list")

Signed-off-by: Zhenbo Gao 
Acked-by: Jon Maloy 
Signed-off-by: Haiqing Bai 
---
 net/tipc/name_table.c | 10 --
 net/tipc/name_table.h |  9 ++---
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 88f027b..66d5b2c 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -980,20 +980,17 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct 
netlink_callback *cb)
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
 {
-   u64 value = (u64)node << 32 | port;
struct tipc_dest *dst;
 
list_for_each_entry(dst, l, list) {
-   if (dst->value != value)
-   continue;
-   return dst;
+   if (dst->node == node && dst->port == port)
+   return dst;
}
return NULL;
 }
 
 bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
 {
-   u64 value = (u64)node << 32 | port;
struct tipc_dest *dst;
 
if (tipc_dest_find(l, node, port))
@@ -1002,7 +999,8 @@ bool tipc_dest_push(struct list_head *l, u32 node, u32 
port)
dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
if (unlikely(!dst))
return false;
-   dst->value = value;
+   dst->node = node;
+   dst->port = port;
list_add(>list, l);
return true;
 }
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 0febba4..892bd75 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -133,13 +133,8 @@ struct publication *tipc_nametbl_remove_publ(struct net 
*net, u32 type,
 
 struct tipc_dest {
struct list_head list;
-   union {
-   struct {
-   u32 port;
-   u32 node;
-   };
-   u64 value;
-   };
+   u32 port;
+   u32 node;
 };
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port);
-- 
1.9.1



[V2][PATCH net] tipc: fix the big/little endian issue in tipc_dest

2018-08-26 Thread Haiqing Bai
In function tipc_dest_push, the 32bit variables 'node' and 'port'
are stored separately in uppper and lower part of 64bit 'value'.
Then this value is assigned to dst->value which is a union like:
union
{
  struct {
u32 port;
u32 node;
  };
  u64 value;
}
This works on little-endian machines like x86 but fails on big-endian
machines.

The fix remove the 'value' stack parameter and even the 'value'
member of the union in tipc_dest, assign the 'node' and 'port' member
directly with the input parameter to avoid the endian issue.

Fixes: a80ae5306a73 ("tipc: improve destination linked list")

Signed-off-by: Zhenbo Gao 
Acked-by: Jon Maloy 
Signed-off-by: Haiqing Bai 
---
 net/tipc/name_table.c | 10 --
 net/tipc/name_table.h |  9 ++---
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 88f027b..66d5b2c 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -980,20 +980,17 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct 
netlink_callback *cb)
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
 {
-   u64 value = (u64)node << 32 | port;
struct tipc_dest *dst;
 
list_for_each_entry(dst, l, list) {
-   if (dst->value != value)
-   continue;
-   return dst;
+   if (dst->node == node && dst->port == port)
+   return dst;
}
return NULL;
 }
 
 bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
 {
-   u64 value = (u64)node << 32 | port;
struct tipc_dest *dst;
 
if (tipc_dest_find(l, node, port))
@@ -1002,7 +999,8 @@ bool tipc_dest_push(struct list_head *l, u32 node, u32 
port)
dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
if (unlikely(!dst))
return false;
-   dst->value = value;
+   dst->node = node;
+   dst->port = port;
list_add(>list, l);
return true;
 }
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 0febba4..892bd75 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -133,13 +133,8 @@ struct publication *tipc_nametbl_remove_publ(struct net 
*net, u32 type,
 
 struct tipc_dest {
struct list_head list;
-   union {
-   struct {
-   u32 port;
-   u32 node;
-   };
-   u64 value;
-   };
+   u32 port;
+   u32 node;
 };
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port);
-- 
1.9.1



[V2][PATCH] ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and io_watchdog_func()

2018-02-01 Thread Haiqing Bai
From: Shigeru Yoshida <shigeru.yosh...@windriver.com>

Running io_watchdog_func() while ohci_urb_enqueue() is running can
cause a race condition where ohci->prev_frame_no is corrupted and the
watchdog can mis-detect following error:

  ohci-platform 664a0800.usb: frame counter not updating; disabled
  ohci-platform 664a0800.usb: HC died; cleaning up

Specifically, following scenario causes a race condition:

  1. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  2. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
  3. ohci_urb_enqueue() sets ohci->prev_frame_no to a frame number
 read by ohci_frame_no(ohci)
  4. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
  5. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section
  6. Later, ohci_urb_enqueue() is called
  7. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  8. The timer scheduled on step 4 expires and io_watchdog_func() runs
  9. io_watchdog_func() calls spin_lock_irqsave(>lock, flags)
 and waits on it because ohci_urb_enqueue() is already in the
 critical section on step 7
 10. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
 11. ohci_urb_enqueue() sets ohci->prev_frame_no to new frame number
 read by ohci_frame_no(ohci) because the frame number proceeded
 between step 3 and 6
 12. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
 13. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section, then wake up
 io_watchdog_func() which is waiting on step 9
 14. io_watchdog_func() enters the critical section
 15. io_watchdog_func() calls ohci_frame_no(ohci) and set frame_no
 variable to the frame number
 16. io_watchdog_func() compares frame_no and ohci->prev_frame_no

On step 16, because this calling of io_watchdog_func() is scheduled on
step 4, the frame number set in ohci->prev_frame_no is expected to the
number set on step 3.  However, ohci->prev_frame_no is overwritten on
step 11.  Because step 16 is executed soon after step 11, the frame
number might not proceed, so ohci->prev_frame_no must equals to
frame_no.

To address above scenario, this patch introduces a special sentinel
value IO_WATCHDOG_OFF and set this value to ohci->prev_frame_no when
the watchdog is not pending or running.  When ohci_urb_enqueue()
schedules the watchdog (step 4 and 12 above), it compares
ohci->prev_frame_no to IO_WATCHDOG_OFF so that ohci->prev_frame_no is
not overwritten while io_watchdog_func() is running.

v2: Instead of adding an extra flag variable, defining IO_WATCHDOG_OFF
as a special sentinel value for prev_frame_no.

Signed-off-by: Shigeru Yoshida <shigeru.yosh...@windriver.com>
Signed-off-by: Haiqing Bai <haiqing@windriver.com>
---
 drivers/usb/host/ohci-hcd.c | 10 +++---
 drivers/usb/host/ohci-hub.c |  4 +++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ee96763..84f88fa 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -74,6 +74,7 @@
 
 #defineSTATECHANGE_DELAY   msecs_to_jiffies(300)
 #defineIO_WATCHDOG_DELAY   msecs_to_jiffies(275)
+#defineIO_WATCHDOG_OFF 0xff00
 
 #include "ohci.h"
 #include "pci-quirks.h"
@@ -231,7 +232,7 @@ static int ohci_urb_enqueue (
}
 
/* Start up the I/O watchdog timer, if it's not running */
-   if (!timer_pending(>io_watchdog) &&
+   if (ohci->prev_frame_no == IO_WATCHDOG_OFF &&
list_empty(>eds_in_use) &&
!(ohci->flags & OHCI_QUIRK_QEMU)) {
ohci->prev_frame_no = ohci_frame_no(ohci);
@@ -501,6 +502,7 @@ static int ohci_init (struct ohci_hcd *ohci)
return 0;
 
timer_setup(>io_watchdog, io_watchdog_func, 0);
+   ohci->prev_frame_no = IO_WATCHDOG_OFF;
 
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
sizeof(*ohci->hcca), >hcca_dma, GFP_KERNEL);
@@ -730,7 +732,7 @@ static void io_watchdog_func(struct timer_list *t)
u32 head;
struct ed   *ed;
struct td   *td, *td_start, *td_next;
-   unsignedframe_no;
+   unsignedframe_no, prev_frame_no = IO_WATCHDOG_OFF;
unsigned long   flags;
 
spin_lock_irqsave(>lock, flags);
@@ -835,7 +837,7 @@ static void io_watchdog_func(struct timer_list *t)
}
}
if (!list_empty(>eds_in_use)) {
-   ohci->prev_frame_no = frame_no;
+  

[V2][PATCH] ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and io_watchdog_func()

2018-02-01 Thread Haiqing Bai
From: Shigeru Yoshida 

Running io_watchdog_func() while ohci_urb_enqueue() is running can
cause a race condition where ohci->prev_frame_no is corrupted and the
watchdog can mis-detect following error:

  ohci-platform 664a0800.usb: frame counter not updating; disabled
  ohci-platform 664a0800.usb: HC died; cleaning up

Specifically, following scenario causes a race condition:

  1. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  2. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
  3. ohci_urb_enqueue() sets ohci->prev_frame_no to a frame number
 read by ohci_frame_no(ohci)
  4. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
  5. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section
  6. Later, ohci_urb_enqueue() is called
  7. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  8. The timer scheduled on step 4 expires and io_watchdog_func() runs
  9. io_watchdog_func() calls spin_lock_irqsave(>lock, flags)
 and waits on it because ohci_urb_enqueue() is already in the
 critical section on step 7
 10. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
 11. ohci_urb_enqueue() sets ohci->prev_frame_no to new frame number
 read by ohci_frame_no(ohci) because the frame number proceeded
 between step 3 and 6
 12. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
 13. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section, then wake up
 io_watchdog_func() which is waiting on step 9
 14. io_watchdog_func() enters the critical section
 15. io_watchdog_func() calls ohci_frame_no(ohci) and set frame_no
 variable to the frame number
 16. io_watchdog_func() compares frame_no and ohci->prev_frame_no

On step 16, because this calling of io_watchdog_func() is scheduled on
step 4, the frame number set in ohci->prev_frame_no is expected to the
number set on step 3.  However, ohci->prev_frame_no is overwritten on
step 11.  Because step 16 is executed soon after step 11, the frame
number might not proceed, so ohci->prev_frame_no must equals to
frame_no.

To address above scenario, this patch introduces a special sentinel
value IO_WATCHDOG_OFF and set this value to ohci->prev_frame_no when
the watchdog is not pending or running.  When ohci_urb_enqueue()
schedules the watchdog (step 4 and 12 above), it compares
ohci->prev_frame_no to IO_WATCHDOG_OFF so that ohci->prev_frame_no is
not overwritten while io_watchdog_func() is running.

v2: Instead of adding an extra flag variable, defining IO_WATCHDOG_OFF
as a special sentinel value for prev_frame_no.

Signed-off-by: Shigeru Yoshida 
Signed-off-by: Haiqing Bai 
---
 drivers/usb/host/ohci-hcd.c | 10 +++---
 drivers/usb/host/ohci-hub.c |  4 +++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ee96763..84f88fa 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -74,6 +74,7 @@
 
 #defineSTATECHANGE_DELAY   msecs_to_jiffies(300)
 #defineIO_WATCHDOG_DELAY   msecs_to_jiffies(275)
+#defineIO_WATCHDOG_OFF 0xff00
 
 #include "ohci.h"
 #include "pci-quirks.h"
@@ -231,7 +232,7 @@ static int ohci_urb_enqueue (
}
 
/* Start up the I/O watchdog timer, if it's not running */
-   if (!timer_pending(>io_watchdog) &&
+   if (ohci->prev_frame_no == IO_WATCHDOG_OFF &&
list_empty(>eds_in_use) &&
!(ohci->flags & OHCI_QUIRK_QEMU)) {
ohci->prev_frame_no = ohci_frame_no(ohci);
@@ -501,6 +502,7 @@ static int ohci_init (struct ohci_hcd *ohci)
return 0;
 
timer_setup(>io_watchdog, io_watchdog_func, 0);
+   ohci->prev_frame_no = IO_WATCHDOG_OFF;
 
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
sizeof(*ohci->hcca), >hcca_dma, GFP_KERNEL);
@@ -730,7 +732,7 @@ static void io_watchdog_func(struct timer_list *t)
u32 head;
struct ed   *ed;
struct td   *td, *td_start, *td_next;
-   unsignedframe_no;
+   unsignedframe_no, prev_frame_no = IO_WATCHDOG_OFF;
unsigned long   flags;
 
spin_lock_irqsave(>lock, flags);
@@ -835,7 +837,7 @@ static void io_watchdog_func(struct timer_list *t)
}
}
if (!list_empty(>eds_in_use)) {
-   ohci->prev_frame_no = frame_no;
+   prev_frame_no = frame_no;
ohci->prev_wdh_cnt = ohci->

[PATCH] ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and io_watchdog_func()

2018-01-31 Thread Haiqing Bai
Running io_watchdog_func() while ohci_urb_enqueue() is running can
cause a race condition where ohci->prev_frame_no is corrupted and the
watchdog can mis-detect following error:

  ohci-platform 664a0800.usb: frame counter not updating; disabled
  ohci-platform 664a0800.usb: HC died; cleaning up

Specifically, following scenario causes a race condition:

  1. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  2. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
  3. ohci_urb_enqueue() sets ohci->prev_frame_no to a frame number
 read by ohci_frame_no(ohci)
  4. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
  5. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section
  6. Later, ohci_urb_enqueue() is called
  7. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  8. The timer scheduled on step 4 expires and io_watchdog_func() runs
  9. io_watchdog_func() calls spin_lock_irqsave(>lock, flags)
 and waits on it because ohci_urb_enqueue() is already in the
 critical section on step 7
 10. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
 11. ohci_urb_enqueue() sets ohci->prev_frame_no to new frame number
 read by ohci_frame_no(ohci) because the frame number proceeded
 between step 3 and 6
 12. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
 13. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section, then wake up
 io_watchdog_func() which is waiting on step 9
 14. io_watchdog_func() enters the critical section
 15. io_watchdog_func() calls ohci_frame_no(ohci) and set frame_no
 variable to the frame number
 16. io_watchdog_func() compares frame_no and ohci->prev_frame_no

On step 16, because this calling of io_watchdog_func() is scheduled on
step 4, the frame number set in ohci->prev_frame_no is expected to the
number set on step 3.  However, ohci->prev_frame_no is overwritten on
step 11.  Because step 16 is executed soon after step 11, the frame
number might not proceed, so ohci->prev_frame_no must equals to
frame_no.

To address above scenario, this patch introduces timer_running flag to
ohci_hcd structure.  Setting true to ohci->timer_running indicates
io_watchdog_func() is scheduled or is running.  ohci_urb_enqueue()
checks the flag when it schedules the watchdog (step 4 and 12 above),
so ohci->prev_frame_no is not overwritten while io_watchdog_func() is
running.

Author: Yoshida, Shigeru <shigeru.yosh...@windriver.com>
Signed-off-by: Haiqing Bai <haiqing@windriver.com>
---
 drivers/usb/host/ohci-hcd.c | 7 +++
 drivers/usb/host/ohci-hub.c | 4 +++-
 drivers/usb/host/ohci.h | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ee9676349333..2c7fa0c05854 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -233,10 +233,12 @@ static int ohci_urb_enqueue (
/* Start up the I/O watchdog timer, if it's not running */
if (!timer_pending(>io_watchdog) &&
list_empty(>eds_in_use) &&
+   !ohci->timer_running &&
!(ohci->flags & OHCI_QUIRK_QEMU)) {
ohci->prev_frame_no = ohci_frame_no(ohci);
mod_timer(>io_watchdog,
jiffies + IO_WATCHDOG_DELAY);
+   ohci->timer_running = 1;
}
list_add(>in_use_list, >eds_in_use);
 
@@ -501,6 +503,7 @@ static int ohci_init (struct ohci_hcd *ohci)
return 0;
 
timer_setup(>io_watchdog, io_watchdog_func, 0);
+   ohci->timer_running = 0;
 
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
sizeof(*ohci->hcca), >hcca_dma, GFP_KERNEL);
@@ -732,6 +735,7 @@ static void io_watchdog_func(struct timer_list *t)
struct td   *td, *td_start, *td_next;
unsignedframe_no;
unsigned long   flags;
+   int timer_running = 0;
 
spin_lock_irqsave(>lock, flags);
 
@@ -841,10 +845,12 @@ static void io_watchdog_func(struct timer_list *t)
>regs->donehead);
mod_timer(>io_watchdog,
jiffies + IO_WATCHDOG_DELAY);
+   timer_running = 1;
}
}
 
  done:
+   ohci->timer_running = timer_running;
spin_unlock_irqrestore(>lock, flags);
 }
 
@@ -973,6 +979,7 @@ static void ohci_stop (struct usb_hcd *hcd)
if (quirk_nec(ohci))

[PATCH] ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and io_watchdog_func()

2018-01-31 Thread Haiqing Bai
Running io_watchdog_func() while ohci_urb_enqueue() is running can
cause a race condition where ohci->prev_frame_no is corrupted and the
watchdog can mis-detect following error:

  ohci-platform 664a0800.usb: frame counter not updating; disabled
  ohci-platform 664a0800.usb: HC died; cleaning up

Specifically, following scenario causes a race condition:

  1. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  2. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
  3. ohci_urb_enqueue() sets ohci->prev_frame_no to a frame number
 read by ohci_frame_no(ohci)
  4. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
  5. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section
  6. Later, ohci_urb_enqueue() is called
  7. ohci_urb_enqueue() calls spin_lock_irqsave(>lock, flags)
 and enters the critical section
  8. The timer scheduled on step 4 expires and io_watchdog_func() runs
  9. io_watchdog_func() calls spin_lock_irqsave(>lock, flags)
 and waits on it because ohci_urb_enqueue() is already in the
 critical section on step 7
 10. ohci_urb_enqueue() calls timer_pending(>io_watchdog) and it
 returns false
 11. ohci_urb_enqueue() sets ohci->prev_frame_no to new frame number
 read by ohci_frame_no(ohci) because the frame number proceeded
 between step 3 and 6
 12. ohci_urb_enqueue() schedules io_watchdog_func() with mod_timer()
 13. ohci_urb_enqueue() calls spin_unlock_irqrestore(>lock,
 flags) and exits the critical section, then wake up
 io_watchdog_func() which is waiting on step 9
 14. io_watchdog_func() enters the critical section
 15. io_watchdog_func() calls ohci_frame_no(ohci) and set frame_no
 variable to the frame number
 16. io_watchdog_func() compares frame_no and ohci->prev_frame_no

On step 16, because this calling of io_watchdog_func() is scheduled on
step 4, the frame number set in ohci->prev_frame_no is expected to the
number set on step 3.  However, ohci->prev_frame_no is overwritten on
step 11.  Because step 16 is executed soon after step 11, the frame
number might not proceed, so ohci->prev_frame_no must equals to
frame_no.

To address above scenario, this patch introduces timer_running flag to
ohci_hcd structure.  Setting true to ohci->timer_running indicates
io_watchdog_func() is scheduled or is running.  ohci_urb_enqueue()
checks the flag when it schedules the watchdog (step 4 and 12 above),
so ohci->prev_frame_no is not overwritten while io_watchdog_func() is
running.

Author: Yoshida, Shigeru 
Signed-off-by: Haiqing Bai 
---
 drivers/usb/host/ohci-hcd.c | 7 +++
 drivers/usb/host/ohci-hub.c | 4 +++-
 drivers/usb/host/ohci.h | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ee9676349333..2c7fa0c05854 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -233,10 +233,12 @@ static int ohci_urb_enqueue (
/* Start up the I/O watchdog timer, if it's not running */
if (!timer_pending(>io_watchdog) &&
list_empty(>eds_in_use) &&
+   !ohci->timer_running &&
!(ohci->flags & OHCI_QUIRK_QEMU)) {
ohci->prev_frame_no = ohci_frame_no(ohci);
mod_timer(>io_watchdog,
jiffies + IO_WATCHDOG_DELAY);
+   ohci->timer_running = 1;
}
list_add(>in_use_list, >eds_in_use);
 
@@ -501,6 +503,7 @@ static int ohci_init (struct ohci_hcd *ohci)
return 0;
 
timer_setup(>io_watchdog, io_watchdog_func, 0);
+   ohci->timer_running = 0;
 
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
sizeof(*ohci->hcca), >hcca_dma, GFP_KERNEL);
@@ -732,6 +735,7 @@ static void io_watchdog_func(struct timer_list *t)
struct td   *td, *td_start, *td_next;
unsignedframe_no;
unsigned long   flags;
+   int timer_running = 0;
 
spin_lock_irqsave(>lock, flags);
 
@@ -841,10 +845,12 @@ static void io_watchdog_func(struct timer_list *t)
>regs->donehead);
mod_timer(>io_watchdog,
jiffies + IO_WATCHDOG_DELAY);
+   timer_running = 1;
}
}
 
  done:
+   ohci->timer_running = timer_running;
spin_unlock_irqrestore(>lock, flags);
 }
 
@@ -973,6 +979,7 @@ static void ohci_stop (struct usb_hcd *hcd)
if (quirk_nec(ohci))
flush_work(>nec_work);
del_timer_sync(>io_watc