2005-04-17 02:20:36 +04:00
/*
* linux / arch / arm / kernel / bios32 . c
*
* PCI bios - type initialisation for PCI machines
*
* Bits taken from various places .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/slab.h>
# include <linux/init.h>
# include <asm/io.h>
# include <asm/mach-types.h>
# include <asm/mach/pci.h>
static int debug_pci ;
static int use_firmware ;
/*
* We can ' t use pci_find_device ( ) here since we are
* called from interrupt context .
*/
static void pcibios_bus_report_status ( struct pci_bus * bus , u_int status_mask , int warn )
{
struct pci_dev * dev ;
list_for_each_entry ( dev , & bus - > devices , bus_list ) {
u16 status ;
/*
* ignore host bridge - we handle
* that separately
*/
if ( dev - > bus - > number = = 0 & & dev - > devfn = = 0 )
continue ;
pci_read_config_word ( dev , PCI_STATUS , & status ) ;
if ( status = = 0xffff )
continue ;
if ( ( status & status_mask ) = = 0 )
continue ;
/* clear the status errors */
pci_write_config_word ( dev , PCI_STATUS , status & status_mask ) ;
if ( warn )
printk ( " (%s: %04X) " , pci_name ( dev ) , status ) ;
}
list_for_each_entry ( dev , & bus - > devices , bus_list )
if ( dev - > subordinate )
pcibios_bus_report_status ( dev - > subordinate , status_mask , warn ) ;
}
void pcibios_report_status ( u_int status_mask , int warn )
{
struct list_head * l ;
list_for_each ( l , & pci_root_buses ) {
struct pci_bus * bus = pci_bus_b ( l ) ;
pcibios_bus_report_status ( bus , status_mask , warn ) ;
}
}
/*
* We don ' t use this to fix the device , but initialisation of it .
* It ' s not the correct use for this , but it works .
* Note that the arbiter / ISA bridge appears to be buggy , specifically in
* the following area :
* 1. park on CPU
* 2. ISA bridge ping - pong
* 3. ISA bridge master handling of target RETRY
*
* Bug 3 is responsible for the sound DMA grinding to a halt . We now
* live with bug 2.
*/
static void __devinit pci_fixup_83c553 ( struct pci_dev * dev )
{
/*
* Set memory region to start at address 0 , and enable IO
*/
pci_write_config_dword ( dev , PCI_BASE_ADDRESS_0 , PCI_BASE_ADDRESS_SPACE_MEMORY ) ;
pci_write_config_word ( dev , PCI_COMMAND , PCI_COMMAND_IO ) ;
dev - > resource [ 0 ] . end - = dev - > resource [ 0 ] . start ;
dev - > resource [ 0 ] . start = 0 ;
/*
* All memory requests from ISA to be channelled to PCI
*/
pci_write_config_byte ( dev , 0x48 , 0xff ) ;
/*
* Enable ping - pong on bus master to ISA bridge transactions .
* This improves the sound DMA substantially . The fixed
* priority arbiter also helps ( see below ) .
*/
pci_write_config_byte ( dev , 0x42 , 0x01 ) ;
/*
* Enable PCI retry
*/
pci_write_config_byte ( dev , 0x40 , 0x22 ) ;
/*
* We used to set the arbiter to " park on last master " ( bit
* 1 set ) , but unfortunately the CyberPro does not park the
* bus . We must therefore park on CPU . Unfortunately , this
* may trigger yet another bug in the 553.
*/
pci_write_config_byte ( dev , 0x83 , 0x02 ) ;
/*
* Make the ISA DMA request lowest priority , and disable
* rotating priorities completely .
*/
pci_write_config_byte ( dev , 0x80 , 0x11 ) ;
pci_write_config_byte ( dev , 0x81 , 0x00 ) ;
/*
* Route INTA input to IRQ 11 , and set IRQ11 to be level
* sensitive .
*/
pci_write_config_word ( dev , 0x44 , 0xb000 ) ;
outb ( 0x08 , 0x4d1 ) ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_WINBOND , PCI_DEVICE_ID_WINBOND_83C553 , pci_fixup_83c553 ) ;
static void __devinit pci_fixup_unassign ( struct pci_dev * dev )
{
dev - > resource [ 0 ] . end - = dev - > resource [ 0 ] . start ;
dev - > resource [ 0 ] . start = 0 ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_WINBOND2 , PCI_DEVICE_ID_WINBOND2_89C940F , pci_fixup_unassign ) ;
/*
* Prevent the PCI layer from seeing the resources allocated to this device
* if it is the host bridge by marking it as such . These resources are of
* no consequence to the PCI layer ( they are handled elsewhere ) .
*/
static void __devinit pci_fixup_dec21285 ( struct pci_dev * dev )
{
int i ;
if ( dev - > devfn = = 0 ) {
dev - > class & = 0xff ;
dev - > class | = PCI_CLASS_BRIDGE_HOST < < 8 ;
for ( i = 0 ; i < PCI_NUM_RESOURCES ; i + + ) {
dev - > resource [ i ] . start = 0 ;
dev - > resource [ i ] . end = 0 ;
dev - > resource [ i ] . flags = 0 ;
}
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_DEC , PCI_DEVICE_ID_DEC_21285 , pci_fixup_dec21285 ) ;
/*
* Same as above . The PrPMC800 carrier board for the PrPMC1100
* card maps the host - bridge @ 00 : 01 : 00 for some reason and it
* ends up getting scanned . Note that we only want to do this
* fixup when we find the IXP4xx on a PrPMC system , which is why
* we check the machine type . We could be running on a board
* with an IXP4xx target device and we don ' t want to kill the
* resources in that case .
*/
static void __devinit pci_fixup_prpmc1100 ( struct pci_dev * dev )
{
int i ;
if ( machine_is_prpmc1100 ( ) ) {
dev - > class & = 0xff ;
dev - > class | = PCI_CLASS_BRIDGE_HOST < < 8 ;
for ( i = 0 ; i < PCI_NUM_RESOURCES ; i + + ) {
dev - > resource [ i ] . start = 0 ;
dev - > resource [ i ] . end = 0 ;
dev - > resource [ i ] . flags = 0 ;
}
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_IXP4XX , pci_fixup_prpmc1100 ) ;
/*
* PCI IDE controllers use non - standard I / O port decoding , respect it .
*/
static void __devinit pci_fixup_ide_bases ( struct pci_dev * dev )
{
struct resource * r ;
int i ;
if ( ( dev - > class > > 8 ) ! = PCI_CLASS_STORAGE_IDE )
return ;
for ( i = 0 ; i < PCI_NUM_RESOURCES ; i + + ) {
r = dev - > resource + i ;
if ( ( r - > start & ~ 0x80 ) = = 0x374 ) {
r - > start | = 2 ;
r - > end = r - > start ;
}
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_ANY_ID , PCI_ANY_ID , pci_fixup_ide_bases ) ;
/*
* Put the DEC21142 to sleep
*/
static void __devinit pci_fixup_dec21142 ( struct pci_dev * dev )
{
pci_write_config_dword ( dev , 0x40 , 0x80000000 ) ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_DEC , PCI_DEVICE_ID_DEC_21142 , pci_fixup_dec21142 ) ;
/*
* The CY82C693 needs some rather major fixups to ensure that it does
* the right thing . Idea from the Alpha people , with a few additions .
*
* We ensure that the IDE base registers are set to 1f 0 / 3f 4 for the
* primary bus , and 170 / 374 for the secondary bus . Also , hide them
* from the PCI subsystem view as well so we won ' t try to perform
* our own auto - configuration on them .
*
* In addition , we ensure that the PCI IDE interrupts are routed to
* IRQ 14 and IRQ 15 respectively .
*
* The above gets us to a point where the IDE on this device is
* functional . However , The CY82C693U _does not work_ in bus
* master mode without locking the PCI bus solid .
*/
static void __devinit pci_fixup_cy82c693 ( struct pci_dev * dev )
{
if ( ( dev - > class > > 8 ) = = PCI_CLASS_STORAGE_IDE ) {
u32 base0 , base1 ;
if ( dev - > class & 0x80 ) { /* primary */
base0 = 0x1f0 ;
base1 = 0x3f4 ;
} else { /* secondary */
base0 = 0x170 ;
base1 = 0x374 ;
}
pci_write_config_dword ( dev , PCI_BASE_ADDRESS_0 ,
base0 | PCI_BASE_ADDRESS_SPACE_IO ) ;
pci_write_config_dword ( dev , PCI_BASE_ADDRESS_1 ,
base1 | PCI_BASE_ADDRESS_SPACE_IO ) ;
dev - > resource [ 0 ] . start = 0 ;
dev - > resource [ 0 ] . end = 0 ;
dev - > resource [ 0 ] . flags = 0 ;
dev - > resource [ 1 ] . start = 0 ;
dev - > resource [ 1 ] . end = 0 ;
dev - > resource [ 1 ] . flags = 0 ;
} else if ( PCI_FUNC ( dev - > devfn ) = = 0 ) {
/*
* Setup IDE IRQ routing .
*/
pci_write_config_byte ( dev , 0x4b , 14 ) ;
pci_write_config_byte ( dev , 0x4c , 15 ) ;
/*
* Disable FREQACK handshake , enable USB .
*/
pci_write_config_byte ( dev , 0x4d , 0x41 ) ;
/*
* Enable PCI retry , and PCI post - write buffer .
*/
pci_write_config_byte ( dev , 0x44 , 0x17 ) ;
/*
* Enable ISA master and DMA post write buffering .
*/
pci_write_config_byte ( dev , 0x45 , 0x03 ) ;
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_CONTAQ , PCI_DEVICE_ID_CONTAQ_82C693 , pci_fixup_cy82c693 ) ;
2007-09-23 18:59:52 +04:00
static void __init pci_fixup_it8152 ( struct pci_dev * dev )
{
int i ;
/* fixup for ITE 8152 devices */
/* FIXME: add defines for class 0x68000 and 0x80103 */
if ( ( dev - > class > > 8 ) = = PCI_CLASS_BRIDGE_HOST | |
dev - > class = = 0x68000 | |
dev - > class = = 0x80103 ) {
for ( i = 0 ; i < PCI_NUM_RESOURCES ; i + + ) {
dev - > resource [ i ] . start = 0 ;
dev - > resource [ i ] . end = 0 ;
dev - > resource [ i ] . flags = 0 ;
}
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_ITE , PCI_DEVICE_ID_ITE_8152 , pci_fixup_it8152 ) ;
2005-04-17 02:20:36 +04:00
void __devinit pcibios_update_irq ( struct pci_dev * dev , int irq )
{
if ( debug_pci )
printk ( " PCI: Assigning IRQ %02d to %s \n " , irq , pci_name ( dev ) ) ;
pci_write_config_byte ( dev , PCI_INTERRUPT_LINE , irq ) ;
}
/*
* If the bus contains any of these devices , then we must not turn on
* parity checking of any kind . Currently this is CyberPro 20 x0 only .
*/
static inline int pdev_bad_for_parity ( struct pci_dev * dev )
{
2007-09-23 18:59:52 +04:00
return ( ( dev - > vendor = = PCI_VENDOR_ID_INTERG & &
( dev - > device = = PCI_DEVICE_ID_INTERG_2000 | |
dev - > device = = PCI_DEVICE_ID_INTERG_2010 ) ) | |
( dev - > vendor = = PCI_VENDOR_ID_ITE & &
dev - > device = = PCI_DEVICE_ID_ITE_8152 ) ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Adjust the device resources from bus - centric to Linux - centric .
*/
static void __devinit
pdev_fixup_device_resources ( struct pci_sys_data * root , struct pci_dev * dev )
{
2006-06-13 04:06:02 +04:00
resource_size_t offset ;
2005-04-17 02:20:36 +04:00
int i ;
for ( i = 0 ; i < PCI_NUM_RESOURCES ; i + + ) {
if ( dev - > resource [ i ] . start = = 0 )
continue ;
if ( dev - > resource [ i ] . flags & IORESOURCE_MEM )
offset = root - > mem_offset ;
else
offset = root - > io_offset ;
dev - > resource [ i ] . start + = offset ;
dev - > resource [ i ] . end + = offset ;
}
}
static void __devinit
pbus_assign_bus_resources ( struct pci_bus * bus , struct pci_sys_data * root )
{
struct pci_dev * dev = bus - > self ;
int i ;
if ( ! dev ) {
/*
* Assign root bus resources .
*/
for ( i = 0 ; i < 3 ; i + + )
bus - > resource [ i ] = root - > resource [ i ] ;
}
}
/*
* pcibios_fixup_bus - Called after each bus is probed ,
* but before its children are examined .
*/
2007-09-30 20:36:22 +04:00
void pcibios_fixup_bus ( struct pci_bus * bus )
2005-04-17 02:20:36 +04:00
{
struct pci_sys_data * root = bus - > sysdata ;
struct pci_dev * dev ;
u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK ;
pbus_assign_bus_resources ( bus , root ) ;
/*
* Walk the devices on this bus , working out what we can
* and can ' t support .
*/
list_for_each_entry ( dev , & bus - > devices , bus_list ) {
u16 status ;
pdev_fixup_device_resources ( root , dev ) ;
pci_read_config_word ( dev , PCI_STATUS , & status ) ;
/*
* If any device on this bus does not support fast back
* to back transfers , then the bus as a whole is not able
* to support them . Having fast back to back transfers
* on saves us one PCI cycle per transaction .
*/
if ( ! ( status & PCI_STATUS_FAST_BACK ) )
features & = ~ PCI_COMMAND_FAST_BACK ;
if ( pdev_bad_for_parity ( dev ) )
features & = ~ ( PCI_COMMAND_SERR | PCI_COMMAND_PARITY ) ;
switch ( dev - > class > > 8 ) {
case PCI_CLASS_BRIDGE_PCI :
pci_read_config_word ( dev , PCI_BRIDGE_CONTROL , & status ) ;
status | = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_MASTER_ABORT ;
status & = ~ ( PCI_BRIDGE_CTL_BUS_RESET | PCI_BRIDGE_CTL_FAST_BACK ) ;
pci_write_config_word ( dev , PCI_BRIDGE_CONTROL , status ) ;
break ;
case PCI_CLASS_BRIDGE_CARDBUS :
pci_read_config_word ( dev , PCI_CB_BRIDGE_CONTROL , & status ) ;
status | = PCI_CB_BRIDGE_CTL_PARITY | PCI_CB_BRIDGE_CTL_MASTER_ABORT ;
pci_write_config_word ( dev , PCI_CB_BRIDGE_CONTROL , status ) ;
break ;
}
}
/*
* Now walk the devices again , this time setting them up .
*/
list_for_each_entry ( dev , & bus - > devices , bus_list ) {
u16 cmd ;
pci_read_config_word ( dev , PCI_COMMAND , & cmd ) ;
cmd | = features ;
pci_write_config_word ( dev , PCI_COMMAND , cmd ) ;
pci_write_config_byte ( dev , PCI_CACHE_LINE_SIZE ,
L1_CACHE_BYTES > > 2 ) ;
}
/*
* Propagate the flags to the PCI bridge .
*/
if ( bus - > self & & bus - > self - > hdr_type = = PCI_HEADER_TYPE_BRIDGE ) {
if ( features & PCI_COMMAND_FAST_BACK )
bus - > bridge_ctl | = PCI_BRIDGE_CTL_FAST_BACK ;
if ( features & PCI_COMMAND_PARITY )
bus - > bridge_ctl | = PCI_BRIDGE_CTL_PARITY ;
}
/*
* Report what we did for this bus
*/
printk ( KERN_INFO " PCI: bus%d: Fast back to back transfers %sabled \n " ,
bus - > number , ( features & PCI_COMMAND_FAST_BACK ) ? " en " : " dis " ) ;
}
/*
* Convert from Linux - centric to bus - centric addresses for bridge devices .
*/
2007-09-30 20:36:22 +04:00
void
2005-04-17 02:20:36 +04:00
pcibios_resource_to_bus ( struct pci_dev * dev , struct pci_bus_region * region ,
struct resource * res )
{
struct pci_sys_data * root = dev - > sysdata ;
unsigned long offset = 0 ;
if ( res - > flags & IORESOURCE_IO )
offset = root - > io_offset ;
if ( res - > flags & IORESOURCE_MEM )
offset = root - > mem_offset ;
region - > start = res - > start - offset ;
region - > end = res - > end - offset ;
}
2005-08-05 05:06:21 +04:00
void __devinit
pcibios_bus_to_resource ( struct pci_dev * dev , struct resource * res ,
struct pci_bus_region * region )
{
struct pci_sys_data * root = dev - > sysdata ;
unsigned long offset = 0 ;
if ( res - > flags & IORESOURCE_IO )
offset = root - > io_offset ;
if ( res - > flags & IORESOURCE_MEM )
offset = root - > mem_offset ;
res - > start = region - > start + offset ;
res - > end = region - > end + offset ;
}
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL ( pcibios_fixup_bus ) ;
EXPORT_SYMBOL ( pcibios_resource_to_bus ) ;
2005-08-05 05:06:21 +04:00
EXPORT_SYMBOL ( pcibios_bus_to_resource ) ;
2005-04-17 02:20:36 +04:00
# endif
/*
* This is the standard PCI - PCI bridge swizzling algorithm :
*
* Dev : 0 1 2 3
* A A B C D
* B B C D A
* C C D A B
* D D A B C
* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ irq pin on bridge
*/
u8 __devinit pci_std_swizzle ( struct pci_dev * dev , u8 * pinp )
{
int pin = * pinp - 1 ;
while ( dev - > bus - > self ) {
pin = ( pin + PCI_SLOT ( dev - > devfn ) ) & 3 ;
/*
* move up the chain of bridges ,
* swizzling as we go .
*/
dev = dev - > bus - > self ;
}
* pinp = pin + 1 ;
return PCI_SLOT ( dev - > devfn ) ;
}
/*
* Swizzle the device pin each time we cross a bridge .
* This might update pin and returns the slot number .
*/
static u8 __devinit pcibios_swizzle ( struct pci_dev * dev , u8 * pin )
{
struct pci_sys_data * sys = dev - > sysdata ;
int slot = 0 , oldpin = * pin ;
if ( sys - > swizzle )
slot = sys - > swizzle ( dev , pin ) ;
if ( debug_pci )
printk ( " PCI: %s swizzling pin %d => pin %d slot %d \n " ,
pci_name ( dev ) , oldpin , * pin , slot ) ;
return slot ;
}
/*
* Map a slot / pin to an IRQ .
*/
static int pcibios_map_irq ( struct pci_dev * dev , u8 slot , u8 pin )
{
struct pci_sys_data * sys = dev - > sysdata ;
int irq = - 1 ;
if ( sys - > map_irq )
irq = sys - > map_irq ( dev , slot , pin ) ;
if ( debug_pci )
printk ( " PCI: %s mapping slot %d pin %d => irq %d \n " ,
pci_name ( dev ) , slot , pin , irq ) ;
return irq ;
}
static void __init pcibios_init_hw ( struct hw_pci * hw )
{
struct pci_sys_data * sys = NULL ;
int ret ;
int nr , busnr ;
for ( nr = busnr = 0 ; nr < hw - > nr_controllers ; nr + + ) {
2006-03-20 22:46:41 +03:00
sys = kzalloc ( sizeof ( struct pci_sys_data ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! sys )
panic ( " PCI: unable to allocate sys data! " ) ;
sys - > hw = hw ;
sys - > busnr = busnr ;
sys - > swizzle = hw - > swizzle ;
sys - > map_irq = hw - > map_irq ;
sys - > resource [ 0 ] = & ioport_resource ;
sys - > resource [ 1 ] = & iomem_resource ;
ret = hw - > setup ( nr , sys ) ;
if ( ret > 0 ) {
sys - > bus = hw - > scan ( nr , sys ) ;
if ( ! sys - > bus )
panic ( " PCI: unable to scan bus! " ) ;
busnr = sys - > bus - > subordinate + 1 ;
list_add ( & sys - > node , & hw - > buses ) ;
} else {
kfree ( sys ) ;
if ( ret < 0 )
break ;
}
}
}
void __init pci_common_init ( struct hw_pci * hw )
{
struct pci_sys_data * sys ;
INIT_LIST_HEAD ( & hw - > buses ) ;
if ( hw - > preinit )
hw - > preinit ( ) ;
pcibios_init_hw ( hw ) ;
if ( hw - > postinit )
hw - > postinit ( ) ;
pci_fixup_irqs ( pcibios_swizzle , pcibios_map_irq ) ;
list_for_each_entry ( sys , & hw - > buses , node ) {
struct pci_bus * bus = sys - > bus ;
if ( ! use_firmware ) {
/*
* Size the bridge windows .
*/
pci_bus_size_bridges ( bus ) ;
/*
* Assign resources .
*/
pci_bus_assign_resources ( bus ) ;
}
/*
* Tell drivers about devices found .
*/
pci_bus_add_devices ( bus ) ;
}
}
char * __init pcibios_setup ( char * str )
{
if ( ! strcmp ( str , " debug " ) ) {
debug_pci = 1 ;
return NULL ;
} else if ( ! strcmp ( str , " firmware " ) ) {
use_firmware = 1 ;
return NULL ;
}
return str ;
}
/*
* From arch / i386 / kernel / pci - i386 . c :
*
* We need to avoid collisions with ` mirrored ' VGA ports
* and other strange ISA hardware , so we always want the
* addresses to be allocated in the 0x000 - 0x0ff region
* modulo 0x400 .
*
* Why ? Because some silly external IO cards only decode
* the low 10 bits of the IO address . The 0x00 - 0xff region
* is reserved for motherboard devices that decode all 16
* bits , so it ' s ok to allocate at , say , 0x2800 - 0x28ff ,
* but we want to try to avoid allocating at 0x2900 - 0x2bff
* which might be mirrored at 0x0100 - 0x03ff . .
*/
void pcibios_align_resource ( void * data , struct resource * res ,
2006-06-13 04:06:02 +04:00
resource_size_t size , resource_size_t align )
2005-04-17 02:20:36 +04:00
{
2006-06-13 04:06:02 +04:00
resource_size_t start = res - > start ;
2005-04-17 02:20:36 +04:00
if ( res - > flags & IORESOURCE_IO & & start & 0x300 )
start = ( start + 0x3ff ) & ~ 0x3ff ;
res - > start = ( start + align - 1 ) & ~ ( align - 1 ) ;
}
/**
* pcibios_enable_device - Enable I / O and memory .
* @ dev : PCI device to be enabled
*/
int pcibios_enable_device ( struct pci_dev * dev , int mask )
{
u16 cmd , old_cmd ;
int idx ;
struct resource * r ;
pci_read_config_word ( dev , PCI_COMMAND , & cmd ) ;
old_cmd = cmd ;
for ( idx = 0 ; idx < 6 ; idx + + ) {
/* Only set up the requested stuff */
if ( ! ( mask & ( 1 < < idx ) ) )
continue ;
r = dev - > resource + idx ;
if ( ! r - > start & & r - > end ) {
printk ( KERN_ERR " PCI: Device %s not available because "
" of resource collisions \n " , pci_name ( dev ) ) ;
return - EINVAL ;
}
if ( r - > flags & IORESOURCE_IO )
cmd | = PCI_COMMAND_IO ;
if ( r - > flags & IORESOURCE_MEM )
cmd | = PCI_COMMAND_MEMORY ;
}
/*
* Bridges ( eg , cardbus bridges ) need to be fully enabled
*/
if ( ( dev - > class > > 16 ) = = PCI_BASE_CLASS_BRIDGE )
cmd | = PCI_COMMAND_IO | PCI_COMMAND_MEMORY ;
if ( cmd ! = old_cmd ) {
printk ( " PCI: enabling device %s (%04x -> %04x) \n " ,
pci_name ( dev ) , old_cmd , cmd ) ;
pci_write_config_word ( dev , PCI_COMMAND , cmd ) ;
}
return 0 ;
}
int pci_mmap_page_range ( struct pci_dev * dev , struct vm_area_struct * vma ,
enum pci_mmap_state mmap_state , int write_combine )
{
struct pci_sys_data * root = dev - > sysdata ;
unsigned long phys ;
if ( mmap_state = = pci_mmap_io ) {
return - EINVAL ;
} else {
phys = vma - > vm_pgoff + ( root - > mem_offset > > PAGE_SHIFT ) ;
}
/*
* Mark this as IO
*/
vma - > vm_page_prot = pgprot_noncached ( vma - > vm_page_prot ) ;
if ( remap_pfn_range ( vma , vma - > vm_start , phys ,
vma - > vm_end - vma - > vm_start ,
vma - > vm_page_prot ) )
return - EAGAIN ;
return 0 ;
}