Skip to content

Commit eacdd6c

Browse files
steveglendavem330
authored andcommitted
smsc75xx: fix error handling in suspend failure case
This patch ensures that if we fail to suspend the LAN7500 device we call usbnet_resume before returning failure, instead of leaving the usbnet driver in an unusable state. Signed-off-by: Steve Glendinning <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f329ccd commit eacdd6c

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

drivers/net/usb/smsc75xx.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
13461346
int ret;
13471347

13481348
ret = usbnet_suspend(intf, message);
1349-
check_warn_return(ret, "usbnet_suspend error\n");
1349+
check_warn_goto_done(ret, "usbnet_suspend error\n");
13501350

13511351
/* determine if link is up using only _nopm functions */
13521352
link_up = smsc75xx_link_ok_nopm(dev);
@@ -1360,28 +1360,29 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
13601360

13611361
/* disable energy detect (link up) & wake up events */
13621362
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1363-
check_warn_return(ret, "Error reading WUCSR\n");
1363+
check_warn_goto_done(ret, "Error reading WUCSR\n");
13641364

13651365
val &= ~(WUCSR_MPEN | WUCSR_WUEN);
13661366

13671367
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1368-
check_warn_return(ret, "Error writing WUCSR\n");
1368+
check_warn_goto_done(ret, "Error writing WUCSR\n");
13691369

13701370
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
1371-
check_warn_return(ret, "Error reading PMT_CTL\n");
1371+
check_warn_goto_done(ret, "Error reading PMT_CTL\n");
13721372

13731373
val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN);
13741374

13751375
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
1376-
check_warn_return(ret, "Error writing PMT_CTL\n");
1376+
check_warn_goto_done(ret, "Error writing PMT_CTL\n");
13771377

1378-
return smsc75xx_enter_suspend2(dev);
1378+
ret = smsc75xx_enter_suspend2(dev);
1379+
goto done;
13791380
}
13801381

13811382
if (pdata->wolopts & WAKE_PHY) {
13821383
ret = smsc75xx_enable_phy_wakeup_interrupts(dev,
13831384
(PHY_INT_MASK_ANEG_COMP | PHY_INT_MASK_LINK_DOWN));
1384-
check_warn_return(ret, "error enabling PHY wakeup ints\n");
1385+
check_warn_goto_done(ret, "error enabling PHY wakeup ints\n");
13851386

13861387
/* if link is down then configure EDPD and enter SUSPEND1,
13871388
* otherwise enter SUSPEND0 below
@@ -1393,15 +1394,16 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
13931394
/* enable energy detect power-down mode */
13941395
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id,
13951396
PHY_MODE_CTRL_STS);
1396-
check_warn_return(ret, "Error reading PHY_MODE_CTRL_STS\n");
1397+
check_warn_goto_done(ret, "Error reading PHY_MODE_CTRL_STS\n");
13971398

13981399
ret |= MODE_CTRL_STS_EDPWRDOWN;
13991400

14001401
smsc75xx_mdio_write_nopm(dev->net, mii->phy_id,
14011402
PHY_MODE_CTRL_STS, ret);
14021403

14031404
/* enter SUSPEND1 mode */
1404-
return smsc75xx_enter_suspend1(dev);
1405+
ret = smsc75xx_enter_suspend1(dev);
1406+
goto done;
14051407
}
14061408
}
14071409

@@ -1411,7 +1413,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
14111413
/* disable all filters */
14121414
for (i = 0; i < WUF_NUM; i++) {
14131415
ret = smsc75xx_write_reg_nopm(dev, WUF_CFGX + i * 4, 0);
1414-
check_warn_return(ret, "Error writing WUF_CFGX\n");
1416+
check_warn_goto_done(ret, "Error writing WUF_CFGX\n");
14151417
}
14161418

14171419
if (pdata->wolopts & WAKE_MCAST) {
@@ -1421,7 +1423,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
14211423
val = WUF_CFGX_EN | WUF_CFGX_ATYPE_MULTICAST
14221424
| smsc_crc(mcast, 3);
14231425
ret = smsc75xx_write_wuff(dev, filter++, val, 0x0007);
1424-
check_warn_return(ret, "Error writing wakeup filter\n");
1426+
check_warn_goto_done(ret, "Error writing wakeup filter\n");
14251427
}
14261428

14271429
if (pdata->wolopts & WAKE_ARP) {
@@ -1431,106 +1433,111 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
14311433
val = WUF_CFGX_EN | WUF_CFGX_ATYPE_ALL | (0x0C << 16)
14321434
| smsc_crc(arp, 2);
14331435
ret = smsc75xx_write_wuff(dev, filter++, val, 0x0003);
1434-
check_warn_return(ret, "Error writing wakeup filter\n");
1436+
check_warn_goto_done(ret, "Error writing wakeup filter\n");
14351437
}
14361438

14371439
/* clear any pending pattern match packet status */
14381440
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1439-
check_warn_return(ret, "Error reading WUCSR\n");
1441+
check_warn_goto_done(ret, "Error reading WUCSR\n");
14401442

14411443
val |= WUCSR_WUFR;
14421444

14431445
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1444-
check_warn_return(ret, "Error writing WUCSR\n");
1446+
check_warn_goto_done(ret, "Error writing WUCSR\n");
14451447

