2005-04-16 15:20:36 -07:00
/*
* Copyright ( C ) 2001 - 2002 Andre Hedrick < andre @ linux - ide . org >
2008-11-02 21:40:08 +01:00
* Portions ( C ) Copyright 2002 Red Hat Inc
2005-04-16 15:20:36 -07: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-24 22:53:32 +02:00
# define DRV_NAME "ide_pci_generic"
2012-01-13 09:32:20 +10:30
static bool ide_generic_all ; /* Set to claim all devices */
2005-06-27 15:24:26 -07:00
2006-10-03 01:14:34 -07: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-27 15:24:26 -07:00
2009-05-30 20:06:54 +02: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-24 22:53:32 +02:00
# define DECLARE_GENERIC_PCI_DEV(extra_flags) \
2007-10-19 00:30:06 +02:00
{ \
2008-07-24 22:53:32 +02:00
. name = DRV_NAME , \
2007-10-19 00:30:06 +02:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
2008-04-26 17:36:35 +02:00
extra_flags , \
2007-10-19 00:30:07 +02:00
. swdma_mask = ATA_SWDMA2 , \
. mwdma_mask = ATA_MWDMA2 , \
. udma_mask = ATA_UDMA6 , \
2005-04-16 15:20:36 -07:00
}
2012-12-21 13:21:03 -08:00
static const struct ide_port_info generic_chipsets [ ] = {
2008-07-24 22:53:32 +02:00
/* 0: Unknown */
DECLARE_GENERIC_PCI_DEV ( 0 ) ,
2007-10-19 00:30:06 +02:00
2008-07-24 22:53:32 +02:00
{ /* 1: NS87410 */
. name = DRV_NAME ,
2008-04-26 17:36:40 +02:00
. enablebits = { { 0x43 , 0x08 , 0x08 } , { 0x47 , 0x08 , 0x08 } } ,
2008-04-26 17:36:35 +02:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA ,
2007-10-19 00:30:07 +02:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2007-10-19 00:30:06 +02:00
} ,
2008-07-24 22:53:32 +02:00
/* 2: SAMURAI / HT6565 / HINT_IDE */
DECLARE_GENERIC_PCI_DEV ( 0 ) ,
/* 3: UM8673F / UM8886A / UM8886BF */
2009-03-24 23:22:52 +01:00
DECLARE_GENERIC_PCI_DEV ( IDE_HFLAG_NO_DMA ) ,
2008-07-24 22:53:32 +02: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 00:30:06 +02:00
. host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD ,
2007-10-19 00:30:07 +02:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2007-10-19 00:30:06 +02:00
} ,
2008-07-24 22:53:32 +02:00
{ /* 6: Revolution */
. name = DRV_NAME ,
2009-05-30 20:06:54 +02:00
. port_ops = & netcell_port_ops ,
2008-02-01 23:09:30 +01:00
. host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
2007-10-19 00:30:06 +02:00
IDE_HFLAG_OFF_BOARD ,
2007-10-19 00:30:07 +02:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA6 ,
2005-04-16 15:20:36 -07: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 17:36:40 +02:00
2012-12-21 13:21:03 -08:00
static int generic_init_one ( struct pci_dev * dev , const struct pci_device_id * id )
2005-04-16 15:20:36 -07:00
{
2007-10-20 00:32:34 +02:00
const struct ide_port_info * d = & generic_chipsets [ id - > driver_data ] ;
2005-04-16 15:20:36 -07:00
int ret = - ENODEV ;
2005-06-27 15:24:26 -07: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 15:14:31 +02: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 10:38:57 -07:00
goto out ;
2007-06-08 15:14:31 +02:00
break ;
2006-10-28 10:38:57 -07:00
}
2006-07-12 15:05:41 +01:00
2006-10-11 01:21:47 -07:00
if ( dev - > vendor ! = PCI_VENDOR_ID_JMICRON ) {
2007-06-08 15:14:31 +02:00
u16 command ;
2006-10-11 01:21:47 -07:00
pci_read_config_word ( dev , PCI_COMMAND , & command ) ;
if ( ! ( command & PCI_COMMAND_IO ) ) {
2008-07-24 22:53:31 +02:00
printk ( KERN_INFO " %s %s: skipping disabled "
" controller \n " , d - > name , pci_name ( dev ) ) ;
2006-10-11 01:21:47 -07:00
goto out ;
}
2005-04-16 15:20:36 -07:00
}
2008-07-24 22:53:14 +02:00
ret = ide_pci_init_one ( dev , d , NULL ) ;
2005-04-16 15:20:36 -07:00
out :
return ret ;
}
2007-10-16 22:29:56 +02: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-24 22:53:32 +02: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-16 15:20:36 -07:00
# ifdef CONFIG_BLK_DEV_IDE_SATA
2008-07-24 22:53:32 +02:00
{ PCI_VDEVICE ( VIA , PCI_DEVICE_ID_VIA_8237_SATA ) , 5 } ,
2005-04-16 15:20:36 -07:00
# endif
2008-07-24 22:53:32 +02:00
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 ) , 4 } ,
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 ) , 4 } ,
2009-11-30 13:23:11 +00:00
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_3 ) , 4 } ,
{ PCI_VDEVICE ( TOSHIBA , PCI_DEVICE_ID_TOSHIBA_PICCOLO_5 ) , 4 } ,
2008-07-24 22:53:32 +02:00
{ PCI_VDEVICE ( NETCELL , PCI_DEVICE_ID_REVOLUTION ) , 6 } ,
2007-10-16 22:29:56 +02: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-16 15:20:36 -07:00
{ 0 , } ,
} ;
MODULE_DEVICE_TABLE ( pci , generic_pci_tbl ) ;
2008-10-13 21:39:41 +02:00
static struct pci_driver generic_pci_driver = {
2005-04-16 15:20:36 -07:00
. name = " PCI_IDE " ,
. id_table = generic_pci_tbl ,
. probe = generic_init_one ,
2008-07-24 22:53:21 +02:00
. remove = ide_pci_remove ,
2008-10-10 22:39:32 +02:00
. suspend = ide_pci_suspend ,
. resume = ide_pci_resume ,
2005-04-16 15:20:36 -07:00
} ;
2007-01-27 13:46:56 +01:00
static int __init generic_ide_init ( void )
2005-04-16 15:20:36 -07:00
{
2008-10-13 21:39:41 +02:00
return ide_pci_register_driver ( & generic_pci_driver ) ;
2005-04-16 15:20:36 -07:00
}
2008-07-24 22:53:21 +02:00
static void __exit generic_ide_exit ( void )
{
2008-10-13 21:39:41 +02:00
pci_unregister_driver ( & generic_pci_driver ) ;
2008-07-24 22:53:21 +02:00
}
2005-04-16 15:20:36 -07:00
module_init ( generic_ide_init ) ;
2008-07-24 22:53:21 +02:00
module_exit ( generic_ide_exit ) ;
2005-04-16 15:20:36 -07:00
MODULE_AUTHOR ( " Andre Hedrick " ) ;
MODULE_DESCRIPTION ( " PCI driver module for generic PCI IDE " ) ;
MODULE_LICENSE ( " GPL " ) ;