aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-06-10 17:23:16 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-15 11:09:34 -0400
commitbbb9d18009373bc74bfeba760097de277f395858 (patch)
tree1fdf2b7c81ae16c39a666823b5e44760081653a2 /drivers/scsi
parentd11e31ddb9718755dc96e1c018843ae6f5bb085e (diff)
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c484
1 files changed, 291 insertions, 193 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 32f8dac6abf..caaa209feca 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2676,72 +2676,6 @@ lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba,
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 **/
2692static int
2693lpfc_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 * lpfc_info - Info entry point of scsi_host_template data structure 2679 * lpfc_info - Info entry point of scsi_host_template data structure
2746 * @host: The scsi host for which this call is being executed. 2680 * @host: The scsi host for which this call is being executed.
2747 * 2681 *
@@ -3121,156 +3055,334 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
3121 return ret; 3055 return ret;
3122} 3056}
3123 3057
3058static char *
3059lpfc_taskmgmt_name(uint8_t task_mgmt_cmd)
3060{
3061 switch (task_mgmt_cmd) {
3062 case FCP_ABORT_TASK_SET:
3063 return "ABORT_TASK_SET";
3064 case FCP_CLEAR_TASK_SET:
3065 return "FCP_CLEAR_TASK_SET";
3066 case FCP_BUS_RESET:
3067 return "FCP_BUS_RESET";
3068 case FCP_LUN_RESET:
3069 return "FCP_LUN_RESET";
3070 case FCP_TARGET_RESET:
3071 return "FCP_TARGET_RESET";
3072 case FCP_CLEAR_ACA:
3073 return "FCP_CLEAR_ACA";
3074 case FCP_TERMINATE_TASK:
3075 return "FCP_TERMINATE_TASK";
3076 default:
3077 return "unknown";
3078 }
3079}
3080
3124/** 3081/**
3125 * lpfc_device_reset_handler - scsi_host_template eh_device_reset entry point 3082 * lpfc_send_taskmgmt - Generic SCSI Task Mgmt Handler
3126 * @cmnd: Pointer to scsi_cmnd data structure. 3083 * @vport: The virtual port for which this call is being executed.
3084 * @rdata: Pointer to remote port local data
3085 * @tgt_id: Target ID of remote device.
3086 * @lun_id: Lun number for the TMF
3087 * @task_mgmt_cmd: type of TMF to send
3127 * 3088 *
3128 * This routine does a device reset by sending a TARGET_RESET task management 3089 * This routine builds and sends a TMF (SCSI Task Mgmt Function) to
3129 * command. 3090 * a remote port.
3130 * 3091 *
3131 * Return code : 3092 * Return Code:
3132 * 0x2003 - Error 3093 * 0x2003 - Error
3133 * 0x2002 - Success 3094 * 0x2002 - Success.
3134 **/ 3095 **/
3135static int 3096static int
3136lpfc_device_reset_handler(struct scsi_cmnd *cmnd) 3097lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
3098 unsigned tgt_id, unsigned int lun_id,
3099 uint8_t task_mgmt_cmd)
3137{ 3100{
3138 struct Scsi_Host *shost = cmnd->device->host;
3139 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
3140 struct lpfc_hba *phba = vport->phba; 3101 struct lpfc_hba *phba = vport->phba;
3141 struct lpfc_scsi_buf *lpfc_cmd; 3102 struct lpfc_scsi_buf *lpfc_cmd;
3142 struct lpfc_iocbq *iocbq, *iocbqrsp; 3103 struct lpfc_iocbq *iocbq;
3143 struct lpfc_rport_data *rdata = cmnd->device->hostdata; 3104 struct lpfc_iocbq *iocbqrsp;
3144 struct lpfc_nodelist *pnode = rdata->pnode; 3105 int ret;
3145 unsigned long later;
3146 int ret = SUCCESS;
3147 int status; 3106 int status;
3148 int cnt;
3149 struct lpfc_scsi_event_header scsi_event;
3150
3151 lpfc_block_error_handler(cmnd);
3152 /*
3153 * If target is not in a MAPPED state, delay the reset until
3154 * target is rediscovered or devloss timeout expires.
3155 */
3156 later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
3157 while (time_after(later, jiffies)) {
3158 if (!pnode || !NLP_CHK_NODE_ACT(pnode))
3159 return FAILED;
3160 if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
3161 break;
3162 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
3163 rdata = cmnd->device->hostdata;
3164 if (!rdata)
3165 break;
3166 pnode = rdata->pnode;
3167 }
3168 3107
3169 scsi_event.event_type = FC_REG_SCSI_EVENT; 3108 if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
3170 scsi_event.subcategory = LPFC_EVENT_TGTRESET;
3171 scsi_event.lun = 0;
3172 memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
3173 memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
3174
3175 fc_host_post_vendor_event(shost,
3176 fc_get_event_number(),
3177 sizeof(scsi_event),
3178 (char *)&scsi_event,
3179 LPFC_NL_VENDOR_ID);
3180
3181 if (!rdata || pnode->nlp_state != NLP_STE_MAPPED_NODE) {
3182 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3183 "0721 LUN Reset rport "
3184 "failure: msec x%x rdata x%p\n",
3185 jiffies_to_msecs(jiffies - later), rdata);
3186 return FAILED; 3109 return FAILED;
3187 } 3110
3188 lpfc_cmd = lpfc_get_scsi_buf(phba); 3111 lpfc_cmd = lpfc_get_scsi_buf(phba);
3189 if (lpfc_cmd == NULL) 3112 if (lpfc_cmd == NULL)
3190 return FAILED; 3113 return FAILED;
3191 lpfc_cmd->timeout = 60; 3114 lpfc_cmd->timeout = 60;
3192 lpfc_cmd->rdata = rdata; 3115 lpfc_cmd->rdata = rdata;
3193 3116
3194 status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, 3117 status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id,
3195 cmnd->device->lun, 3118 task_mgmt_cmd);
3196 FCP_TARGET_RESET);
3197 if (!status) { 3119 if (!status) {
3198 lpfc_release_scsi_buf(phba, lpfc_cmd); 3120 lpfc_release_scsi_buf(phba, lpfc_cmd);
3199 return FAILED; 3121 return FAILED;
3200 } 3122 }
3201 iocbq = &lpfc_cmd->cur_iocbq;
3202 3123
3203 /* get a buffer for this IOCB command response */ 3124 iocbq = &lpfc_cmd->cur_iocbq;
3204 iocbqrsp = lpfc_sli_get_iocbq(phba); 3125 iocbqrsp = lpfc_sli_get_iocbq(phba);
3205 if (iocbqrsp == NULL) { 3126 if (iocbqrsp == NULL) {
3206 lpfc_release_scsi_buf(phba, lpfc_cmd); 3127 lpfc_release_scsi_buf(phba, lpfc_cmd);
3207 return FAILED; 3128 return FAILED;
3208 } 3129 }
3130
3209 lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 3131 lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
3210 "0703 Issue target reset to TGT %d LUN %d " 3132 "0702 Issue %s to TGT %d LUN %d "
3211 "rpi x%x nlp_flag x%x\n", cmnd->device->id, 3133 "rpi x%x nlp_flag x%x\n",
3212 cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); 3134 lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
3135 rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag);
3136
3213 status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, 3137 status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
3214 iocbq, iocbqrsp, lpfc_cmd->timeout); 3138 iocbq, iocbqrsp, lpfc_cmd->timeout);
3215 if (status == IOCB_TIMEDOUT) { 3139 if (status != IOCB_SUCCESS) {
3216 iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; 3140 if (status == IOCB_TIMEDOUT) {
3217 ret = TIMEOUT_ERROR; 3141 iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
3218 } else { 3142 ret = TIMEOUT_ERROR;
3219 if (status != IOCB_SUCCESS) 3143 } else
3220 ret = FAILED; 3144 ret = FAILED;
3221 lpfc_release_scsi_buf(phba, lpfc_cmd); 3145 lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
3222 } 3146 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3223 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3147 "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n",
3224 "0713 SCSI layer issued device reset (%d, %d) " 3148 lpfc_taskmgmt_name(task_mgmt_cmd),
3225 "return x%x status x%x result x%x\n", 3149 tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
3226 cmnd->device->id, cmnd->device->lun, ret,
3227 iocbqrsp->iocb.ulpStatus,
3228 iocbqrsp->iocb.un.ulpWord[4]); 3150 iocbqrsp->iocb.un.ulpWord[4]);
3151 } else
3152 ret = SUCCESS;
3153
3229 lpfc_sli_release_iocbq(phba, iocbqrsp); 3154 lpfc_sli_release_iocbq(phba, iocbqrsp);
3230 cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, cmnd->device->lun, 3155
3231 LPFC_CTX_TGT); 3156 if (ret != TIMEOUT_ERROR)
3157 lpfc_release_scsi_buf(phba, lpfc_cmd);
3158
3159 return ret;
3160}
3161
3162/**
3163 * lpfc_chk_tgt_mapped -
3164 * @vport: The virtual port to check on
3165 * @cmnd: Pointer to scsi_cmnd data structure.
3166 *
3167 * This routine delays until the scsi target (aka rport) for the
3168 * command exists (is present and logged in) or we declare it non-existent.
3169 *
3170 * Return code :
3171 * 0x2003 - Error
3172 * 0x2002 - Success
3173 **/
3174static int
3175lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd)
3176{
3177 struct lpfc_rport_data *rdata = cmnd->device->hostdata;
3178 struct lpfc_nodelist *pnode = rdata->pnode;
3179 unsigned long later;
3180
3181 /*
3182 * If target is not in a MAPPED state, delay until
3183 * target is rediscovered or devloss timeout expires.
3184 */
3185 later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
3186 while (time_after(later, jiffies)) {
3187 if (!pnode || !NLP_CHK_NODE_ACT(pnode))
3188 return FAILED;
3189 if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
3190 return SUCCESS;
3191 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
3192 rdata = cmnd->device->hostdata;
3193 if (!rdata)
3194 return FAILED;
3195 pnode = rdata->pnode;
3196 }
3197 if (!pnode || !NLP_CHK_NODE_ACT(pnode) ||
3198 (pnode->nlp_state != NLP_STE_MAPPED_NODE))
3199 return FAILED;
3200 return SUCCESS;
3201}
3202
3203/**
3204 * lpfc_reset_flush_io_context -
3205 * @vport: The virtual port (scsi_host) for the flush context
3206 * @tgt_id: If aborting by Target contect - specifies the target id
3207 * @lun_id: If aborting by Lun context - specifies the lun id
3208 * @context: specifies the context level to flush at.
3209 *
3210 * After a reset condition via TMF, we need to flush orphaned i/o
3211 * contexts from the adapter. This routine aborts any contexts
3212 * outstanding, then waits for their completions. The wait is
3213 * bounded by devloss_tmo though.
3214 *
3215 * Return code :
3216 * 0x2003 - Error
3217 * 0x2002 - Success
3218 **/
3219static int
3220lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id,
3221 uint64_t lun_id, lpfc_ctx_cmd context)
3222{
3223 struct lpfc_hba *phba = vport->phba;
3224 unsigned long later;
3225 int cnt;
3226
3227 cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context);
3232 if (cnt) 3228 if (cnt)
3233 lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 3229 lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
3234 cmnd->device->id, cmnd->device->lun, 3230 tgt_id, lun_id, context);
3235 LPFC_CTX_TGT);
3236 later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; 3231 later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
3237 while (time_after(later, jiffies) && cnt) { 3232 while (time_after(later, jiffies) && cnt) {
3238 schedule_timeout_uninterruptible(msecs_to_jiffies(20)); 3233 schedule_timeout_uninterruptible(msecs_to_jiffies(20));
3239 cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, 3234 cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context);
3240 cmnd->device->lun, LPFC_CTX_TGT);
3241 } 3235 }
3242 if (cnt) { 3236 if (cnt) {
3243 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3237 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3244 "0719 device reset I/O flush failure: " 3238 "0724 I/O flush failure for context %s : cnt x%x\n",
3245 "cnt x%x\n", cnt); 3239 ((context == LPFC_CTX_LUN) ? "LUN" :
3246 ret = FAILED; 3240 ((context == LPFC_CTX_TGT) ? "TGT" :
3241 ((context == LPFC_CTX_HOST) ? "HOST" : "Unknown"))),
3242 cnt);
3243 return FAILED;
3247 } 3244 }
3248 return ret; 3245 return SUCCESS;
3246}
3247
3248/**
3249 * lpfc_device_reset_handler - scsi_host_template eh_device_reset entry point
3250 * @cmnd: Pointer to scsi_cmnd data structure.
3251 *
3252 * This routine does a device reset by sending a LUN_RESET task management
3253 * command.
3254 *
3255 * Return code :
3256 * 0x2003 - Error
3257 * 0x2002 - Success
3258 **/
3259static int
3260lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
3261{
3262 struct Scsi_Host *shost = cmnd->device->host;
3263 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
3264 struct lpfc_rport_data *rdata = cmnd->device->hostdata;
3265 struct lpfc_nodelist *pnode = rdata->pnode;
3266 unsigned tgt_id = cmnd->device->id;
3267 unsigned int lun_id = cmnd->device->lun;
3268 struct lpfc_scsi_event_header scsi_event;
3269 int status;
3270
3271 lpfc_block_error_handler(cmnd);
3272
3273 status = lpfc_chk_tgt_mapped(vport, cmnd);
3274 if (status == FAILED) {
3275 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3276 "0721 Device Reset rport failure: rdata x%p\n", rdata);
3277 return FAILED;
3278 }
3279
3280 scsi_event.event_type = FC_REG_SCSI_EVENT;
3281 scsi_event.subcategory = LPFC_EVENT_LUNRESET;
3282 scsi_event.lun = lun_id;
3283 memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
3284 memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
3285
3286 fc_host_post_vendor_event(shost, fc_get_event_number(),
3287 sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
3288
3289 status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id,
3290 FCP_LUN_RESET);
3291
3292 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3293 "0713 SCSI layer issued Device Reset (%d, %d) "
3294 "return x%x\n", tgt_id, lun_id, status);
3295
3296 /*
3297 * We have to clean up i/o as : they may be orphaned by the TMF;
3298 * or if the TMF failed, they may be in an indeterminate state.
3299 * So, continue on.
3300 * We will report success if all the i/o aborts successfully.
3301 */
3302 status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
3303 LPFC_CTX_LUN);
3304 return status;
3305}
3306
3307/**
3308 * lpfc_target_reset_handler - scsi_host_template eh_target_reset entry point
3309 * @cmnd: Pointer to scsi_cmnd data structure.
3310 *
3311 * This routine does a target reset by sending a TARGET_RESET task management
3312 * command.
3313 *
3314 * Return code :
3315 * 0x2003 - Error
3316 * 0x2002 - Success
3317 **/
3318static int
3319lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
3320{
3321 struct Scsi_Host *shost = cmnd->device->host;
3322 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
3323 struct lpfc_rport_data *rdata = cmnd->device->hostdata;
3324 struct lpfc_nodelist *pnode = rdata->pnode;
3325 unsigned tgt_id = cmnd->device->id;
3326 unsigned int lun_id = cmnd->device->lun;
3327 struct lpfc_scsi_event_header scsi_event;
3328 int status;
3329
3330 lpfc_block_error_handler(cmnd);
3331
3332 status = lpfc_chk_tgt_mapped(vport, cmnd);
3333 if (status == FAILED) {
3334 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3335 "0722 Target Reset rport failure: rdata x%p\n", rdata);
3336 return FAILED;
3337 }
3338
3339 scsi_event.event_type = FC_REG_SCSI_EVENT;
3340 scsi_event.subcategory = LPFC_EVENT_TGTRESET;
3341 scsi_event.lun = 0;
3342 memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
3343 memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
3344
3345 fc_host_post_vendor_event(shost, fc_get_event_number(),
3346 sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
3347
3348 status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id,
3349 FCP_TARGET_RESET);
3350
3351 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3352 "0723 SCSI layer issued Target Reset (%d, %d) "
3353 "return x%x\n", tgt_id, lun_id, status);
3354
3355 /*
3356 * We have to clean up i/o as : they may be orphaned by the TMF;
3357 * or if the TMF failed, they may be in an indeterminate state.
3358 * So, continue on.
3359 * We will report success if all the i/o aborts successfully.
3360 */
3361 status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
3362 LPFC_CTX_TGT);
3363 return status;
3249} 3364}
3250 3365
3251/** 3366/**
3252 * lpfc_bus_reset_handler - scsi_host_template eh_bus_reset_handler entry point 3367 * lpfc_bus_reset_handler - scsi_host_template eh_bus_reset_handler entry point
3253 * @cmnd: Pointer to scsi_cmnd data structure. 3368 * @cmnd: Pointer to scsi_cmnd data structure.
3254 * 3369 *
3255 * This routine does target reset to all target on @cmnd->device->host. 3370 * This routine does target reset to all targets on @cmnd->device->host.
3371 * This emulates Parallel SCSI Bus Reset Semantics.
3256 * 3372 *
3257 * Return Code: 3373 * Return code :
3258 * 0x2003 - Error 3374 * 0x2003 - Error
3259 * 0x2002 - Success 3375 * 0x2002 - Success
3260 **/ 3376 **/
3261static int 3377static int
3262lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) 3378lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
3263{ 3379{
3264 struct Scsi_Host *shost = cmnd->device->host; 3380 struct Scsi_Host *shost = cmnd->device->host;
3265 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 3381 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
3266 struct lpfc_hba *phba = vport->phba;
3267 struct lpfc_nodelist *ndlp = NULL; 3382 struct lpfc_nodelist *ndlp = NULL;
3268 int match;
3269 int ret = SUCCESS, status = SUCCESS, i;
3270 int cnt;
3271 struct lpfc_scsi_buf * lpfc_cmd;
3272 unsigned long later;
3273 struct lpfc_scsi_event_header scsi_event; 3383 struct lpfc_scsi_event_header scsi_event;
3384 int match;
3385 int ret = SUCCESS, status, i;
3274 3386
3275 scsi_event.event_type = FC_REG_SCSI_EVENT; 3387 scsi_event.event_type = FC_REG_SCSI_EVENT;
3276 scsi_event.subcategory = LPFC_EVENT_BUSRESET; 3388 scsi_event.subcategory = LPFC_EVENT_BUSRESET;
@@ -3278,13 +3390,11 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
3278 memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name)); 3390 memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name));
3279 memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name)); 3391 memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name));
3280 3392
3281 fc_host_post_vendor_event(shost, 3393 fc_host_post_vendor_event(shost, fc_get_event_number(),
3282 fc_get_event_number(), 3394 sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
3283 sizeof(scsi_event),
3284 (char *)&scsi_event,
3285 LPFC_NL_VENDOR_ID);
3286 3395
3287 lpfc_block_error_handler(cmnd); 3396 lpfc_block_error_handler(cmnd);
3397
3288 /* 3398 /*
3289 * Since the driver manages a single bus device, reset all 3399 * Since the driver manages a single bus device, reset all
3290 * targets known to the driver. Should any target reset 3400 * targets known to the driver. Should any target reset
@@ -3307,16 +3417,11 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
3307 spin_unlock_irq(shost->host_lock); 3417 spin_unlock_irq(shost->host_lock);
3308 if (!match) 3418 if (!match)
3309 continue; 3419 continue;
3310 lpfc_cmd = lpfc_get_scsi_buf(phba); 3420
3311 if (lpfc_cmd) { 3421 status = lpfc_send_taskmgmt(vport, ndlp->rport->dd_data,
3312 lpfc_cmd->timeout = 60; 3422 i, 0, FCP_TARGET_RESET);
3313 status = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i, 3423
3314 cmnd->device->lun, 3424 if (status != SUCCESS) {
3315 ndlp->rport->dd_data);
3316 if (status != TIMEOUT_ERROR)
3317 lpfc_release_scsi_buf(phba, lpfc_cmd);
3318 }
3319 if (!lpfc_cmd || status != SUCCESS) {
3320 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3425 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3321 "0700 Bus Reset on target %d failed\n", 3426 "0700 Bus Reset on target %d failed\n",
3322 i); 3427 i);
@@ -3324,25 +3429,16 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
3324 } 3429 }
3325 } 3430 }
3326 /* 3431 /*
3327 * All outstanding txcmplq I/Os should have been aborted by 3432 * We have to clean up i/o as : they may be orphaned by the TMFs
3328 * the targets. Unfortunately, some targets do not abide by 3433 * above; or if any of the TMFs failed, they may be in an
3329 * this forcing the driver to double check. 3434 * indeterminate state.
3435 * We will report success if all the i/o aborts successfully.
3330 */ 3436 */
3331 cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); 3437
3332 if (cnt) 3438 status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST);
3333 lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 3439 if (status != SUCCESS)
3334 0, 0, LPFC_CTX_HOST);
3335 later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
3336 while (time_after(later, jiffies) && cnt) {
3337 schedule_timeout_uninterruptible(msecs_to_jiffies(20));
3338 cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST);
3339 }
3340 if (cnt) {
3341 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3342 "0715 Bus Reset I/O flush failure: "
3343 "cnt x%x left x%x\n", cnt, i);
3344 ret = FAILED; 3440 ret = FAILED;
3345 } 3441
3346 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 3442 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
3347 "0714 SCSI layer issued Bus Reset Data: x%x\n", ret); 3443 "0714 SCSI layer issued Bus Reset Data: x%x\n", ret);
3348 return ret; 3444 return ret;
@@ -3475,7 +3571,8 @@ struct scsi_host_template lpfc_template = {
3475 .info = lpfc_info, 3571 .info = lpfc_info,
3476 .queuecommand = lpfc_queuecommand, 3572 .queuecommand = lpfc_queuecommand,
3477 .eh_abort_handler = lpfc_abort_handler, 3573 .eh_abort_handler = lpfc_abort_handler,
3478 .eh_device_reset_handler= lpfc_device_reset_handler, 3574 .eh_device_reset_handler = lpfc_device_reset_handler,
3575 .eh_target_reset_handler = lpfc_target_reset_handler,
3479 .eh_bus_reset_handler = lpfc_bus_reset_handler, 3576 .eh_bus_reset_handler = lpfc_bus_reset_handler,
3480 .slave_alloc = lpfc_slave_alloc, 3577 .slave_alloc = lpfc_slave_alloc,
3481 .slave_configure = lpfc_slave_configure, 3578 .slave_configure = lpfc_slave_configure,
@@ -3495,7 +3592,8 @@ struct scsi_host_template lpfc_vport_template = {
3495 .info = lpfc_info, 3592 .info = lpfc_info,
3496 .queuecommand = lpfc_queuecommand, 3593 .queuecommand = lpfc_queuecommand,
3497 .eh_abort_handler = lpfc_abort_handler, 3594 .eh_abort_handler = lpfc_abort_handler,
3498 .eh_device_reset_handler= lpfc_device_reset_handler, 3595 .eh_device_reset_handler = lpfc_device_reset_handler,
3596 .eh_target_reset_handler = lpfc_target_reset_handler,
3499 .eh_bus_reset_handler = lpfc_bus_reset_handler, 3597 .eh_bus_reset_handler = lpfc_bus_reset_handler,
3500 .slave_alloc = lpfc_slave_alloc, 3598 .slave_alloc = lpfc_slave_alloc,
3501 .slave_configure = lpfc_slave_configure, 3599 .slave_configure = lpfc_slave_configure,