.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
---|
3 | 4 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
---|
4 | 5 | <http://rt2x00.serialmonkey.com> |
---|
5 | 6 | |
---|
6 | | - This program is free software; you can redistribute it and/or modify |
---|
7 | | - it under the terms of the GNU General Public License as published by |
---|
8 | | - the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - (at your option) any later version. |
---|
10 | | - |
---|
11 | | - This program is distributed in the hope that it will be useful, |
---|
12 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - GNU General Public License for more details. |
---|
15 | | - |
---|
16 | | - You should have received a copy of the GNU General Public License |
---|
17 | | - along with this program; if not, see <http://www.gnu.org/licenses/>. |
---|
18 | 7 | */ |
---|
19 | 8 | |
---|
20 | 9 | /* |
---|
.. | .. |
---|
30 | 19 | |
---|
31 | 20 | #include "rt2x00.h" |
---|
32 | 21 | #include "rt2x00usb.h" |
---|
| 22 | + |
---|
| 23 | +static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status) |
---|
| 24 | +{ |
---|
| 25 | + if (status == -ENODEV || status == -ENOENT) |
---|
| 26 | + return true; |
---|
| 27 | + |
---|
| 28 | + if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) |
---|
| 29 | + return false; |
---|
| 30 | + |
---|
| 31 | + if (status == -EPROTO || status == -ETIMEDOUT) |
---|
| 32 | + rt2x00dev->num_proto_errs++; |
---|
| 33 | + else |
---|
| 34 | + rt2x00dev->num_proto_errs = 0; |
---|
| 35 | + |
---|
| 36 | + if (rt2x00dev->num_proto_errs > 3) |
---|
| 37 | + return true; |
---|
| 38 | + |
---|
| 39 | + return false; |
---|
| 40 | +} |
---|
33 | 41 | |
---|
34 | 42 | /* |
---|
35 | 43 | * Interfacing with the HW. |
---|
.. | .. |
---|
57 | 65 | if (status >= 0) |
---|
58 | 66 | return 0; |
---|
59 | 67 | |
---|
60 | | - if (status == -ENODEV || status == -ENOENT) { |
---|
| 68 | + if (rt2x00usb_check_usb_error(rt2x00dev, status)) { |
---|
61 | 69 | /* Device has disappeared. */ |
---|
62 | 70 | clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
---|
63 | 71 | break; |
---|
.. | .. |
---|
321 | 329 | |
---|
322 | 330 | status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); |
---|
323 | 331 | if (status) { |
---|
324 | | - if (status == -ENODEV || status == -ENOENT) |
---|
| 332 | + if (rt2x00usb_check_usb_error(rt2x00dev, status)) |
---|
325 | 333 | clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
---|
326 | 334 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
---|
327 | 335 | rt2x00lib_dmadone(entry); |
---|
.. | .. |
---|
344 | 352 | while (!rt2x00queue_empty(rt2x00dev->rx)) { |
---|
345 | 353 | entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); |
---|
346 | 354 | |
---|
347 | | - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
---|
348 | | - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
---|
| 355 | + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
---|
349 | 356 | break; |
---|
350 | 357 | |
---|
351 | 358 | /* |
---|
.. | .. |
---|
367 | 374 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
---|
368 | 375 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
---|
369 | 376 | |
---|
370 | | - if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
---|
| 377 | + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
---|
371 | 378 | return; |
---|
372 | | - |
---|
373 | | - /* |
---|
374 | | - * Report the frame as DMA done |
---|
375 | | - */ |
---|
376 | | - rt2x00lib_dmadone(entry); |
---|
377 | 379 | |
---|
378 | 380 | /* |
---|
379 | 381 | * Check if the received data is simply too small |
---|
.. | .. |
---|
384 | 386 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
---|
385 | 387 | |
---|
386 | 388 | /* |
---|
387 | | - * Schedule the delayed work for reading the RX status |
---|
388 | | - * from the device. |
---|
| 389 | + * Report the frame as DMA done |
---|
| 390 | + */ |
---|
| 391 | + rt2x00lib_dmadone(entry); |
---|
| 392 | + |
---|
| 393 | + /* |
---|
| 394 | + * Schedule the delayed work for processing RX data |
---|
389 | 395 | */ |
---|
390 | 396 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); |
---|
391 | 397 | } |
---|
.. | .. |
---|
397 | 403 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
---|
398 | 404 | int status; |
---|
399 | 405 | |
---|
400 | | - if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
---|
401 | | - test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
---|
| 406 | + if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
---|
402 | 407 | return false; |
---|
403 | 408 | |
---|
404 | 409 | rt2x00lib_dmastart(entry); |
---|
.. | .. |
---|
410 | 415 | |
---|
411 | 416 | status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); |
---|
412 | 417 | if (status) { |
---|
413 | | - if (status == -ENODEV || status == -ENOENT) |
---|
| 418 | + if (rt2x00usb_check_usb_error(rt2x00dev, status)) |
---|
414 | 419 | clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
---|
415 | 420 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
---|
416 | 421 | rt2x00lib_dmadone(entry); |
---|
.. | .. |
---|
520 | 525 | |
---|
521 | 526 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) |
---|
522 | 527 | { |
---|
523 | | - rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", |
---|
| 528 | + rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced reset\n", |
---|
524 | 529 | queue->qid); |
---|
525 | 530 | |
---|
526 | 531 | rt2x00queue_stop_queue(queue); |
---|
.. | .. |
---|
884 | 889 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); |
---|
885 | 890 | struct rt2x00_dev *rt2x00dev = hw->priv; |
---|
886 | 891 | |
---|
887 | | - return rt2x00lib_suspend(rt2x00dev, state); |
---|
| 892 | + return rt2x00lib_suspend(rt2x00dev); |
---|
888 | 893 | } |
---|
889 | 894 | EXPORT_SYMBOL_GPL(rt2x00usb_suspend); |
---|
890 | 895 | |
---|