unsigned char msgout = NOP;
        int sink = 0;
        int len;
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
        int transfersize;
-#endif
        unsigned char *data;
        unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
        struct scsi_cmnd *cmd;
                                } else
 #endif                         /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
                                {
-                                       spin_unlock_irq(&hostdata->lock);
-                                       NCR5380_transfer_pio(instance, &phase,
-                                                            (int *)&cmd->SCp.this_residual,
+                                       /* Break up transfer into 3 ms chunks,
+                                        * presuming 6 accesses per handshake.
+                                        */
+                                       transfersize = min((unsigned long)cmd->SCp.this_residual,
+                                                          hostdata->accesses_per_ms / 2);
+                                       len = transfersize;
+                                       NCR5380_transfer_pio(instance, &phase, &len,
                                                             (unsigned char **)&cmd->SCp.ptr);
-                                       spin_lock_irq(&hostdata->lock);
+                                       cmd->SCp.this_residual -= transfersize - len;
                                }
-                               break;
+                               return;
                        case PHASE_MSGIN:
                                len = 1;
                                data = &tmp;
 
        unsigned char msgout = NOP;
        int sink = 0;
        int len;
-#if defined(REAL_DMA)
        int transfersize;
-#endif
        unsigned char *data;
        unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
        struct scsi_cmnd *cmd;
                                } else
 #endif /* defined(REAL_DMA) */
                                {
-                                       spin_unlock_irq(&hostdata->lock);
-                                       NCR5380_transfer_pio(instance, &phase,
-                                                            (int *)&cmd->SCp.this_residual,
+                                       /* Break up transfer into 3 ms chunks,
+                                        * presuming 6 accesses per handshake.
+                                        */
+                                       transfersize = min((unsigned long)cmd->SCp.this_residual,
+                                                          hostdata->accesses_per_ms / 2);
+                                       len = transfersize;
+                                       NCR5380_transfer_pio(instance, &phase, &len,
                                                             (unsigned char **)&cmd->SCp.ptr);
-                                       spin_lock_irq(&hostdata->lock);
+                                       cmd->SCp.this_residual -= transfersize - len;
                                }
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
                                /* if we had intended to dma that command clear it */
                                if (sun3_dma_setup_done == cmd)
                                        sun3_dma_setup_done = NULL;
 #endif
-                               break;
+                               return;
                        case PHASE_MSGIN:
                                len = 1;
                                data = &tmp;