#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"
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)
return orig_len - len;
}
-static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
{
struct Scsi_Host *dev = dev_id;
int base = 0;
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;
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;
}
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++)
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;
}
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,