linux/drivers/scsi/a4000t.c
<<
>>
Prefs
   1/*
   2 * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
   3 *              Amiga Technologies A4000T SCSI controller.
   4 *
   5 * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk>
   6 * plus modifications of the 53c7xx.c driver to support the Amiga.
   7 *
   8 * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org>
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <linux/init.h>
  14#include <linux/interrupt.h>
  15#include <linux/slab.h>
  16#include <asm/amigahw.h>
  17#include <asm/amigaints.h>
  18#include <scsi/scsi_host.h>
  19#include <scsi/scsi_transport_spi.h>
  20
  21#include "53c700.h"
  22
  23
  24static struct scsi_host_template a4000t_scsi_driver_template = {
  25        .name           = "A4000T builtin SCSI",
  26        .proc_name      = "A4000t",
  27        .this_id        = 7,
  28        .module         = THIS_MODULE,
  29};
  30
  31
  32#define A4000T_SCSI_OFFSET      0x40
  33
  34static int __init amiga_a4000t_scsi_probe(struct platform_device *pdev)
  35{
  36        struct resource *res;
  37        phys_addr_t scsi_addr;
  38        struct NCR_700_Host_Parameters *hostdata;
  39        struct Scsi_Host *host;
  40
  41        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  42        if (!res)
  43                return -ENODEV;
  44
  45        if (!request_mem_region(res->start, resource_size(res),
  46                                "A4000T builtin SCSI"))
  47                return -EBUSY;
  48
  49        hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters),
  50                           GFP_KERNEL);
  51        if (!hostdata) {
  52                dev_err(&pdev->dev, "Failed to allocate host data\n");
  53                goto out_release;
  54        }
  55
  56        scsi_addr = res->start + A4000T_SCSI_OFFSET;
  57
  58        /* Fill in the required pieces of hostdata */
  59        hostdata->base = (void __iomem *)ZTWO_VADDR(scsi_addr);
  60        hostdata->clock = 50;
  61        hostdata->chip710 = 1;
  62        hostdata->dmode_extra = DMODE_FC2;
  63        hostdata->dcntl_extra = EA_710;
  64
  65        /* and register the chip */
  66        host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata,
  67                              &pdev->dev);
  68        if (!host) {
  69                dev_err(&pdev->dev,
  70                        "No host detected; board configuration problem?\n");
  71                goto out_free;
  72        }
  73
  74        host->this_id = 7;
  75        host->base = scsi_addr;
  76        host->irq = IRQ_AMIGA_PORTS;
  77
  78        if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "a4000t-scsi",
  79                        host)) {
  80                dev_err(&pdev->dev, "request_irq failed\n");
  81                goto out_put_host;
  82        }
  83
  84        platform_set_drvdata(pdev, host);
  85        scsi_scan_host(host);
  86        return 0;
  87
  88 out_put_host:
  89        scsi_host_put(host);
  90 out_free:
  91        kfree(hostdata);
  92 out_release:
  93        release_mem_region(res->start, resource_size(res));
  94        return -ENODEV;
  95}
  96
  97static int __exit amiga_a4000t_scsi_remove(struct platform_device *pdev)
  98{
  99        struct Scsi_Host *host = platform_get_drvdata(pdev);
 100        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 101        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 102
 103        scsi_remove_host(host);
 104        NCR_700_release(host);
 105        kfree(hostdata);
 106        free_irq(host->irq, host);
 107        release_mem_region(res->start, resource_size(res));
 108        return 0;
 109}
 110
 111static struct platform_driver amiga_a4000t_scsi_driver = {
 112        .remove = __exit_p(amiga_a4000t_scsi_remove),
 113        .driver   = {
 114                .name   = "amiga-a4000t-scsi",
 115                .owner  = THIS_MODULE,
 116        },
 117};
 118
 119module_platform_driver_probe(amiga_a4000t_scsi_driver, amiga_a4000t_scsi_probe);
 120
 121MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / "
 122              "Kars de Jong <jongk@linux-m68k.org>");
 123MODULE_DESCRIPTION("Amiga A4000T NCR53C710 driver");
 124MODULE_LICENSE("GPL");
 125MODULE_ALIAS("platform:amiga-a4000t-scsi");
 126