diff options
author | Hayes Wang <hayeswang@realtek.com> | 2019-07-04 17:36:32 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-05 15:37:32 -0700 |
commit | ffa9fec30ca0ceb7d5156a1649b9576058756616 (patch) | |
tree | 8a01ea019bc940af3333576bf04f529433ae29d3 /drivers/net/usb/r8152.c | |
parent | fa8043017cf83427c7e3d7d8defe2c2133edffea (diff) | |
download | linux-ffa9fec30ca0ceb7d5156a1649b9576058756616.tar.gz linux-ffa9fec30ca0ceb7d5156a1649b9576058756616.tar.bz2 linux-ffa9fec30ca0ceb7d5156a1649b9576058756616.zip |
r8152: set RTL8152_UNPLUG only for real disconnection
Set the flag of RTL8152_UNPLUG if and only if the device is unplugged.
Some error codes sometimes don't mean the real disconnection of usb device.
For those situations, set the flag of RTL8152_UNPLUG causes the driver skips
some flows of disabling the device, and it let the device stay at incorrect
state.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb/r8152.c')
-rw-r--r-- | drivers/net/usb/r8152.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e887ac86fbef..39e0768d734d 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -28,7 +28,7 @@ #define NETNEXT_VERSION "09" /* Information for net */ -#define NET_VERSION "9" +#define NET_VERSION "10" #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" @@ -825,6 +825,14 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) return ret; } +static void rtl_set_unplug(struct r8152 *tp) +{ + if (tp->udev->state == USB_STATE_NOTATTACHED) { + set_bit(RTL8152_UNPLUG, &tp->flags); + smp_mb__after_atomic(); + } +} + static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data, u16 type) { @@ -863,7 +871,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, } if (ret == -ENODEV) - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); return ret; } @@ -933,7 +941,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, error1: if (ret == -ENODEV) - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); return ret; } @@ -1321,7 +1329,7 @@ static void read_bulk_callback(struct urb *urb) napi_schedule(&tp->napi); return; case -ESHUTDOWN: - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); netif_device_detach(tp->netdev); return; case -ENOENT: @@ -1441,7 +1449,7 @@ static void intr_callback(struct urb *urb) resubmit: res = usb_submit_urb(urb, GFP_ATOMIC); if (res == -ENODEV) { - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); netif_device_detach(tp->netdev); } else if (res) { netif_err(tp, intr, tp->netdev, @@ -2036,7 +2044,7 @@ static void tx_bottom(struct r8152 *tp) struct net_device *netdev = tp->netdev; if (res == -ENODEV) { - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); netif_device_detach(netdev); } else { struct net_device_stats *stats = &netdev->stats; @@ -2110,7 +2118,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) ret = usb_submit_urb(agg->urb, mem_flags); if (ret == -ENODEV) { - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); netif_device_detach(tp->netdev); } else if (ret) { struct urb *urb = agg->urb; @@ -5355,10 +5363,7 @@ static void rtl8152_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (tp) { - struct usb_device *udev = tp->udev; - - if (udev->state == USB_STATE_NOTATTACHED) - set_bit(RTL8152_UNPLUG, &tp->flags); + rtl_set_unplug(tp); netif_napi_del(&tp->napi); unregister_netdev(tp->netdev); |