summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/atari_NCR5380.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-01-03 06:05:23 +0100
committerMartin K. Petersen <martin.petersen@oracle.com>2016-01-07 03:42:56 +0100
commitae753a3387504daa11b8779a00d37923f971c6d0 (patch)
tree2249c062810abfb64f7b973af8de27d0c6e49646 /drivers/scsi/atari_NCR5380.c
parentncr5380: Sleep when polling, if possible (diff)
downloadlinux-ae753a3387504daa11b8779a00d37923f971c6d0.tar.xz
linux-ae753a3387504daa11b8779a00d37923f971c6d0.zip
ncr5380: Eliminate selecting state
Linux v2.1.105 changed the algorithm for polling for the BSY signal in NCR5380_select() and NCR5380_main(). Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1) meant reschedule main() after sleeping for 10 ms. Repeated 25 times this provided the recommended 250 ms selection time-out delay. This got broken when HZ became configurable. We could fix this but there's no need to reschedule the main loop. This BSY polling presently happens when the NCR5380_main() work queue item calls NCR5380_select(), which in turn schedules NCR5380_main(), which calls NCR5380_select() again, and so on. This algorithm is a deviation from the simpler one in atari_NCR5380.c. The extra complexity and state is pointless. There's no reason to stop selection half-way and return to to the main loop when the main loop can do nothing useful until selection completes. So just poll for BSY. We can sleep while polling now that we have a suitable workqueue. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/atari_NCR5380.c')
-rw-r--r--drivers/scsi/atari_NCR5380.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 8b4e321b8399..34cf4d938589 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -1431,7 +1431,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
unsigned char tmp[3], phase;
unsigned char *data;
int len;
- unsigned long timeout;
+ int err;
unsigned long flags;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
@@ -1605,25 +1605,8 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
* selection.
*/
- timeout = jiffies + msecs_to_jiffies(250);
-
- /*
- * XXX very interesting - we're seeing a bounce where the BSY we
- * asserted is being reflected / still asserted (propagation delay?)
- * and it's detecting as true. Sigh.
- */
-
-#if 0
- /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
- * IO while SEL is true. But again, there are some disks out the in the
- * world that do that nevertheless. (Somebody claimed that this announces
- * reselection capability of the target.) So we better skip that test and
- * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
- */
-
- while (time_before(jiffies, timeout) &&
- !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
- ;
+ err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+ msecs_to_jiffies(250));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1633,22 +1616,8 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
-#else
- while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
- ;
-#endif
-
- /*
- * No less than two deskew delays after the initiator detects the
- * BSY signal is true, it shall release the SEL signal and may
- * change the DATA BUS. -wingel
- */
-
- udelay(1);
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
- if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
+ if (err < 0) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
#ifdef SUPPORT_TAGS
@@ -1661,6 +1630,16 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
}
/*
+ * No less than two deskew delays after the initiator detects the
+ * BSY signal is true, it shall release the SEL signal and may
+ * change the DATA BUS. -wingel
+ */
+
+ udelay(1);
+
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+
+ /*
* Since we followed the SCSI spec, and raised ATN while SEL
* was true but before BSY was false during selection, the information
* transfer phase should be a MESSAGE OUT phase so that we can send the