2005-04-17 02:20:36 +04:00
/*
* generic / default IDE host driver
*
2009-03-31 22:15:24 +04:00
* Copyright ( C ) 2004 , 2008 - 2009 Bartlomiej Zolnierkiewicz
2005-04-17 02:20:36 +04:00
* This code was split off from ide . c . See it for original copyrights .
*
* May be copied or modified under the terms of the GNU General Public License .
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/ide.h>
2008-10-11 00:39:35 +04:00
# include <linux/pci_ids.h>
2005-04-17 02:20:36 +04:00
2009-03-31 22:15:24 +04:00
/* FIXME: convert arm and m32r to use ide_platform host driver */
# ifdef CONFIG_ARM
# include <asm/irq.h>
# endif
2008-07-25 00:53:31 +04:00
# ifdef CONFIG_M32R
# include <asm/m32r.h>
# endif
2008-04-18 02:46:23 +04:00
# define DRV_NAME "ide_generic"
2008-10-11 00:39:35 +04:00
static int probe_mask ;
2008-06-15 23:00:24 +04:00
module_param ( probe_mask , int , 0 ) ;
MODULE_PARM_DESC ( probe_mask , " probe mask for legacy ISA IDE ports " ) ;
2009-03-27 14:46:17 +03:00
static const struct ide_port_info ide_generic_port_info = {
. host_flags = IDE_HFLAG_NO_DMA ,
2009-05-17 21:12:22 +04:00
. chipset = ide_generic ,
2009-03-27 14:46:17 +03:00
} ;
2009-03-31 22:15:24 +04:00
# ifdef CONFIG_ARM
static const u16 legacy_bases [ ] = { 0x1f0 } ;
static const int legacy_irqs [ ] = { IRQ_HARDDISK } ;
# elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
defined ( CONFIG_PLAT_OPSPUT )
2008-07-25 00:53:31 +04:00
static const u16 legacy_bases [ ] = { 0x1f0 } ;
static const int legacy_irqs [ ] = { PLD_IRQ_CFIREQ } ;
# elif defined(CONFIG_PLAT_MAPPI3)
static const u16 legacy_bases [ ] = { 0x1f0 , 0x170 } ;
static const int legacy_irqs [ ] = { PLD_IRQ_CFIREQ , PLD_IRQ_IDEIREQ } ;
# elif defined(CONFIG_ALPHA)
static const u16 legacy_bases [ ] = { 0x1f0 , 0x170 , 0x1e8 , 0x168 } ;
static const int legacy_irqs [ ] = { 14 , 15 , 11 , 10 } ;
# else
static const u16 legacy_bases [ ] = { 0x1f0 , 0x170 , 0x1e8 , 0x168 , 0x1e0 , 0x160 } ;
static const int legacy_irqs [ ] = { 14 , 15 , 11 , 10 , 8 , 12 } ;
# endif
2008-10-11 00:39:35 +04:00
static void ide_generic_check_pci_legacy_iobases ( int * primary , int * secondary )
{
2009-03-31 22:15:24 +04:00
# ifdef CONFIG_PCI
2008-10-11 00:39:35 +04:00
struct pci_dev * p = NULL ;
u16 val ;
for_each_pci_dev ( p ) {
if ( pci_resource_start ( p , 0 ) = = 0x1f0 )
* primary = 1 ;
if ( pci_resource_start ( p , 2 ) = = 0x170 )
* secondary = 1 ;
/* Cyrix CS55{1,2}0 pre SFF MWDMA ATA on the bridge */
if ( p - > vendor = = PCI_VENDOR_ID_CYRIX & &
( p - > device = = PCI_DEVICE_ID_CYRIX_5510 | |
p - > device = = PCI_DEVICE_ID_CYRIX_5520 ) )
* primary = * secondary = 1 ;
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if ( p - > vendor = = PCI_VENDOR_ID_INTEL & &
p - > device = = PCI_DEVICE_ID_INTEL_82371MX ) {
pci_read_config_word ( p , 0x6C , & val ) ;
if ( val & 0x8000 ) {
/* ATA port enabled */
if ( val & 0x4000 )
* secondary = 1 ;
else
* primary = 1 ;
}
}
}
2009-03-31 22:15:24 +04:00
# endif
2008-10-11 00:39:35 +04:00
}
2005-04-17 02:20:36 +04:00
static int __init ide_generic_init ( void )
{
2009-05-17 21:12:25 +04:00
struct ide_hw hw , * hws [ ] = { & hw } ;
2008-07-23 21:55:59 +04:00
unsigned long io_addr ;
2008-10-13 23:39:42 +04:00
int i , rc = 0 , primary = 0 , secondary = 0 ;
2008-01-26 22:13:05 +03:00
2008-10-11 00:39:35 +04:00
ide_generic_check_pci_legacy_iobases ( & primary , & secondary ) ;
if ( ! probe_mask ) {
printk ( KERN_INFO DRV_NAME " : please use \" probe_mask=0x3f \" "
" module parameter for probing all legacy ISA IDE ports \n " ) ;
if ( primary = = 0 )
probe_mask | = 0x1 ;
if ( secondary = = 0 )
probe_mask | = 0x2 ;
} else
printk ( KERN_INFO DRV_NAME " : enforcing probing of I/O ports "
" upon user request \n " ) ;
2008-06-15 23:00:24 +04:00
2008-07-25 00:53:31 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( legacy_bases ) ; i + + ) {
io_addr = legacy_bases [ i ] ;
2008-04-18 02:46:35 +04:00
2008-06-15 23:00:24 +04:00
if ( ( probe_mask & ( 1 < < i ) ) & & io_addr ) {
2008-04-27 00:25:17 +04:00
if ( ! request_region ( io_addr , 8 , DRV_NAME ) ) {
printk ( KERN_ERR " %s: I/O resource 0x%lX-0x%lX "
" not free. \n " ,
DRV_NAME , io_addr , io_addr + 7 ) ;
2009-03-31 22:15:24 +04:00
rc = - EBUSY ;
2008-04-27 00:25:17 +04:00
continue ;
}
if ( ! request_region ( io_addr + 0x206 , 1 , DRV_NAME ) ) {
printk ( KERN_ERR " %s: I/O resource 0x%lX "
" not free. \n " ,
DRV_NAME , io_addr + 0x206 ) ;
release_region ( io_addr , 8 ) ;
2009-03-31 22:15:24 +04:00
rc = - EBUSY ;
2008-04-27 00:25:17 +04:00
continue ;
}
2008-10-13 23:39:42 +04:00
memset ( & hw , 0 , sizeof ( hw ) ) ;
ide_std_init_ports ( & hw , io_addr , io_addr + 0x206 ) ;
2008-07-25 00:53:31 +04:00
# ifdef CONFIG_IA64
2008-10-13 23:39:42 +04:00
hw . irq = isa_irq_to_vector ( legacy_irqs [ i ] ) ;
2008-07-25 00:53:31 +04:00
# else
2008-10-13 23:39:42 +04:00
hw . irq = legacy_irqs [ i ] ;
2008-07-25 00:53:31 +04:00
# endif
2009-05-17 21:12:24 +04:00
rc = ide_host_add ( & ide_generic_port_info , hws , 1 , NULL ) ;
2008-10-13 23:39:42 +04:00
if ( rc ) {
release_region ( io_addr + 0x206 , 1 ) ;
release_region ( io_addr , 8 ) ;
}
2008-04-27 00:25:17 +04:00
}
ide-generic: probing bugfix
On Tuesday 05 February 2008, Linus Torvalds wrote:
>
> On Sat, 2 Feb 2008, Bartlomiej Zolnierkiewicz wrote:
> >
> > * next part of IDE probing code re-organization saga
> > (that would be me)
>
> This seems to cause very irritating and bogus messages for me:
>
> Probing IDE interface ide0...
> Probing IDE interface ide1...
> ide2: I/O resource 0x0-0x7 not free.
> ide2: ports already in use, skipping probe
> ide3: I/O resource 0x0-0x7 not free.
> ide3: ports already in use, skipping probe
> ide4: I/O resource 0x0-0x7 not free.
> ide4: ports already in use, skipping probe
> ide5: I/O resource 0x0-0x7 not free.
> ide5: ports already in use, skipping probe
> ide6: I/O resource 0x0-0x7 not free.
> ide6: ports already in use, skipping probe
> ide7: I/O resource 0x0-0x7 not free.
> ide7: ports already in use, skipping probe
> ide8: I/O resource 0x0-0x7 not free.
> ide8: ports already in use, skipping probe
> ide9: I/O resource 0x0-0x7 not free.
> ide9: ports already in use, skipping probe
>
> and that's just totally bogus. It shouldn't even request that region,
> since it's not been allocated!
The commit 139ddfcab50e5eabcc88341c8743a990ac1be6a2 ("ide: move handling of
I/O resources out of ide_probe_port()") changed the ordering of hwif->noprobe
check vs ide_hwif_request_regions() call (so that we now reserve I/O regions
before checking for hwif->noprobe). However ide-generic host driver depended
on hwif->noprobe to be set for skipping probing of empty ide_hwifs[] slots.
Fix it by passing only indexes of non-empty slots to ide_device_add_all()
from ide_generic_init().
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-02-06 04:57:48 +03:00
}
2008-01-26 22:13:05 +03:00
2008-07-23 21:55:59 +04:00
return rc ;
2005-04-17 02:20:36 +04:00
}
module_init ( ide_generic_init ) ;
MODULE_LICENSE ( " GPL " ) ;