145804fbbSKars de Jong /* 245804fbbSKars de Jong * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux. 345804fbbSKars de Jong * Amiga MacroSystemUS WarpEngine SCSI controller. 445804fbbSKars de Jong * Amiga Technologies/DKB A4091 SCSI controller. 545804fbbSKars de Jong * 645804fbbSKars de Jong * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk> 745804fbbSKars de Jong * plus modifications of the 53c7xx.c driver to support the Amiga. 845804fbbSKars de Jong * 945804fbbSKars de Jong * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org> 1045804fbbSKars de Jong */ 1145804fbbSKars de Jong 1245804fbbSKars de Jong #include <linux/module.h> 1345804fbbSKars de Jong #include <linux/init.h> 1445804fbbSKars de Jong #include <linux/interrupt.h> 1545804fbbSKars de Jong #include <linux/zorro.h> 1645804fbbSKars de Jong #include <asm/amigaints.h> 1745804fbbSKars de Jong #include <scsi/scsi_host.h> 1845804fbbSKars de Jong #include <scsi/scsi_transport_spi.h> 1945804fbbSKars de Jong 2045804fbbSKars de Jong #include "53c700.h" 2145804fbbSKars de Jong 2245804fbbSKars de Jong MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / Kars de Jong <jongk@linux-m68k.org>"); 2345804fbbSKars de Jong MODULE_DESCRIPTION("Amiga Zorro NCR53C710 driver"); 2445804fbbSKars de Jong MODULE_LICENSE("GPL"); 2545804fbbSKars de Jong 2645804fbbSKars de Jong 2745804fbbSKars de Jong static struct scsi_host_template zorro7xx_scsi_driver_template = { 2845804fbbSKars de Jong .proc_name = "zorro7xx", 2945804fbbSKars de Jong .this_id = 7, 3045804fbbSKars de Jong .module = THIS_MODULE, 3145804fbbSKars de Jong }; 3245804fbbSKars de Jong 3345804fbbSKars de Jong static struct zorro_driver_data { 3445804fbbSKars de Jong const char *name; 3545804fbbSKars de Jong unsigned long offset; 3645804fbbSKars de Jong int absolute; /* offset is absolute address */ 3745804fbbSKars de Jong } zorro7xx_driver_data[] __devinitdata = { 3845804fbbSKars de Jong { .name = "PowerUP 603e+", .offset = 0xf40000, .absolute = 1 }, 3945804fbbSKars de Jong { .name = "WarpEngine 40xx", .offset = 0x40000 }, 4045804fbbSKars de Jong { .name = "A4091", .offset = 0x800000 }, 4145804fbbSKars de Jong { .name = "GForce 040/060", .offset = 0x40000 }, 4245804fbbSKars de Jong { 0 } 4345804fbbSKars de Jong }; 4445804fbbSKars de Jong 4545804fbbSKars de Jong static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = { 4645804fbbSKars de Jong { 4745804fbbSKars de Jong .id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, 4845804fbbSKars de Jong .driver_data = (unsigned long)&zorro7xx_driver_data[0], 4945804fbbSKars de Jong }, 5045804fbbSKars de Jong { 5145804fbbSKars de Jong .id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, 5245804fbbSKars de Jong .driver_data = (unsigned long)&zorro7xx_driver_data[1], 5345804fbbSKars de Jong }, 5445804fbbSKars de Jong { 5545804fbbSKars de Jong .id = ZORRO_PROD_CBM_A4091_1, 5645804fbbSKars de Jong .driver_data = (unsigned long)&zorro7xx_driver_data[2], 5745804fbbSKars de Jong }, 5845804fbbSKars de Jong { 5945804fbbSKars de Jong .id = ZORRO_PROD_CBM_A4091_2, 6045804fbbSKars de Jong .driver_data = (unsigned long)&zorro7xx_driver_data[2], 6145804fbbSKars de Jong }, 6245804fbbSKars de Jong { 6345804fbbSKars de Jong .id = ZORRO_PROD_GVP_GFORCE_040_060, 6445804fbbSKars de Jong .driver_data = (unsigned long)&zorro7xx_driver_data[3], 6545804fbbSKars de Jong }, 6645804fbbSKars de Jong { 0 } 6745804fbbSKars de Jong }; 6845804fbbSKars de Jong 6945804fbbSKars de Jong static int __devinit zorro7xx_init_one(struct zorro_dev *z, 7045804fbbSKars de Jong const struct zorro_device_id *ent) 7145804fbbSKars de Jong { 7245804fbbSKars de Jong struct Scsi_Host * host = NULL; 7345804fbbSKars de Jong struct NCR_700_Host_Parameters *hostdata; 7445804fbbSKars de Jong struct zorro_driver_data *zdd; 7545804fbbSKars de Jong unsigned long board, ioaddr; 7645804fbbSKars de Jong 7745804fbbSKars de Jong board = zorro_resource_start(z); 7845804fbbSKars de Jong zdd = (struct zorro_driver_data *)ent->driver_data; 7945804fbbSKars de Jong 8045804fbbSKars de Jong if (zdd->absolute) { 8145804fbbSKars de Jong ioaddr = zdd->offset; 8245804fbbSKars de Jong } else { 8345804fbbSKars de Jong ioaddr = board + zdd->offset; 8445804fbbSKars de Jong } 8545804fbbSKars de Jong 8645804fbbSKars de Jong if (!zorro_request_device(z, zdd->name)) { 8745804fbbSKars de Jong printk(KERN_ERR "zorro7xx: cannot reserve region 0x%lx, abort\n", 8845804fbbSKars de Jong board); 8945804fbbSKars de Jong return -EBUSY; 9045804fbbSKars de Jong } 9145804fbbSKars de Jong 9245804fbbSKars de Jong hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); 9345804fbbSKars de Jong if (hostdata == NULL) { 9445804fbbSKars de Jong printk(KERN_ERR "zorro7xx: Failed to allocate host data\n"); 9545804fbbSKars de Jong goto out_release; 9645804fbbSKars de Jong } 9745804fbbSKars de Jong 9845804fbbSKars de Jong memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); 9945804fbbSKars de Jong 10045804fbbSKars de Jong /* Fill in the required pieces of hostdata */ 10145804fbbSKars de Jong if (ioaddr > 0x01000000) 10245804fbbSKars de Jong hostdata->base = ioremap(ioaddr, zorro_resource_len(z)); 10345804fbbSKars de Jong else 10445804fbbSKars de Jong hostdata->base = (void __iomem *)ZTWO_VADDR(ioaddr); 10545804fbbSKars de Jong 10645804fbbSKars de Jong hostdata->clock = 50; 10745804fbbSKars de Jong hostdata->chip710 = 1; 10845804fbbSKars de Jong 10945804fbbSKars de Jong /* Settings for at least WarpEngine 40xx */ 11045804fbbSKars de Jong hostdata->ctest7_extra = CTEST7_TT1; 11145804fbbSKars de Jong 11245804fbbSKars de Jong zorro7xx_scsi_driver_template.name = zdd->name; 11345804fbbSKars de Jong 11445804fbbSKars de Jong /* and register the chip */ 11545804fbbSKars de Jong host = NCR_700_detect(&zorro7xx_scsi_driver_template, hostdata, 11645804fbbSKars de Jong &z->dev); 11745804fbbSKars de Jong if (!host) { 11845804fbbSKars de Jong printk(KERN_ERR "zorro7xx: No host detected; " 11945804fbbSKars de Jong "board configuration problem?\n"); 12045804fbbSKars de Jong goto out_free; 12145804fbbSKars de Jong } 12245804fbbSKars de Jong 12345804fbbSKars de Jong host->this_id = 7; 12445804fbbSKars de Jong host->base = ioaddr; 12545804fbbSKars de Jong host->irq = IRQ_AMIGA_PORTS; 12645804fbbSKars de Jong 12745804fbbSKars de Jong if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "zorro7xx-scsi", 12845804fbbSKars de Jong host)) { 12945804fbbSKars de Jong printk(KERN_ERR "zorro7xx: request_irq failed\n"); 13045804fbbSKars de Jong goto out_put_host; 13145804fbbSKars de Jong } 13245804fbbSKars de Jong 133*3ac709c1SMatthew Wilcox zorro_set_drvdata(z, host); 13445804fbbSKars de Jong scsi_scan_host(host); 13545804fbbSKars de Jong 13645804fbbSKars de Jong return 0; 13745804fbbSKars de Jong 13845804fbbSKars de Jong out_put_host: 13945804fbbSKars de Jong scsi_host_put(host); 14045804fbbSKars de Jong out_free: 14145804fbbSKars de Jong if (ioaddr > 0x01000000) 14245804fbbSKars de Jong iounmap(hostdata->base); 14345804fbbSKars de Jong kfree(hostdata); 14445804fbbSKars de Jong out_release: 14545804fbbSKars de Jong zorro_release_device(z); 14645804fbbSKars de Jong 14745804fbbSKars de Jong return -ENODEV; 14845804fbbSKars de Jong } 14945804fbbSKars de Jong 15045804fbbSKars de Jong static __devexit void zorro7xx_remove_one(struct zorro_dev *z) 15145804fbbSKars de Jong { 152*3ac709c1SMatthew Wilcox struct Scsi_Host *host = zorro_get_drvdata(z); 15345804fbbSKars de Jong struct NCR_700_Host_Parameters *hostdata = shost_priv(host); 15445804fbbSKars de Jong 15545804fbbSKars de Jong scsi_remove_host(host); 15645804fbbSKars de Jong 15745804fbbSKars de Jong NCR_700_release(host); 15845804fbbSKars de Jong kfree(hostdata); 15945804fbbSKars de Jong free_irq(host->irq, host); 16045804fbbSKars de Jong zorro_release_device(z); 16145804fbbSKars de Jong } 16245804fbbSKars de Jong 16345804fbbSKars de Jong static struct zorro_driver zorro7xx_driver = { 16445804fbbSKars de Jong .name = "zorro7xx-scsi", 16545804fbbSKars de Jong .id_table = zorro7xx_zorro_tbl, 16645804fbbSKars de Jong .probe = zorro7xx_init_one, 16745804fbbSKars de Jong .remove = __devexit_p(zorro7xx_remove_one), 16845804fbbSKars de Jong }; 16945804fbbSKars de Jong 17045804fbbSKars de Jong static int __init zorro7xx_scsi_init(void) 17145804fbbSKars de Jong { 17245804fbbSKars de Jong return zorro_register_driver(&zorro7xx_driver); 17345804fbbSKars de Jong } 17445804fbbSKars de Jong 17545804fbbSKars de Jong static void __exit zorro7xx_scsi_exit(void) 17645804fbbSKars de Jong { 17745804fbbSKars de Jong zorro_unregister_driver(&zorro7xx_driver); 17845804fbbSKars de Jong } 17945804fbbSKars de Jong 18045804fbbSKars de Jong module_init(zorro7xx_scsi_init); 18145804fbbSKars de Jong module_exit(zorro7xx_scsi_exit); 182