diff options
author | Benjamin Li <benjamin.li@qlogic.com> | 2007-02-26 14:06:35 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-27 04:21:44 -0500 |
commit | 04f10773535248466455ae80c1eedeb205c81e9a (patch) | |
tree | bb56b2f7972ec5f3a332bc636117c8ad887104d9 /drivers/net | |
parent | cd238faa32c4ee0791125526e518f87f48493292 (diff) |
qla3xxx: Fix deadlock issue on error paths
1) Fix deadlock issue when in QL_RESET_ACTIVE state and traversing
through the Link State Machine
2) Fix deadlock issue when ethtool would call ql_get_settings()
3) Fix deadlock issue when adaptor is ifup'ed but adaptor fails to initialize
Signed-off-by: Benjamin Li <benjamin.li@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rwxr-xr-x | drivers/net/qla3xxx.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 77fc77ff1505..df18aada17a7 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c | |||
@@ -1388,6 +1388,8 @@ static void ql_link_state_machine(struct ql3_adapter *qdev) | |||
1388 | printk(KERN_INFO PFX | 1388 | printk(KERN_INFO PFX |
1389 | "%s: Reset in progress, skip processing link " | 1389 | "%s: Reset in progress, skip processing link " |
1390 | "state.\n", qdev->ndev->name); | 1390 | "state.\n", qdev->ndev->name); |
1391 | |||
1392 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | ||
1391 | return; | 1393 | return; |
1392 | } | 1394 | } |
1393 | 1395 | ||
@@ -1519,8 +1521,10 @@ static int ql_get_auto_cfg_status(struct ql3_adapter *qdev) | |||
1519 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); | 1521 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); |
1520 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, | 1522 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, |
1521 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * | 1523 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * |
1522 | 2) << 7)) | 1524 | 2) << 7)) { |
1525 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | ||
1523 | return 0; | 1526 | return 0; |
1527 | } | ||
1524 | status = ql_is_auto_cfg(qdev); | 1528 | status = ql_is_auto_cfg(qdev); |
1525 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); | 1529 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); |
1526 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 1530 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
@@ -1534,8 +1538,10 @@ static u32 ql_get_speed(struct ql3_adapter *qdev) | |||
1534 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); | 1538 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); |
1535 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, | 1539 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, |
1536 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * | 1540 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * |
1537 | 2) << 7)) | 1541 | 2) << 7)) { |
1542 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | ||
1538 | return 0; | 1543 | return 0; |
1544 | } | ||
1539 | status = ql_get_link_speed(qdev); | 1545 | status = ql_get_link_speed(qdev); |
1540 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); | 1546 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); |
1541 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 1547 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
@@ -1549,8 +1555,10 @@ static int ql_get_full_dup(struct ql3_adapter *qdev) | |||
1549 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); | 1555 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); |
1550 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, | 1556 | if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, |
1551 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * | 1557 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * |
1552 | 2) << 7)) | 1558 | 2) << 7)) { |
1559 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | ||
1553 | return 0; | 1560 | return 0; |
1561 | } | ||
1554 | status = ql_is_link_full_dup(qdev); | 1562 | status = ql_is_link_full_dup(qdev); |
1555 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); | 1563 | ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); |
1556 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 1564 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
@@ -3294,6 +3302,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) | |||
3294 | err_init: | 3302 | err_init: |
3295 | ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); | 3303 | ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); |
3296 | err_lock: | 3304 | err_lock: |
3305 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | ||
3297 | free_irq(qdev->pdev->irq, ndev); | 3306 | free_irq(qdev->pdev->irq, ndev); |
3298 | err_irq: | 3307 | err_irq: |
3299 | if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { | 3308 | if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { |