Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / scsi / sym53c416.c
index de21eab..8640253 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/blkdev.h>
 #include <linux/isapnp.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "sym53c416.h"
 
 #define VERSION_STRING        "Version 1.0.0-ac"
@@ -239,7 +239,7 @@ static void sym53c416_set_transfer_counter(int base, unsigned int len)
        outb((len & 0xFF0000) >> 16, base + TC_HIGH);
 }
 
-static spinlock_t sym53c416_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sym53c416_lock);
 
 /* Returns the number of bytes read */
 static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
@@ -616,23 +616,24 @@ static struct isapnp_device_id id_table[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(isapnp, id_table);
 
-void sym53c416_probe(void)
+static void sym53c416_probe(void)
 {
        int *base = probeaddrs;
        int ints[2];
 
        ints[0] = 1;
-       for(; *base; base++)
-       {
-               if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
-               {
-                       ints[1] = *base;
-                       sym53c416_setup(NULL, ints);
+       for(; *base; base++) {
+               if (request_region(*base, IO_RANGE, ID)) {
+                       if (sym53c416_test(*base)) {
+                               ints[1] = *base;
+                               sym53c416_setup(NULL, ints);
+                       }
+                       release_region(*base, IO_RANGE);
                }
        }
 }
 
-int __init sym53c416_detect(Scsi_Host_Template *tpnt)
+int __init sym53c416_detect(struct scsi_host_template *tpnt)
 {
        unsigned long flags;
        struct Scsi_Host * shpnt = NULL;
@@ -702,44 +703,42 @@ int __init sym53c416_detect(Scsi_Host_Template *tpnt)
        sym53c416_probe();
 
        /* Now we register and set up each host adapter found... */
-       for(count = 0, i = 0; i < host_index; i++)
-       {
-               if(!sym53c416_test(hosts[i].base))
+       for(count = 0, i = 0; i < host_index; i++) {
+               if (!request_region(hosts[i].base, IO_RANGE, ID))
+                       continue;
+               if (!sym53c416_test(hosts[i].base)) {
                        printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
-               else
-               {
-                       if(hosts[i].irq == 0)
-                       /* We don't have an irq yet, so we should probe for one */
-                               if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
-                                       printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
-                       if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
-                       {
-                               shpnt = scsi_register(tpnt, 0);
-                               if(shpnt==NULL)
-                                       continue;
-                               spin_lock_irqsave(&sym53c416_lock, flags);
-                               /* Request for specified IRQ */
-                               if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
-                               {
-                                       spin_unlock_irqrestore(&sym53c416_lock, flags);
-                                       printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq);
-                                       scsi_unregister(shpnt);
-                               }
-                               else
-                               {
-                                       /* Inform the kernel of our IO range */
-                                       request_region(hosts[i].base, IO_RANGE, ID);
-                                       shpnt->unique_id = hosts[i].base;
-                                       shpnt->io_port = hosts[i].base;
-                                       shpnt->n_io_port = IO_RANGE;
-                                       shpnt->irq = hosts[i].irq;
-                                       shpnt->this_id = hosts[i].scsi_id;
-                                       sym53c416_init(hosts[i].base, hosts[i].scsi_id);
-                                       count++;
-                                       spin_unlock_irqrestore(&sym53c416_lock, flags);
-                               }
-                       }
+                       goto fail_release_region;
                }
+
+               /* We don't have an irq yet, so we should probe for one */
+               if (!hosts[i].irq)
+                       hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
+               if (!hosts[i].irq)
+                       goto fail_release_region;
+       
+               shpnt = scsi_register(tpnt, 0);
+               if (!shpnt)
+                       goto fail_release_region;
+               /* Request for specified IRQ */
+               if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
+                       goto fail_free_host;
+
+               spin_lock_irqsave(&sym53c416_lock, flags);
+               shpnt->unique_id = hosts[i].base;
+               shpnt->io_port = hosts[i].base;
+               shpnt->n_io_port = IO_RANGE;
+               shpnt->irq = hosts[i].irq;
+               shpnt->this_id = hosts[i].scsi_id;
+               sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+               count++;
+               spin_unlock_irqrestore(&sym53c416_lock, flags);
+               continue;
+
+ fail_free_host:
+               scsi_unregister(shpnt);
+ fail_release_region:
+               release_region(hosts[i].base, IO_RANGE);
        }
        return count;
 }
@@ -774,7 +773,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        current_command->SCp.Message = 0;
 
        spin_lock_irqsave(&sym53c416_lock, flags);
-       outb(SCpnt->device->id, base + DEST_BUS_ID); /* Set scsi id target        */
+       outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target        */
        outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
        /* Write SCSI command into the SCSI fifo */
        for(i = 0; i < SCpnt->cmd_len; i++)
@@ -786,37 +785,27 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
-static int sym53c416_abort(Scsi_Cmnd *SCpnt)
-{
-       return FAILED;
-}
-
-static int sym53c416_bus_reset(Scsi_Cmnd *SCpnt)
-{
-       return FAILED;
-}
-
-static int sym53c416_device_reset(Scsi_Cmnd *SCpnt)
-{
-       return FAILED;
-}
-
 static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
 {
        int base;
        int scsi_id = -1;       
        int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sym53c416_lock, flags);
 
        /* printk("sym53c416_reset\n"); */
        base = SCpnt->device->host->io_port;
        /* search scsi_id - fixme, we shouldnt need to iterate for this! */
-       for(i = 0; i < host_index && scsi_id != -1; i++)
+       for(i = 0; i < host_index && scsi_id == -1; i++)
                if(hosts[i].base == base)
                        scsi_id = hosts[i].scsi_id;
        outb(RESET_CHIP, base + COMMAND_REG);
        outb(NOOP | PIO_MODE, base + COMMAND_REG);
        outb(RESET_SCSI_BUS, base + COMMAND_REG);
        sym53c416_init(base, scsi_id);
+
+       spin_unlock_irqrestore(&sym53c416_lock, flags);
        return SUCCESS;
 }
 
@@ -853,23 +842,20 @@ static int sym53c416_bios_param(struct scsi_device *sdev,
 MODULE_AUTHOR("Lieven Willems");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(sym53c416, "1-2i");
-MODULE_PARM(sym53c416_1, "1-2i");
-MODULE_PARM(sym53c416_2, "1-2i");
-MODULE_PARM(sym53c416_3, "1-2i");
+module_param_array(sym53c416, uint, NULL, 0);
+module_param_array(sym53c416_1, uint, NULL, 0);
+module_param_array(sym53c416_2, uint, NULL, 0);
+module_param_array(sym53c416_3, uint, NULL, 0);
 
 #endif
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
        .proc_name =            "sym53c416",
        .name =                 "Symbios Logic 53c416",
        .detect =               sym53c416_detect,
        .info =                 sym53c416_info, 
        .queuecommand =         sym53c416_queuecommand,
-       .eh_abort_handler =     sym53c416_abort,
        .eh_host_reset_handler =sym53c416_host_reset,
-       .eh_bus_reset_handler = sym53c416_bus_reset,
-       .eh_device_reset_handler =sym53c416_device_reset,
        .release =              sym53c416_release,
        .bios_param =           sym53c416_bios_param,
        .can_queue =            1,