scsi: pm80xx: Fix double completion for SATA devices
Current code handles completions for SATA devices in mpi_sata_completion() and mpi_sata_event(). However, at the time when any SATA event happens, for almost all the event types, the command is still in the target. It is therefore incorrect to complete the task in sata_event(). There are some events for which we get sata_completions, some need recovery procedure and others abort. All the tasks must be completed via sata_completion() path. Removed the task done related code from sata_events(). For tasks where we don't get completions, let top layer call abort() to abort the command post timeout. Link: https://lore.kernel.org/r/20220124082255.86223-1-Ajish.Koshy@microchip.com Acked-by: Jack Wang <jinpu.wang@ionos.com> Co-developed-by: Viswas G <Viswas.G@microchip.com> Signed-off-by: Viswas G <Viswas.G@microchip.com> Signed-off-by: Ajish Koshy <Ajish.Koshy@microchip.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
4db09593af
commit
c26b85ea16
@ -2692,7 +2692,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
u32 tag = le32_to_cpu(psataPayload->tag);
|
||||
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
||||
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
||||
unsigned long flags;
|
||||
|
||||
if (event)
|
||||
pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", event);
|
||||
@ -2724,8 +2723,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
ts->resp = SAS_TASK_COMPLETE;
|
||||
ts->stat = SAS_DATA_OVERRUN;
|
||||
ts->residual = 0;
|
||||
if (pm8001_dev)
|
||||
atomic_dec(&pm8001_dev->running_req);
|
||||
break;
|
||||
case IO_XFER_ERROR_BREAK:
|
||||
pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
|
||||
@ -2767,7 +2764,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
|
||||
ts->resp = SAS_TASK_COMPLETE;
|
||||
ts->stat = SAS_QUEUE_FULL;
|
||||
pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -2853,20 +2849,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
ts->stat = SAS_OPEN_TO;
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&t->task_state_lock, flags);
|
||||
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
||||
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
||||
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
||||
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
||||
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
||||
t, event, ts->resp, ts->stat);
|
||||
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
||||
pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
|
||||
}
|
||||
}
|
||||
|
||||
/*See the comments for mpi_ssp_completion */
|
||||
|
@ -2821,7 +2821,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
|
||||
u32 tag = le32_to_cpu(psataPayload->tag);
|
||||
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
||||
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
||||
unsigned long flags;
|
||||
|
||||
if (event)
|
||||
pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", event);
|
||||
@ -2854,8 +2853,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
|
||||
ts->resp = SAS_TASK_COMPLETE;
|
||||
ts->stat = SAS_DATA_OVERRUN;
|
||||
ts->residual = 0;
|
||||
if (pm8001_dev)
|
||||
atomic_dec(&pm8001_dev->running_req);
|
||||
break;
|
||||
case IO_XFER_ERROR_BREAK:
|
||||
pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
|
||||
@ -2904,11 +2901,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
|
||||
IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
|
||||
ts->resp = SAS_TASK_COMPLETE;
|
||||
ts->stat = SAS_QUEUE_FULL;
|
||||
spin_unlock_irqrestore(&circularQ->oq_lock,
|
||||
circularQ->lock_flags);
|
||||
pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
|
||||
spin_lock_irqsave(&circularQ->oq_lock,
|
||||
circularQ->lock_flags);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -3008,24 +3000,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
|
||||
ts->stat = SAS_OPEN_TO;
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&t->task_state_lock, flags);
|
||||
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
||||
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
||||
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
||||
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
||||
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
||||
t, event, ts->resp, ts->stat);
|
||||
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
||||
spin_unlock_irqrestore(&circularQ->oq_lock,
|
||||
circularQ->lock_flags);
|
||||
pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
|
||||
spin_lock_irqsave(&circularQ->oq_lock,
|
||||
circularQ->lock_flags);
|
||||
}
|
||||
}
|
||||
|
||||
/*See the comments for mpi_ssp_completion */
|
||||
|
Loading…
Reference in New Issue
Block a user