diff options
author | David S. Miller <davem@davemloft.net> | 2014-11-21 14:53:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-21 14:53:05 -0500 |
commit | c92d418f97aa2a35591601dc0b90cfc5fa8c603c (patch) | |
tree | 7e7068970167deef51d65de96ae99c1f9f6bcee8 | |
parent | f869c912869edc2754355af9e10e5aaff8ff5a40 (diff) | |
parent | 7bcf4f605b4592452fba1e421b930909f7842310 (diff) |
Merge branch 'r8152-next'
Hayes Wang says:
====================
r8152: adjust rx functions
v3:
For patch #1, remove unnecessary initialization for ret and
unnecessary blank line in r8152_submit_rx().
v2:
For patch #1, set actual_length to 0 before adding the rx to the
list, when a error occurs.
For patch #2, change the flow. Stop submitting the rx if a error
occurs, and add the remaining rx to the list for submitting later.
v1:
Adjust some flows and codes which are relative to r8152_submit_rx()
and rtl_start_rx().
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/r8152.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0a30fd3f673d..4a9ece01def6 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -1032,7 +1032,6 @@ static void read_bulk_callback(struct urb *urb) | |||
1032 | int status = urb->status; | 1032 | int status = urb->status; |
1033 | struct rx_agg *agg; | 1033 | struct rx_agg *agg; |
1034 | struct r8152 *tp; | 1034 | struct r8152 *tp; |
1035 | int result; | ||
1036 | 1035 | ||
1037 | agg = urb->context; | 1036 | agg = urb->context; |
1038 | if (!agg) | 1037 | if (!agg) |
@@ -1083,16 +1082,7 @@ static void read_bulk_callback(struct urb *urb) | |||
1083 | break; | 1082 | break; |
1084 | } | 1083 | } |
1085 | 1084 | ||
1086 | result = r8152_submit_rx(tp, agg, GFP_ATOMIC); | 1085 | r8152_submit_rx(tp, agg, GFP_ATOMIC); |
1087 | if (result == -ENODEV) { | ||
1088 | set_bit(RTL8152_UNPLUG, &tp->flags); | ||
1089 | netif_device_detach(tp->netdev); | ||
1090 | } else if (result) { | ||
1091 | spin_lock(&tp->rx_lock); | ||
1092 | list_add_tail(&agg->list, &tp->rx_done); | ||
1093 | spin_unlock(&tp->rx_lock); | ||
1094 | tasklet_schedule(&tp->tl); | ||
1095 | } | ||
1096 | } | 1086 | } |
1097 | 1087 | ||
1098 | static void write_bulk_callback(struct urb *urb) | 1088 | static void write_bulk_callback(struct urb *urb) |
@@ -1680,7 +1670,6 @@ static void rx_bottom(struct r8152 *tp) | |||
1680 | int len_used = 0; | 1670 | int len_used = 0; |
1681 | struct urb *urb; | 1671 | struct urb *urb; |
1682 | u8 *rx_data; | 1672 | u8 *rx_data; |
1683 | int ret; | ||
1684 | 1673 | ||
1685 | list_del_init(cursor); | 1674 | list_del_init(cursor); |
1686 | 1675 | ||
@@ -1733,13 +1722,7 @@ find_next_rx: | |||
1733 | } | 1722 | } |
1734 | 1723 | ||
1735 | submit: | 1724 | submit: |
1736 | ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); | 1725 | r8152_submit_rx(tp, agg, GFP_ATOMIC); |
1737 | if (ret && ret != -ENODEV) { | ||
1738 | spin_lock_irqsave(&tp->rx_lock, flags); | ||
1739 | list_add_tail(&agg->list, &tp->rx_done); | ||
1740 | spin_unlock_irqrestore(&tp->rx_lock, flags); | ||
1741 | tasklet_schedule(&tp->tl); | ||
1742 | } | ||
1743 | } | 1726 | } |
1744 | } | 1727 | } |
1745 | 1728 | ||
@@ -1806,11 +1789,28 @@ static void bottom_half(unsigned long data) | |||
1806 | static | 1789 | static |
1807 | int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) | 1790 | int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) |
1808 | { | 1791 | { |
1792 | int ret; | ||
1793 | |||
1809 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), | 1794 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), |
1810 | agg->head, agg_buf_sz, | 1795 | agg->head, agg_buf_sz, |
1811 | (usb_complete_t)read_bulk_callback, agg); | 1796 | (usb_complete_t)read_bulk_callback, agg); |
1812 | 1797 | ||
1813 | return usb_submit_urb(agg->urb, mem_flags); | 1798 | ret = usb_submit_urb(agg->urb, mem_flags); |
1799 | if (ret == -ENODEV) { | ||
1800 | set_bit(RTL8152_UNPLUG, &tp->flags); | ||
1801 | netif_device_detach(tp->netdev); | ||
1802 | } else if (ret) { | ||
1803 | struct urb *urb = agg->urb; | ||
1804 | unsigned long flags; | ||
1805 | |||
1806 | urb->actual_length = 0; | ||
1807 | spin_lock_irqsave(&tp->rx_lock, flags); | ||
1808 | list_add_tail(&agg->list, &tp->rx_done); | ||
1809 | spin_unlock_irqrestore(&tp->rx_lock, flags); | ||
1810 | tasklet_schedule(&tp->tl); | ||
1811 | } | ||
1812 | |||
1813 | return ret; | ||
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | static void rtl_drop_queued_tx(struct r8152 *tp) | 1816 | static void rtl_drop_queued_tx(struct r8152 *tp) |
@@ -2001,6 +2001,25 @@ static int rtl_start_rx(struct r8152 *tp) | |||
2001 | break; | 2001 | break; |
2002 | } | 2002 | } |
2003 | 2003 | ||
2004 | if (ret && ++i < RTL8152_MAX_RX) { | ||
2005 | struct list_head rx_queue; | ||
2006 | unsigned long flags; | ||
2007 | |||
2008 | INIT_LIST_HEAD(&rx_queue); | ||
2009 | |||
2010 | do { | ||
2011 | struct rx_agg *agg = &tp->rx_info[i++]; | ||
2012 | struct urb *urb = agg->urb; | ||
2013 | |||
2014 | urb->actual_length = 0; | ||
2015 | list_add_tail(&agg->list, &rx_queue); | ||
2016 | } while (i < RTL8152_MAX_RX); | ||
2017 | |||
2018 | spin_lock_irqsave(&tp->rx_lock, flags); | ||
2019 | list_splice_tail(&rx_queue, &tp->rx_done); | ||
2020 | spin_unlock_irqrestore(&tp->rx_lock, flags); | ||
2021 | } | ||
2022 | |||
2004 | return ret; | 2023 | return ret; |
2005 | } | 2024 | } |
2006 | 2025 | ||