]> git.hungrycats.org Git - linux/commitdiff
[ARM] Make Acorn SCSI drivers build again.
authorRussell King <rmk@flint.arm.linux.org.uk>
Thu, 23 May 2002 02:25:47 +0000 (03:25 +0100)
committerRussell King <rmk@flint.arm.linux.org.uk>
Thu, 23 May 2002 02:25:47 +0000 (03:25 +0100)
 Acorn machines will never have "highmem" support, so can
 combine page + offset into the scsi pointer structure for
 now.

drivers/acorn/scsi/acornscsi.c
drivers/acorn/scsi/cumana_2.c
drivers/acorn/scsi/eesox.c
drivers/acorn/scsi/fas216.c
drivers/acorn/scsi/powertec.c
drivers/acorn/scsi/scsi.h [new file with mode: 0644]

index 267cf61a9d6da34ce530759d3ecfd21280d7659c..6f28450fe79000bcf7febd892f895b8526fecb94 100644 (file)
 #include "../../scsi/constants.h"
 #include "acornscsi.h"
 #include "msgqueue.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
@@ -902,17 +903,8 @@ void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int len
     SCp->ptr += length;
     SCp->this_residual -= length;
 
-    if (!SCp->this_residual) {
-       if (SCp->buffers_residual) {
-           SCp->buffer++;
-           SCp->buffers_residual--;
-           SCp->ptr = (char *)SCp->buffer->address;
-           SCp->this_residual = SCp->buffer->length;
-       } else {
-           SCp->ptr = NULL;
-           host->dma.xfer_done = 1;
-       }
-    }
+    if (SCp->this_residual == 0 && next_SCp(SCp) == 0)
+       host->dma.xfer_done = 1;
 }
 
 /*
@@ -2558,20 +2550,8 @@ int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
     SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
     SCpnt->SCp.sent_command = 0;
     SCpnt->SCp.scsi_xferred = 0;
-    SCpnt->SCp.Status = 0;
-    SCpnt->SCp.Message = 0;
-
-    if (SCpnt->use_sg) {
-       SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
-       SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
-       SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
-       SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
-    } else {
-       SCpnt->SCp.buffer = NULL;
-       SCpnt->SCp.buffers_residual = 0;
-       SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
-       SCpnt->SCp.this_residual = SCpnt->request_bufflen;
-    }
+
+    init_SCp(SCpnt);
 
     host->stats.queues += 1;
 
index 0b98eccd255d12db196a3aa389a0c3a0f6839f23..ea1ef16bf37ef1165f5d07325ae0649caee9ac30 100644 (file)
@@ -38,6 +38,7 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
@@ -188,15 +189,9 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 
        if (dmach != NO_DMA &&
            (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-               int bufs = SCp->buffers_residual;
-               int pci_dir, dma_dir, alatch_dir;
-
-               if (bufs)
-                       memcpy(info->sg + 1, SCp->buffer + 1,
-                               sizeof(struct scatterlist) * bufs);
-               info->sg[0].address = SCp->ptr;
-               info->sg[0].page    = NULL;
-               info->sg[0].length  = SCp->this_residual;
+               int bufs, pci_dir, dma_dir, alatch_dir;
+
+               bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
                if (direction == DMA_OUT)
                        pci_dir = PCI_DMA_TODEVICE,
index a3a49f3924beee45fb47ae631a45407f0a1d2947..a6d1f3cc2d924ddca1010b4fcb60844a37d8d20e 100644 (file)
@@ -44,6 +44,7 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
@@ -192,15 +193,9 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 
        if (dmach != NO_DMA &&
            (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-               int bufs = SCp->buffers_residual;
-               int pci_dir, dma_dir;
-
-               if (bufs)
-                       memcpy(info->sg + 1, SCp->buffer + 1,
-                               sizeof(struct scatterlist) * bufs);
-               info->sg[0].address = SCp->ptr;
-               info->sg[0].page    = NULL;
-               info->sg[0].length  = SCp->this_residual;
+               int bufs, pci_dir, dma_dir;
+
+               bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
                if (direction == DMA_OUT)
                        pci_dir = PCI_DMA_TODEVICE,
index 31e92aae0aa7420b22bd3ea104f8ab210fd767b4..445c1574453d0d942060e54130392785c2fc546b 100644 (file)
@@ -59,6 +59,7 @@
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #define VER_MAJOR      0
 #define VER_MINOR      0
@@ -588,38 +589,32 @@ fas216_handlewide(FAS216_Info *info, char *msg)
 static void
 fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
 {
-       unsigned char *ptr;
-       unsigned int residual;
+       Scsi_Pointer *SCp = &info->scsi.SCp;
 
        fas216_checkmagic(info);
 
-       ptr = info->scsi.SCp.ptr;
-       residual = info->scsi.SCp.this_residual;
-
        info->SCpnt->request_bufflen -= bytes_transferred;
 
-       while (residual <= bytes_transferred && bytes_transferred) {
-               /* We have used up this buffer */
-               bytes_transferred -= residual;
-               if (info->scsi.SCp.buffers_residual) {
-                       info->scsi.SCp.buffer++;
-                       info->scsi.SCp.buffers_residual--;
-                       ptr = (unsigned char *)info->scsi.SCp.buffer->address;
-                       residual = info->scsi.SCp.buffer->length;
-               } else {
-                       ptr = NULL;
-                       residual = 0;
+       while (bytes_transferred != 0) {
+               if (SCp->this_residual > bytes_transferred)
+                       break;
+               /*
+                * We have used up this buffer.  Move on to the
+                * next buffer.
+                */
+               bytes_transferred -= SCp->this_residual;
+               if (!next_SCp(&info->scsi.SCp)) {
+                       printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
+                               info->host->host_no, '0' + info->SCpnt->target);
+                       return;
                }
        }
 