14461448
netdev_info(dev->net, "enabling packet match detection\n");
14471449
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1448-
check_warn_return(ret, "Error reading WUCSR\n");
1450+
check_warn_goto_done(ret, "Error reading WUCSR\n");
14491451

14501452
val |= WUCSR_WUEN;
14511453

14521454
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1453-
check_warn_return(ret, "Error writing WUCSR\n");
1455+
check_warn_goto_done(ret, "Error writing WUCSR\n");
14541456
} else {
14551457
netdev_info(dev->net, "disabling packet match detection\n");
14561458
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1457-
check_warn_return(ret, "Error reading WUCSR\n");
1459+
check_warn_goto_done(ret, "Error reading WUCSR\n");
14581460

14591461
val &= ~WUCSR_WUEN;
14601462

14611463
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1462-
check_warn_return(ret, "Error writing WUCSR\n");
1464+
check_warn_goto_done(ret, "Error writing WUCSR\n");
14631465
}
14641466

14651467
/* disable magic, bcast & unicast wakeup sources */
14661468
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1467-
check_warn_return(ret, "Error reading WUCSR\n");
1469+
check_warn_goto_done(ret, "Error reading WUCSR\n");
14681470

14691471
val &= ~(WUCSR_MPEN | WUCSR_BCST_EN | WUCSR_PFDA_EN);
14701472

14711473
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1472-
check_warn_return(ret, "Error writing WUCSR\n");
1474+
check_warn_goto_done(ret, "Error writing WUCSR\n");
14731475

14741476
if (pdata->wolopts & WAKE_PHY) {
14751477
netdev_info(dev->net, "enabling PHY wakeup\n");
14761478

14771479
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
1478-
check_warn_return(ret, "Error reading PMT_CTL\n");
1480+
check_warn_goto_done(ret, "Error reading PMT_CTL\n");
14791481

14801482
/* clear wol status, enable energy detection */
14811483
val &= ~PMT_CTL_WUPS;
14821484
val |= (PMT_CTL_WUPS_ED | PMT_CTL_ED_EN);
14831485

14841486
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
1485-
check_warn_return(ret, "Error writing PMT_CTL\n");
1487+
check_warn_goto_done(ret, "Error writing PMT_CTL\n");
14861488
}
14871489

14881490
if (pdata->wolopts & WAKE_MAGIC) {
14891491
netdev_info(dev->net, "enabling magic packet wakeup\n");
14901492
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1491-
check_warn_return(ret, "Error reading WUCSR\n");
1493+
check_warn_goto_done(ret, "Error reading WUCSR\n");
14921494

14931495
/* clear any pending magic packet status */
14941496
val |= WUCSR_MPR | WUCSR_MPEN;
14951497

14961498
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1497-
check_warn_return(ret, "Error writing WUCSR\n");
1499+
check_warn_goto_done(ret, "Error writing WUCSR\n");
14981500
}
14991501

15001502
if (pdata->wolopts & WAKE_BCAST) {
15011503
netdev_info(dev->net, "enabling broadcast detection\n");
15021504
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1503-
check_warn_return(ret, "Error reading WUCSR\n");
1505+
check_warn_goto_done(ret, "Error reading WUCSR\n");
15041506

15051507
val |= WUCSR_BCAST_FR | WUCSR_BCST_EN;
15061508

15071509
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1508-
check_warn_return(ret, "Error writing WUCSR\n");
1510+
check_warn_goto_done(ret, "Error writing WUCSR\n");
15091511
}
15101512

15111513
if (pdata->wolopts & WAKE_UCAST) {
15121514
netdev_info(dev->net, "enabling unicast detection\n");
15131515
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
1514-
check_warn_return(ret, "Error reading WUCSR\n");
1516+
check_warn_goto_done(ret, "Error reading WUCSR\n");
15151517

15161518
val |= WUCSR_WUFR | WUCSR_PFDA_EN;
15171519

15181520
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
1519-
check_warn_return(ret, "Error writing WUCSR\n");
1521+
check_warn_goto_done(ret, "Error writing WUCSR\n");
15201522
}
15211523

15221524
/* enable receiver to enable frame reception */
15231525
ret = smsc75xx_read_reg_nopm(dev, MAC_RX, &val);
1524-
check_warn_return(ret, "Failed to read MAC_RX: %d\n", ret);
1526+
check_warn_goto_done(ret, "Failed to read MAC_RX: %d\n", ret);
15251527

15261528
val |= MAC_RX_RXEN;
15271529

15281530
ret = smsc75xx_write_reg_nopm(dev, MAC_RX, val);
1529-
check_warn_return(ret, "Failed to write MAC_RX: %d\n", ret);
1531+
check_warn_goto_done(ret, "Failed to write MAC_RX: %d\n", ret);
15301532

15311533
/* some wol options are enabled, so enter SUSPEND0 */
15321534
netdev_info(dev->net, "entering SUSPEND0 mode\n");
1533-
return smsc75xx_enter_suspend0(dev);
1535+
ret = smsc75xx_enter_suspend0(dev);
1536+
1537+
done:
1538+
if (ret)
1539+
usbnet_resume(intf);
1540+
return ret;
15341541
}
15351542

15361543
static int smsc75xx_resume(struct usb_interface *intf)

0 commit comments

Comments
 (0)