scsi: NCR5380: Don't clear busy flag when abort fails
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: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
7ef55f6744
commit
45ddc1b248
|
@ -522,8 +522,6 @@ static void complete_cmd(struct Scsi_Host *instance,
|
|||
hostdata->sensing = NULL;
|
||||
}
|
||||
|
||||
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
|
||||
|
||||
cmd->scsi_done(cmd);
|
||||
}
|
||||
|
||||
|
@ -1713,6 +1711,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
|||
cmd->result = DID_ERROR << 16;
|
||||
complete_cmd(instance, cmd);
|
||||
hostdata->connected = NULL;
|
||||
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
|
||||
return;
|
||||
#endif
|
||||
case PHASE_DATAIN:
|
||||
|
@ -1795,6 +1794,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
|||
cmd, scmd_id(cmd), cmd->device->lun);
|
||||
|
||||
hostdata->connected = NULL;
|
||||
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
|
||||
|
||||
cmd->result &= ~0xffff;
|
||||
cmd->result |= cmd->SCp.Status;
|
||||
|
@ -1953,6 +1953,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
|||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||
if (msgout == ABORT) {
|
||||
hostdata->connected = NULL;
|
||||
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
|
||||
cmd->result = DID_ERROR << 16;
|
||||
complete_cmd(instance, cmd);
|
||||
maybe_release_dma_irq(instance);
|
||||
|
@ -2108,13 +2109,16 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
|
|||
dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
|
||||
"reselect: removed %p from disconnected queue\n", tmp);
|
||||
} else {
|
||||
int target = ffs(target_mask) - 1;
|
||||
|
||||
shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
|
||||
target_mask, lun);
|
||||
/*
|
||||
* Since we have an established nexus that we can't do anything
|
||||
* with, we must abort it.
|
||||
*/
|
||||
do_abort(instance);
|
||||
if (do_abort(instance) == 0)
|
||||
hostdata->busy[target] &= ~(1 << lun);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2285,8 +2289,10 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
|
|||
out:
|
||||
if (result == FAILED)
|
||||
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);
|
||||
}
|
||||
|
||||
queue_work(hostdata->work_q, &hostdata->main_task);
|
||||
maybe_release_dma_irq(instance);
|
||||
|
|
Loading…
Reference in New Issue