-       residual -= bytes_transferred;
-       ptr += bytes_transferred;
-
-       if (residual == 0)
-               ptr = NULL;
-
-       info->scsi.SCp.ptr = ptr;
-       info->scsi.SCp.this_residual = residual;
+       SCp->this_residual -= bytes_transferred;
+       if (SCp->this_residual)
+               SCp->ptr += bytes_transferred;
+       else
+               SCp->ptr = NULL;
 }
 
 /* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
@@ -631,35 +626,12 @@ fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
 static void
 fas216_pio(FAS216_Info *info, fasdmadir_t direction)
 {
-       unsigned int residual;
-       char *ptr;
-
        fas216_checkmagic(info);
 
-       residual = info->scsi.SCp.this_residual;
-       ptr = info->scsi.SCp.ptr;
-
        if (direction == DMA_OUT)
-               outb(*ptr++, REG_FF(info));
+               outb(get_next_SCp_byte(&info->scsi.SCp), REG_FF(info));
        else
-               *ptr++ = inb(REG_FF(info));
-
-       residual -= 1;
-
-       if (residual == 0) {
-               if (info->scsi.SCp.buffers_residual) {
-                       info->scsi.SCp.buffer++;
-                       info->scsi.SCp.buffers_residual--;
-                       ptr = (unsigned char *)info->scsi.SCp.buffer->address;
-                       residual = info->scsi.SCp.buffer->length;
-               } else {
-                       ptr = NULL;
-                       residual = 0;
-               }
-       }
-
-       info->scsi.SCp.ptr = ptr;
-       info->scsi.SCp.this_residual = residual;
+               put_next_SCp_byte(&info->scsi.SCp, inb(REG_FF(info)));
 }
 
 /* Function: void fas216_starttransfer(FAS216_Info *info,
@@ -2034,48 +2006,8 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        SCpnt->scsi_done = done;
        SCpnt->host_scribble = (void *)fas216_std_done;
        SCpnt->result = 0;
-       SCpnt->SCp.Message = 0;
-       SCpnt->SCp.Status = 0;
-
-       if (SCpnt->use_sg) {
-               unsigned long len = 0;
-               int buf;
 
-               SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
-               SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
-               SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
-               SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
-               /*
-                * Calculate correct buffer length.  Some commands
-                * come in with the wrong request_bufflen.
-                */
-               for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
-                       len += SCpnt->SCp.buffer[buf].length;
-
-               if (SCpnt->request_bufflen != len)
-                       printk(KERN_WARNING "scsi%d.%c: bad request buffer "
-                              "length %d, should be %ld\n", info->host->host_no,
-                              '0' + SCpnt->target, SCpnt->request_bufflen, len);
-               SCpnt->request_bufflen = len;
-       } else {
-               SCpnt->SCp.buffer = NULL;
-               SCpnt->SCp.buffers_residual = 0;
-               SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
-               SCpnt->SCp.this_residual = SCpnt->request_bufflen;
-       }
-
-       /*
-        * If the upper SCSI layers pass a buffer, but zero length,
-        * we aren't interested in the buffer pointer.
-        */
-       if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
-#if 0
-               printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
-                      "command ", info->host->host_no, '0' + SCpnt->target);
-               print_command(SCpnt->cmnd);
-#endif
-               SCpnt->SCp.ptr = NULL;
-       }
+       init_SCp(SCpnt);
 
        info->stats.queues += 1;
        SCpnt->tag = 0;
index 8892b80fbef0032a13eff80b3ce85b62a4a2816b..c6d31e5ad92441713cab12c82784c0689ba94d7b 100644 (file)
@@ -41,6 +41,7 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
@@ -180,15 +181,9 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 
        if (dmach != NO_DMA &&
            (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-               int bufs = SCp->buffers_residual;
-               int pci_dir, dma_dir;
-
-               if (bufs)
-                       memcpy(info->sg + 1, SCp->buffer + 1,
-                               sizeof(struct scatterlist) * bufs);
-               info->sg[0].address = SCp->ptr;
-               info->sg[0].page    = NULL;
-               info->sg[0].length  = SCp->this_residual;
+               int bufs, pci_dir, dma_dir;
+
+               bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
                if (direction == DMA_OUT)
                        pci_dir = PCI_DMA_TODEVICE,
diff --git a/drivers/acorn/scsi/scsi.h b/drivers/acorn/scsi/scsi.h
new file mode 100644 (file)
index 0000000..fe4e8c8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ *  linux/drivers/acorn/scsi/scsi.h
+ *
+ *  Copyright (C) 2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Commonly used scsi driver functions.
+ */
+
+#define BELT_AND_BRACES
+
+/*
+ * The scatter-gather list handling.  This contains all
+ * the yucky stuff that needs to be fixed properly.
+ */
+static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max)
+{
+       int bufs = SCp->buffers_residual;
+
+       BUG_ON(bufs + 1 > max);
+
+       sg->page   = virt_to_page(SCp->ptr);
+       sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
+       sg->length = SCp->this_residual;
+
+       if (bufs)
+               memcpy(sg + 1, SCp->buffer + 1,
+                      sizeof(struct scatterlist) * bufs);
+       return bufs + 1;
+}
+
+static inline int next_SCp(Scsi_Pointer *SCp)
+{
+       int ret = SCp->buffers_residual;
+       if (ret) {
+               SCp->buffer++;
+               SCp->buffers_residual--;
+               SCp->ptr = (char *)
+                        (page_address(SCp->buffer->page) +
+                         SCp->buffer->offset);
+               SCp->this_residual = SCp->buffer->length;
+       } else {
+               SCp->ptr = NULL;
+               SCp->this_residual = 0;
+       }
+       return ret;
+}
+
+static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
+{
+       char c = SCp->ptr;
+
+       SCp->ptr += 1;
+       SCp->this_residual -= 1;
+       if (SCp->this_residual == 0)
+               next_SCp(SCp);
+
+       return c;
+}
+
+static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c)
+{
+       SCp->ptr = c;
+       SCp->ptr += 1;
+       SCp->this_residual -= 1;
+       if (SCp->this_residual == 0)
+               next_SCp(SCp);
+}
+
+static inline void init_SCp(Scsi_Cmnd *SCpnt)
+{
+       SCpnt->SCp.Message = 0;
+       SCpnt->SCp.Status = 0;
+
+       if (SCpnt->use_sg) {
+               unsigned long len = 0;
+               int buf;
+
+               SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
+               SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
+               SCpnt->SCp.ptr = (char *)
+                        (page_address(SCpnt->SCp.buffer->page) +
+                         SCpnt->SCp.buffer->offset);
+               SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+
+#ifdef BELT_AND_BRACES
+               /*
+                * Calculate correct buffer length.  Some commands
+                * come in with the wrong request_bufflen.
+                */
+               for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
+                       len += SCpnt->SCp.buffer[buf].length;
+
+               if (SCpnt->request_bufflen != len)
+                       printk(KERN_WARNING "scsi%d.%c: bad request buffer "
+                              "length %d, should be %ld\n", SCpnt->host->host_no,
+                              '0' + SCpnt->target, SCpnt->request_bufflen, len);
+               SCpnt->request_bufflen = len;
+#endif
+       } else {
+               SCpnt->SCp.buffer = NULL;
+               SCpnt->SCp.buffers_residual = 0;
+               SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
+               SCpnt->SCp.this_residual = SCpnt->request_bufflen;
+       }
+
+       /*
+        * If the upper SCSI layers pass a buffer, but zero length,
+        * we aren't interested in the buffer pointer.
+        */
+       if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
+#ifdef BELT_AND_BRACES
+               printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
+                      "command ", SCpnt->host->host_no, '0' + SCpnt->target);
+               print_command(SCpnt->cmnd);
+#endif
+               SCpnt->SCp.ptr = NULL;
+       }
+}