X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2FNCR_D700.c;h=9859cd17fc574ffe4d7791ab7369039f07241f14;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=329f0eea156dcbf372218a7fb7ed2f02306ef467;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 329f0eea1..9859cd17f 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -97,22 +97,24 @@ #include #include #include +#include #include - -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include #include "53c700.h" #include "NCR_D700.h" -char *NCR_D700; /* command line from insmod */ +static char *NCR_D700; /* command line from insmod */ MODULE_AUTHOR("James Bottomley"); MODULE_DESCRIPTION("NCR Dual700 SCSI Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(NCR_D700, "s"); +module_param(NCR_D700, charp, 0); -static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = +static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 }; #ifdef MODULE @@ -156,7 +158,7 @@ param_setup(char *string) /* Host template. The 53c700 routine NCR_700_detect will * fill in all of the missing routines */ -static Scsi_Host_Template NCR_D700_driver_template = { +static struct scsi_host_template NCR_D700_driver_template = { .module = THIS_MODULE, .name = "NCR Dual 700 MCA", .proc_name = "NCR_D700", @@ -167,11 +169,13 @@ static Scsi_Host_Template NCR_D700_driver_template = { struct NCR_D700_private { struct device *dev; struct Scsi_Host *hosts[2]; + char name[30]; + char pad; }; -static int -NCR_D700_probe_one(struct NCR_D700_private *p, int siop, - int irq, int slot, u32 region, int differential) +static int __devinit +NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, + int slot, u32 region, int differential) { struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; @@ -193,54 +197,53 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, } /* Fill in the three required pieces of hostdata */ - hostdata->base = region; + hostdata->base = ioport_map(region, 64); hostdata->differential = (((1<clock = NCR_D700_CLOCK_MHZ; - NCR_700_set_io_mapped(hostdata); - /* and register the siop */ - host = NCR_700_detect(&NCR_D700_driver_template, hostdata); + host = NCR_700_detect(&NCR_D700_driver_template, hostdata, p->dev); if (!host) { ret = -ENOMEM; goto detect_failed; } - host->irq = irq; - /* FIXME: Read this from SUS */ + p->hosts[siop] = host; + /* FIXME: read this from SUS */ host->this_id = id_array[slot * 2 + siop]; - printk(KERN_NOTICE "NCR D700: SIOP%d, SCSI id is %d\n", - siop, host->this_id); - if (request_irq(irq, NCR_700_intr, SA_SHIRQ, "NCR_D700", host)) { - printk(KERN_ERR "NCR D700: SIOP%d: irq problem, " - "detatching\n", siop); - ret = -ENODEV; - goto irq_failed; - } - - scsi_add_host(host, p->dev); /* XXX handle failure */ + host->irq = irq; + host->base = region; scsi_scan_host(host); - p->hosts[siop] = host; - hostdata->dev = p->dev; return 0; - irq_failed: - scsi_host_put(host); - NCR_700_release(host); detect_failed: - release_region(host->base, 64); + release_region(region, 64); region_failed: kfree(hostdata); return ret; } +static int +NCR_D700_intr(int irq, void *data) +{ + struct NCR_D700_private *p = (struct NCR_D700_private *)data; + int i, found = 0; + + for (i = 0; i < 2; i++) + if (p->hosts[i] && + NCR_700_intr(irq, p->hosts[i]) == IRQ_HANDLED) + found++; + + return found ? IRQ_HANDLED : IRQ_NONE; +} + /* Detect a D700 card. Note, because of the setup --- the chips are * essentially connectecd to the MCA bus independently, it is easier * to set them up as two separate host adapters, rather than one * adapter with two channels */ -static int +static int __devinit NCR_D700_probe(struct device *dev) { struct NCR_D700_private *p; @@ -314,8 +317,14 @@ NCR_D700_probe(struct device *dev) p = kmalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; + memset(p, '\0', sizeof(*p)); p->dev = dev; - + snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id); + if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) { + printk(KERN_ERR "D700: request_irq failed\n"); + kfree(p); + return -EBUSY; + } /* plumb in both 700 chips */ for (i = 0; i < 2; i++) { int err; @@ -340,7 +349,7 @@ NCR_D700_probe(struct device *dev) return 0; } -static void +static void __devexit NCR_D700_remove_one(struct Scsi_Host *host) { scsi_remove_host(host); @@ -350,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host) release_region(host->base, 64); } -static int +static int __devexit NCR_D700_remove(struct device *dev) { struct NCR_D700_private *p = dev_get_drvdata(dev); @@ -365,13 +374,13 @@ NCR_D700_remove(struct device *dev) static short NCR_D700_id_table[] = { NCR_D700_MCA_ID, 0 }; -struct mca_driver NCR_D700_driver = { +static struct mca_driver NCR_D700_driver = { .id_table = NCR_D700_id_table, .driver = { .name = "NCR_D700", .bus = &mca_bus_type, .probe = NCR_D700_probe, - .remove = NCR_D700_remove, + .remove = __devexit_p(NCR_D700_remove), }, };