".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;
        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)
 {
 
        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)
                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;
                        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;
 }
 
 
        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)
                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;
                                            "%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;
 
                        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;
 }