/*
 * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
 *		Amiga MacroSystemUS WarpEngine SCSI controller.
 *		Amiga Technologies/DKB A4091 SCSI controller.
 *
 * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk>
 * plus modifications of the 53c7xx.c driver to support the Amiga.
 *
 * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org>
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/zorro.h>
#include <asm/amigaints.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>

#include "53c700.h"

MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / Kars de Jong <jongk@linux-m68k.org>");
MODULE_DESCRIPTION("Amiga Zorro NCR53C710 driver");
MODULE_LICENSE("GPL");


static struct scsi_host_template zorro7xx_scsi_driver_template = {
	.proc_name	= "zorro7xx",
	.this_id	= 7,
	.module		= THIS_MODULE,
};

static struct zorro_driver_data {
	const char *name;
	unsigned long offset;
	int absolute;	/* offset is absolute address */
} zorro7xx_driver_data[] __devinitdata = {
	{ .name = "PowerUP 603e+", .offset = 0xf40000, .absolute = 1 },
	{ .name = "WarpEngine 40xx", .offset = 0x40000 },
	{ .name = "A4091", .offset = 0x800000 },
	{ .name = "GForce 040/060", .offset = 0x40000 },
	{ 0 }
};

static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = {
	{
		.id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS,
		.driver_data = (unsigned long)&zorro7xx_driver_data[0],
	},
	{
		.id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx,
		.driver_data = (unsigned long)&zorro7xx_driver_data[1],
	},
	{
		.id = ZORRO_PROD_CBM_A4091_1,
		.driver_data = (unsigned long)&zorro7xx_driver_data[2],
	},
	{
		.id = ZORRO_PROD_CBM_A4091_2,
		.driver_data = (unsigned long)&zorro7xx_driver_data[2],
	},
	{
		.id = ZORRO_PROD_GVP_GFORCE_040_060,
		.driver_data = (unsigned long)&zorro7xx_driver_data[3],
	},
	{ 0 }
};

static int __devinit zorro7xx_init_one(struct zorro_dev *z,
				       const struct zorro_device_id *ent)
{
	struct Scsi_Host * host = NULL;
	struct NCR_700_Host_Parameters *hostdata;
	struct zorro_driver_data *zdd;
	unsigned long board, ioaddr;

	board = zorro_resource_start(z);
	zdd = (struct zorro_driver_data *)ent->driver_data;

	if (zdd->absolute) {
		ioaddr = zdd->offset;
	} else {
		ioaddr = board + zdd->offset;
	}

	if (!zorro_request_device(z, zdd->name)) {
		printk(KERN_ERR "zorro7xx: cannot reserve region 0x%lx, abort\n",
		       board);
		return -EBUSY;
	}

	hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
	if (hostdata == NULL) {
		printk(KERN_ERR "zorro7xx: Failed to allocate host data\n");
		goto out_release;
	}

	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));

	/* Fill in the required pieces of hostdata */
	if (ioaddr > 0x01000000)
		hostdata->base = ioremap(ioaddr, zorro_resource_len(z));
	else
		hostdata->base = (void __iomem *)ZTWO_VADDR(ioaddr);

	hostdata->clock = 50;
	hostdata->chip710 = 1;

	/* Settings for at least WarpEngine 40xx */
	hostdata->ctest7_extra = CTEST7_TT1;

	zorro7xx_scsi_driver_template.name = zdd->name;

	/* and register the chip */
	host = NCR_700_detect(&zorro7xx_scsi_driver_template, hostdata,
			      &z->dev);
	if (!host) {
		printk(KERN_ERR "zorro7xx: No host detected; "
				"board configuration problem?\n");
		goto out_free;
	}

	host->this_id = 7;
	host->base = ioaddr;
	host->irq = IRQ_AMIGA_PORTS;

	if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "zorro7xx-scsi",
			host)) {
		printk(KERN_ERR "zorro7xx: request_irq failed\n");
		goto out_put_host;
	}

	scsi_scan_host(host);

	return 0;

 out_put_host:
	scsi_host_put(host);
 out_free:
	if (ioaddr > 0x01000000)
		iounmap(hostdata->base);
	kfree(hostdata);
 out_release:
	zorro_release_device(z);

	return -ENODEV;
}

static __devexit void zorro7xx_remove_one(struct zorro_dev *z)
{
	struct Scsi_Host *host = dev_to_shost(&z->dev);
	struct NCR_700_Host_Parameters *hostdata = shost_priv(host);

	scsi_remove_host(host);

	NCR_700_release(host);
	kfree(hostdata);
	free_irq(host->irq, host);
	zorro_release_device(z);
}

static struct zorro_driver zorro7xx_driver = {
	.name	  = "zorro7xx-scsi",
	.id_table = zorro7xx_zorro_tbl,
	.probe	  = zorro7xx_init_one,
	.remove	  = __devexit_p(zorro7xx_remove_one),
};

static int __init zorro7xx_scsi_init(void)
{
	return zorro_register_driver(&zorro7xx_driver);
}

static void __exit zorro7xx_scsi_exit(void)
{
	zorro_unregister_driver(&zorro7xx_driver);
}

module_init(zorro7xx_scsi_init);
module_exit(zorro7xx_scsi_exit);
