diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_nx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 614d745d7e11..8d8e40b829e4 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -3152,6 +3152,20 @@ qla82xx_start_iocbs(srb_t *sp) | |||
3152 | } | 3152 | } |
3153 | } | 3153 | } |
3154 | 3154 | ||
3155 | void qla82xx_rom_lock_recovery(struct qla_hw_data *ha) | ||
3156 | { | ||
3157 | if (qla82xx_rom_lock(ha)) | ||
3158 | /* Someone else is holding the lock. */ | ||
3159 | qla_printk(KERN_INFO, ha, "Resetting rom_lock\n"); | ||
3160 | |||
3161 | /* | ||
3162 | * Either we got the lock, or someone | ||
3163 | * else died while holding it. | ||
3164 | * In either case, unlock. | ||
3165 | */ | ||
3166 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK)); | ||
3167 | } | ||
3168 | |||
3155 | /* | 3169 | /* |
3156 | * qla82xx_device_bootstrap | 3170 | * qla82xx_device_bootstrap |
3157 | * Initialize device, set DEV_READY, start fw | 3171 | * Initialize device, set DEV_READY, start fw |
@@ -3166,12 +3180,13 @@ qla82xx_start_iocbs(srb_t *sp) | |||
3166 | static int | 3180 | static int |
3167 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) | 3181 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) |
3168 | { | 3182 | { |
3169 | int rval, i, timeout; | 3183 | int rval = QLA_SUCCESS; |
3184 | int i, timeout; | ||
3170 | uint32_t old_count, count; | 3185 | uint32_t old_count, count; |
3171 | struct qla_hw_data *ha = vha->hw; | 3186 | struct qla_hw_data *ha = vha->hw; |
3187 | int need_reset = 0, peg_stuck = 1; | ||
3172 | 3188 | ||
3173 | if (qla82xx_need_reset(ha)) | 3189 | need_reset = qla82xx_need_reset(ha); |
3174 | goto dev_initialize; | ||
3175 | 3190 | ||
3176 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3191 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
3177 | 3192 | ||
@@ -3185,9 +3200,27 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha) | |||
3185 | 3200 | ||
3186 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3201 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
3187 | if (count != old_count) | 3202 | if (count != old_count) |
3203 | peg_stuck = 0; | ||
3204 | } | ||
3205 | |||
3206 | if (need_reset) { | ||
3207 | /* We are trying to perform a recovery here. */ | ||
3208 | if (peg_stuck) | ||
3209 | qla82xx_rom_lock_recovery(ha); | ||
3210 | goto dev_initialize; | ||
3211 | } else { | ||
3212 | /* Start of day for this ha context. */ | ||
3213 | if (peg_stuck) { | ||
3214 | /* Either we are the first or recovery in progress. */ | ||
3215 | qla82xx_rom_lock_recovery(ha); | ||
3216 | goto dev_initialize; | ||
3217 | } else | ||
3218 | /* Firmware already running. */ | ||
3188 | goto dev_ready; | 3219 | goto dev_ready; |
3189 | } | 3220 | } |
3190 | 3221 | ||
3222 | return rval; | ||
3223 | |||
3191 | dev_initialize: | 3224 | dev_initialize: |
3192 | /* set to DEV_INITIALIZING */ | 3225 | /* set to DEV_INITIALIZING */ |
3193 | qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); | 3226 | qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); |