scsi: mac_scsi: Refactor polling loop
authorFinn Thain <fthain@linux-m68k.org>
Wed, 7 Aug 2024 03:36:28 +0000 (13:36 +1000)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 13 Aug 2024 02:05:48 +0000 (22:05 -0400)
Before the error handling can be revised, some preparation is needed.
Refactor the polling loop with a new function, macscsi_wait_for_drq().
This function will gain more call sites in the next patch.

Cc: stable@vger.kernel.org # 5.15+
Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Link: https://lore.kernel.org/r/6a5ffabb4290c0d138c6d285fda8fa3902e926f0.1723001788.git.fthain@linux-m68k.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mac_scsi.c

index e67b038a3577401a2566b45472911f4db45931fb..99a2008f875287bbb055f649b325524e14753333 100644 (file)
@@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);
                ".previous                     \n" \
                : "+a" (addr), "+r" (n), "+r" (result) : "a" (io))
 
-#define MAC_PDMA_DELAY         32
-
 static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n)
 {
        unsigned char *addr = start;
@@ -274,6 +272,36 @@ static inline void write_ctrl_reg(struct NCR5380_hostdata *hostdata, u32 value)
        out_be32(hostdata->io + (CTRL_REG << 4), value);
 }
 
+static inline int macscsi_wait_for_drq(struct NCR5380_hostdata *hostdata)
+{
+       unsigned int n = 1; /* effectively multiplies NCR5380_REG_POLL_TIME */
+       unsigned char basr;
+
+again:
+       basr = NCR5380_read(BUS_AND_STATUS_REG);
+
+       if (!(basr & BASR_PHASE_MATCH))
+               return 1;
+
+       if (basr & BASR_IRQ)
+               return -1;
+
+       if (basr & BASR_DRQ)
+               return 0;
+
+       if (n-- == 0) {
+               NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
+               dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
+                        "%s: DRQ timeout\n", __func__);
+               return -1;
+       }
+
+       NCR5380_poll_politely2(hostdata,
+                              BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
+                              BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, 0);
+       goto again;
+}
+
 static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
                                 unsigned char *dst, int len)
 {
@@ -283,9 +311,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
 
        hostdata->pdma_residual = len;
 
-       while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
-                                     BASR_DRQ | BASR_PHASE_MATCH,
-                                     BASR_DRQ | BASR_PHASE_MATCH, 0)) {
+       while (macscsi_wait_for_drq(hostdata) == 0) {
                int bytes, chunk_bytes;
 
                if (macintosh_config->ident == MAC_MODEL_IIFX)
@@ -295,19 +321,16 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
                chunk_bytes = min(hostdata->pdma_residual, 512);
                bytes = mac_pdma_recv(s, d, chunk_bytes);
 
+               if (macintosh_config->ident == MAC_MODEL_IIFX)
+                       write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
+
                if (bytes > 0) {
                        d += bytes;
                        hostdata->pdma_residual -= bytes;
                }
 
                if (hostdata->pdma_residual == 0)
-                       goto out;
-
-               if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
-                       goto out;
-
-               if (bytes == 0)
-                       udelay(MAC_PDMA_DELAY);
+                       break;
 
                if (bytes > 0)
                        continue;
@@ -321,16 +344,9 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
                        continue;
 
                result = -1;
-               goto out;
+               break;
        }
 
-       scmd_printk(KERN_ERR, hostdata->connected,
-                   "%s: phase mismatch or !DRQ\n", __func__);
-       NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
-       result = -1;
-out:
-       if (macintosh_config->ident == MAC_MODEL_IIFX)
-               write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
        return result;
 }
 
@@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
 
        hostdata->pdma_residual = len;
 
-       while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
-                                     BASR_DRQ | BASR_PHASE_MATCH,
-                                     BASR_DRQ | BASR_PHASE_MATCH, 0)) {
+       while (macscsi_wait_for_drq(hostdata) == 0) {
                int bytes, chunk_bytes;
 
                if (macintosh_config->ident == MAC_MODEL_IIFX)
@@ -355,6 +369,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
                chunk_bytes = min(hostdata->pdma_residual, 512);
                bytes = mac_pdma_send(s, d, chunk_bytes);
 
+               if (macintosh_config->ident == MAC_MODEL_IIFX)
+                       write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
+
                if (bytes > 0) {
                        s += bytes;
                        hostdata->pdma_residual -= bytes;
@@ -369,15 +386,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
                                            "%s: Last Byte Sent timeout\n", __func__);
                                result = -1;
                        }
-                       goto out;
+                       break;
                }
 
-               if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
-                       goto out;
-
-               if (bytes == 0)
-                       udelay(MAC_PDMA_DELAY);
-
                if (bytes > 0)
                        continue;
 
@@ -390,16 +401,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
                        continue;
 
                result = -1;
-               goto out;
+               break;
        }
 
-       scmd_printk(KERN_ERR, hostdata->connected,
-                   "%s: phase mismatch or !DRQ\n", __func__);
-       NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
-       result = -1;
-out:
-       if (macintosh_config->ident == MAC_MODEL_IIFX)
-               write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
        return result;
 }