11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds dmx3191d.c - driver for the Domex DMX3191D SCSI card. 31da177e4SLinus Torvalds Copyright (C) 2000 by Massimo Piccioni <dafastidio@libero.it> 41da177e4SLinus Torvalds Portions Copyright (C) 2004 by Christoph Hellwig <hch@lst.de> 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Based on the generic NCR5380 driver by Drew Eckhardt et al. 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License as published by 101da177e4SLinus Torvalds the Free Software Foundation; either version 2 of the License, or 111da177e4SLinus Torvalds (at your option) any later version. 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds This program is distributed in the hope that it will be useful, 141da177e4SLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 151da177e4SLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 161da177e4SLinus Torvalds GNU General Public License for more details. 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds You should have received a copy of the GNU General Public License 191da177e4SLinus Torvalds along with this program; if not, write to the Free Software 201da177e4SLinus Torvalds Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds #include <linux/init.h> 241da177e4SLinus Torvalds #include <linux/ioport.h> 251da177e4SLinus Torvalds #include <linux/kernel.h> 261da177e4SLinus Torvalds #include <linux/module.h> 271da177e4SLinus Torvalds #include <linux/pci.h> 281da177e4SLinus Torvalds #include <linux/interrupt.h> 291da177e4SLinus Torvalds #include <asm/io.h> 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds #include <scsi/scsi_host.h> 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds /* 346070d81eSAdam Buchbinder * Definitions for the generic 5380 driver. 351da177e4SLinus Torvalds */ 361da177e4SLinus Torvalds 37fd9cd67cSFinn Thain #define DONT_USE_INTR 38fd9cd67cSFinn Thain 3954d8fe44SFinn Thain #define NCR5380_read(reg) inb(instance->io_port + reg) 4054d8fe44SFinn Thain #define NCR5380_write(reg, value) outb(value, instance->io_port + reg) 411da177e4SLinus Torvalds 42f825e40bSFinn Thain #define NCR5380_dma_xfer_len(instance, cmd, phase) (0) 43*6c4b88caSFinn Thain #define NCR5380_dma_recv_setup(instance, dst, len) (0) 44*6c4b88caSFinn Thain #define NCR5380_dma_send_setup(instance, src, len) (0) 45f825e40bSFinn Thain 46acfc8cadSFinn Thain #define NCR5380_implementation_fields /* none */ 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds #include "NCR5380.h" 491da177e4SLinus Torvalds #include "NCR5380.c" 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds #define DMX3191D_DRIVER_NAME "dmx3191d" 521da177e4SLinus Torvalds #define DMX3191D_REGION_LEN 8 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds static struct scsi_host_template dmx3191d_driver_template = { 56aa2e2cb1SFinn Thain .module = THIS_MODULE, 571da177e4SLinus Torvalds .proc_name = DMX3191D_DRIVER_NAME, 581da177e4SLinus Torvalds .name = "Domex DMX3191D", 598c32513bSFinn Thain .info = NCR5380_info, 601da177e4SLinus Torvalds .queuecommand = NCR5380_queue_command, 611da177e4SLinus Torvalds .eh_abort_handler = NCR5380_abort, 621da177e4SLinus Torvalds .eh_bus_reset_handler = NCR5380_bus_reset, 631da177e4SLinus Torvalds .can_queue = 32, 641da177e4SLinus Torvalds .this_id = 7, 651da177e4SLinus Torvalds .sg_tablesize = SG_ALL, 661da177e4SLinus Torvalds .cmd_per_lun = 2, 671da177e4SLinus Torvalds .use_clustering = DISABLE_CLUSTERING, 6832b26a10SFinn Thain .cmd_size = NCR5380_CMD_SIZE, 690a4e3612SFinn Thain .max_sectors = 128, 701da177e4SLinus Torvalds }; 711da177e4SLinus Torvalds 726f039790SGreg Kroah-Hartman static int dmx3191d_probe_one(struct pci_dev *pdev, 731da177e4SLinus Torvalds const struct pci_device_id *id) 741da177e4SLinus Torvalds { 751da177e4SLinus Torvalds struct Scsi_Host *shost; 761da177e4SLinus Torvalds unsigned long io; 771da177e4SLinus Torvalds int error = -ENODEV; 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds if (pci_enable_device(pdev)) 801da177e4SLinus Torvalds goto out; 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds io = pci_resource_start(pdev, 0); 831da177e4SLinus Torvalds if (!request_region(io, DMX3191D_REGION_LEN, DMX3191D_DRIVER_NAME)) { 841da177e4SLinus Torvalds printk(KERN_ERR "dmx3191: region 0x%lx-0x%lx already reserved\n", 851da177e4SLinus Torvalds io, io + DMX3191D_REGION_LEN); 861da177e4SLinus Torvalds goto out_disable_device; 871da177e4SLinus Torvalds } 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds shost = scsi_host_alloc(&dmx3191d_driver_template, 901da177e4SLinus Torvalds sizeof(struct NCR5380_hostdata)); 911da177e4SLinus Torvalds if (!shost) 921da177e4SLinus Torvalds goto out_release_region; 931da177e4SLinus Torvalds shost->io_port = io; 94fd9cd67cSFinn Thain 95fd9cd67cSFinn Thain /* This card does not seem to raise an interrupt on pdev->irq. 96fd9cd67cSFinn Thain * Steam-powered SCSI controllers run without an IRQ anyway. 97fd9cd67cSFinn Thain */ 98fd9cd67cSFinn Thain shost->irq = NO_IRQ; 991da177e4SLinus Torvalds 1007e9ec8d9SFinn Thain error = NCR5380_init(shost, 0); 1010ad0eff9SFinn Thain if (error) 1020ad0eff9SFinn Thain goto out_host_put; 1031da177e4SLinus Torvalds 104b6488f97SFinn Thain NCR5380_maybe_reset_bus(shost); 105b6488f97SFinn Thain 1061da177e4SLinus Torvalds pci_set_drvdata(pdev, shost); 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds error = scsi_add_host(shost, &pdev->dev); 1091da177e4SLinus Torvalds if (error) 1100ad0eff9SFinn Thain goto out_exit; 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds scsi_scan_host(shost); 1131da177e4SLinus Torvalds return 0; 1141da177e4SLinus Torvalds 1150ad0eff9SFinn Thain out_exit: 1160ad0eff9SFinn Thain NCR5380_exit(shost); 1170ad0eff9SFinn Thain out_host_put: 1180ad0eff9SFinn Thain scsi_host_put(shost); 1191da177e4SLinus Torvalds out_release_region: 120c3c026baSAdrian Bunk release_region(io, DMX3191D_REGION_LEN); 1211da177e4SLinus Torvalds out_disable_device: 1221da177e4SLinus Torvalds pci_disable_device(pdev); 1231da177e4SLinus Torvalds out: 1241da177e4SLinus Torvalds return error; 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds 1276f039790SGreg Kroah-Hartman static void dmx3191d_remove_one(struct pci_dev *pdev) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds struct Scsi_Host *shost = pci_get_drvdata(pdev); 1300ad0eff9SFinn Thain unsigned long io = shost->io_port; 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds scsi_remove_host(shost); 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds NCR5380_exit(shost); 1351da177e4SLinus Torvalds scsi_host_put(shost); 1360ad0eff9SFinn Thain release_region(io, DMX3191D_REGION_LEN); 1370ad0eff9SFinn Thain pci_disable_device(pdev); 1381da177e4SLinus Torvalds } 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds static struct pci_device_id dmx3191d_pci_tbl[] = { 1411da177e4SLinus Torvalds {PCI_VENDOR_ID_DOMEX, PCI_DEVICE_ID_DOMEX_DMX3191D, 1421da177e4SLinus Torvalds PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, 1431da177e4SLinus Torvalds { } 1441da177e4SLinus Torvalds }; 1451da177e4SLinus Torvalds MODULE_DEVICE_TABLE(pci, dmx3191d_pci_tbl); 1461da177e4SLinus Torvalds 1471da177e4SLinus Torvalds static struct pci_driver dmx3191d_pci_driver = { 1481da177e4SLinus Torvalds .name = DMX3191D_DRIVER_NAME, 1491da177e4SLinus Torvalds .id_table = dmx3191d_pci_tbl, 1501da177e4SLinus Torvalds .probe = dmx3191d_probe_one, 1516f039790SGreg Kroah-Hartman .remove = dmx3191d_remove_one, 1521da177e4SLinus Torvalds }; 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds static int __init dmx3191d_init(void) 1551da177e4SLinus Torvalds { 156dcbccbdeSHenrik Kretzschmar return pci_register_driver(&dmx3191d_pci_driver); 1571da177e4SLinus Torvalds } 1581da177e4SLinus Torvalds 1591da177e4SLinus Torvalds static void __exit dmx3191d_exit(void) 1601da177e4SLinus Torvalds { 1611da177e4SLinus Torvalds pci_unregister_driver(&dmx3191d_pci_driver); 1621da177e4SLinus Torvalds } 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds module_init(dmx3191d_init); 1651da177e4SLinus Torvalds module_exit(dmx3191d_exit); 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); 1681da177e4SLinus Torvalds MODULE_DESCRIPTION("Domex DMX3191D SCSI driver"); 1691da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 170