diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-31 20:43:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-31 20:43:12 -0400 |
commit | ce9d8d9f7214c7b74a5dd7be8221545269a31155 (patch) | |
tree | f6d529ea1d0b1c801af4a938b30de94b00ef9ca3 /drivers/scsi/qla4xxx/ql4_nx.c | |
parent | 82279e6bd7643da1b3fbda42555c3238c7b00d38 (diff) | |
parent | 592488a32b87daf27b92d2c1c5cdc440d1a1beae (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (70 commits)
[SCSI] pmcraid: add support for set timestamp command and other fixes
[SCSI] pmcraid: remove duplicate struct member
[SCSI] qla4xxx: Fix cmd check in qla4xxx_cmd_wait
[SCSI] megaraid_sas: Version and documentation update
[SCSI] megaraid_sas: Add three times Online controller reset
[SCSI] megaraid_sas: Add input parameter for max_sectors
[SCSI] megaraid_sas: support devices update flag
[SCSI] libosd: write/read_sg_kern API
[SCSI] libosd: Support for scatter gather write/read commands
[SCSI] libosd: Free resources in reverse order of allocation
[SCSI] libosd: Fix bug in attr_page handling
[SCSI] lpfc 8.3.18: Update lpfc driver version to 8.3.18
[SCSI] lpfc 8.3.18: Add new WQE support
[SCSI] lpfc 8.3.18: Fix critical errors
[SCSI] lpfc 8.3.18: Adapter Shutdown and Unregistration cleanup
[SCSI] lpfc 8.3.18: Add logic to detect last devloss timeout
[SCSI] lpfc 8.3.18: Add support of received ELS commands
[SCSI] lpfc 8.3.18: FC/FCoE Discovery fixes
[SCSI] ipr: add definitions for a new adapter
[SCSI] bfa: fix comments for c files
...
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_nx.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_nx.c | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 449256f2c5f..474b10d7136 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) done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK)); if (done == 1) break; - if (timeout >= qla4_8xxx_rom_lock_timeout) + if (timeout >= qla4_8xxx_rom_lock_timeout) { + ql4_printk(KERN_WARNING, ha, + "%s: Failed to acquire rom lock", __func__); return -1; + } timeout++; @@ -1078,21 +1081,6 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) return 0; } -static int qla4_8xxx_check_for_bad_spd(struct scsi_qla_host *ha) -{ - u32 val = 0; - val = qla4_8xxx_rd_32(ha, BOOT_LOADER_DIMM_STATUS) ; - val &= QLA82XX_BOOT_LOADER_MN_ISSUE; - if (val & QLA82XX_PEG_TUNE_MN_SPD_ZEROED) { - printk("Memory DIMM SPD not programmed. Assumed valid.\n"); - return 1; - } else if (val) { - printk("Memory DIMM type incorrect. Info:%08X.\n", val); - return 2; - } - return 0; -} - static int qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start) { @@ -1377,8 +1365,6 @@ static int qla4_8xxx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val) } while (--retries); - qla4_8xxx_check_for_bad_spd(ha); - if (!retries) { pegtune_val = qla4_8xxx_rd_32(ha, QLA82XX_ROMUSB_GLB_PEGTUNE_DONE); @@ -1540,14 +1526,31 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha) ql4_printk(KERN_INFO, ha, "FW: Attempting to load firmware from flash...\n"); rval = qla4_8xxx_start_firmware(ha, ha->hw.flt_region_fw); - if (rval == QLA_SUCCESS) - return rval; - ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash FAILED...\n"); + if (rval != QLA_SUCCESS) { + ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash" + " FAILED...\n"); + return rval; + } return rval; } +static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha) +{ + if (qla4_8xxx_rom_lock(ha)) { + /* Someone else is holding the lock. */ + dev_info(&ha->pdev->dev, "Resetting rom_lock\n"); + } + + /* + * Either we got the lock, or someone + * else died while holding it. + * In either case, unlock. + */ + qla4_8xxx_rom_unlock(ha); +} + /** * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw * @ha: pointer to adapter structure @@ -1557,11 +1560,12 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha) static int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) { - int rval, i, timeout; + int rval = QLA_ERROR; + int i, timeout; uint32_t old_count, count; + int need_reset = 0, peg_stuck = 1; - if (qla4_8xxx_need_reset(ha)) - goto dev_initialize; + need_reset = qla4_8xxx_need_reset(ha); old_count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); @@ -1570,12 +1574,30 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) if (timeout) { qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED); - return QLA_ERROR; + return rval; } count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); if (count != old_count) + peg_stuck = 0; + } + + if (need_reset) { + /* We are trying to perform a recovery here. */ + if (peg_stuck) + qla4_8xxx_rom_lock_recovery(ha); + goto dev_initialize; + } else { + /* Start of day for this ha context. */ + if (peg_stuck) { + /* Either we are the first or recovery in progress. */ + qla4_8xxx_rom_lock_recovery(ha); + goto dev_initialize; + } else { + /* Firmware already running. */ + rval = QLA_SUCCESS; goto dev_ready; + } } dev_initialize: @@ -1601,7 +1623,7 @@ dev_ready: ql4_printk(KERN_INFO, ha, "HW State: READY\n"); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY); - return QLA_SUCCESS; + return rval; } /** @@ -1764,20 +1786,9 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha) int retval; retval = qla4_8xxx_device_state_handler(ha); - if (retval == QLA_SUCCESS && - !test_bit(AF_INIT_DONE, &ha->flags)) { + if (retval == QLA_SUCCESS && !test_bit(AF_INIT_DONE, &ha->flags)) retval = qla4xxx_request_irqs(ha); - if (retval != QLA_SUCCESS) { - ql4_printk(KERN_WARNING, ha, - "Failed to reserve interrupt %d already in use.\n", - ha->pdev->irq); - } else { - set_bit(AF_IRQ_ATTACHED, &ha->flags); - ha->host->irq = ha->pdev->irq; - ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n", - __func__, ha->pdev->irq); - } - } + return retval; } |