fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / wd7000.c
index 193e40c..30be765 100644 (file)
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/stat.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <asm/dma.h>
-#include <asm/io.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsicam.h>
 
 
-#define ANY2SCSI_INLINE                /* undef this to use old macros */
 #undef  WD7000_DEBUG           /* general debug                */
 #ifdef WD7000_DEBUG
 #define dprintk printk
@@ -268,7 +267,7 @@ static const long wd7000_biosaddr[] = {
        0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000,
        0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000
 };
-#define NUM_ADDRS (sizeof(wd7000_biosaddr)/sizeof(long))
+#define NUM_ADDRS ARRAY_SIZE(wd7000_biosaddr)
 
 static const unsigned short wd7000_iobase[] = {
        0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338,
@@ -276,13 +275,13 @@ static const unsigned short wd7000_iobase[] = {
        0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8,
        0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8
 };
-#define NUM_IOPORTS (sizeof(wd7000_iobase)/sizeof(unsigned short))
+#define NUM_IOPORTS ARRAY_SIZE(wd7000_iobase)
 
 static const short wd7000_irq[] = { 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 };
-#define NUM_IRQS (sizeof(wd7000_irq)/sizeof(short))
+#define NUM_IRQS ARRAY_SIZE(wd7000_irq)
 
 static const short wd7000_dma[] = { 5, 6, 7 };
-#define NUM_DMAS (sizeof(wd7000_dma)/sizeof(short))
+#define NUM_DMAS ARRAY_SIZE(wd7000_dma)
 
 /*
  * The following is set up by wd7000_detect, and used thereafter for
@@ -318,7 +317,7 @@ static Config configs[] = {
        {7, 6, 0x350, BUS_ON, BUS_OFF}, /* My configuration (Zaga)     */
        {-1, -1, 0x0, BUS_ON, BUS_OFF}  /* Empty slot                  */
 };
-#define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
+#define NUM_CONFIGS ARRAY_SIZE(configs)
 
 /*
  *  The following list defines strings to look for in the BIOS that identify
@@ -334,7 +333,7 @@ typedef struct signature {
 static const Signature signatures[] = {
        {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */
 };
-#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
+#define NUM_SIGNATURES ARRAY_SIZE(signatures)
 
 
 /*
@@ -590,7 +589,7 @@ typedef union icb {
 
 #ifdef MODULE
 static char *wd7000;
-MODULE_PARM(wd7000, "s");
+module_param(wd7000, charp, 0);
 #endif
 
 /*
@@ -726,55 +725,17 @@ static int __init wd7000_setup(char *str)
 
 __setup("wd7000=", wd7000_setup);
 
-#ifdef ANY2SCSI_INLINE
-/*
- * Since they're used a lot, I've redone the following from the macros
- * formerly in wd7000.h, hopefully to speed them up by getting rid of
- * all the shifting (it may not matter; GCC might have done as well anyway).
- *
- * xany2scsi and xscsi2int were not being used, and are no longer defined.
- * (They were simply 4-byte versions of these routines).
- */
-typedef union {                        /* let's cheat... */
-       int i;
-       unchar u[sizeof(int)];  /* the sizeof(int) makes it more portable */
-} i_u;
-
-
 static inline void any2scsi(unchar * scsi, int any)
 {
-       *scsi++ = ((i_u) any).u[2];
-       *scsi++ = ((i_u) any).u[1];
-       *scsi++ = ((i_u) any).u[0];
+       *scsi++ = (unsigned)any >> 16;
+       *scsi++ = (unsigned)any >> 8;
+       *scsi++ = any;
 }
 
-
 static inline int scsi2int(unchar * scsi)
 {
-       i_u result;
-
-       result.i = 0;           /* clears unused bytes */
-       result.u[2] = *scsi++;
-       result.u[1] = *scsi++;
-       result.u[0] = *scsi++;
-
-       return (result.i);
+       return (scsi[0] << 16) | (scsi[1] << 8) | scsi[2];
 }
-#else
-/*
- * These are the old ones - I've just moved them here...
- */
-#undef any2scsi
-#define any2scsi(up, p)   (up)[0] = (((unsigned long) (p)) >> 16);     \
-                         (up)[1] = ((unsigned long) (p)) >> 8;         \
-                         (up)[2] = ((unsigned long) (p));
-
-#undef scsi2int
-#define scsi2int(up)   ( (((unsigned long) *(up)) << 16) +     \
-                        (((unsigned long) (up)[1]) << 8) +     \
-                        ((unsigned long) (up)[2]) )
-#endif
-
 
 static inline void wd7000_enable_intr(Adapter * host)
 {
@@ -1037,7 +998,7 @@ static int make_code(unsigned hosterr, unsigned scsierr)
 #define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 
 
-static irqreturn_t wd7000_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wd7000_intr(int irq, void *dev_id)
 {
        Adapter *host = (Adapter *) dev_id;
        int flag, icmb, errstatus, icmb_status;
@@ -1289,7 +1250,7 @@ static int wd7000_init(Adapter * host)
                return 0;
 
 
-       if (request_irq(host->irq, wd7000_intr, SA_INTERRUPT, "wd7000", host)) {
+       if (request_irq(host->irq, wd7000_intr, IRQF_DISABLED, "wd7000", host)) {
                printk("wd7000_init: can't get IRQ %d.\n", host->irq);
                return (0);
        }
@@ -1430,7 +1391,7 @@ static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start,
  *
  */
 
-static int wd7000_detect(struct scsi_host_template *tpnt)
+static __init int wd7000_detect(struct scsi_host_template *tpnt)
 {
        short present = 0, biosaddr_ptr, sig_ptr, i, pass;
        short biosptr[NUM_CONFIGS];
@@ -1468,16 +1429,16 @@ static int wd7000_detect(struct scsi_host_template *tpnt)
                                                break;
 
                                if (i == pass) {
-                                       void *biosaddr = ioremap(wd7000_biosaddr[biosaddr_ptr] + signatures[sig_ptr].ofs,
+                                       void __iomem *biosaddr = ioremap(wd7000_biosaddr[biosaddr_ptr] + signatures[sig_ptr].ofs,
                                                                 signatures[sig_ptr].len);
-                                       short bios_match = 0;
+                                       short bios_match = 1;
 
                                        if (biosaddr)
-                                               bios_match = memcmp((char *) biosaddr, signatures[sig_ptr].sig, signatures[sig_ptr].len);
+                                               bios_match = check_signature(biosaddr, signatures[sig_ptr].sig, signatures[sig_ptr].len);
 
                                        iounmap(biosaddr);
 
-                                       if (!bios_match)
+                                       if (bios_match)
                                                goto bios_matched;
                                }
                        }
@@ -1512,8 +1473,7 @@ static int wd7000_detect(struct scsi_host_template *tpnt)
                         * ASC reset...
                         */
                        outb(ASC_RES, iobase + ASC_CONTROL);
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ / 100);
+                       msleep(10);
                        outb(0, iobase + ASC_CONTROL);
 
                        if (WAIT(iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
@@ -1626,9 +1586,16 @@ static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
 {
        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
-       if (wd7000_adapter_reset(host) < 0)
+       spin_unlock_irq(SCpnt->device->host->host_lock);
+
+       if (wd7000_adapter_reset(host) < 0) {
+               spin_unlock_irq(SCpnt->device->host->host_lock);
                return FAILED;
+       }
+
        wd7000_enable_intr(host);
+
+       spin_unlock_irq(SCpnt->device->host->host_lock);
        return SUCCESS;
 }