ncr5380: Fix NCR5380_select() EH checks and result handling

Add missing checks for EH abort during arbitration and selection.
Rework the handling of NCR5380_select() result to improve clarity.

Fixes: 707d62b37f ("ncr5380: Fix EH during arbitration and selection")
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Cc: <stable@vger.kernel.org> # 4.5
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Finn Thain 2016-02-23 10:07:08 +11:00 committed by Martin K. Petersen
parent dc18396528
commit ccf6efd783
2 changed files with 22 additions and 10 deletions

View File

@ -815,15 +815,17 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *cmd;
int done;
do {
done = 1;
spin_lock_irq(&hostdata->lock);
while (!hostdata->connected &&
(cmd = dequeue_next_cmd(instance))) {
while (!hostdata->connected && !hostdata->selecting) {
struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
if (!cmd)
break;
dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
@ -840,8 +842,7 @@ static void NCR5380_main(struct work_struct *work)
* entire unit.
*/
cmd = NCR5380_select(instance, cmd);
if (!cmd) {
if (!NCR5380_select(instance, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Reselection interrupt */
goto out;
}
if (!hostdata->selecting) {
/* Command was aborted */
NCR5380_write(MODE_REG, MR_BASE);
goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,

View File

@ -923,7 +923,6 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *cmd;
int done;
/*
@ -936,8 +935,11 @@ static void NCR5380_main(struct work_struct *work)
done = 1;
spin_lock_irq(&hostdata->lock);
while (!hostdata->connected &&
(cmd = dequeue_next_cmd(instance))) {
while (!hostdata->connected && !hostdata->selecting) {
struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
if (!cmd)
break;
dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
@ -960,8 +962,7 @@ static void NCR5380_main(struct work_struct *work)
#ifdef SUPPORT_TAGS
cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
#endif
cmd = NCR5380_select(instance, cmd);
if (!cmd) {
if (!NCR5380_select(instance, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
maybe_release_dma_irq(instance);
} else {
@ -1257,6 +1258,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Reselection interrupt */
goto out;
}
if (!hostdata->selecting) {
/* Command was aborted */
NCR5380_write(MODE_REG, MR_BASE);
goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,