diff options
author | Robert Foss <robert.foss@collabora.com> | 2016-08-29 09:32:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-01 00:07:05 -0400 |
commit | 8a46f665833a2085e402bd0827be380f161f09ef (patch) | |
tree | d15ae39e7a98704fad123b6be04674114fc41592 /drivers/net/usb/asix_common.c | |
parent | d9fe64e511144c1ee7d7555b4111f09dde9692ef (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.c | 56 |
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); |