1 /* -*- mode: c; c-basic-offset: 8 -*- */
 
   3 /* PARISC LASI driver for the 53c700 chip
 
   5  * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
 
   6 **-----------------------------------------------------------------------------
 
   8 **  This program is free software; you can redistribute it and/or modify
 
   9 **  it under the terms of the GNU General Public License as published by
 
  10 **  the Free Software Foundation; either version 2 of the License, or
 
  11 **  (at your option) any later version.
 
  13 **  This program is distributed in the hope that it will be useful,
 
  14 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  15 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  16 **  GNU General Public License for more details.
 
  18 **  You should have received a copy of the GNU General Public License
 
  19 **  along with this program; if not, write to the Free Software
 
  20 **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
  22 **-----------------------------------------------------------------------------
 
  26  * Many thanks to Richard Hirst <rhirst@linuxcare.com> for patiently
 
  27  * debugging this driver on the parisc architecture and suggesting
 
  28  * many improvements and bug fixes.
 
  30  * Thanks also go to Linuxcare Inc. for providing several PARISC
 
  31  * machines for me to debug the driver on.
 
  34 #include <linux/kernel.h>
 
  35 #include <linux/module.h>
 
  36 #include <linux/init.h>
 
  37 #include <linux/types.h>
 
  38 #include <linux/stat.h>
 
  40 #include <linux/blkdev.h>
 
  41 #include <linux/sched.h>
 
  42 #include <linux/ioport.h>
 
  43 #include <linux/dma-mapping.h>
 
  46 #include <asm/pgtable.h>
 
  48 #include <asm/hardware.h>
 
  49 #include <asm/parisc-device.h>
 
  50 #include <asm/delay.h>
 
  52 #include <scsi/scsi_host.h>
 
  53 #include <scsi/scsi_device.h>
 
  54 #include <scsi/scsi_transport.h>
 
  55 #include <scsi/scsi_transport_spi.h>
 
  59 MODULE_AUTHOR("James Bottomley");
 
  60 MODULE_DESCRIPTION("lasi700 SCSI Driver");
 
  61 MODULE_LICENSE("GPL");
 
  63 #define LASI_700_SVERSION 0x00071
 
  64 #define LASI_710_SVERSION 0x00082
 
  66 #define LASI700_ID_TABLE {                      \
 
  67         .hw_type        = HPHW_FIO,             \
 
  68         .sversion       = LASI_700_SVERSION,    \
 
  69         .hversion       = HVERSION_ANY_ID,      \
 
  70         .hversion_rev   = HVERSION_REV_ANY_ID,  \
 
  73 #define LASI710_ID_TABLE {                      \
 
  74         .hw_type        = HPHW_FIO,             \
 
  75         .sversion       = LASI_710_SVERSION,    \
 
  76         .hversion       = HVERSION_ANY_ID,      \
 
  77         .hversion_rev   = HVERSION_REV_ANY_ID,  \
 
  80 #define LASI700_CLOCK   25
 
  81 #define LASI710_CLOCK   40
 
  82 #define LASI_SCSI_CORE_OFFSET 0x100
 
  84 static struct parisc_device_id lasi700_ids[] = {
 
  90 static struct scsi_host_template lasi700_template = {
 
  91         .name           = "LASI SCSI 53c700",
 
  92         .proc_name      = "lasi700",
 
  94         .module         = THIS_MODULE,
 
  96 MODULE_DEVICE_TABLE(parisc, lasi700_ids);
 
  99 lasi700_probe(struct parisc_device *dev)
 
 101         unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET;
 
 102         struct NCR_700_Host_Parameters *hostdata;
 
 103         struct Scsi_Host *host;
 
 105         hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL);
 
 107                 printk(KERN_ERR "%s: Failed to allocate host data\n",
 
 111         memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
 
 113         hostdata->dev = &dev->dev;
 
 114         dma_set_mask(&dev->dev, DMA_32BIT_MASK);
 
 115         hostdata->base = ioremap(base, 0x100);
 
 116         hostdata->differential = 0;
 
 118         if (dev->id.sversion == LASI_700_SVERSION) {
 
 119                 hostdata->clock = LASI700_CLOCK;
 
 120                 hostdata->force_le_on_be = 1;
 
 122                 hostdata->clock = LASI710_CLOCK;
 
 123                 hostdata->force_le_on_be = 0;
 
 124                 hostdata->chip710 = 1;
 
 125                 hostdata->dmode_extra = DMODE_FC2;
 
 128         host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev);
 
 133         host->irq = dev->irq;
 
 134         if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) {
 
 135                 printk(KERN_ERR "lasi700: request_irq failed!\n");
 
 139         dev_set_drvdata(&dev->dev, host);
 
 140         scsi_scan_host(host);
 
 147         iounmap(hostdata->base);
 
 153 lasi700_driver_remove(struct parisc_device *dev)
 
 155         struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
 
 156         struct NCR_700_Host_Parameters *hostdata = 
 
 157                 (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
 159         scsi_remove_host(host);
 
 160         NCR_700_release(host);
 
 161         free_irq(host->irq, host);
 
 162         iounmap(hostdata->base);
 
 168 static struct parisc_driver lasi700_driver = {
 
 170         .id_table =     lasi700_ids,
 
 171         .probe =        lasi700_probe,
 
 172         .remove =       __devexit_p(lasi700_driver_remove),
 
 178         return register_parisc_driver(&lasi700_driver);
 
 184         unregister_parisc_driver(&lasi700_driver);
 
 187 module_init(lasi700_init);
 
 188 module_exit(lasi700_exit);