]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/scsi/NCR5380.c
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / scsi / NCR5380.c
index fe0535affc148fcf932c12fb1bb4e4e2f1829826..536426f25e866dab327bf8764e4b19a3422d0590 100644 (file)
@@ -149,12 +149,10 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
 
        if (scsi_bufflen(cmd)) {
                cmd->SCp.buffer = scsi_sglist(cmd);
-               cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
                cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        } else {
                cmd->SCp.buffer = NULL;
-               cmd->SCp.buffers_residual = 0;
                cmd->SCp.ptr = NULL;
                cmd->SCp.this_residual = 0;
        }
@@ -163,6 +161,17 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
        cmd->SCp.Message = 0;
 }
 
+static inline void advance_sg_buffer(struct scsi_cmnd *cmd)
+{
+       struct scatterlist *s = cmd->SCp.buffer;
+
+       if (!cmd->SCp.this_residual && s && !sg_is_last(s)) {
+               cmd->SCp.buffer = sg_next(s);
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
+               cmd->SCp.this_residual = cmd->SCp.buffer->length;
+       }
+}
+
 /**
  * NCR5380_poll_politely2 - wait for two chip register values
  * @hostdata: host private data
@@ -709,6 +718,8 @@ static void NCR5380_main(struct work_struct *work)
                        NCR5380_information_transfer(instance);
                        done = 0;
                }
+               if (!hostdata->connected)
+                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                spin_unlock_irq(&hostdata->lock);
                if (!done)
                        cond_resched();
@@ -1110,8 +1121,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
                spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_reselect(instance);
-               if (!hostdata->connected)
-                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
                goto out;
        }
@@ -1119,7 +1128,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        if (err < 0) {
                spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
                /* Can't touch cmd if it has been reclaimed by the scsi ML */
                if (!hostdata->selecting)
@@ -1157,7 +1165,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        if (err < 0) {
                shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                goto out;
        }
        if (!hostdata->selecting) {
@@ -1672,12 +1679,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                            sun3_dma_setup_done != cmd) {
                                int count;
 
-                               if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-                                       ++cmd->SCp.buffer;
-                                       --cmd->SCp.buffers_residual;
-                                       cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-                               }
+                               advance_sg_buffer(cmd);
 
                                count = sun3scsi_dma_xfer_len(hostdata, cmd);
 
@@ -1727,15 +1729,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                 * scatter-gather list, move onto the next one.
                                 */
 
-                               if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-                                       ++cmd->SCp.buffer;
-                                       --cmd->SCp.buffers_residual;
-                                       cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-                                       dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
-                                                cmd->SCp.this_residual,
-                                                cmd->SCp.buffers_residual);
-                               }
+                               advance_sg_buffer(cmd);
+                               dsprintk(NDEBUG_INFORMATION, instance,
+                                       "this residual %d, sg ents %d\n",
+                                       cmd->SCp.this_residual,
+                                       sg_nents(cmd->SCp.buffer));
 
                                /*
                                 * The preferred transfer method is going to be
@@ -1763,10 +1761,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                scmd_printk(KERN_INFO, cmd,
                                                        "switching to slow handshake\n");
                                                cmd->device->borken = 1;
-                                               sink = 1;
-                                               do_abort(instance);
-                                               cmd->result = DID_ERROR << 16;
-                                               /* XXX - need to source or sink data here, as appropriate */
+                                               do_reset(instance);
+                                               bus_reset_cleanup(instance);
                                        }
                                } else {
                                        /* Transfer a small chunk so that the
@@ -1826,9 +1822,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                         */
                                        NCR5380_write(TARGET_COMMAND_REG, 0);
 
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-
                                        maybe_release_dma_irq(instance);
                                        return;
                                case MESSAGE_REJECT:
@@ -1860,8 +1853,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                         */
                                        NCR5380_write(TARGET_COMMAND_REG, 0);
 
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 #ifdef SUN3_SCSI_VME
                                        dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -1964,7 +1955,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        cmd->result = DID_ERROR << 16;
                                        complete_cmd(instance, cmd);
                                        maybe_release_dma_irq(instance);
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        return;
                                }
                                msgout = NOP;
@@ -2136,12 +2126,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
        if (sun3_dma_setup_done != tmp) {
                int count;
 
-               if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
-                       ++tmp->SCp.buffer;
-                       --tmp->SCp.buffers_residual;
-                       tmp->SCp.this_residual = tmp->SCp.buffer->length;
-                       tmp->SCp.ptr = sg_virt(tmp->SCp.buffer);
-               }
+               advance_sg_buffer(tmp);
 
                count = sun3scsi_dma_xfer_len(hostdata, tmp);