aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
authorShyam Sundar <shyam.sundar@qlogic.com>2010-10-07 01:50:51 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-25 15:53:29 -0400
commitb25ee66f2d4e5f14e69d75a7363e55889e9aff92 (patch)
treef0a2732267387c98eb872d32911247016841426c /drivers/scsi/qla4xxx
parent2657c800dbb24761097ef341dfa43672c08a7a9e (diff)
[SCSI] qla4xxx: Clear the rom lock if the firmware died while holding it.
There is a possibility that the firmware dies while the rom lock is held. The only way to recover from this condition is to forcefully unlock. Signed-off-by: Shyam Sundar <shyam.sundar@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: Ravi Anand <ravi.anand@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index b311a96acf11..74582cb46a28 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -839,8 +839,11 @@ qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
839 done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK)); 839 done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
840 if (done == 1) 840 if (done == 1)
841 break; 841 break;
842 if (timeout >= qla4_8xxx_rom_lock_timeout) 842 if (timeout >= qla4_8xxx_rom_lock_timeout) {
843 ql4_printk(KERN_WARNING, ha,
844 "%s: Failed to acquire rom lock", __func__);
843 return -1; 845 return -1;
846 }
844 847
845 timeout++; 848 timeout++;
846 849
@@ -1550,6 +1553,21 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
1550 return rval; 1553 return rval;
1551} 1554}
1552 1555
1556static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha)
1557{
1558 if (qla4_8xxx_rom_lock(ha)) {
1559 /* Someone else is holding the lock. */
1560 dev_info(&ha->pdev->dev, "Resetting rom_lock\n");
1561 }
1562
1563 /*
1564 * Either we got the lock, or someone
1565 * else died while holding it.
1566 * In either case, unlock.
1567 */
1568 qla4_8xxx_rom_unlock(ha);
1569}
1570
1553/** 1571/**
1554 * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw 1572 * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw
1555 * @ha: pointer to adapter structure 1573 * @ha: pointer to adapter structure
@@ -1559,11 +1577,12 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
1559static int 1577static int
1560qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) 1578qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
1561{ 1579{
1562 int rval, i, timeout; 1580 int rval = QLA_ERROR;
1581 int i, timeout;
1563 uint32_t old_count, count; 1582 uint32_t old_count, count;
1583 int need_reset = 0, peg_stuck = 1;
1564 1584
1565 if (qla4_8xxx_need_reset(ha)) 1585 need_reset = qla4_8xxx_need_reset(ha);
1566 goto dev_initialize;
1567 1586
1568 old_count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); 1587 old_count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
1569 1588
@@ -1572,12 +1591,30 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
1572 if (timeout) { 1591 if (timeout) {
1573 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 1592 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
1574 QLA82XX_DEV_FAILED); 1593 QLA82XX_DEV_FAILED);
1575 return QLA_ERROR; 1594 return rval;
1576 } 1595 }
1577 1596
1578 count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); 1597 count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
1579 if (count != old_count) 1598 if (count != old_count)
1599 peg_stuck = 0;
1600 }
1601
1602 if (need_reset) {
1603 /* We are trying to perform a recovery here. */
1604 if (peg_stuck)
1605 qla4_8xxx_rom_lock_recovery(ha);
1606 goto dev_initialize;
1607 } else {
1608 /* Start of day for this ha context. */
1609 if (peg_stuck) {
1610 /* Either we are the first or recovery in progress. */
1611 qla4_8xxx_rom_lock_recovery(ha);
1612 goto dev_initialize;
1613 } else {
1614 /* Firmware already running. */
1615 rval = QLA_SUCCESS;
1580 goto dev_ready; 1616 goto dev_ready;
1617 }
1581 } 1618 }
1582 1619
1583dev_initialize: 1620dev_initialize:
@@ -1603,7 +1640,7 @@ dev_ready:
1603 ql4_printk(KERN_INFO, ha, "HW State: READY\n"); 1640 ql4_printk(KERN_INFO, ha, "HW State: READY\n");
1604 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY); 1641 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY);
1605 1642
1606 return QLA_SUCCESS; 1643 return rval;
1607} 1644}
1608 1645
1609/** 1646/**