Commit 23635cf2 authored by Finn Thain's avatar Finn Thain Committed by Greg Kroah-Hartman

scsi: NCR5380: Don't clear busy flag when abort fails

[ Upstream commit 45ddc1b2 ]

When NCR5380_abort() returns FAILED, the driver forgets that the target is
still busy. Hence, further commands may be sent to the target, which may fail
during selection and produce the error message, "reselection after won
arbitration?". Prevent this by leaving the busy flag set when NCR5380_abort()
fails.
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent aeb0ed2e
...@@ -522,8 +522,6 @@ static void complete_cmd(struct Scsi_Host *instance, ...@@ -522,8 +522,6 @@ static void complete_cmd(struct Scsi_Host *instance,
hostdata->sensing = NULL; hostdata->sensing = NULL;
} }
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
...@@ -1711,6 +1709,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1711,6 +1709,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
complete_cmd(instance, cmd); complete_cmd(instance, cmd);
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
return; return;
#endif #endif
case PHASE_DATAIN: case PHASE_DATAIN:
...@@ -1793,6 +1792,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1793,6 +1792,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
cmd, scmd_id(cmd), cmd->device->lun); cmd, scmd_id(cmd), cmd->device->lun);
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
cmd->result &= ~0xffff; cmd->result &= ~0xffff;
cmd->result |= cmd->SCp.Status; cmd->result |= cmd->SCp.Status;
...@@ -1946,6 +1946,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1946,6 +1946,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
NCR5380_transfer_pio(instance, &phase, &len, &data); NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) { if (msgout == ABORT) {
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
complete_cmd(instance, cmd); complete_cmd(instance, cmd);
maybe_release_dma_irq(instance); maybe_release_dma_irq(instance);
...@@ -2100,13 +2101,16 @@ static void NCR5380_reselect(struct Scsi_Host *instance) ...@@ -2100,13 +2101,16 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance, dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
"reselect: removed %p from disconnected queue\n", tmp); "reselect: removed %p from disconnected queue\n", tmp);
} else { } else {
int target = ffs(target_mask) - 1;
shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n", shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
target_mask, lun); target_mask, lun);
/* /*
* Since we have an established nexus that we can't do anything * Since we have an established nexus that we can't do anything
* with, we must abort it. * with, we must abort it.
*/ */
do_abort(instance); if (do_abort(instance) == 0)
hostdata->busy[target] &= ~(1 << lun);
return; return;
} }
...@@ -2277,8 +2281,10 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) ...@@ -2277,8 +2281,10 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
out: out:
if (result == FAILED) if (result == FAILED)
dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd); dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd);
else else {
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd); dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
}
queue_work(hostdata->work_q, &hostdata->main_task); queue_work(hostdata->work_q, &hostdata->main_task);
maybe_release_dma_irq(instance); maybe_release_dma_irq(instance);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment