fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / seagate.c
index 3a73cc7..ff62e97 100644 (file)
 #include <linux/string.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#include "scsi.h"
-#include "hosts.h"
-#include "seagate.h"
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi.h>
+
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_host.h>
 
-#include <scsi/scsi_ioctl.h>
 
 #ifdef DEBUG
 #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0)
 #else
 #define DPRINTK( when, msg... ) do { } while (0)
+#define DEBUG 0
 #endif
 #define DANY( msg... ) DPRINTK( 0xffff, msg );
 
@@ -237,13 +240,13 @@ static unsigned int base_address = 0;     /* Where the card ROM starts, used to
                                           calculate memory mapped register
                                           location.  */
 
-static unsigned long st0x_cr_sr;       /* control register write, status
+static void __iomem *st0x_cr_sr;       /* control register write, status
                                           register read.  256 bytes in
                                           length.
                                           Read is status of SCSI BUS, as per 
                                           STAT masks.  */
 
-static unsigned long st0x_dr;  /* data register, read write 256
+static void __iomem *st0x_dr;  /* data register, read write 256
                                   bytes in length.  */
 
 static volatile int st0x_aborted = 0;  /* set when we are aborted, ie by a
@@ -254,17 +257,17 @@ static unsigned char controller_type = 0; /* set to SEAGATE for ST0x
                                                   boards */
 static int irq = IRQ;
 
-MODULE_PARM (base_address, "i");
-MODULE_PARM (controller_type, "b");
-MODULE_PARM (irq, "i");
+module_param(base_address, uint, 0);
+module_param(controller_type, byte, 0);
+module_param(irq, int, 0);
 MODULE_LICENSE("GPL");
 
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
-#define STATUS ((u8) isa_readb(st0x_cr_sr))
-#define DATA ((u8) isa_readb(st0x_dr))
-#define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
-#define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }
+#define STATUS ((u8) readb(st0x_cr_sr))
+#define DATA ((u8) readb(st0x_dr))
+#define WRITE_CONTROL(d) { writeb((d), st0x_cr_sr); }
+#define WRITE_DATA(d) { writeb((d), st0x_dr); }
 
 #ifndef OVERRIDE
 static unsigned int seagate_bases[] = {
@@ -310,7 +313,7 @@ static Signature __initdata signatures[] = {
        {"IBM F1 V1.2009/22/93", 5, 25, FD},
 };
 
-#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
+#define NUM_SIGNATURES ARRAY_SIZE(signatures)
 #endif                         /* n OVERRIDE */
 
 /*
@@ -318,8 +321,9 @@ static Signature __initdata signatures[] = {
  */
 
 static int hostno = -1;
-static void seagate_reconnect_intr (int, void *, struct pt_regs *);
-static irqreturn_t do_seagate_reconnect_intr (int, void *, struct pt_regs *);
+static void seagate_reconnect_intr (int, void *);
+static irqreturn_t do_seagate_reconnect_intr (int, void *);
+static int seagate_st0x_bus_reset(struct scsi_cmnd *);
 
 #ifdef FAST
 static int fast = 1;
@@ -416,10 +420,11 @@ static inline void borken_wait (void)
 #define ULOOP( i ) for (clock = i*8;;)
 #define TIMEOUT (!(clock--))
 
-int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
+int __init seagate_st0x_detect (struct scsi_host_template * tpnt)
 {
        struct Scsi_Host *instance;
        int i, j;
+       unsigned long cr, dr;
 
        tpnt->proc_name = "seagate";
 /*
@@ -454,12 +459,18 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
  * space for the on-board RAM instead.
  */
 
-               for (i = 0; i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
-                       for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
-                               if (isa_check_signature(seagate_bases[i] + signatures[j].offset, signatures[j].signature, signatures[j].length)) {
+               for (i = 0; i < ARRAY_SIZE(seagate_bases); ++i) {
+                       void __iomem *p = ioremap(seagate_bases[i], 0x2000);
+                       if (!p)
+                               continue;
+                       for (j = 0; j < NUM_SIGNATURES; ++j)
+                               if (check_signature(p + signatures[j].offset, signatures[j].signature, signatures[j].length)) {
                                        base_address = seagate_bases[i];
                                        controller_type = signatures[j].type;
+                                       break;
                                }
+                       iounmap(p);
+               }
 #endif                         /* OVERRIDE */
        }
        /* (! controller_type) */
@@ -471,11 +482,13 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
                return 0;
        }
 
-       st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
-       st0x_dr = st0x_cr_sr + 0x200;
+       cr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+       dr = cr + 0x200;
+       st0x_cr_sr = ioremap(cr, 0x100);
+       st0x_dr = ioremap(dr, 0x100);
 
        DANY("%s detected. Base address = %x, cr = %x, dr = %x\n",
-             tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+             tpnt->name, base_address, cr, dr);
 
        /*
         *      At all times, we will use IRQ 5.  Should also check for IRQ3
@@ -486,7 +499,7 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
                return 0;
 
        hostno = instance->host_no;
-       if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT, (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", instance)) {
+       if (request_irq (irq, do_seagate_reconnect_intr, IRQF_DISABLED, (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", instance)) {
                printk(KERN_ERR "scsi%d : unable to allocate IRQ%d\n", hostno, irq);
                return 0;
        }
@@ -511,7 +524,7 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
 #ifdef ARBITRATE
                " ARBITRATE"
 #endif
-#ifdef DEBUG
+#if DEBUG
                " DEBUG"
 #endif
 #ifdef FAST
@@ -574,8 +587,8 @@ static int linked_connected = 0;
 static unsigned char linked_target, linked_lun;
 #endif
 
-static void (*done_fn) (Scsi_Cmnd *) = NULL;
-static Scsi_Cmnd *SCint = NULL;
+static void (*done_fn) (struct scsi_cmnd *) = NULL;
+static struct scsi_cmnd *SCint = NULL;
 
 /*
  * These control whether or not disconnect / reconnect will be attempted,
@@ -607,22 +620,21 @@ static int should_reconnect = 0;
  * asserting SEL.
  */
 
-static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
        
        spin_lock_irqsave (dev->host_lock, flags);
-       seagate_reconnect_intr (irq, dev_id, regs);
+       seagate_reconnect_intr (irq, dev_id);
        spin_unlock_irqrestore (dev->host_lock, flags);
        return IRQ_HANDLED;
 }
 
-static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
+static void seagate_reconnect_intr (int irq, void *dev_id)
 {
        int temp;
-       Scsi_Cmnd *SCtmp;
+       struct scsi_cmnd *SCtmp;
 
        DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
 
@@ -664,10 +676,11 @@ static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 
 static int recursion_depth = 0;
 
-static int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int seagate_st0x_queue_command(struct scsi_cmnd * SCpnt,
+                                     void (*done) (struct scsi_cmnd *))
 {
        int result, reconnect;
-       Scsi_Cmnd *SCtmp;
+       struct scsi_cmnd *SCtmp;
 
        DANY ("seagate: que_command");
        done_fn = done;
@@ -721,7 +734,7 @@ static int internal_command (unsigned char target, unsigned char lun,
        unsigned char *data = NULL;
        struct scatterlist *buffer = NULL;
        int clock, temp, nobuffs = 0, done = 0, len = 0;
-#ifdef DEBUG
+#if DEBUG
        int transfered = 0, phase = 0, newphase;
 #endif
        register unsigned char status_read;
@@ -737,7 +750,7 @@ static int internal_command (unsigned char target, unsigned char lun,
 
 #if (DEBUG & PRINT_COMMAND)
        printk("scsi%d : target = %d, command = ", hostno, target);
-       print_command((unsigned char *) cmnd);
+       __scsi_print_command((unsigned char *) cmnd);
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
@@ -991,7 +1004,7 @@ connect_loop:
                        }
 #endif
 
-                       buffer = (struct scatterlist *) SCint->buffer;
+                       buffer = (struct scatterlist *) SCint->request_buffer;
                        len = buffer->length;
                        data = page_address(buffer->page) + buffer->offset;
                } else {
@@ -1140,7 +1153,7 @@ connect_loop:
 #endif
                                                 "loop 1b;"
                                      /* output */ :
-                                     /* input */ :"D" (phys_to_virt (st0x_dr)),
+                                     /* input */ :"D" (st0x_dr),
                                                 "S"
                                                 (data),
                                                 "c" (SCint->transfersize)
@@ -1148,19 +1161,7 @@ connect_loop:
                                      :  "eax", "ecx",
                                                 "esi");
 #else                          /* SEAGATE_USE_ASM */
-                                       {
-#ifdef FAST32
-                                               unsigned int *iop = phys_to_virt (st0x_dr);
-                                               const unsigned int *dp =(unsigned int *) data;
-                                               int xferlen = transfersize >> 2;
-#else
-                                               unsigned char *iop = phys_to_virt (st0x_dr);
-                                               const unsigned char *dp = data;
-                                               int xferlen = transfersize;
-#endif
-                                               for (; xferlen; --xferlen)
-                                                       *iop = *dp++;
-                                       }
+                                       memcpy_toio(st0x_dr, data, transfersize);
 #endif                         /* SEAGATE_USE_ASM */
 /* SJT: End */
                                        len -= transfersize;
@@ -1212,10 +1213,8 @@ connect_loop:
                                                        "=D" (__dummy_2)
 /* input */
                                      :         "0" (data), "1" (len),
-                                                       "2" (phys_to_virt
-                                                            (st0x_cr_sr)),
-                                                       "3" (phys_to_virt
-                                                            (st0x_dr))
+                                                       "2" (st0x_cr_sr),
+                                                       "3" (st0x_dr)
 /* clobbered */
                                      :         "eax");
 #else                          /* SEAGATE_USE_ASM */
@@ -1292,7 +1291,7 @@ connect_loop:
 #endif
                                                 "loop 1b\n\t"
                                      /* output */ :
-                                     /* input */ :"S" (phys_to_virt (st0x_dr)),
+                                     /* input */ :"S" (st0x_dr),
                                                 "D"
                                                 (data),
                                                 "c" (SCint->transfersize)
@@ -1300,22 +1299,7 @@ connect_loop:
                                      :  "eax", "ecx",
                                                 "edi");
 #else                          /* SEAGATE_USE_ASM */
-                                       {
-#ifdef FAST32
-                                               const unsigned int *iop =
-                                                   phys_to_virt (st0x_dr);
-                                               unsigned int *dp =
-                                                   (unsigned int *) data;
-                                               int xferlen = len >> 2;
-#else
-                                               const unsigned char *iop =
-                                                   phys_to_virt (st0x_dr);
-                                               unsigned char *dp = data;
-                                               int xferlen = len;
-#endif
-                                               for (; xferlen; --xferlen)
-                                                       *dp++ = *iop;
-                                       }
+                                       memcpy_fromio(data, st0x_dr, len);
 #endif                         /* SEAGATE_USE_ASM */
 /* SJT: End */
                                        len -= transfersize;
@@ -1381,10 +1365,8 @@ connect_loop:
                                                        "=b" (__dummy_4)
 /* input */
                                      :         "0" (data), "1" (len),
-                                                       "2" (phys_to_virt
-                                                            (st0x_cr_sr)),
-                                                       "3" (phys_to_virt
-                                                            (st0x_dr))
+                                                       "2" (st0x_cr_sr),
+                                                       "3" (st0x_dr)
 /* clobbered */
                                      :         "eax");
 #else                          /* SEAGATE_USE_ASM */
@@ -1575,7 +1557,7 @@ connect_loop:
        printk("\n");
 #endif
        printk("scsi%d : status = ", hostno);
-       print_status(status);
+       scsi_print_status(status);
        printk(" message = %02x\n", message);
 #endif
 
@@ -1629,7 +1611,7 @@ connect_loop:
        return retcode (st0x_aborted);
 }                              /* end of internal_command */
 
-static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
+static int seagate_st0x_abort(struct scsi_cmnd * SCpnt)
 {
        st0x_aborted = DID_ABORT;
        return SUCCESS;
@@ -1644,7 +1626,7 @@ static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
  * May be called with SCpnt = NULL
  */
 
-static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt)
+static int seagate_st0x_bus_reset(struct scsi_cmnd * SCpnt)
 {
        /* No timeouts - this command is going to fail because it was reset. */
        DANY ("scsi%d: Reseting bus... ", hostno);
@@ -1652,7 +1634,7 @@ static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt)
        /* assert  RESET signal on SCSI bus.  */
        WRITE_CONTROL (BASE_CMD | CMD_RST);
 
-       udelay (20 * 1000);
+       mdelay (20);
 
        WRITE_CONTROL (BASE_CMD);
        st0x_aborted = DID_RESET;
@@ -1661,16 +1643,6 @@ static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt)
        return SUCCESS;
 }
 
-static int seagate_st0x_host_reset(Scsi_Cmnd *SCpnt)
-{
-       return FAILED;
-}
-
-static int seagate_st0x_device_reset(Scsi_Cmnd *SCpnt)
-{
-       return FAILED;
-}
-
 static int seagate_st0x_release(struct Scsi_Host *shost)
 {
        if (shost->irq)
@@ -1679,15 +1651,13 @@ static int seagate_st0x_release(struct Scsi_Host *shost)
        return 0;
 }
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
        .detect                 = seagate_st0x_detect,
        .release                = seagate_st0x_release,
        .info                   = seagate_st0x_info,
        .queuecommand           = seagate_st0x_queue_command,
        .eh_abort_handler       = seagate_st0x_abort,
        .eh_bus_reset_handler   = seagate_st0x_bus_reset,
-       .eh_host_reset_handler  = seagate_st0x_host_reset,
-       .eh_device_reset_handler = seagate_st0x_device_reset,
        .can_queue              = 1,
        .this_id                = 7,
        .sg_tablesize           = SG_ALL,