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