+++ /dev/null
-From jejb@kernel.org Thu Oct 23 20:53:38 2008
-From: Bob Copeland <me@bobcopeland.com>
-Date: Fri, 24 Oct 2008 02:50:07 GMT
-Subject: ath5k: fix suspend-related oops on rmmod
-To: jejb@kernel.org, stable@kernel.org
-Message-ID: <200810240250.m9O2o7pk015148@hera.kernel.org>
-
-From: Bob Copeland <me@bobcopeland.com>
-
-commit 8bdd5b9c6bd53add260756b6673a0545fbdbba21 upstream
-
-Based on a patch by Elias Oltmanns, we call ath5k_init in resume even
-if we didn't previously open the device. Besides starting up the
-device unnecessarily, this also causes an oops on rmmod because
-mac80211 will not invoke ath5k_stop and softirqs are left running after
-the module has been unloaded. Add a new state bit, ATH_STAT_STARTED,
-to indicate that we have been started up.
-
-Reported-by: Toralf Förster <toralf.foerster@gmx.de>
-Signed-off-by: Elias Oltmanns <eo@nebensachen.de>
-Signed-off-by: Bob Copeland <me@bobcopeland.com>
-Signed-off-by: John W. Linville <linville@tuxdriver.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/net/wireless/ath5k/base.c | 28 ++++++++++++++++++++--------
- drivers/net/wireless/ath5k/base.h | 3 ++-
- 2 files changed, 22 insertions(+), 9 deletions(-)
-
---- a/drivers/net/wireless/ath5k/base.c
-+++ b/drivers/net/wireless/ath5k/base.c
-@@ -294,9 +294,9 @@ static inline u64 ath5k_extend_tsf(struc
- }
-
- /* Interrupt handling */
--static int ath5k_init(struct ath5k_softc *sc);
-+static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
- static int ath5k_stop_locked(struct ath5k_softc *sc);
--static int ath5k_stop_hw(struct ath5k_softc *sc);
-+static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
- static irqreturn_t ath5k_intr(int irq, void *dev_id);
- static void ath5k_tasklet_reset(unsigned long data);
-
-@@ -584,7 +584,7 @@ ath5k_pci_suspend(struct pci_dev *pdev,
-
- ath5k_led_off(sc);
-
-- ath5k_stop_hw(sc);
-+ ath5k_stop_hw(sc, true);
-
- free_irq(pdev->irq, sc);
- pci_save_state(pdev);
-@@ -621,7 +621,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
- goto err_no_irq;
- }
-
-- err = ath5k_init(sc);
-+ err = ath5k_init(sc, true);
- if (err)
- goto err_irq;
- ath5k_led_enable(sc);
-@@ -2197,12 +2197,17 @@ ath5k_beacon_config(struct ath5k_softc *
- \********************/
-
- static int
--ath5k_init(struct ath5k_softc *sc)
-+ath5k_init(struct ath5k_softc *sc, bool is_resume)
- {
- int ret;
-
- mutex_lock(&sc->lock);
-
-+ if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
-+ goto out_ok;
-+
-+ __clear_bit(ATH_STAT_STARTED, sc->status);
-+
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
-
- /*
-@@ -2250,12 +2255,16 @@ ath5k_init(struct ath5k_softc *sc)
- AR5K_INT_MIB;
-
- ath5k_hw_set_intr(sc->ah, sc->imask);
-+
-+ __set_bit(ATH_STAT_STARTED, sc->status);
-+
- /* Set ack to be sent at low bit-rates */
- ath5k_hw_set_ack_bitrate_high(sc->ah, false);
-
- mod_timer(&sc->calib_tim, round_jiffies(jiffies +
- msecs_to_jiffies(ath5k_calinterval * 1000)));
-
-+out_ok:
- ret = 0;
- done:
- mmiowb();
-@@ -2310,7 +2319,7 @@ ath5k_stop_locked(struct ath5k_softc *sc
- * stop is preempted).
- */
- static int
--ath5k_stop_hw(struct ath5k_softc *sc)
-+ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
- {
- int ret;
-
-@@ -2341,6 +2350,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
- }
- }
- ath5k_txbuf_free(sc, sc->bbuf);
-+ if (!is_suspend)
-+ __clear_bit(ATH_STAT_STARTED, sc->status);
-+
- mmiowb();
- mutex_unlock(&sc->lock);
-
-@@ -2719,12 +2731,12 @@ err:
-
- static int ath5k_start(struct ieee80211_hw *hw)
- {
-- return ath5k_init(hw->priv);
-+ return ath5k_init(hw->priv, false);
- }
-
- static void ath5k_stop(struct ieee80211_hw *hw)
- {
-- ath5k_stop_hw(hw->priv);
-+ ath5k_stop_hw(hw->priv, false);
- }
-
- static int ath5k_add_interface(struct ieee80211_hw *hw,
---- a/drivers/net/wireless/ath5k/base.h
-+++ b/drivers/net/wireless/ath5k/base.h
-@@ -132,11 +132,12 @@ struct ath5k_softc {
- size_t desc_len; /* size of TX/RX descriptors */
- u16 cachelsz; /* cache line size */
-
-- DECLARE_BITMAP(status, 4);
-+ DECLARE_BITMAP(status, 5);
- #define ATH_STAT_INVALID 0 /* disable hardware accesses */
- #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
- #define ATH_STAT_PROMISC 2
- #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
-+#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
-
- unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
- unsigned int curmode; /* current phy mode */
--- /dev/null
+From c82732a42896364296599b0f73f01c5e3fd781ae Mon Sep 17 00:00:00 2001
+From: Mike Isely <isely@pobox.com>
+Date: Sun, 19 Oct 2008 16:26:05 -0300
+Subject: [PATCH] V4L/DVB (9300): pvrusb2: Fix deadlock problem
+
+From: Mike Isely <isely@pobox.com>
+
+commit c82732a42896364296599b0f73f01c5e3fd781ae upstream
+
+Fix deadlock problem in 2.6.27 caused by new USB core behavior in
+response to a USB device reset request. With older kernels, the USB
+device reset was "in line"; the reset simply took place and the driver
+retained its association with the hardware. However now this reset
+triggers a disconnect, and worse still the disconnect callback happens
+in the context of the caller who asked for the device reset. This
+results in an attempt by the pvrusb2 driver to recursively take a
+mutex it already has, which deadlocks the driver's worker thread.
+(Even if the disconnect callback were to happen on a different thread
+we'd still have problems however - because while the driver should
+survive and correctly disconnect / reconnect, it will then trigger
+another device reset during the repeated initialization, which will
+then cause another disconect, etc, forever.) The fix here is simply
+to not attempt the device reset (it was of marginal value anyway).
+
+Signed-off-by: Mike Isely <isely@pobox.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+@@ -60,7 +60,6 @@ static struct pvr2_hdw *unit_pointers[PV
+ static DEFINE_MUTEX(pvr2_unit_mtx);
+
+ static int ctlchg;
+-static int initusbreset = 1;
+ static int procreload;
+ static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
+ static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
+@@ -71,8 +70,6 @@ module_param(ctlchg, int, S_IRUGO|S_IWUS
+ MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
+ module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
+-module_param(initusbreset, int, S_IRUGO|S_IWUSR);
+-MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
+ module_param(procreload, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(procreload,
+ "Attempt init failure recovery with firmware reload");
+@@ -1698,9 +1695,6 @@ static void pvr2_hdw_setup_low(struct pv
+ }
+ hdw->fw1_state = FW1_STATE_OK;
+
+- if (initusbreset) {
+- pvr2_hdw_device_reset(hdw);
+- }
+ if (!pvr2_hdw_dev_ok(hdw)) return;
+
+ for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {