Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: rtl8712: Improve suspend/resume functionality.

Cancel pending URBs during suspend operation to avoid receiving ESHUTDOWN
in read/write completion callbacks while the device is suspended.

Receiving ESHUTDOWN in read/write completion callbacks will cause the
driver to enter a non-functioning "stopped" state from which the driver is
unable to recover without reloading the module.

Signed-off-by: Hemmo Nieminen <hemmo.nieminen@iki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Hemmo Nieminen and committed by
Greg Kroah-Hartman
39e9526c 549d33d2

+17 -1
+1
drivers/staging/rtl8712/drv_types.h
··· 159 159 struct mp_priv mppriv; 160 160 s32 bDriverStopped; 161 161 s32 bSurpriseRemoved; 162 + s32 bSuspended; 162 163 u32 IsrContent; 163 164 u32 ImrContent; 164 165 u8 EepromAddressSize;
+12
drivers/staging/rtl8712/usb_intf.c
··· 205 205 static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) 206 206 { 207 207 struct net_device *pnetdev = usb_get_intfdata(pusb_intf); 208 + struct _adapter *padapter = netdev_priv(pnetdev); 208 209 209 210 netdev_info(pnetdev, "Suspending...\n"); 210 211 if (!pnetdev || !netif_running(pnetdev)) { 211 212 netdev_info(pnetdev, "Unable to suspend\n"); 212 213 return 0; 213 214 } 215 + padapter->bSuspended = true; 216 + rtl871x_intf_stop(padapter); 214 217 if (pnetdev->netdev_ops->ndo_stop) 215 218 pnetdev->netdev_ops->ndo_stop(pnetdev); 216 219 mdelay(10); ··· 221 218 return 0; 222 219 } 223 220 221 + void rtl871x_intf_resume(struct _adapter *padapter) 222 + { 223 + if (padapter->dvobjpriv.inirp_init) 224 + padapter->dvobjpriv.inirp_init(padapter); 225 + } 226 + 224 227 static int r871x_resume(struct usb_interface *pusb_intf) 225 228 { 226 229 struct net_device *pnetdev = usb_get_intfdata(pusb_intf); 230 + struct _adapter *padapter = netdev_priv(pnetdev); 227 231 228 232 netdev_info(pnetdev, "Resuming...\n"); 229 233 if (!pnetdev || !netif_running(pnetdev)) { ··· 240 230 netif_device_attach(pnetdev); 241 231 if (pnetdev->netdev_ops->ndo_open) 242 232 pnetdev->netdev_ops->ndo_open(pnetdev); 233 + padapter->bSuspended = false; 234 + rtl871x_intf_resume(padapter); 243 235 return 0; 244 236 } 245 237
+4 -1
drivers/staging/rtl8712/usb_ops_linux.c
··· 228 228 } 229 229 } else { 230 230 switch (purb->status) { 231 + case -ENOENT: 232 + if (padapter->bSuspended) 233 + break; 234 + /* Fall through. */ 231 235 case -EINVAL: 232 236 case -EPIPE: 233 237 case -ENODEV: 234 238 case -ESHUTDOWN: 235 - case -ENOENT: 236 239 padapter->bDriverStopped = true; 237 240 break; 238 241 case -EPROTO: