2019-05-20 10:19:02 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-17 02:20:36 +04:00
/*
dmx3191d . c - driver for the Domex DMX3191D SCSI card .
Copyright ( C ) 2000 by Massimo Piccioni < dafastidio @ libero . it >
Portions Copyright ( C ) 2004 by Christoph Hellwig < hch @ lst . de >
Based on the generic NCR5380 driver by Drew Eckhardt et al .
*/
# include <linux/init.h>
# include <linux/ioport.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/interrupt.h>
# include <asm/io.h>
# include <scsi/scsi_host.h>
/*
2009-12-04 23:47:01 +03:00
* Definitions for the generic 5380 driver .
2005-04-17 02:20:36 +04:00
*/
2016-10-10 07:46:53 +03:00
# define NCR5380_read(reg) inb(hostdata->base + (reg))
# define NCR5380_write(reg, value) outb(value, hostdata->base + (reg))
2005-04-17 02:20:36 +04:00
2016-10-10 07:46:53 +03:00
# define NCR5380_dma_xfer_len NCR5380_dma_xfer_none
# define NCR5380_dma_recv_setup NCR5380_dma_setup_none
# define NCR5380_dma_send_setup NCR5380_dma_setup_none
# define NCR5380_dma_residual NCR5380_dma_residual_none
2016-03-23 13:10:15 +03:00
2014-11-12 08:11:48 +03:00
# define NCR5380_implementation_fields /* none */
2005-04-17 02:20:36 +04:00
# include "NCR5380.h"
# include "NCR5380.c"
# define DMX3191D_DRIVER_NAME "dmx3191d"
# define DMX3191D_REGION_LEN 8
static struct scsi_host_template dmx3191d_driver_template = {
2016-01-03 08:05:48 +03:00
. module = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. proc_name = DMX3191D_DRIVER_NAME ,
. name = " Domex DMX3191D " ,
2014-11-12 08:11:58 +03:00
. info = NCR5380_info ,
2005-04-17 02:20:36 +04:00
. queuecommand = NCR5380_queue_command ,
. eh_abort_handler = NCR5380_abort ,
2017-08-25 14:57:10 +03:00
. eh_host_reset_handler = NCR5380_host_reset ,
2005-04-17 02:20:36 +04:00
. can_queue = 32 ,
. this_id = 7 ,
. sg_tablesize = SG_ALL ,
. cmd_per_lun = 2 ,
2018-12-13 18:17:09 +03:00
. dma_boundary = PAGE_SIZE - 1 ,
2016-01-03 08:05:58 +03:00
. cmd_size = NCR5380_CMD_SIZE ,
2005-04-17 02:20:36 +04:00
} ;
2012-12-22 01:08:55 +04:00
static int dmx3191d_probe_one ( struct pci_dev * pdev ,
const struct pci_device_id * id )
2005-04-17 02:20:36 +04:00
{
struct Scsi_Host * shost ;
2016-10-10 07:46:53 +03:00
struct NCR5380_hostdata * hostdata ;
2005-04-17 02:20:36 +04:00
unsigned long io ;
int error = - ENODEV ;
if ( pci_enable_device ( pdev ) )
goto out ;
io = pci_resource_start ( pdev , 0 ) ;
if ( ! request_region ( io , DMX3191D_REGION_LEN , DMX3191D_DRIVER_NAME ) ) {
printk ( KERN_ERR " dmx3191: region 0x%lx-0x%lx already reserved \n " ,
io , io + DMX3191D_REGION_LEN ) ;
goto out_disable_device ;
}
shost = scsi_host_alloc ( & dmx3191d_driver_template ,
sizeof ( struct NCR5380_hostdata ) ) ;
if ( ! shost )
goto out_release_region ;
2016-10-10 07:46:53 +03:00
hostdata = shost_priv ( shost ) ;
hostdata - > base = io ;
2005-04-17 02:20:36 +04:00
2014-11-12 08:12:03 +03:00
/* This card does not seem to raise an interrupt on pdev->irq.
* Steam - powered SCSI controllers run without an IRQ anyway .
*/
shost - > irq = NO_IRQ ;
2005-04-17 02:20:36 +04:00
2016-03-23 13:10:11 +03:00
error = NCR5380_init ( shost , 0 ) ;
2016-01-03 08:05:21 +03:00
if ( error )
goto out_host_put ;
2005-04-17 02:20:36 +04:00
2016-01-03 08:05:08 +03:00
NCR5380_maybe_reset_bus ( shost ) ;
2005-04-17 02:20:36 +04:00
pci_set_drvdata ( pdev , shost ) ;
error = scsi_add_host ( shost , & pdev - > dev ) ;
if ( error )
2016-01-03 08:05:21 +03:00
goto out_exit ;
2005-04-17 02:20:36 +04:00
scsi_scan_host ( shost ) ;
return 0 ;
2016-01-03 08:05:21 +03:00
out_exit :
NCR5380_exit ( shost ) ;
out_host_put :
scsi_host_put ( shost ) ;
2005-04-17 02:20:36 +04:00
out_release_region :
2006-03-11 01:24:21 +03:00
release_region ( io , DMX3191D_REGION_LEN ) ;
2005-04-17 02:20:36 +04:00
out_disable_device :
pci_disable_device ( pdev ) ;
out :
return error ;
}
2012-12-22 01:08:55 +04:00
static void dmx3191d_remove_one ( struct pci_dev * pdev )
2005-04-17 02:20:36 +04:00
{
struct Scsi_Host * shost = pci_get_drvdata ( pdev ) ;
2016-10-10 07:46:53 +03:00
struct NCR5380_hostdata * hostdata = shost_priv ( shost ) ;
unsigned long io = hostdata - > base ;
2005-04-17 02:20:36 +04:00
scsi_remove_host ( shost ) ;
NCR5380_exit ( shost ) ;
scsi_host_put ( shost ) ;
2016-01-03 08:05:21 +03:00
release_region ( io , DMX3191D_REGION_LEN ) ;
pci_disable_device ( pdev ) ;
2005-04-17 02:20:36 +04:00
}
static struct pci_device_id dmx3191d_pci_tbl [ ] = {
{ PCI_VENDOR_ID_DOMEX , PCI_DEVICE_ID_DOMEX_DMX3191D ,
PCI_ANY_ID , PCI_ANY_ID , 0 , 0 , 4 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( pci , dmx3191d_pci_tbl ) ;
static struct pci_driver dmx3191d_pci_driver = {
. name = DMX3191D_DRIVER_NAME ,
. id_table = dmx3191d_pci_tbl ,
. probe = dmx3191d_probe_one ,
2012-12-22 01:08:55 +04:00
. remove = dmx3191d_remove_one ,
2005-04-17 02:20:36 +04:00
} ;
2016-11-16 16:00:58 +03:00
module_pci_driver ( dmx3191d_pci_driver ) ;
2005-04-17 02:20:36 +04:00
MODULE_AUTHOR ( " Massimo Piccioni <dafastidio@libero.it> " ) ;
MODULE_DESCRIPTION ( " Domex DMX3191D SCSI driver " ) ;
MODULE_LICENSE ( " GPL " ) ;