Commit ccf6efd7 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen

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: 707d62b3 ("ncr5380: Fix EH during arbitration and selection")
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Cc: <stable@vger.kernel.org> # 4.5
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dc183965
...@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_struct *work) ...@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata = struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task); container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host; struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *cmd;
int done; int done;
do { do {
done = 1; done = 1;
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
while (!hostdata->connected && while (!hostdata->connected && !hostdata->selecting) {
(cmd = dequeue_next_cmd(instance))) { struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
if (!cmd)
break;
dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd); dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
...@@ -840,8 +842,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -840,8 +842,7 @@ static void NCR5380_main(struct work_struct *work)
* entire unit. * entire unit.
*/ */
cmd = NCR5380_select(instance, cmd); if (!NCR5380_select(instance, cmd)) {
if (!cmd) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else { } else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
...@@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance, ...@@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Reselection interrupt */ /* Reselection interrupt */
goto out; goto out;
} }
if (!hostdata->selecting) {
/* Command was aborted */
NCR5380_write(MODE_REG, MR_BASE);
goto out;
}
if (err < 0) { if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE); NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance, shost_printk(KERN_ERR, instance,
......
...@@ -923,7 +923,6 @@ static void NCR5380_main(struct work_struct *work) ...@@ -923,7 +923,6 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata = struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task); container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host; struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *cmd;
int done; int done;
/* /*
...@@ -936,8 +935,11 @@ static void NCR5380_main(struct work_struct *work) ...@@ -936,8 +935,11 @@ static void NCR5380_main(struct work_struct *work)
done = 1; done = 1;
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
while (!hostdata->connected && while (!hostdata->connected && !hostdata->selecting) {
(cmd = dequeue_next_cmd(instance))) { struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
if (!cmd)
break;
dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd); dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
...@@ -960,8 +962,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -960,8 +962,7 @@ static void NCR5380_main(struct work_struct *work)
#ifdef SUPPORT_TAGS #ifdef SUPPORT_TAGS
cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE); cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
#endif #endif
cmd = NCR5380_select(instance, cmd); if (!NCR5380_select(instance, cmd)) {
if (!cmd) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
maybe_release_dma_irq(instance); maybe_release_dma_irq(instance);
} else { } else {
...@@ -1257,6 +1258,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance, ...@@ -1257,6 +1258,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Reselection interrupt */ /* Reselection interrupt */
goto out; goto out;
} }
if (!hostdata->selecting) {
/* Command was aborted */
NCR5380_write(MODE_REG, MR_BASE);
goto out;
}
if (err < 0) { if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE); NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance, shost_printk(KERN_ERR, 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