2005-04-17 02:20:36 +04:00
/*
* generic / default IDE host driver
*
2008-04-18 02:46:23 +04:00
* Copyright ( C ) 2004 , 2008 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 .
*/
2008-04-18 02:46:23 +04:00
/*
* For special cases new interfaces may be added using sysfs , i . e .
*
* echo - n " 0x168:0x36e:10 " > / sys / class / ide_generic / add
*
* will add an interface using I / O ports 0x168 - 0x16f / 0x36e and IRQ 10.
*/
2005-04-17 02:20:36 +04:00
# 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
2008-07-25 00:53:31 +04:00
/* FIXME: convert m32r to use ide_platform host driver */
# 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 " ) ;
2008-04-18 02:46:23 +04:00
static ssize_t store_add ( struct class * cls , const char * buf , size_t n )
{
unsigned int base , ctl ;
ide: add ide_host_add() helper
Add ide_host_add() helper which does ide_host_alloc()+ide_host_register(),
then convert ide_setup_pci_device[s](), ide_legacy_device_add() and some
host drivers to use it.
While at it:
* Fix ide_setup_pci_device[s](), ide_arm.c, gayle.c, ide-4drives.c,
macide.c, q40ide.c, cmd640.c and cs5520.c to return correct error value.
* -ENOENT -> -ENOMEM in rapide.c, ide-h8300.c, ide-generic.c, au1xxx-ide.c
and pmac.c
* -ENODEV -> -ENOMEM in palm_bk3710.c, ide_platform.c and delkin_cb.c
* -1 -> -ENOMEM in ide-pnp.c
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-07-23 21:55:57 +04:00
int irq , rc ;
2008-07-23 21:55:50 +04:00
hw_regs_t hw , * hws [ ] = { & hw , NULL , NULL , NULL } ;
2008-04-18 02:46:23 +04:00
if ( sscanf ( buf , " %x:%x:%d " , & base , & ctl , & irq ) ! = 3 )
return - EINVAL ;
memset ( & hw , 0 , sizeof ( hw ) ) ;
ide_std_init_ports ( & hw , base , ctl ) ;
hw . irq = irq ;
hw . chipset = ide_generic ;
ide: add ide_host_add() helper
Add ide_host_add() helper which does ide_host_alloc()+ide_host_register(),
then convert ide_setup_pci_device[s](), ide_legacy_device_add() and some
host drivers to use it.
While at it:
* Fix ide_setup_pci_device[s](), ide_arm.c, gayle.c, ide-4drives.c,
macide.c, q40ide.c, cmd640.c and cs5520.c to return correct error value.
* -ENOENT -> -ENOMEM in rapide.c, ide-h8300.c, ide-generic.c, au1xxx-ide.c
and pmac.c
* -ENODEV -> -ENOMEM in palm_bk3710.c, ide_platform.c and delkin_cb.c
* -1 -> -ENOMEM in ide-pnp.c
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-07-23 21:55:57 +04:00
rc = ide_host_add ( NULL , hws , NULL ) ;
if ( rc )
return rc ;
2008-04-18 02:46:23 +04:00
return n ;
} ;
static struct class_attribute ide_generic_class_attrs [ ] = {
__ATTR ( add , S_IWUSR , NULL , store_add ) ,
__ATTR_NULL
} ;
static void ide_generic_class_release ( struct class * cls )
{
kfree ( cls ) ;
}
static int __init ide_generic_sysfs_init ( void )
{
struct class * cls ;
int rc ;
cls = kzalloc ( sizeof ( * cls ) , GFP_KERNEL ) ;
if ( ! cls )
return - ENOMEM ;
cls - > name = DRV_NAME ;
cls - > owner = THIS_MODULE ;
cls - > class_release = ide_generic_class_release ;
cls - > class_attrs = ide_generic_class_attrs ;
rc = class_register ( cls ) ;
if ( rc ) {
kfree ( cls ) ;
return rc ;
}
return 0 ;
}
2008-07-25 00:53:31 +04:00
# if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
| | defined ( CONFIG_PLAT_OPSPUT )
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 )
{
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 ;
}
}
}
}
2005-04-17 02:20:36 +04:00
static int __init ide_generic_init ( void )
{
2008-10-13 23:39:42 +04:00
hw_regs_t hw , * hws [ ] = { & hw , NULL , NULL , NULL } ;
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 ) ;
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 ) ;
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
2008-10-13 23:39:42 +04:00
hw . chipset = ide_generic ;
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-10-13 23:39:42 +04:00
rc = ide_host_add ( NULL , hws , NULL ) ;
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-04-18 02:46:23 +04:00
if ( ide_generic_sysfs_init ( ) )
printk ( KERN_ERR DRV_NAME " : failed to create ide_generic "
" class \n " ) ;
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 " ) ;