mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-17 15:14:35 +08:00
carl9170: fix sleep in softirq context
This patch fixes the following bug: usb 1-1.1: restart device (8) BUG: sleeping function called from invalid context at drivers/usb/core/urb.c:654 in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper (usb_poison_urb+0x1c/0xf8) (usb_poison_anchored_urbs+0x48/0x78) (carl9170_usb_handle_tx_err+0x128/0x150) (carl9170_usb_reset+0xc/0x20) (carl9170_handle_command_response+0x298/0xea8) (carl9170_usb_tasklet+0x68/0x184) (tasklet_hi_action+0x84/0xdc) this only happens if the device is plugged in an USB port, the driver is loaded but inactive (e.g. the wlan interface is down). If the device is active everything is fine. Signed-off-by: Ronald Wahl <ronald.wahl@raritan.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
9c371f9973
commit
5bcbc3fcbd
@ -303,6 +303,7 @@ struct ar9170 {
|
||||
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
|
||||
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
|
||||
bool needs_full_reset;
|
||||
bool force_usb_reset;
|
||||
atomic_t pending_restarts;
|
||||
|
||||
/* interface mode settings */
|
||||
|
@ -465,27 +465,26 @@ static void carl9170_restart_work(struct work_struct *work)
|
||||
{
|
||||
struct ar9170 *ar = container_of(work, struct ar9170,
|
||||
restart_work);
|
||||
int err;
|
||||
int err = -EIO;
|
||||
|
||||
ar->usedkeys = 0;
|
||||
ar->filter_state = 0;
|
||||
carl9170_cancel_worker(ar);
|
||||
|
||||
mutex_lock(&ar->mutex);
|
||||
err = carl9170_usb_restart(ar);
|
||||
if (net_ratelimit()) {
|
||||
if (err) {
|
||||
dev_err(&ar->udev->dev, "Failed to restart device "
|
||||
" (%d).\n", err);
|
||||
} else {
|
||||
dev_info(&ar->udev->dev, "device restarted "
|
||||
"successfully.\n");
|
||||
if (!ar->force_usb_reset) {
|
||||
err = carl9170_usb_restart(ar);
|
||||
if (net_ratelimit()) {
|
||||
if (err)
|
||||
dev_err(&ar->udev->dev, "Failed to restart device (%d).\n", err);
|
||||
else
|
||||
dev_info(&ar->udev->dev, "device restarted successfully.\n");
|
||||
}
|
||||
}
|
||||
|
||||
carl9170_zap_queues(ar);
|
||||
mutex_unlock(&ar->mutex);
|
||||
if (!err) {
|
||||
|
||||
if (!err && !ar->force_usb_reset) {
|
||||
ar->restart_counter++;
|
||||
atomic_set(&ar->pending_restarts, 0);
|
||||
|
||||
@ -526,10 +525,10 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
|
||||
if (!ar->registered)
|
||||
return;
|
||||
|
||||
if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset)
|
||||
ieee80211_queue_work(ar->hw, &ar->restart_work);
|
||||
else
|
||||
carl9170_usb_reset(ar);
|
||||
if (!IS_ACCEPTING_CMD(ar) || ar->needs_full_reset)
|
||||
ar->force_usb_reset = true;
|
||||
|
||||
ieee80211_queue_work(ar->hw, &ar->restart_work);
|
||||
|
||||
/*
|
||||
* At this point, the device instance might have vanished/disabled.
|
||||
|
Loading…
Reference in New Issue
Block a user