2005-04-17 02:20:36 +04:00
/*
* Copyright ( C ) 2001 - 2002 Andre Hedrick < andre @ linux - ide . org >
2008-11-02 23:40:08 +03:00
* Portions ( C ) Copyright 2002 Red Hat Inc
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 , or ( at your option ) any
* later version .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* For the avoidance of doubt the " preferred form " of this code is one which
* is in an open non patent encumbered format . Where cryptographic key signing
* forms part of the process of creating an executable the information
* including keys needed to generate an equivalently functional executable
* are deemed to be part of the source code .
*/
# include <linux/types.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/ide.h>
# include <linux/init.h>
2008-07-25 00:53:32 +04:00
# define DRV_NAME "ide_pci_generic"
2005-06-28 02:24:26 +04:00
static int ide_generic_all ; /* Set to claim all devices */
2006-10-03 12:14:34 +04:00
module_param_named ( all_generic_ide , ide_generic_all , bool , 0444 ) ;
MODULE_PARM_DESC ( all_generic_ide , " IDE generic will claim all unknown PCI IDE storage controllers. " ) ;
2005-06-28 02:24:26 +04:00
2009-05-30 22:06:54 +04:00
static void netcell_quirkproc ( ide_drive_t * drive )
{
/* mark words 85-87 as valid */
drive - > id [ ATA_ID_CSF_DEFAULT ] | = 0x4000 ;
}
static const struct ide_port_ops netcell_port_ops = {
. quirkproc = netcell_quirkproc ,
} ;
2008-07-25 00:53:32 +04:00
# define DECLARE_GENERIC_PCI_DEV(extra_flags) \
2007-10-19 02:30:06 +04:00
{ \
2008-07-25 00:53:32 +04:00
. name = DRV_NAME , \
2007-10-19 02:30:06 +04:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
2008-04-26 19:36:35 +04:00
extra_flags , \
2007-10-19 02:30:07 +04:00
. swdma_mask = ATA_SWDMA2 , \
. mwdma_mask = ATA_MWDMA2 , \
. udma_mask = ATA_UDMA6 , \
2005-04-17 02:20:36 +04:00
}
2007-10-20 02:32:34 +04:00
static const struct ide_port_info generic_chipsets [ ] __devinitdata = {
2008-07-25 00:53:32 +04:00
/* 0: Unknown */
DECLARE_GENERIC_PCI_DEV ( 0 ) ,
2007-10-19 02:30:06 +04:00
2008-07-25 00:53:32 +04:00
{ /* 1: NS87410 */
. name = DRV_NAME ,
2008-04-26 19:36:40 +04:00
. enablebits = { { 0x43 , 0x08 , 0x08 } , { 0x47 , 0x08 , 0x08 } } ,
2008-04-26 19:36:35 +04:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA ,
2007-10-19 02:30:07 +04:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2007-10-19 02:30:06 +04:00
} ,
2008-07-25 00:53:32 +04:00
/* 2: SAMURAI / HT6565 / HINT_IDE */
DECLARE_GENERIC_PCI_DEV ( 0 ) ,
/* 3: UM8673F / UM8886A / UM8886BF */
2009-03-25 01:22:52 +03:00
DECLARE_GENERIC_PCI_DEV ( IDE_HFLAG_NO_DMA ) ,
2008-07-25 00:53:32 +04:00
/* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */
DECLARE_GENERIC_PCI_DEV ( IDE_HFLAG_NO_AUTODMA ) ,
{ /* 5: VIA8237SATA */
. name = DRV_NAME ,
2007-10-19 02:30:06 +04:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD ,
2007-10-19 02:30:07 +04:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2007-10-19 02:30:06 +04:00
} ,
2008-07-25 00:53:32 +04:00
{ /* 6: Revolution */
. name = DRV_NAME ,
2009-05-30 22:06:54 +04:00
. port_ops = & netcell_port_ops ,
2008-02-02 01:09:30 +03:00
. host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
2007-10-19 02:30:06 +04:00
IDE_HFLAG_OFF_BOARD ,
2007-10-19 02:30:07 +04:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2005-04-17 02:20:36 +04:00
}
} ;
/**
* generic_init_one - called when a PIIX is found
* @ dev : the generic device
* @ id : the matching pci id
*
* Called when the PCI registration layer ( or the IDE initialization )
* finds a device matching our IDE device tables .
*/
2008-04-26 19:36:40 +04:00
2005-04-17 02:20:36 +04:00
static int __devinit generic_init_one ( struct pci_dev * dev , const struct pci_device_id * id )
{
2007-10-20 02:32:34 +04:00
const struct ide_port_info * d = & generic_chipsets [ id - > driver_data ] ;
2005-04-17 02:20:36 +04:00
int ret = - ENODEV ;
2005-06-28 02:24:26 +04:00
/* Don't use the generic entry unless instructed to do so */
if ( id - > driver_data = = 0 & & ide_generic_all = = 0 )
goto out ;
2007-06-08 17:14:31 +04:00
switch ( dev - > vendor ) {
case PCI_VENDOR_ID_UMC :
if ( dev - > device = = PCI_DEVICE_ID_UMC_UM8886A & &
! ( PCI_FUNC ( dev - > devfn ) & 1 ) )
goto out ; /* UM8886A/BF pair */
break ;
case PCI_VENDOR_ID_OPTI :
if ( dev - > device = = PCI_DEVICE_ID_OPTI_82C558 & &
! ( PCI_FUNC ( dev - > devfn ) & 1 ) )
goto out ;
break ;
case PCI_VENDOR_ID_JMICRON :
if ( dev - > device ! = PCI_DEVICE_ID_JMICRON_JMB368 & &
PCI_FUNC ( dev - > devfn ) ! = 1 )
goto out ;
break ;
case PCI_VENDOR_ID_NS :
if ( dev - > device = = PCI_DEVICE_ID_NS_87410 & &
( dev - > class > > 8 ) ! = PCI_CLASS_STORAGE_IDE )
2006-10-28 21:38:57 +04:00
goto out ;
2007-06-08 17:14:31 +04:00
break ;
2006-10-28 21:38:57 +04:00
}
2006-07-12 18:05:41 +04:00
2006-10-11 12:21:47 +04:00
if ( dev - > vendor ! = PCI_VENDOR_ID_JMICRON ) {
2007-06-08 17:14:31 +04:00
u16 command ;
2006-10-11 12:21:47 +04:00
pci_read_config_word ( dev , PCI_COMMAND , & command ) ;
if ( ! ( command & PCI_COMMAND_IO ) ) {
2008-07-25 00:53:31 +04:00
printk ( KERN_INFO " %s %s: skipping disabled "
" controller \n " , d - > name , pci_name ( dev ) ) ;
2006-10-11 12:21:47 +04:00
goto out ;
}
2005-04-17 02:20:36 +04:00
}
2008-07-25 00:53:14 +04:00
ret = ide_pci_init_one ( dev , d , NULL ) ;
2005-04-17 02:20:36 +04:00
out :
return ret ;
}
2007-10-17 00:29:56 +04:00
static const struct pci_device_id generic_pci_tbl [ ] = {
{ PCI_VDEVICE ( NS , PCI_DEVICE_ID_NS_87410 ) , 1 } ,
{ PCI_VDEVICE ( PCTECH , PCI_DEVICE_ID_PCTECH_SAMURAI_IDE ) , 2 } ,
2008-07-25 00:53:32 +04:00
{ PCI_VDEVICE ( HOLTEK , PCI_DEVICE_ID_HOLTEK_6565 ) , 2 } ,
{ PCI_VDEVICE ( UMC , PCI_DEVICE_ID_UMC_UM8673F ) , 3 } ,
{ PCI_VDEVICE ( UMC , PCI_DEVICE_ID_UMC_UM8886A ) , 3 } ,
{ PCI_VDEVICE ( UMC , PCI_DEVICE_ID_UMC_UM8886BF ) , 3 } ,
{ PCI_VDEVICE ( HINT , PCI_DEVICE_ID_HINT_VXPROII_IDE ) , 2 } ,
{ PCI_VDEVICE ( VIA , PCI_DEVICE_ID_VIA_82C561 ) , 4 } ,
{ PCI_VDEVICE ( OPTI , PCI_DEVICE_ID_OPTI_82C558 ) , 4 } ,
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_BLK_DEV_IDE_SATA
2008-07-25 00:53:32 +04:00
{ PCI_VDEVICE ( VIA , PCI_DEVICE_ID_VIA_8237_SATA ) , 5 } ,
2005-04-17 02:20:36 +04:00
# endif
2008-07-25 00:53:32 +04:00
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 ) , 4 } ,
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 ) , 4 } ,
2009-11-30 16:23:11 +03:00
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_3 ) , 4 } ,
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_5 ) , 4 } ,
2008-07-25 00:53:32 +04:00
{ PCI_VDEVICE ( NETCELL , PCI_DEVICE_ID_REVOLUTION ) , 6 } ,
2007-10-17 00:29:56 +04:00
/*
* Must come last . If you add entries adjust
* this table and generic_chipsets [ ] appropriately .
*/
{ PCI_ANY_ID , PCI_ANY_ID , PCI_ANY_ID , PCI_ANY_ID , PCI_CLASS_STORAGE_IDE < < 8 , 0xFFFFFF00UL , 0 } ,
2005-04-17 02:20:36 +04:00
{ 0 , } ,
} ;
MODULE_DEVICE_TABLE ( pci , generic_pci_tbl ) ;
2008-10-13 23:39:41 +04:00
static struct pci_driver generic_pci_driver = {
2005-04-17 02:20:36 +04:00
. name = " PCI_IDE " ,
. id_table = generic_pci_tbl ,
. probe = generic_init_one ,
2008-07-25 00:53:21 +04:00
. remove = ide_pci_remove ,
2008-10-11 00:39:32 +04:00
. suspend = ide_pci_suspend ,
. resume = ide_pci_resume ,
2005-04-17 02:20:36 +04:00
} ;
2007-01-27 15:46:56 +03:00
static int __init generic_ide_init ( void )
2005-04-17 02:20:36 +04:00
{
2008-10-13 23:39:41 +04:00
return ide_pci_register_driver ( & generic_pci_driver ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-25 00:53:21 +04:00
static void __exit generic_ide_exit ( void )
{
2008-10-13 23:39:41 +04:00
pci_unregister_driver ( & generic_pci_driver ) ;
2008-07-25 00:53:21 +04:00
}
2005-04-17 02:20:36 +04:00
module_init ( generic_ide_init ) ;
2008-07-25 00:53:21 +04:00
module_exit ( generic_ide_exit ) ;
2005-04-17 02:20:36 +04:00
MODULE_AUTHOR ( " Andre Hedrick " ) ;
MODULE_DESCRIPTION ( " PCI driver module for generic PCI IDE " ) ;
MODULE_LICENSE ( " GPL " ) ;