Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] lpfc 8.3.3 : Add support for Target Reset handler entrypoint

Patch was originally submitted upstream on 4/21/2008:
http://marc.info/?l=linux-scsi&m=120880973719266&w=2

Somewhere, it never get merged. The patch restructures the task mgmt
routines, commonizing like behavior. Then the patch changes device
reset to LUN resets, and adds a target reset handler.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

James Smart and committed by
James Bottomley
bbb9d180 d11e31dd

+300 -202
+300 -202
drivers/scsi/lpfc/lpfc_scsi.c
··· 2676 2676 } 2677 2677 2678 2678 /** 2679 - * lpfc_scsi_tgt_reset - Target reset handler 2680 - * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure 2681 - * @vport: The virtual port for which this call is being executed. 2682 - * @tgt_id: Target ID. 2683 - * @lun: Lun number. 2684 - * @rdata: Pointer to lpfc_rport_data. 2685 - * 2686 - * This routine issues a TARGET RESET iocb to reset a target with @tgt_id ID. 2687 - * 2688 - * Return Code: 2689 - * 0x2003 - Error 2690 - * 0x2002 - Success. 2691 - **/ 2692 - static int 2693 - lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, 2694 - unsigned tgt_id, unsigned int lun, 2695 - struct lpfc_rport_data *rdata) 2696 - { 2697 - struct lpfc_hba *phba = vport->phba; 2698 - struct lpfc_iocbq *iocbq; 2699 - struct lpfc_iocbq *iocbqrsp; 2700 - int ret; 2701 - int status; 2702 - 2703 - if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) 2704 - return FAILED; 2705 - 2706 - lpfc_cmd->rdata = rdata; 2707 - status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun, 2708 - FCP_TARGET_RESET); 2709 - if (!status) 2710 - return FAILED; 2711 - 2712 - iocbq = &lpfc_cmd->cur_iocbq; 2713 - iocbqrsp = lpfc_sli_get_iocbq(phba); 2714 - 2715 - if (!iocbqrsp) 2716 - return FAILED; 2717 - 2718 - /* Issue Target Reset to TGT <num> */ 2719 - lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 2720 - "0702 Issue Target Reset to TGT %d Data: x%x x%x\n", 2721 - tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); 2722 - status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, 2723 - iocbq, iocbqrsp, lpfc_cmd->timeout); 2724 - if (status != IOCB_SUCCESS) { 2725 - if (status == IOCB_TIMEDOUT) { 2726 - iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; 2727 - ret = TIMEOUT_ERROR; 2728 - } else 2729 - ret = FAILED; 2730 - lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 2731 - } else { 2732 - ret = SUCCESS; 2733 - lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4]; 2734 - lpfc_cmd->status = iocbqrsp->iocb.ulpStatus; 2735 - if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT && 2736 - (lpfc_cmd->result & IOERR_DRVR_MASK)) 2737 - lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 2738 - } 2739 - 2740 - lpfc_sli_release_iocbq(phba, iocbqrsp); 2741 - return ret; 2742 - } 2743 - 2744 - /** 2745 2679 * lpfc_info - Info entry point of scsi_host_template data structure 2746 2680 * @host: The scsi host for which this call is being executed. 2747 2681 * ··· 3055 3121 return ret; 3056 3122 } 3057 3123 3124 + static char * 3125 + lpfc_taskmgmt_name(uint8_t task_mgmt_cmd) 3126 + { 3127 + switch (task_mgmt_cmd) { 3128 + case FCP_ABORT_TASK_SET: 3129 + return "ABORT_TASK_SET"; 3130 + case FCP_CLEAR_TASK_SET: 3131 + return "FCP_CLEAR_TASK_SET"; 3132 + case FCP_BUS_RESET: 3133 + return "FCP_BUS_RESET"; 3134 + case FCP_LUN_RESET: 3135 + return "FCP_LUN_RESET"; 3136 + case FCP_TARGET_RESET: 3137 + return "FCP_TARGET_RESET"; 3138 + case FCP_CLEAR_ACA: 3139 + return "FCP_CLEAR_ACA"; 3140 + case FCP_TERMINATE_TASK: 3141 + return "FCP_TERMINATE_TASK"; 3142 + default: 3143 + return "unknown"; 3144 + } 3145 + } 3146 + 3147 + /** 3148 + * lpfc_send_taskmgmt - Generic SCSI Task Mgmt Handler 3149 + * @vport: The virtual port for which this call is being executed. 3150 + * @rdata: Pointer to remote port local data 3151 + * @tgt_id: Target ID of remote device. 3152 + * @lun_id: Lun number for the TMF 3153 + * @task_mgmt_cmd: type of TMF to send 3154 + * 3155 + * This routine builds and sends a TMF (SCSI Task Mgmt Function) to 3156 + * a remote port. 3157 + * 3158 + * Return Code: 3159 + * 0x2003 - Error 3160 + * 0x2002 - Success. 3161 + **/ 3162 + static int 3163 + lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata, 3164 + unsigned tgt_id, unsigned int lun_id, 3165 + uint8_t task_mgmt_cmd) 3166 + { 3167 + struct lpfc_hba *phba = vport->phba; 3168 + struct lpfc_scsi_buf *lpfc_cmd; 3169 + struct lpfc_iocbq *iocbq; 3170 + struct lpfc_iocbq *iocbqrsp; 3171 + int ret; 3172 + int status; 3173 + 3174 + if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) 3175 + return FAILED; 3176 + 3177 + lpfc_cmd = lpfc_get_scsi_buf(phba); 3178 + if (lpfc_cmd == NULL) 3179 + return FAILED; 3180 + lpfc_cmd->timeout = 60; 3181 + lpfc_cmd->rdata = rdata; 3182 + 3183 + status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id, 3184 + task_mgmt_cmd); 3185 + if (!status) { 3186 + lpfc_release_scsi_buf(phba, lpfc_cmd); 3187 + return FAILED; 3188 + } 3189 + 3190 + iocbq = &lpfc_cmd->cur_iocbq; 3191 + iocbqrsp = lpfc_sli_get_iocbq(phba); 3192 + if (iocbqrsp == NULL) { 3193 + lpfc_release_scsi_buf(phba, lpfc_cmd); 3194 + return FAILED; 3195 + } 3196 + 3197 + lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 3198 + "0702 Issue %s to TGT %d LUN %d " 3199 + "rpi x%x nlp_flag x%x\n", 3200 + lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, 3201 + rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); 3202 + 3203 + status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, 3204 + iocbq, iocbqrsp, lpfc_cmd->timeout); 3205 + if (status != IOCB_SUCCESS) { 3206 + if (status == IOCB_TIMEDOUT) { 3207 + iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; 3208 + ret = TIMEOUT_ERROR; 3209 + } else 3210 + ret = FAILED; 3211 + lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 3212 + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3213 + "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n", 3214 + lpfc_taskmgmt_name(task_mgmt_cmd), 3215 + tgt_id, lun_id, iocbqrsp->iocb.ulpStatus, 3216 + iocbqrsp->iocb.un.ulpWord[4]); 3217 + } else 3218 + ret = SUCCESS; 3219 + 3220 + lpfc_sli_release_iocbq(phba, iocbqrsp); 3221 + 3222 + if (ret != TIMEOUT_ERROR) 3223 + lpfc_release_scsi_buf(phba, lpfc_cmd); 3224 + 3225 + return ret; 3226 + } 3227 + 3228 + /** 3229 + * lpfc_chk_tgt_mapped - 3230 + * @vport: The virtual port to check on 3231 + * @cmnd: Pointer to scsi_cmnd data structure. 3232 + * 3233 + * This routine delays until the scsi target (aka rport) for the 3234 + * command exists (is present and logged in) or we declare it non-existent. 3235 + * 3236 + * Return code : 3237 + * 0x2003 - Error 3238 + * 0x2002 - Success 3239 + **/ 3240 + static int 3241 + lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd) 3242 + { 3243 + struct lpfc_rport_data *rdata = cmnd->device->hostdata; 3244 + struct lpfc_nodelist *pnode = rdata->pnode; 3245 + unsigned long later; 3246 + 3247 + /* 3248 + * If target is not in a MAPPED state, delay until 3249 + * target is rediscovered or devloss timeout expires. 3250 + */ 3251 + later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3252 + while (time_after(later, jiffies)) { 3253 + if (!pnode || !NLP_CHK_NODE_ACT(pnode)) 3254 + return FAILED; 3255 + if (pnode->nlp_state == NLP_STE_MAPPED_NODE) 3256 + return SUCCESS; 3257 + schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 3258 + rdata = cmnd->device->hostdata; 3259 + if (!rdata) 3260 + return FAILED; 3261 + pnode = rdata->pnode; 3262 + } 3263 + if (!pnode || !NLP_CHK_NODE_ACT(pnode) || 3264 + (pnode->nlp_state != NLP_STE_MAPPED_NODE)) 3265 + return FAILED; 3266 + return SUCCESS; 3267 + } 3268 + 3269 + /** 3270 + * lpfc_reset_flush_io_context - 3271 + * @vport: The virtual port (scsi_host) for the flush context 3272 + * @tgt_id: If aborting by Target contect - specifies the target id 3273 + * @lun_id: If aborting by Lun context - specifies the lun id 3274 + * @context: specifies the context level to flush at. 3275 + * 3276 + * After a reset condition via TMF, we need to flush orphaned i/o 3277 + * contexts from the adapter. This routine aborts any contexts 3278 + * outstanding, then waits for their completions. The wait is 3279 + * bounded by devloss_tmo though. 3280 + * 3281 + * Return code : 3282 + * 0x2003 - Error 3283 + * 0x2002 - Success 3284 + **/ 3285 + static int 3286 + lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id, 3287 + uint64_t lun_id, lpfc_ctx_cmd context) 3288 + { 3289 + struct lpfc_hba *phba = vport->phba; 3290 + unsigned long later; 3291 + int cnt; 3292 + 3293 + cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); 3294 + if (cnt) 3295 + lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 3296 + tgt_id, lun_id, context); 3297 + later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3298 + while (time_after(later, jiffies) && cnt) { 3299 + schedule_timeout_uninterruptible(msecs_to_jiffies(20)); 3300 + cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); 3301 + } 3302 + if (cnt) { 3303 + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3304 + "0724 I/O flush failure for context %s : cnt x%x\n", 3305 + ((context == LPFC_CTX_LUN) ? "LUN" : 3306 + ((context == LPFC_CTX_TGT) ? "TGT" : 3307 + ((context == LPFC_CTX_HOST) ? "HOST" : "Unknown"))), 3308 + cnt); 3309 + return FAILED; 3310 + } 3311 + return SUCCESS; 3312 + } 3313 + 3058 3314 /** 3059 3315 * lpfc_device_reset_handler - scsi_host_template eh_device_reset entry point 3060 3316 * @cmnd: Pointer to scsi_cmnd data structure. 3061 3317 * 3062 - * This routine does a device reset by sending a TARGET_RESET task management 3318 + * This routine does a device reset by sending a LUN_RESET task management 3063 3319 * command. 3064 3320 * 3065 3321 * Return code : ··· 3261 3137 { 3262 3138 struct Scsi_Host *shost = cmnd->device->host; 3263 3139 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 3264 - struct lpfc_hba *phba = vport->phba; 3265 - struct lpfc_scsi_buf *lpfc_cmd; 3266 - struct lpfc_iocbq *iocbq, *iocbqrsp; 3267 3140 struct lpfc_rport_data *rdata = cmnd->device->hostdata; 3268 3141 struct lpfc_nodelist *pnode = rdata->pnode; 3269 - unsigned long later; 3270 - int ret = SUCCESS; 3271 - int status; 3272 - int cnt; 3142 + unsigned tgt_id = cmnd->device->id; 3143 + unsigned int lun_id = cmnd->device->lun; 3273 3144 struct lpfc_scsi_event_header scsi_event; 3145 + int status; 3274 3146 3275 3147 lpfc_block_error_handler(cmnd); 3148 + 3149 + status = lpfc_chk_tgt_mapped(vport, cmnd); 3150 + if (status == FAILED) { 3151 + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3152 + "0721 Device Reset rport failure: rdata x%p\n", rdata); 3153 + return FAILED; 3154 + } 3155 + 3156 + scsi_event.event_type = FC_REG_SCSI_EVENT; 3157 + scsi_event.subcategory = LPFC_EVENT_LUNRESET; 3158 + scsi_event.lun = lun_id; 3159 + memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name)); 3160 + memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name)); 3161 + 3162 + fc_host_post_vendor_event(shost, fc_get_event_number(), 3163 + sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); 3164 + 3165 + status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id, 3166 + FCP_LUN_RESET); 3167 + 3168 + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3169 + "0713 SCSI layer issued Device Reset (%d, %d) " 3170 + "return x%x\n", tgt_id, lun_id, status); 3171 + 3276 3172 /* 3277 - * If target is not in a MAPPED state, delay the reset until 3278 - * target is rediscovered or devloss timeout expires. 3173 + * We have to clean up i/o as : they may be orphaned by the TMF; 3174 + * or if the TMF failed, they may be in an indeterminate state. 3175 + * So, continue on. 3176 + * We will report success if all the i/o aborts successfully. 3279 3177 */ 3280 - later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3281 - while (time_after(later, jiffies)) { 3282 - if (!pnode || !NLP_CHK_NODE_ACT(pnode)) 3283 - return FAILED; 3284 - if (pnode->nlp_state == NLP_STE_MAPPED_NODE) 3285 - break; 3286 - schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 3287 - rdata = cmnd->device->hostdata; 3288 - if (!rdata) 3289 - break; 3290 - pnode = rdata->pnode; 3178 + status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id, 3179 + LPFC_CTX_LUN); 3180 + return status; 3181 + } 3182 + 3183 + /** 3184 + * lpfc_target_reset_handler - scsi_host_template eh_target_reset entry point 3185 + * @cmnd: Pointer to scsi_cmnd data structure. 3186 + * 3187 + * This routine does a target reset by sending a TARGET_RESET task management 3188 + * command. 3189 + * 3190 + * Return code : 3191 + * 0x2003 - Error 3192 + * 0x2002 - Success 3193 + **/ 3194 + static int 3195 + lpfc_target_reset_handler(struct scsi_cmnd *cmnd) 3196 + { 3197 + struct Scsi_Host *shost = cmnd->device->host; 3198 + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 3199 + struct lpfc_rport_data *rdata = cmnd->device->hostdata; 3200 + struct lpfc_nodelist *pnode = rdata->pnode; 3201 + unsigned tgt_id = cmnd->device->id; 3202 + unsigned int lun_id = cmnd->device->lun; 3203 + struct lpfc_scsi_event_header scsi_event; 3204 + int status; 3205 + 3206 + lpfc_block_error_handler(cmnd); 3207 + 3208 + status = lpfc_chk_tgt_mapped(vport, cmnd); 3209 + if (status == FAILED) { 3210 + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3211 + "0722 Target Reset rport failure: rdata x%p\n", rdata); 3212 + return FAILED; 3291 3213 } 3292 3214 3293 3215 scsi_event.event_type = FC_REG_SCSI_EVENT; ··· 3342 3172 memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name)); 3343 3173 memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name)); 3344 3174 3345 - fc_host_post_vendor_event(shost, 3346 - fc_get_event_number(), 3347 - sizeof(scsi_event), 3348 - (char *)&scsi_event, 3349 - LPFC_NL_VENDOR_ID); 3175 + fc_host_post_vendor_event(shost, fc_get_event_number(), 3176 + sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); 3350 3177 3351 - if (!rdata || pnode->nlp_state != NLP_STE_MAPPED_NODE) { 3352 - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3353 - "0721 LUN Reset rport " 3354 - "failure: msec x%x rdata x%p\n", 3355 - jiffies_to_msecs(jiffies - later), rdata); 3356 - return FAILED; 3357 - } 3358 - lpfc_cmd = lpfc_get_scsi_buf(phba); 3359 - if (lpfc_cmd == NULL) 3360 - return FAILED; 3361 - lpfc_cmd->timeout = 60; 3362 - lpfc_cmd->rdata = rdata; 3178 + status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id, 3179 + FCP_TARGET_RESET); 3363 3180 3364 - status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, 3365 - cmnd->device->lun, 3366 - FCP_TARGET_RESET); 3367 - if (!status) { 3368 - lpfc_release_scsi_buf(phba, lpfc_cmd); 3369 - return FAILED; 3370 - } 3371 - iocbq = &lpfc_cmd->cur_iocbq; 3372 - 3373 - /* get a buffer for this IOCB command response */ 3374 - iocbqrsp = lpfc_sli_get_iocbq(phba); 3375 - if (iocbqrsp == NULL) { 3376 - lpfc_release_scsi_buf(phba, lpfc_cmd); 3377 - return FAILED; 3378 - } 3379 - lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 3380 - "0703 Issue target reset to TGT %d LUN %d " 3381 - "rpi x%x nlp_flag x%x\n", cmnd->device->id, 3382 - cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); 3383 - status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, 3384 - iocbq, iocbqrsp, lpfc_cmd->timeout); 3385 - if (status == IOCB_TIMEDOUT) { 3386 - iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; 3387 - ret = TIMEOUT_ERROR; 3388 - } else { 3389 - if (status != IOCB_SUCCESS) 3390 - ret = FAILED; 3391 - lpfc_release_scsi_buf(phba, lpfc_cmd); 3392 - } 3393 3181 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3394 - "0713 SCSI layer issued device reset (%d, %d) " 3395 - "return x%x status x%x result x%x\n", 3396 - cmnd->device->id, cmnd->device->lun, ret, 3397 - iocbqrsp->iocb.ulpStatus, 3398 - iocbqrsp->iocb.un.ulpWord[4]); 3399 - lpfc_sli_release_iocbq(phba, iocbqrsp); 3400 - cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, cmnd->device->lun, 3401 - LPFC_CTX_TGT); 3402 - if (cnt) 3403 - lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 3404 - cmnd->device->id, cmnd->device->lun, 3405 - LPFC_CTX_TGT); 3406 - later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3407 - while (time_after(later, jiffies) && cnt) { 3408 - schedule_timeout_uninterruptible(msecs_to_jiffies(20)); 3409 - cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, 3410 - cmnd->device->lun, LPFC_CTX_TGT); 3411 - } 3412 - if (cnt) { 3413 - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3414 - "0719 device reset I/O flush failure: " 3415 - "cnt x%x\n", cnt); 3416 - ret = FAILED; 3417 - } 3418 - return ret; 3182 + "0723 SCSI layer issued Target Reset (%d, %d) " 3183 + "return x%x\n", tgt_id, lun_id, status); 3184 + 3185 + /* 3186 + * We have to clean up i/o as : they may be orphaned by the TMF; 3187 + * or if the TMF failed, they may be in an indeterminate state. 3188 + * So, continue on. 3189 + * We will report success if all the i/o aborts successfully. 3190 + */ 3191 + status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id, 3192 + LPFC_CTX_TGT); 3193 + return status; 3419 3194 } 3420 3195 3421 3196 /** 3422 3197 * lpfc_bus_reset_handler - scsi_host_template eh_bus_reset_handler entry point 3423 3198 * @cmnd: Pointer to scsi_cmnd data structure. 3424 3199 * 3425 - * This routine does target reset to all target on @cmnd->device->host. 3200 + * This routine does target reset to all targets on @cmnd->device->host. 3201 + * This emulates Parallel SCSI Bus Reset Semantics. 3426 3202 * 3427 - * Return Code: 3428 - * 0x2003 - Error 3429 - * 0x2002 - Success 3203 + * Return code : 3204 + * 0x2003 - Error 3205 + * 0x2002 - Success 3430 3206 **/ 3431 3207 static int 3432 3208 lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) 3433 3209 { 3434 3210 struct Scsi_Host *shost = cmnd->device->host; 3435 3211 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 3436 - struct lpfc_hba *phba = vport->phba; 3437 3212 struct lpfc_nodelist *ndlp = NULL; 3438 - int match; 3439 - int ret = SUCCESS, status = SUCCESS, i; 3440 - int cnt; 3441 - struct lpfc_scsi_buf * lpfc_cmd; 3442 - unsigned long later; 3443 3213 struct lpfc_scsi_event_header scsi_event; 3214 + int match; 3215 + int ret = SUCCESS, status, i; 3444 3216 3445 3217 scsi_event.event_type = FC_REG_SCSI_EVENT; 3446 3218 scsi_event.subcategory = LPFC_EVENT_BUSRESET; ··· 3390 3278 memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name)); 3391 3279 memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name)); 3392 3280 3393 - fc_host_post_vendor_event(shost, 3394 - fc_get_event_number(), 3395 - sizeof(scsi_event), 3396 - (char *)&scsi_event, 3397 - LPFC_NL_VENDOR_ID); 3281 + fc_host_post_vendor_event(shost, fc_get_event_number(), 3282 + sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); 3398 3283 3399 3284 lpfc_block_error_handler(cmnd); 3285 + 3400 3286 /* 3401 3287 * Since the driver manages a single bus device, reset all 3402 3288 * targets known to the driver. Should any target reset ··· 3417 3307 spin_unlock_irq(shost->host_lock); 3418 3308 if (!match) 3419 3309 continue; 3420 - lpfc_cmd = lpfc_get_scsi_buf(phba); 3421 - if (lpfc_cmd) { 3422 - lpfc_cmd->timeout = 60; 3423 - status = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i, 3424 - cmnd->device->lun, 3425 - ndlp->rport->dd_data); 3426 - if (status != TIMEOUT_ERROR) 3427 - lpfc_release_scsi_buf(phba, lpfc_cmd); 3428 - } 3429 - if (!lpfc_cmd || status != SUCCESS) { 3310 + 3311 + status = lpfc_send_taskmgmt(vport, ndlp->rport->dd_data, 3312 + i, 0, FCP_TARGET_RESET); 3313 + 3314 + if (status != SUCCESS) { 3430 3315 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3431 3316 "0700 Bus Reset on target %d failed\n", 3432 3317 i); ··· 3429 3324 } 3430 3325 } 3431 3326 /* 3432 - * All outstanding txcmplq I/Os should have been aborted by 3433 - * the targets. Unfortunately, some targets do not abide by 3434 - * this forcing the driver to double check. 3327 + * We have to clean up i/o as : they may be orphaned by the TMFs 3328 + * above; or if any of the TMFs failed, they may be in an 3329 + * indeterminate state. 3330 + * We will report success if all the i/o aborts successfully. 3435 3331 */ 3436 - cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); 3437 - if (cnt) 3438 - lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 3439 - 0, 0, LPFC_CTX_HOST); 3440 - later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3441 - while (time_after(later, jiffies) && cnt) { 3442 - schedule_timeout_uninterruptible(msecs_to_jiffies(20)); 3443 - cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); 3444 - } 3445 - if (cnt) { 3446 - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3447 - "0715 Bus Reset I/O flush failure: " 3448 - "cnt x%x left x%x\n", cnt, i); 3332 + 3333 + status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST); 3334 + if (status != SUCCESS) 3449 3335 ret = FAILED; 3450 - } 3336 + 3451 3337 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3452 3338 "0714 SCSI layer issued Bus Reset Data: x%x\n", ret); 3453 3339 return ret; ··· 3571 3475 .info = lpfc_info, 3572 3476 .queuecommand = lpfc_queuecommand, 3573 3477 .eh_abort_handler = lpfc_abort_handler, 3574 - .eh_device_reset_handler= lpfc_device_reset_handler, 3478 + .eh_device_reset_handler = lpfc_device_reset_handler, 3479 + .eh_target_reset_handler = lpfc_target_reset_handler, 3575 3480 .eh_bus_reset_handler = lpfc_bus_reset_handler, 3576 3481 .slave_alloc = lpfc_slave_alloc, 3577 3482 .slave_configure = lpfc_slave_configure, ··· 3592 3495 .info = lpfc_info, 3593 3496 .queuecommand = lpfc_queuecommand, 3594 3497 .eh_abort_handler = lpfc_abort_handler, 3595 - .eh_device_reset_handler= lpfc_device_reset_handler, 3498 + .eh_device_reset_handler = lpfc_device_reset_handler, 3499 + .eh_target_reset_handler = lpfc_target_reset_handler, 3596 3500 .eh_bus_reset_handler = lpfc_bus_reset_handler, 3597 3501 .slave_alloc = lpfc_slave_alloc, 3598 3502 .slave_configure = lpfc_slave_configure,