@@ -3839,6 +3839,18 @@ int mpi3mr_issue_tm(struct mpi3mr_ioc *mrioc, u8 tm_type,
38393839 tgtdev = mpi3mr_get_tgtdev_by_handle (mrioc , handle );
38403840
38413841 if (scmd ) {
3842+ if (tm_type == MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK ) {
3843+ cmd_priv = scsi_cmd_priv (scmd );
3844+ if (!cmd_priv )
3845+ goto out_unlock ;
3846+
3847+ struct op_req_qinfo * op_req_q ;
3848+
3849+ op_req_q = & mrioc -> req_qinfo [cmd_priv -> req_q_idx ];
3850+ tm_req .task_host_tag = cpu_to_le16 (cmd_priv -> host_tag );
3851+ tm_req .task_request_queue_id =
3852+ cpu_to_le16 (op_req_q -> qid );
3853+ }
38423854 sdev = scmd -> device ;
38433855 sdev_priv_data = sdev -> hostdata ;
38443856 scsi_tgt_priv_data = ((sdev_priv_data ) ?
@@ -4387,6 +4399,92 @@ static int mpi3mr_eh_dev_reset(struct scsi_cmnd *scmd)
43874399 return retval ;
43884400}
43894401
4402+ /**
4403+ * mpi3mr_eh_abort - Callback function for abort error handling
4404+ * @scmd: SCSI command reference
4405+ *
4406+ * Issues Abort Task Management if the command is in LLD scope
4407+ * and verifies if it is aborted successfully, and return status
4408+ * accordingly.
4409+ *
4410+ * Return: SUCCESS if the abort was successful, otherwise FAILED
4411+ */
4412+ static int mpi3mr_eh_abort (struct scsi_cmnd * scmd )
4413+ {
4414+ struct mpi3mr_ioc * mrioc = shost_priv (scmd -> device -> host );
4415+ struct mpi3mr_stgt_priv_data * stgt_priv_data ;
4416+ struct mpi3mr_sdev_priv_data * sdev_priv_data ;
4417+ struct scmd_priv * cmd_priv ;
4418+ u16 dev_handle , timeout = MPI3MR_ABORTTM_TIMEOUT ;
4419+ u8 resp_code = 0 ;
4420+ int retval = FAILED , ret = 0 ;
4421+ struct request * rq = scsi_cmd_to_rq (scmd );
4422+ unsigned long scmd_age_ms = jiffies_to_msecs (jiffies - scmd -> jiffies_at_alloc );
4423+ unsigned long scmd_age_sec = scmd_age_ms / HZ ;
4424+
4425+ sdev_printk (KERN_INFO , scmd -> device ,
4426+ "%s: attempting abort task for scmd(%p)\n" , mrioc -> name , scmd );
4427+
4428+ sdev_printk (KERN_INFO , scmd -> device ,
4429+ "%s: scmd(0x%p) is outstanding for %lus %lums, timeout %us, retries %d, allowed %d\n" ,
4430+ mrioc -> name , scmd , scmd_age_sec , scmd_age_ms % HZ , rq -> timeout / HZ ,
4431+ scmd -> retries , scmd -> allowed );
4432+
4433+ scsi_print_command (scmd );
4434+
4435+ sdev_priv_data = scmd -> device -> hostdata ;
4436+ if (!sdev_priv_data || !sdev_priv_data -> tgt_priv_data ) {
4437+ sdev_printk (KERN_INFO , scmd -> device ,
4438+ "%s: Device not available, Skip issuing abort task\n" ,
4439+ mrioc -> name );
4440+ retval = SUCCESS ;
4441+ goto out ;
4442+ }
4443+
4444+ stgt_priv_data = sdev_priv_data -> tgt_priv_data ;
4445+ dev_handle = stgt_priv_data -> dev_handle ;
4446+
4447+ cmd_priv = scsi_cmd_priv (scmd );
4448+ if (!cmd_priv -> in_lld_scope ||
4449+ cmd_priv -> host_tag == MPI3MR_HOSTTAG_INVALID ) {
4450+ sdev_printk (KERN_INFO , scmd -> device ,
4451+ "%s: scmd (0x%p) not in LLD scope, Skip issuing Abort Task\n" ,
4452+ mrioc -> name , scmd );
4453+ retval = SUCCESS ;
4454+ goto out ;
4455+ }
4456+
4457+ if (stgt_priv_data -> dev_removed ) {
4458+ sdev_printk (KERN_INFO , scmd -> device ,
4459+ "%s: Device (handle = 0x%04x) removed, Skip issuing Abort Task\n" ,
4460+ mrioc -> name , dev_handle );
4461+ retval = FAILED ;
4462+ goto out ;
4463+ }
4464+
4465+ ret = mpi3mr_issue_tm (mrioc , MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK ,
4466+ dev_handle , sdev_priv_data -> lun_id , MPI3MR_HOSTTAG_BLK_TMS ,
4467+ timeout , & mrioc -> host_tm_cmds , & resp_code , scmd );
4468+
4469+ if (ret )
4470+ goto out ;
4471+
4472+ if (cmd_priv -> in_lld_scope ) {
4473+ sdev_printk (KERN_INFO , scmd -> device ,
4474+ "%s: Abort task failed. scmd (0x%p) was not terminated\n" ,
4475+ mrioc -> name , scmd );
4476+ goto out ;
4477+ }
4478+
4479+ retval = SUCCESS ;
4480+ out :
4481+ sdev_printk (KERN_INFO , scmd -> device ,
4482+ "%s: Abort Task %s for scmd (0x%p)\n" , mrioc -> name ,
4483+ ((retval == SUCCESS ) ? "SUCCEEDED" : "FAILED" ), scmd );
4484+
4485+ return retval ;
4486+ }
4487+
43904488/**
43914489 * mpi3mr_scan_start - Scan start callback handler
43924490 * @shost: SCSI host reference
@@ -5069,6 +5167,7 @@ static struct scsi_host_template mpi3mr_driver_template = {
50695167 .scan_finished = mpi3mr_scan_finished ,
50705168 .scan_start = mpi3mr_scan_start ,
50715169 .change_queue_depth = mpi3mr_change_queue_depth ,
5170+ .eh_abort_handler = mpi3mr_eh_abort ,
50725171 .eh_device_reset_handler = mpi3mr_eh_dev_reset ,
50735172 .eh_target_reset_handler = mpi3mr_eh_target_reset ,
50745173 .eh_bus_reset_handler = mpi3mr_eh_bus_reset ,
0 commit comments