Commit 04f10773 authored by Benjamin Li's avatar Benjamin Li Committed by Jeff Garzik

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: default avatarBenjamin Li <benjamin.li@qlogic.com>
Signed-off-by: default avatarRon Mercer <ron.mercer@qlogic.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent cd238faa
...@@ -1388,6 +1388,8 @@ static void ql_link_state_machine(struct ql3_adapter *qdev) ...@@ -1388,6 +1388,8 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
printk(KERN_INFO PFX printk(KERN_INFO PFX
"%s: Reset in progress, skip processing link " "%s: Reset in progress, skip processing link "
"state.\n", qdev->ndev->name); "state.\n", qdev->ndev->name);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return; return;
} }
...@@ -1519,8 +1521,10 @@ static int ql_get_auto_cfg_status(struct ql3_adapter *qdev) ...@@ -1519,8 +1521,10 @@ static int ql_get_auto_cfg_status(struct ql3_adapter *qdev)
spin_lock_irqsave(&qdev->hw_lock, hw_flags); spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
2) << 7)) 2) << 7)) {
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return 0; return 0;
}
status = ql_is_auto_cfg(qdev); status = ql_is_auto_cfg(qdev);
ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
...@@ -1534,8 +1538,10 @@ static u32 ql_get_speed(struct ql3_adapter *qdev) ...@@ -1534,8 +1538,10 @@ static u32 ql_get_speed(struct ql3_adapter *qdev)
spin_lock_irqsave(&qdev->hw_lock, hw_flags); spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
2) << 7)) 2) << 7)) {
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return 0; return 0;
}
status = ql_get_link_speed(qdev); status = ql_get_link_speed(qdev);
ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
...@@ -1549,8 +1555,10 @@ static int ql_get_full_dup(struct ql3_adapter *qdev) ...@@ -1549,8 +1555,10 @@ static int ql_get_full_dup(struct ql3_adapter *qdev)
spin_lock_irqsave(&qdev->hw_lock, hw_flags); spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
2) << 7)) 2) << 7)) {
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return 0; return 0;
}
status = ql_is_link_full_dup(qdev); status = ql_is_link_full_dup(qdev);
ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
...@@ -3294,6 +3302,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) ...@@ -3294,6 +3302,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev)
err_init: err_init:
ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); ql_sem_unlock(qdev, QL_DRVR_SEM_MASK);
err_lock: err_lock:
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
free_irq(qdev->pdev->irq, ndev); free_irq(qdev->pdev->irq, ndev);
err_irq: err_irq:
if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment