2005-04-16 15:20:36 -07:00
/*
2008-02-01 23:09:33 +01:00
* Copyright ( C ) 1998 - 2000 Andre Hedrick < andre @ linux - ide . org >
* Copyright ( C ) 1995 - 1998 Mark Lord
* Copyright ( C ) 2007 Bartlomiej Zolnierkiewicz
2008-02-01 23:09:33 +01:00
*
2005-04-16 15:20:36 -07:00
* May be copied or modified under the terms of the GNU General Public License
*/
# include <linux/module.h>
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/init.h>
# include <linux/timer.h>
# include <linux/mm.h>
# include <linux/interrupt.h>
# include <linux/ide.h>
# include <linux/dma-mapping.h>
# include <asm/io.h>
# include <asm/irq.h>
/**
* ide_match_hwif - match a PCI IDE against an ide_hwif
* @ io_base : I / O base of device
* @ bootable : set if its bootable
* @ name : name of device
*
* Match a PCI IDE port against an entry in ide_hwifs [ ] ,
* based on io_base port if possible . Return the matching hwif ,
* or a new hwif . If we find an error ( clashing , out of devices , etc )
* return NULL
*
* FIXME : we need to handle mmio matches here too
*/
static ide_hwif_t * ide_match_hwif ( unsigned long io_base , u8 bootable , const char * name )
{
int h ;
ide_hwif_t * hwif ;
/*
* Look for a hwif with matching io_base specified using
* parameters to ide_setup ( ) .
*/
for ( h = 0 ; h < MAX_HWIFS ; + + h ) {
hwif = & ide_hwifs [ h ] ;
if ( hwif - > io_ports [ IDE_DATA_OFFSET ] = = io_base ) {
if ( hwif - > chipset = = ide_forced )
return hwif ; /* a perfect match */
}
}
/*
* Look for a hwif with matching io_base default value .
* If chipset is " ide_unknown " , then claim that hwif slot .
* Otherwise , some other chipset has already claimed it . . : (
*/
for ( h = 0 ; h < MAX_HWIFS ; + + h ) {
hwif = & ide_hwifs [ h ] ;
if ( hwif - > io_ports [ IDE_DATA_OFFSET ] = = io_base ) {
if ( hwif - > chipset = = ide_unknown )
return hwif ; /* match */
printk ( KERN_ERR " %s: port 0x%04lx already claimed by %s \n " ,
name , io_base , hwif - > name ) ;
return NULL ; /* already claimed */
}
}
/*
* Okay , there is no hwif matching our io_base ,
* so we ' ll just claim an unassigned slot .
* Give preference to claiming other slots before claiming ide0 / ide1 ,
* just in case there ' s another interface yet - to - be - scanned
* which uses ports 1f 0 / 170 ( the ide0 / ide1 defaults ) .
*
* Unless there is a bootable card that does not use the standard
* ports 1f 0 / 170 ( the ide0 / ide1 defaults ) . The ( bootable ) flag .
*/
if ( bootable ) {
for ( h = 0 ; h < MAX_HWIFS ; + + h ) {
hwif = & ide_hwifs [ h ] ;
if ( hwif - > chipset = = ide_unknown )
return hwif ; /* pick an unused entry */
}
} else {
for ( h = 2 ; h < MAX_HWIFS ; + + h ) {
hwif = ide_hwifs + h ;
if ( hwif - > chipset = = ide_unknown )
return hwif ; /* pick an unused entry */
}
}
2006-10-03 01:14:16 -07:00
for ( h = 0 ; h < 2 & & h < MAX_HWIFS ; + + h ) {
2005-04-16 15:20:36 -07:00
hwif = ide_hwifs + h ;
if ( hwif - > chipset = = ide_unknown )
return hwif ; /* pick an unused entry */
}
printk ( KERN_ERR " %s: too many IDE interfaces, no room in table \n " , name ) ;
return NULL ;
}
/**
* ide_setup_pci_baseregs - place a PCI IDE controller native
* @ dev : PCI device of interface to switch native
* @ name : Name of interface
*
* We attempt to place the PCI interface into PCI native mode . If
* we succeed the BARs are ok and the controller is in PCI mode .
* Returns 0 on success or an errno code .
*
* FIXME : if we program the interface and then fail to set the BARS
* we don ' t switch it back to legacy mode . Do we actually care ? ?
*/
static int ide_setup_pci_baseregs ( struct pci_dev * dev , const char * name )
{
u8 progif = 0 ;
/*
* Place both IDE interfaces into PCI " native " mode :
*/
if ( pci_read_config_byte ( dev , PCI_CLASS_PROG , & progif ) | |
( progif & 5 ) ! = 5 ) {
if ( ( progif & 0xa ) ! = 0xa ) {
printk ( KERN_INFO " %s: device not capable of full "
" native PCI mode \n " , name ) ;
return - EOPNOTSUPP ;
}
printk ( " %s: placing both ports into native PCI mode \n " , name ) ;
( void ) pci_write_config_byte ( dev , PCI_CLASS_PROG , progif | 5 ) ;
if ( pci_read_config_byte ( dev , PCI_CLASS_PROG , & progif ) | |
( progif & 5 ) ! = 5 ) {
printk ( KERN_ERR " %s: rewrite of PROGIF failed, wanted "
" 0x%04x, got 0x%04x \n " ,
name , progif | 5 , progif ) ;
return - EOPNOTSUPP ;
}
}
return 0 ;
}
# ifdef CONFIG_BLK_DEV_IDEDMA_PCI
2008-02-01 23:09:30 +01:00
static void ide_pci_clear_simplex ( unsigned long dma_base , const char * name )
{
u8 dma_stat = inb ( dma_base + 2 ) ;
outb ( dma_stat & 0x60 , dma_base + 2 ) ;
dma_stat = inb ( dma_base + 2 ) ;
if ( dma_stat & 0x80 )
printk ( KERN_INFO " %s: simplex device: DMA forced \n " , name ) ;
}
2005-04-16 15:20:36 -07:00
/**
* ide_get_or_set_dma_base - setup BMIBA
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
* @ hwif : IDE interface
2005-04-16 15:20:36 -07:00
*
2007-10-16 22:29:56 +02:00
* Fetch the DMA Bus - Master - I / O - Base - Address ( BMIBA ) from PCI space .
* Where a device has a partner that is already in DMA mode we check
* and enforce IDE simplex rules .
2005-04-16 15:20:36 -07:00
*/
2007-10-20 00:32:34 +02:00
static unsigned long ide_get_or_set_dma_base ( const struct ide_port_info * d , ide_hwif_t * hwif )
2005-04-16 15:20:36 -07:00
{
2008-02-01 23:09:31 +01:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
unsigned long dma_base = 0 ;
2008-02-01 23:09:30 +01:00
u8 dma_stat = 0 ;
2005-04-16 15:20:36 -07:00
if ( hwif - > mmio )
return hwif - > dma_base ;
if ( hwif - > mate & & hwif - > mate - > dma_base ) {
dma_base = hwif - > mate - > dma_base - ( hwif - > channel ? 0 : 8 ) ;
} else {
2007-10-19 00:30:07 +02:00
u8 baridx = ( d - > host_flags & IDE_HFLAG_CS5520 ) ? 2 : 4 ;
dma_base = pci_resource_start ( dev , baridx ) ;
2008-01-26 20:12:59 +01:00
if ( dma_base = = 0 ) {
2007-10-19 00:30:07 +02:00
printk ( KERN_ERR " %s: DMA base is invalid \n " , d - > name ) ;
2008-01-26 20:12:59 +01:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
}
2008-01-26 20:12:59 +01:00
if ( hwif - > channel )
dma_base + = 8 ;
2008-02-01 23:09:30 +01:00
if ( d - > host_flags & IDE_HFLAG_CS5520 )
goto out ;
if ( d - > host_flags & IDE_HFLAG_CLEAR_SIMPLEX ) {
ide_pci_clear_simplex ( dma_base , d - > name ) ;
goto out ;
}
/*
* If the device claims " simplex " DMA , this means that only one of
* the two interfaces can be trusted with DMA at any point in time
* ( so we should enable DMA only on one of the two interfaces ) .
*
* FIXME : At this point we haven ' t probed the drives so we can ' t make
* the appropriate decision . Really we should defer this problem until
* we tune the drive then try to grab DMA ownership if we want to be
* the DMA end . This has to be become dynamic to handle hot - plug .
*/
dma_stat = hwif - > INB ( dma_base + 2 ) ;
if ( ( dma_stat & 0x80 ) & & hwif - > mate & & hwif - > mate - > dma_base ) {
printk ( KERN_INFO " %s: simplex device: DMA disabled \n " , d - > name ) ;
dma_base = 0 ;
2005-04-16 15:20:36 -07:00
}
2008-02-01 23:09:30 +01:00
out :
2005-04-16 15:20:36 -07:00
return dma_base ;
}
# endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
2007-10-20 00:32:34 +02:00
void ide_setup_pci_noise ( struct pci_dev * dev , const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
2007-10-20 00:32:36 +02:00
printk ( KERN_INFO " %s: IDE controller (0x%04x:0x%04x rev 0x%02x) at "
" PCI slot %s \n " , d - > name , dev - > vendor , dev - > device ,
dev - > revision , pci_name ( dev ) ) ;
2005-04-16 15:20:36 -07:00
}
EXPORT_SYMBOL_GPL ( ide_setup_pci_noise ) ;
/**
* ide_pci_enable - do PCI enables
* @ dev : PCI device
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
2005-04-16 15:20:36 -07:00
*
* Enable the IDE PCI device . We attempt to enable the device in full
2007-12-20 15:28:09 +11:00
* but if that fails then we only need IO space . The PCI code should
* have setup the proper resources for us already for controllers in
* legacy mode .
2005-04-16 15:20:36 -07:00
*
* Returns zero on success or an error code
*/
2007-10-20 00:32:34 +02:00
2007-10-20 00:32:34 +02:00
static int ide_pci_enable ( struct pci_dev * dev , const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
int ret ;
if ( pci_enable_device ( dev ) ) {
2007-12-20 15:28:09 +11:00
ret = pci_enable_device_io ( dev ) ;
2005-04-16 15:20:36 -07:00
if ( ret < 0 ) {
printk ( KERN_WARNING " %s: (ide_setup_pci_device:) "
" Could not enable device. \n " , d - > name ) ;
goto out ;
}
printk ( KERN_WARNING " %s: BIOS configuration fixed. \n " , d - > name ) ;
}
/*
2007-10-20 00:32:34 +02:00
* assume all devices can do 32 - bit DMA for now , we can add
* a DMA mask field to the struct ide_port_info if we need it
* ( or let lower level driver set the DMA mask )
2005-04-16 15:20:36 -07:00
*/
ret = pci_set_dma_mask ( dev , DMA_32BIT_MASK ) ;
if ( ret < 0 ) {
printk ( KERN_ERR " %s: can't set dma mask \n " , d - > name ) ;
goto out ;
}
/* FIXME: Temporary - until we put in the hotplug interface logic
Check that the bits we want are not in use by someone else . */
ret = pci_request_region ( dev , 4 , " ide_tmp " ) ;
if ( ret < 0 )
goto out ;
pci_release_region ( dev , 4 ) ;
out :
return ret ;
}
/**
* ide_pci_configure - configure an unconfigured device
* @ dev : PCI device
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
2005-04-16 15:20:36 -07:00
*
* Enable and configure the PCI device we have been passed .
* Returns zero on success or an error code .
*/
2007-10-20 00:32:34 +02:00
2007-10-20 00:32:34 +02:00
static int ide_pci_configure ( struct pci_dev * dev , const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
u16 pcicmd = 0 ;
/*
* PnP BIOS was * supposed * to have setup this device , but we
* can do it ourselves , so long as the BIOS has assigned an IRQ
* ( or possibly the device is using a " legacy header " for IRQs ) .
* Maybe the user deliberately * disabled * the device ,
* but we ' ll eventually ignore it again if no drives respond .
*/
if ( ide_setup_pci_baseregs ( dev , d - > name ) | | pci_write_config_word ( dev , PCI_COMMAND , pcicmd | PCI_COMMAND_IO ) )
{
printk ( KERN_INFO " %s: device disabled (BIOS) \n " , d - > name ) ;
return - ENODEV ;
}
if ( pci_read_config_word ( dev , PCI_COMMAND , & pcicmd ) ) {
printk ( KERN_ERR " %s: error accessing PCI regs \n " , d - > name ) ;
return - EIO ;
}
if ( ! ( pcicmd & PCI_COMMAND_IO ) ) {
printk ( KERN_ERR " %s: unable to enable IDE controller \n " , d - > name ) ;
return - ENXIO ;
}
return 0 ;
}
/**
* ide_pci_check_iomem - check a register is I / O
2007-10-20 00:32:34 +02:00
* @ dev : PCI device
* @ d : IDE port info
* @ bar : BAR number
2005-04-16 15:20:36 -07:00
*
* Checks if a BAR is configured and points to MMIO space . If so
* print an error and return an error code . Otherwise return 0
*/
2007-10-20 00:32:34 +02:00
2007-10-20 00:32:34 +02:00
static int ide_pci_check_iomem ( struct pci_dev * dev , const struct ide_port_info * d , int bar )
2005-04-16 15:20:36 -07:00
{
ulong flags = pci_resource_flags ( dev , bar ) ;
/* Unconfigured ? */
if ( ! flags | | pci_resource_len ( dev , bar ) = = 0 )
return 0 ;
/* I/O space */
if ( flags & PCI_BASE_ADDRESS_IO_MASK )
return 0 ;
/* Bad */
printk ( KERN_ERR " %s: IO baseregs (BIOS) are reported "
" as MEM, report to "
" <andre@linux-ide.org>. \n " , d - > name ) ;
return - EINVAL ;
}
/**
* ide_hwif_configure - configure an IDE interface
* @ dev : PCI device holding interface
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
2008-02-02 19:56:30 +01:00
* @ port : port number
* @ irq : PCI IRQ
2005-04-16 15:20:36 -07:00
*
* Perform the initial set up for the hardware interface structure . This
* is done per interface port rather than per PCI device . There may be
* more than one port per device .
*
* Returns the new hardware interface structure , or NULL on a failure
*/
2007-10-20 00:32:34 +02:00
2008-02-02 19:56:30 +01:00
static ide_hwif_t * ide_hwif_configure ( struct pci_dev * dev ,
const struct ide_port_info * d ,
unsigned int port , int irq )
2005-04-16 15:20:36 -07:00
{
unsigned long ctl = 0 , base = 0 ;
ide_hwif_t * hwif ;
2007-10-19 00:30:06 +02:00
u8 bootable = ( d - > host_flags & IDE_HFLAG_BOOTABLE ) ? 1 : 0 ;
2008-01-26 20:13:08 +01:00
u8 oldnoprobe = 0 ;
struct hw_regs_s hw ;
2005-04-16 15:20:36 -07:00
2007-07-20 01:11:55 +02:00
if ( ( d - > host_flags & IDE_HFLAG_ISA_PORTS ) = = 0 ) {
2005-04-16 15:20:36 -07:00
/* Possibly we should fail if these checks report true */
ide_pci_check_iomem ( dev , d , 2 * port ) ;
ide_pci_check_iomem ( dev , d , 2 * port + 1 ) ;
ctl = pci_resource_start ( dev , 2 * port + 1 ) ;
base = pci_resource_start ( dev , 2 * port ) ;
if ( ( ctl & & ! base ) | | ( base & & ! ctl ) ) {
printk ( KERN_ERR " %s: inconsistent baseregs (BIOS) "
" for port %d, skipping \n " , d - > name , port ) ;
return NULL ;
}
}
if ( ! ctl )
{
/* Use default values */
ctl = port ? 0x374 : 0x3f4 ;
base = port ? 0x170 : 0x1f0 ;
}
2007-10-19 00:30:06 +02:00
if ( ( hwif = ide_match_hwif ( base , bootable , d - > name ) ) = = NULL )
2005-04-16 15:20:36 -07:00
return NULL ; /* no room in ide_hwifs[] */
2008-01-26 20:13:08 +01:00
memset ( & hw , 0 , sizeof ( hw ) ) ;
hw . irq = hwif - > irq ? hwif - > irq : irq ;
hw . dev = & dev - > dev ;
hw . chipset = d - > chipset ? d - > chipset : ide_pci ;
ide_std_init_ports ( & hw , base , ctl | 2 ) ;
if ( hwif - > io_ports [ IDE_DATA_OFFSET ] = = base & &
hwif - > io_ports [ IDE_CONTROL_OFFSET ] = = ( ctl | 2 ) )
oldnoprobe = hwif - > noprobe ;
ide_init_port_hw ( hwif , & hw ) ;
hwif - > noprobe = oldnoprobe ;
2008-02-01 23:09:31 +01:00
hwif - > dev = & dev - > dev ;
2007-10-20 00:32:34 +02:00
hwif - > cds = d ;
2005-04-16 15:20:36 -07:00
return hwif ;
}
2008-02-02 19:56:31 +01:00
# ifdef CONFIG_BLK_DEV_IDEDMA_PCI
2005-04-16 15:20:36 -07:00
/**
* ide_hwif_setup_dma - configure DMA interface
2007-10-20 00:32:34 +02:00
* @ hwif : IDE interface
2008-02-02 19:56:31 +01:00
* @ d : IDE port info
2005-04-16 15:20:36 -07:00
*
* Set up the DMA base for the interface . Enable the master bits as
* necessary and attempt to bring the device DMA into a ready to use
* state
*/
2007-10-20 00:32:34 +02:00
2008-02-02 19:56:31 +01:00
void ide_hwif_setup_dma ( ide_hwif_t * hwif , const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
2008-02-02 19:56:31 +01:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
2005-04-16 15:20:36 -07:00
u16 pcicmd ;
2007-10-19 00:30:06 +02:00
2005-04-16 15:20:36 -07:00
pci_read_config_word ( dev , PCI_COMMAND , & pcicmd ) ;
2007-10-19 00:30:06 +02:00
if ( ( d - > host_flags & IDE_HFLAG_NO_AUTODMA ) = = 0 | |
2005-04-16 15:20:36 -07:00
( ( dev - > class > > 8 ) = = PCI_CLASS_STORAGE_IDE & &
( dev - > class & 0x80 ) ) ) {
2007-10-19 00:30:07 +02:00
unsigned long dma_base = ide_get_or_set_dma_base ( d , hwif ) ;
2005-04-16 15:20:36 -07:00
if ( dma_base & & ! ( pcicmd & PCI_COMMAND_MASTER ) ) {
/*
* Set up BM - DMA capability
* ( PnP BIOS should have done this )
*/
pci_set_master ( dev ) ;
if ( pci_read_config_word ( dev , PCI_COMMAND , & pcicmd ) | | ! ( pcicmd & PCI_COMMAND_MASTER ) ) {
printk ( KERN_ERR " %s: %s error updating PCICMD \n " ,
hwif - > name , d - > name ) ;
dma_base = 0 ;
}
}
if ( dma_base ) {
if ( d - > init_dma ) {
d - > init_dma ( hwif , dma_base ) ;
} else {
2008-02-01 23:09:30 +01:00
ide_setup_dma ( hwif , dma_base ) ;
2005-04-16 15:20:36 -07:00
}
} else {
printk ( KERN_INFO " %s: %s Bus-Master DMA disabled "
" (BIOS) \n " , hwif - > name , d - > name ) ;
}
}
2007-10-20 00:32:34 +02:00
}
2008-02-02 19:56:31 +01:00
# endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
2005-04-16 15:20:36 -07:00
/**
* ide_setup_pci_controller - set up IDE PCI
* @ dev : PCI device
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
2005-04-16 15:20:36 -07:00
* @ noisy : verbose flag
* @ config : returned as 1 if we configured the hardware
*
* Set up the PCI and controller side of the IDE interface . This brings
* up the PCI side of the device , checks that the device is enabled
* and enables it if need be
*/
2007-10-20 00:32:34 +02:00
2007-10-20 00:32:34 +02:00
static int ide_setup_pci_controller ( struct pci_dev * dev , const struct ide_port_info * d , int noisy , int * config )
2005-04-16 15:20:36 -07:00
{
int ret ;
u16 pcicmd ;
if ( noisy )
ide_setup_pci_noise ( dev , d ) ;
ret = ide_pci_enable ( dev , d ) ;
if ( ret < 0 )
goto out ;
ret = pci_read_config_word ( dev , PCI_COMMAND , & pcicmd ) ;
if ( ret < 0 ) {
printk ( KERN_ERR " %s: error accessing PCI regs \n " , d - > name ) ;
goto out ;
}
if ( ! ( pcicmd & PCI_COMMAND_IO ) ) { /* is device disabled? */
ret = ide_pci_configure ( dev , d ) ;
if ( ret < 0 )
goto out ;
* config = 1 ;
printk ( KERN_INFO " %s: device enabled (Linux) \n " , d - > name ) ;
}
out :
return ret ;
}
/**
* ide_pci_setup_ports - configure ports / devices on PCI IDE
* @ dev : PCI device
2007-10-20 00:32:34 +02:00
* @ d : IDE port info
2005-04-16 15:20:36 -07:00
* @ pciirq : IRQ line
2007-10-20 00:32:31 +02:00
* @ idx : ATA index table to update
2005-04-16 15:20:36 -07:00
*
* Scan the interfaces attached to this device and do any
* necessary per port setup . Attach the devices and ask the
* generic DMA layer to do its work for us .
*
* Normally called automaticall from do_ide_pci_setup_device ,
* but is also used directly as a helper function by some controllers
* where the chipset setup is not the default PCI IDE one .
*/
2007-10-20 00:32:31 +02:00
2007-10-20 00:32:34 +02:00
void ide_pci_setup_ports ( struct pci_dev * dev , const struct ide_port_info * d , int pciirq , u8 * idx )
2005-04-16 15:20:36 -07:00
{
2007-07-20 01:11:55 +02:00
int channels = ( d - > host_flags & IDE_HFLAG_SINGLE ) ? 1 : 2 , port ;
2008-02-02 19:56:31 +01:00
ide_hwif_t * hwif ;
2005-04-16 15:20:36 -07:00
u8 tmp ;
/*
* Set up the IDE ports
*/
2007-10-20 00:32:29 +02:00
2007-07-20 01:11:55 +02:00
for ( port = 0 ; port < channels ; + + port ) {
2007-10-20 00:32:34 +02:00
const ide_pci_enablebit_t * e = & ( d - > enablebits [ port ] ) ;
2005-04-16 15:20:36 -07:00
if ( e - > reg & & ( pci_read_config_byte ( dev , e - > reg , & tmp ) | |
2007-10-20 00:32:29 +02:00
( tmp & e - > mask ) ! = e - > val ) ) {
printk ( KERN_INFO " %s: IDE port disabled \n " , d - > name ) ;
2005-04-16 15:20:36 -07:00
continue ; /* port not enabled */
2007-10-20 00:32:29 +02:00
}
2005-04-16 15:20:36 -07:00
2008-02-02 19:56:30 +01:00
hwif = ide_hwif_configure ( dev , d , port , pciirq ) ;
if ( hwif = = NULL )
2005-04-16 15:20:36 -07:00
continue ;
2007-10-20 00:32:31 +02:00
* ( idx + port ) = hwif - > index ;
2008-02-02 19:56:30 +01:00
}
2005-04-16 15:20:36 -07:00
}
EXPORT_SYMBOL_GPL ( ide_pci_setup_ports ) ;
/*
* ide_setup_pci_device ( ) looks at the primary / secondary interfaces
* on a PCI IDE device and , if they are enabled , prepares the IDE driver
* for use with them . This generic code works for most PCI chipsets .
*
* One thing that is not standardized is the location of the
* primary / secondary interface " enable/disable " bits . For chipsets that
2007-10-20 00:32:34 +02:00
* we " know " about , this information is in the struct ide_port_info ;
2005-04-16 15:20:36 -07:00
* for all other chipsets , we just assume both interfaces are enabled .
*/
2007-10-20 00:32:34 +02:00
static int do_ide_setup_pci_device ( struct pci_dev * dev ,
2007-10-20 00:32:34 +02:00
const struct ide_port_info * d ,
2007-10-20 00:32:31 +02:00
u8 * idx , u8 noisy )
2005-04-16 15:20:36 -07:00
{
int tried_config = 0 ;
int pciirq , ret ;
ret = ide_setup_pci_controller ( dev , d , noisy , & tried_config ) ;
if ( ret < 0 )
goto out ;
/*
* Can we trust the reported IRQ ?
*/
pciirq = dev - > irq ;
/* Is it an "IDE storage" device in non-PCI mode? */
if ( ( dev - > class > > 8 ) = = PCI_CLASS_STORAGE_IDE & & ( dev - > class & 5 ) ! = 5 ) {
if ( noisy )
printk ( KERN_INFO " %s: not 100%% native mode: "
" will probe irqs later \n " , d - > name ) ;
/*
* This allows offboard ide - pci cards the enable a BIOS ,
* verify interrupt settings of split - mirror pci - config
* space , place chipset into init - mode , and / or preserve
* an interrupt if the card is not native ide support .
*/
ret = d - > init_chipset ? d - > init_chipset ( dev , d - > name ) : 0 ;
if ( ret < 0 )
goto out ;
pciirq = ret ;
} else if ( tried_config ) {
if ( noisy )
printk ( KERN_INFO " %s: will probe irqs later \n " , d - > name ) ;
pciirq = 0 ;
} else if ( ! pciirq ) {
if ( noisy )
printk ( KERN_WARNING " %s: bad irq (%d): will probe later \n " ,
d - > name , pciirq ) ;
pciirq = 0 ;
} else {
if ( d - > init_chipset ) {
ret = d - > init_chipset ( dev , d - > name ) ;
if ( ret < 0 )
goto out ;
}
if ( noisy )
printk ( KERN_INFO " %s: 100%% native mode on irq %d \n " ,
d - > name , pciirq ) ;
}
/* FIXME: silent failure can happen */
2007-10-20 00:32:31 +02:00
ide_pci_setup_ports ( dev , d , pciirq , idx ) ;
2005-04-16 15:20:36 -07:00
out :
return ret ;
}
2007-10-20 00:32:34 +02:00
int ide_setup_pci_device ( struct pci_dev * dev , const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
2007-10-20 00:32:31 +02:00
u8 idx [ 4 ] = { 0xff , 0xff , 0xff , 0xff } ;
2005-04-16 15:20:36 -07:00
int ret ;
2007-10-20 00:32:31 +02:00
ret = do_ide_setup_pci_device ( dev , d , & idx [ 0 ] , 1 ) ;
2005-04-16 15:20:36 -07:00
2007-10-20 00:32:31 +02:00
if ( ret > = 0 )
2008-02-02 19:56:31 +01:00
ide_device_add ( idx , d ) ;
2005-04-16 15:20:36 -07:00
return ret ;
}
EXPORT_SYMBOL_GPL ( ide_setup_pci_device ) ;
int ide_setup_pci_devices ( struct pci_dev * dev1 , struct pci_dev * dev2 ,
2007-10-20 00:32:34 +02:00
const struct ide_port_info * d )
2005-04-16 15:20:36 -07:00
{
struct pci_dev * pdev [ ] = { dev1 , dev2 } ;
int ret , i ;
2007-10-20 00:32:31 +02:00
u8 idx [ 4 ] = { 0xff , 0xff , 0xff , 0xff } ;
2005-04-16 15:20:36 -07:00
for ( i = 0 ; i < 2 ; i + + ) {
2007-10-20 00:32:31 +02:00
ret = do_ide_setup_pci_device ( pdev [ i ] , d , & idx [ i * 2 ] , ! i ) ;
2005-04-16 15:20:36 -07:00
/*
* FIXME : Mom , mom , they stole me the helper function to undo
* do_ide_setup_pci_device ( ) on the first device !
*/
if ( ret < 0 )
goto out ;
}
2008-02-02 19:56:31 +01:00
ide_device_add ( idx , d ) ;
2005-04-16 15:20:36 -07:00
out :
return ret ;
}
EXPORT_SYMBOL_GPL ( ide_setup_pci_devices ) ;