2007-06-17 16:47:09 +04:00
/*
* 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 53 c7xx . c driver to support the Amiga .
*
* Rewritten to use 53 c700 . 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 ;
}
2007-07-17 23:38:03 +04:00
zorro_set_drvdata ( z , host ) ;
2007-06-17 16:47:09 +04:00
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 )
{
2007-07-17 23:38:03 +04:00
struct Scsi_Host * host = zorro_get_drvdata ( z ) ;
2007-06-17 16:47:09 +04:00
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 ) ;