aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/asix_common.c
diff options
context:
space:
mode:
authorRobert Foss <robert.foss@collabora.com>2016-08-29 09:32:16 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-01 00:07:05 -0400
commit8a46f665833a2085e402bd0827be380f161f09ef (patch)
treed15ae39e7a98704fad123b6be04674114fc41592 /drivers/net/usb/asix_common.c
parentd9fe64e511144c1ee7d7555b4111f09dde9692ef (diff)
net: asix: Avoid looping when the device is disconnected
From: Vincent Palatin <vpalatin@chromium.org> Check the answers from the USB stack and avoid re-sending multiple times the request if the device has disappeared. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> Signed-off-by: Robert Foss <robert.foss@collabora.com> Tested-by: Robert Foss <robert.foss@collabora.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb/asix_common.c')
-rw-r--r--drivers/net/usb/asix_common.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index 25609eefc762..f79eb12c326a 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c
@@ -428,13 +428,21 @@ int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
428 __le16 res; 428 __le16 res;
429 u8 smsr; 429 u8 smsr;
430 int i = 0; 430 int i = 0;
431 int ret;
431 432
432 mutex_lock(&dev->phy_mutex); 433 mutex_lock(&dev->phy_mutex);
433 do { 434 do {
434 asix_set_sw_mii(dev, 0); 435 ret = asix_set_sw_mii(dev, 0);
436 if (ret == -ENODEV)
437 break;
435 usleep_range(1000, 1100); 438 usleep_range(1000, 1100);
436 asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 0); 439 ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG,
437 } while (!(smsr & AX_HOST_EN) && (i++ < 30)); 440 0, 0, 1, &smsr, 0);
441 } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV));
442 if (ret == -ENODEV) {
443 mutex_unlock(&dev->phy_mutex);
444 return ret;
445 }
438 446
439 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, 447 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
440 (__u16)loc, 2, &res, 0); 448 (__u16)loc, 2, &res, 0);
@@ -453,16 +461,24 @@ void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
453 __le16 res = cpu_to_le16(val); 461 __le16 res = cpu_to_le16(val);
454 u8 smsr; 462 u8 smsr;
455 int i = 0; 463 int i = 0;
464 int ret;
456 465
457 netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", 466 netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
458 phy_id, loc, val); 467 phy_id, loc, val);
459 468
460 mutex_lock(&dev->phy_mutex); 469 mutex_lock(&dev->phy_mutex);
461 do { 470 do {
462 asix_set_sw_mii(dev, 0); 471 ret = asix_set_sw_mii(dev, 0);
472 if (ret == -ENODEV)
473 break;
463 usleep_range(1000, 1100); 474 usleep_range(1000, 1100);
464 asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 0); 475 ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG,
465 } while (!(smsr & AX_HOST_EN) && (i++ < 30)); 476 0, 0, 1, &smsr, 0);
477 } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV));
478 if (ret == -ENODEV) {
479 mutex_unlock(&dev->phy_mutex);
480 return;
481 }
466 482
467 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, 483 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
468 (__u16)loc, 2, &res, 0); 484 (__u16)loc, 2, &res, 0);
@@ -476,13 +492,21 @@ int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc)
476 __le16 res; 492 __le16 res;
477 u8 smsr; 493 u8 smsr;
478 int i = 0; 494 int i = 0;
495 int ret;
479 496
480 mutex_lock(&dev->phy_mutex); 497 mutex_lock(&dev->phy_mutex);
481 do { 498 do {
482 asix_set_sw_mii(dev, 1); 499 ret = asix_set_sw_mii(dev, 1);
500 if (ret == -ENODEV)
501 break;
483 usleep_range(1000, 1100); 502 usleep_range(1000, 1100);
484 asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 1); 503 ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG,
485 } while (!(smsr & AX_HOST_EN) && (i++ < 30)); 504 0, 0, 1, &smsr, 1);
505 } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV));
506 if (ret == -ENODEV) {
507 mutex_unlock(&dev->phy_mutex);
508 return ret;
509 }
486 510
487 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, 511 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
488 (__u16)loc, 2, &res, 1); 512 (__u16)loc, 2, &res, 1);
@@ -502,16 +526,24 @@ asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val)
502 __le16 res = cpu_to_le16(val); 526 __le16 res = cpu_to_le16(val);
503 u8 smsr; 527 u8 smsr;
504 int i = 0; 528 int i = 0;
529 int ret;
505 530
506 netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", 531 netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
507 phy_id, loc, val); 532 phy_id, loc, val);
508 533
509 mutex_lock(&dev->phy_mutex); 534 mutex_lock(&dev->phy_mutex);
510 do { 535 do {
511 asix_set_sw_mii(dev, 1); 536 ret = asix_set_sw_mii(dev, 1);
537 if (ret == -ENODEV)
538 break;
512 usleep_range(1000, 1100); 539 usleep_range(1000, 1100);
513 asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 1); 540 ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG,
514 } while (!(smsr & AX_HOST_EN) && (i++ < 30)); 541 0, 0, 1, &smsr, 1);
542 } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV));
543 if (ret == -ENODEV) {
544 mutex_unlock(&dev->phy_mutex);
545 return;
546 }
515 547
516 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, 548 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
517 (__u16)loc, 2, &res, 1); 549 (__u16)loc, 2, &res, 1);