mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-03 12:24:45 +08:00
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 tag = le32_to_cpu(psataPayload->tag);
|
||||||
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
||||||
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", 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->resp = SAS_TASK_COMPLETE;
|
||||||
ts->stat = SAS_DATA_OVERRUN;
|
ts->stat = SAS_DATA_OVERRUN;
|
||||||
ts->residual = 0;
|
ts->residual = 0;
|
||||||
if (pm8001_dev)
|
|
||||||
atomic_dec(&pm8001_dev->running_req);
|
|
||||||
break;
|
break;
|
||||||
case IO_XFER_ERROR_BREAK:
|
case IO_XFER_ERROR_BREAK:
|
||||||
pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
|
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);
|
IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
|
||||||
ts->resp = SAS_TASK_COMPLETE;
|
ts->resp = SAS_TASK_COMPLETE;
|
||||||
ts->stat = SAS_QUEUE_FULL;
|
ts->stat = SAS_QUEUE_FULL;
|
||||||
pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2853,20 +2849,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
ts->stat = SAS_OPEN_TO;
|
ts->stat = SAS_OPEN_TO;
|
||||||
break;
|
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 */
|
/*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 tag = le32_to_cpu(psataPayload->tag);
|
||||||
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
u32 port_id = le32_to_cpu(psataPayload->port_id);
|
||||||
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
u32 dev_id = le32_to_cpu(psataPayload->device_id);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", 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->resp = SAS_TASK_COMPLETE;
|
||||||
ts->stat = SAS_DATA_OVERRUN;
|
ts->stat = SAS_DATA_OVERRUN;
|
||||||
ts->residual = 0;
|
ts->residual = 0;
|
||||||
if (pm8001_dev)
|
|
||||||
atomic_dec(&pm8001_dev->running_req);
|
|
||||||
break;
|
break;
|
||||||
case IO_XFER_ERROR_BREAK:
|
case IO_XFER_ERROR_BREAK:
|
||||||
pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
|
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);
|
IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
|
||||||
ts->resp = SAS_TASK_COMPLETE;
|
ts->resp = SAS_TASK_COMPLETE;
|
||||||
ts->stat = SAS_QUEUE_FULL;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3008,24 +3000,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
|
|||||||
ts->stat = SAS_OPEN_TO;
|
ts->stat = SAS_OPEN_TO;
|
||||||
break;
|
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 */
|
/*See the comments for mpi_ssp_completion */
|
||||||
|
Loading…
Reference in New Issue
Block a user