Commit 39e9526c authored by Hemmo Nieminen's avatar Hemmo Nieminen Committed by Greg Kroah-Hartman
Browse files

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: default avatarHemmo Nieminen <hemmo.nieminen@iki.fi>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 549d33d2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ struct _adapter {
	struct mp_priv  mppriv;
	s32	bDriverStopped;
	s32	bSurpriseRemoved;
	s32	bSuspended;
	u32	IsrContent;
	u32	ImrContent;
	u8	EepromAddressSize;
+12 −0
Original line number Diff line number Diff line
@@ -205,12 +205,15 @@ struct drv_priv {
static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state)
{
	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
	struct _adapter *padapter = netdev_priv(pnetdev);

	netdev_info(pnetdev, "Suspending...\n");
	if (!pnetdev || !netif_running(pnetdev)) {
		netdev_info(pnetdev, "Unable to suspend\n");
		return 0;
	}
	padapter->bSuspended = true;
	rtl871x_intf_stop(padapter);
	if (pnetdev->netdev_ops->ndo_stop)
		pnetdev->netdev_ops->ndo_stop(pnetdev);
	mdelay(10);
@@ -218,9 +221,16 @@ static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state)
	return 0;
}

void rtl871x_intf_resume(struct _adapter *padapter)
{
	if (padapter->dvobjpriv.inirp_init)
		padapter->dvobjpriv.inirp_init(padapter);
}

static int r871x_resume(struct usb_interface *pusb_intf)
{
	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
	struct _adapter *padapter = netdev_priv(pnetdev);

	netdev_info(pnetdev,  "Resuming...\n");
	if (!pnetdev || !netif_running(pnetdev)) {
@@ -230,6 +240,8 @@ static int r871x_resume(struct usb_interface *pusb_intf)
	netif_device_attach(pnetdev);
	if (pnetdev->netdev_ops->ndo_open)
		pnetdev->netdev_ops->ndo_open(pnetdev);
	padapter->bSuspended = false;
	rtl871x_intf_resume(padapter);
	return 0;
}

+4 −1
Original line number Diff line number Diff line
@@ -228,11 +228,14 @@ static void r8712_usb_read_port_complete(struct urb *purb)
		}
	} else {
		switch (purb->status) {
		case -ENOENT:
			if (padapter->bSuspended)
				break;
			/* Fall through. */
		case -EINVAL:
		case -EPIPE:
		case -ENODEV:
		case -ESHUTDOWN:
		case -ENOENT:
			padapter->bDriverStopped = true;
			break;
		case -EPROTO: