linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup
@ 2009-02-21  7:53 Kalle Valo
  2009-02-21  7:53 ` [PATCH 1/4] at76c50x-usb: fix oops on disconnect Kalle Valo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Kalle Valo @ 2009-02-21  7:53 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

Hi John,

here are few fixes from Jason and a comment change from me. Please apply
to the wireless-testing tree.

---

Jason Andryuk (3):
      at76c50x-usb: additional disconnect fixes
      at76c50x-usb: clean up DMA on stack
      at76c50x-usb: fix oops on disconnect

Kalle Valo (1):
      at76c50x-usb: add link to the TODO list


 drivers/net/wireless/at76c50x-usb.c |   80 +++++++++++++++++++++++------------
 1 files changed, 52 insertions(+), 28 deletions(-)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] at76c50x-usb: fix oops on disconnect
  2009-02-21  7:53 [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup Kalle Valo
@ 2009-02-21  7:53 ` Kalle Valo
  2009-02-21  7:53 ` [PATCH 2/4] at76c50x-usb: clean up DMA on stack Kalle Valo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2009-02-21  7:53 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Jason Andryuk <jandryuk@gmail.com>

flush_workqueue needs to be called instead of the generic one and the
associated functions need to be modified to prevent re-adding
themselves to the workqueue.

The rx_tasklet is also killed in the small (?) chance it is scheduled.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Signed-off-by: Kalle Valo <kalle.valo@iki.fi>
---

 drivers/net/wireless/at76c50x-usb.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index aa06b90..c79591e 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1848,6 +1848,9 @@ static void at76_dwork_hw_scan(struct work_struct *work)
 					      dwork_hw_scan.work);
 	int ret;
 
+	if (priv->device_unplugged)
+		return;
+
 	mutex_lock(&priv->mtx);
 
 	ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
@@ -1882,6 +1885,9 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
 
 	at76_dbg(DBG_MAC80211, "%s():", __func__);
 
+	if (priv->device_unplugged)
+		return 0;
+
 	mutex_lock(&priv->mtx);
 
 	ieee80211_stop_queues(hw);
@@ -1985,6 +1991,10 @@ static void at76_configure_filter(struct ieee80211_hw *hw,
 	flags = changed_flags & AT76_SUPPORTED_FILTERS;
 	*total_flags = AT76_SUPPORTED_FILTERS;
 
+	/* Bail out after updating flags to prevent a WARN_ON in mac80211. */
+	if (priv->device_unplugged)
+		return;
+
 	/* FIXME: access to priv->promisc should be protected with
 	 * priv->mtx, but it's impossible because this function needs to be
 	 * atomic */
@@ -2085,8 +2095,7 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
 	INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
 	INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
 
-	priv->rx_tasklet.func = at76_rx_tasklet;
-	priv->rx_tasklet.data = 0;
+	tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
 
 	priv->pm_mode = AT76_PM_OFF;
 	priv->pm_period = 0;
@@ -2225,6 +2234,7 @@ static int at76_init_new_device(struct at76_priv *priv,
 	priv->scan_min_time = DEF_SCAN_MIN_TIME;
 	priv->scan_max_time = DEF_SCAN_MAX_TIME;
 	priv->scan_mode = SCAN_TYPE_ACTIVE;
+	priv->device_unplugged = 0;
 
 	/* mac80211 initialisation */
 	priv->hw->wiphy->max_scan_ssids = 1;
@@ -2266,13 +2276,12 @@ static void at76_delete_device(struct at76_priv *priv)
 	/* The device is gone, don't bother turning it off */
 	priv->device_unplugged = 1;
 
-	if (priv->mac80211_registered)
-		ieee80211_unregister_hw(priv->hw);
+	tasklet_kill(&priv->rx_tasklet);
 
-	/* assuming we used keventd, it must quiesce too */
-	flush_scheduled_work();
-
-	kfree(priv->bulk_out_buffer);
+	if (priv->mac80211_registered) {
+		flush_workqueue(priv->hw->workqueue);
+		ieee80211_unregister_hw(priv->hw);
+	}
 
 	if (priv->tx_urb) {
 		usb_kill_urb(priv->tx_urb);
@@ -2285,6 +2294,8 @@ static void at76_delete_device(struct at76_priv *priv)
 
 	at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
 
+	kfree(priv->bulk_out_buffer);
+
 	if (priv->rx_skb)
 		kfree_skb(priv->rx_skb);
 


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] at76c50x-usb: clean up DMA on stack
  2009-02-21  7:53 [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup Kalle Valo
  2009-02-21  7:53 ` [PATCH 1/4] at76c50x-usb: fix oops on disconnect Kalle Valo
@ 2009-02-21  7:53 ` Kalle Valo
  2009-02-21  7:53 ` [PATCH 3/4] at76c50x-usb: additional disconnect fixes Kalle Valo
  2009-02-21  7:53 ` [PATCH 4/4] at76c50x-usb: add link to the TODO list Kalle Valo
  3 siblings, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2009-02-21  7:53 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Jason Andryuk <jandryuk@gmail.com>

Cleanup dma on stack issues:

- no DMA on stack
- cleanup unclear endianness issue

Corrected version of Oliver Neukum's original patch for at76_usb.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Signed-off-by: Kalle Valo <kalle.valo@iki.fi>
---

 drivers/net/wireless/at76c50x-usb.c |   35 +++++++++++++++++++++++------------
 1 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index c79591e..46ac9e2 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -580,18 +580,25 @@ static int at76_remap(struct usb_device *udev)
 static int at76_get_op_mode(struct usb_device *udev)
 {
 	int ret;
-	u8 op_mode;
+	u8 saved;
+	u8 *op_mode;
 
+	op_mode = kmalloc(1, GFP_NOIO);
+	if (!op_mode)
+		return -ENOMEM;
 	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
 			      USB_TYPE_VENDOR | USB_DIR_IN |
-			      USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
+			      USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
 			      USB_CTRL_GET_TIMEOUT);
+	saved = *op_mode;
+	kfree(op_mode);
+
 	if (ret < 0)
 		return ret;
 	else if (ret < 1)
 		return -EIO;
 	else
-		return op_mode;
+		return saved;
 }
 
 /* Load a block of the second ("external") part of the firmware */
@@ -704,21 +711,25 @@ static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
 /* Return positive number for status, negative for an error */
 static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
 {
-	u8 stat_buf[40];
+	u8 *stat_buf;
 	int ret;
 
+	stat_buf = kmalloc(40, GFP_NOIO);
+	if (!stat_buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
-			      USB_TYPE_VENDOR | USB_DIR_IN |
-			      USB_RECIP_INTERFACE, cmd, 0, stat_buf,
-			      sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
-	if (ret < 0)
-		return ret;
+			USB_TYPE_VENDOR | USB_DIR_IN |
+			USB_RECIP_INTERFACE, cmd, 0, stat_buf,
+			40, USB_CTRL_GET_TIMEOUT);
+	if (ret >= 0)
+		ret = stat_buf[5];
+	kfree(stat_buf);
 
-	return stat_buf[5];
+	return ret;
 }
 
 #define MAKE_CMD_CASE(c) case (c): return #c
-
 static const char *at76_get_cmd_string(u8 cmd_status)
 {
 	switch (cmd_status) {
@@ -735,7 +746,7 @@ static const char *at76_get_cmd_string(u8 cmd_status)
 	return "UNKNOWN";
 }
 
-static int at76_set_card_command(struct usb_device *udev, int cmd, void *buf,
+static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
 				 int buf_size)
 {
 	int ret;


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] at76c50x-usb: additional disconnect fixes
  2009-02-21  7:53 [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup Kalle Valo
  2009-02-21  7:53 ` [PATCH 1/4] at76c50x-usb: fix oops on disconnect Kalle Valo
  2009-02-21  7:53 ` [PATCH 2/4] at76c50x-usb: clean up DMA on stack Kalle Valo
@ 2009-02-21  7:53 ` Kalle Valo
  2009-02-21  7:53 ` [PATCH 4/4] at76c50x-usb: add link to the TODO list Kalle Valo
  3 siblings, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2009-02-21  7:53 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Jason Andryuk <jandryuk@gmail.com>

Additional attempts to fix Oops on disconnect, that appear to be successful.
However, some may be extraneous.

The cancel_delayed_work call is probably the most necessary.  The
device_unplugged check may not be necessary.  del_timer_sync may not
be necessary either, but the Oops I was receiving was related to
timers.  Hence the addition.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Signed-off-by: Kalle Valo <kalle.valo@iki.fi>
---

 drivers/net/wireless/at76c50x-usb.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 46ac9e2..64d4192 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1497,6 +1497,9 @@ static void at76_work_set_promisc(struct work_struct *work)
 					      work_set_promisc);
 	int ret = 0;
 
+	if (priv->device_unplugged)
+		return;
+
 	mutex_lock(&priv->mtx);
 
 	priv->mib_buf.type = MIB_LOCAL;
@@ -2290,6 +2293,7 @@ static void at76_delete_device(struct at76_priv *priv)
 	tasklet_kill(&priv->rx_tasklet);
 
 	if (priv->mac80211_registered) {
+		cancel_delayed_work(&priv->dwork_hw_scan);
 		flush_workqueue(priv->hw->workqueue);
 		ieee80211_unregister_hw(priv->hw);
 	}
@@ -2307,6 +2311,8 @@ static void at76_delete_device(struct at76_priv *priv)
 
 	kfree(priv->bulk_out_buffer);
 
+	del_timer_sync(&ledtrig_tx_timer);
+
 	if (priv->rx_skb)
 		kfree_skb(priv->rx_skb);
 


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] at76c50x-usb: add link to the TODO list
  2009-02-21  7:53 [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup Kalle Valo
                   ` (2 preceding siblings ...)
  2009-02-21  7:53 ` [PATCH 3/4] at76c50x-usb: additional disconnect fixes Kalle Valo
@ 2009-02-21  7:53 ` Kalle Valo
  3 siblings, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2009-02-21  7:53 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

It's easier to have the TODO list in wiki, so add a link to the list.

Signed-off-by: Kalle Valo <kalle.valo@iki.fi>
---

 drivers/net/wireless/at76c50x-usb.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 64d4192..cc2a267 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -18,14 +18,10 @@
  *
  * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
  *
- * TODO for the mac80211 port:
- * o adhoc support
- * o RTS/CTS support
- * o Power Save Mode support
- * o support for short/long preambles
- * o export variables through debugfs/sysfs
- * o remove hex2str
- * o remove mac2str
+ * TODO list is at the wiki:
+ *
+ * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
+ *
  */
 
 #include <linux/init.h>


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-02-21  7:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-21  7:53 [PATCH 0/4] at76c50x-usb: disconnect fixes and dma cleanup Kalle Valo
2009-02-21  7:53 ` [PATCH 1/4] at76c50x-usb: fix oops on disconnect Kalle Valo
2009-02-21  7:53 ` [PATCH 2/4] at76c50x-usb: clean up DMA on stack Kalle Valo
2009-02-21  7:53 ` [PATCH 3/4] at76c50x-usb: additional disconnect fixes Kalle Valo
2009-02-21  7:53 ` [PATCH 4/4] at76c50x-usb: add link to the TODO list Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).