Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
7efe5d7c
Commit
7efe5d7c
authored
Oct 28, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
parents
dbe0580d
f8977d0a
Changes
37
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
739 additions
and
6349 deletions
+739
-6349
Documentation/DocBook/kernel-api.tmpl
Documentation/DocBook/kernel-api.tmpl
+3
-1
arch/i386/pci/fixup.c
arch/i386/pci/fixup.c
+59
-0
drivers/pci/access.c
drivers/pci/access.c
+89
-0
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_glue.c
+8
-0
drivers/pci/hotplug/cpcihp_zt5550.c
drivers/pci/hotplug/cpcihp_zt5550.c
+21
-4
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_core.c
+19
-5
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp.h
+2
-1
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_core.c
+4
-1
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_pci.c
+3
-8
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp.h
+18
-104
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_core.c
+21
-90
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/hotplug/shpchp_ctrl.c
+84
-1950
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/hotplug/shpchp_hpc.c
+37
-138
drivers/pci/hotplug/shpchp_pci.c
drivers/pci/hotplug/shpchp_pci.c
+114
-747
drivers/pci/hotplug/shpchp_sysfs.c
drivers/pci/hotplug/shpchp_sysfs.c
+36
-83
drivers/pci/hotplug/shpchprm.h
drivers/pci/hotplug/shpchprm.h
+0
-55
drivers/pci/hotplug/shpchprm_acpi.c
drivers/pci/hotplug/shpchprm_acpi.c
+61
-1588
drivers/pci/hotplug/shpchprm_legacy.c
drivers/pci/hotplug/shpchprm_legacy.c
+5
-390
drivers/pci/hotplug/shpchprm_legacy.h
drivers/pci/hotplug/shpchprm_legacy.h
+0
-113
drivers/pci/hotplug/shpchprm_nonacpi.c
drivers/pci/hotplug/shpchprm_nonacpi.c
+5
-384
drivers/pci/hotplug/shpchprm_nonacpi.h
drivers/pci/hotplug/shpchprm_nonacpi.h
+0
-56
drivers/pci/msi.c
drivers/pci/msi.c
+2
-0
drivers/pci/pci-driver.c
drivers/pci/pci-driver.c
+13
-4
drivers/pci/pci-sysfs.c
drivers/pci/pci-sysfs.c
+10
-10
drivers/pci/pci.c
drivers/pci/pci.c
+11
-10
drivers/pci/pci.h
drivers/pci/pci.h
+7
-0
drivers/pci/probe.c
drivers/pci/probe.c
+1
-0
drivers/pci/proc.c
drivers/pci/proc.c
+14
-14
drivers/pci/quirks.c
drivers/pci/quirks.c
+37
-0
drivers/pci/syscall.c
drivers/pci/syscall.c
+7
-7
drivers/scsi/ipr.c
drivers/scsi/ipr.c
+2
-0
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mbox.c
+4
-6
drivers/video/cirrusfb.c
drivers/video/cirrusfb.c
+12
-12
include/linux/pci.h
include/linux/pci.h
+7
-0
include/linux/pci_ids.h
include/linux/pci_ids.h
+7
-556
sound/oss/ymfpci.c
sound/oss/ymfpci.c
+9
-8
sound/pci/bt87x.c
sound/pci/bt87x.c
+7
-4
No files found.
Documentation/DocBook/kernel-api.tmpl
View file @
7efe5d7c
...
...
@@ -286,7 +286,9 @@ X!Edrivers/pci/search.c
-->
!Edrivers/pci/msi.c
!Edrivers/pci/bus.c
!Edrivers/pci/hotplug.c
<!-- FIXME: Removed for now since no structured comments in source
X!Edrivers/pci/hotplug.c
-->
!Edrivers/pci/probe.c
!Edrivers/pci/rom.c
</sect1>
...
...
arch/i386/pci/fixup.c
View file @
7efe5d7c
...
...
@@ -2,6 +2,8 @@
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
*/
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
...
...
@@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_HEADER
(
PCI_ANY_ID
,
PCI_ANY_ID
,
pci_fixup_video
);
/*
* Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
*
* We pretend to bring them out of full D3 state, and restore the proper
* IRQ, PCI cache line size, and BARs, otherwise the device won't function
* properly. In some cases, the device will generate an interrupt on
* the wrong IRQ line, causing any devices sharing the the line it's
* *supposed* to use to be disabled by the kernel's IRQ debug code.
*/
static
u16
toshiba_line_size
;
static
struct
dmi_system_id
__devinit
toshiba_ohci1394_dmi_table
[]
=
{
{
.
ident
=
"Toshiba PS5 based laptop"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"TOSHIBA"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"PS5"
),
},
},
{
.
ident
=
"Toshiba PSM4 based laptop"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"TOSHIBA"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"PSM4"
),
},
},
{
}
};
static
void
__devinit
pci_pre_fixup_toshiba_ohci1394
(
struct
pci_dev
*
dev
)
{
if
(
!
dmi_check_system
(
toshiba_ohci1394_dmi_table
))
return
;
/* only applies to certain Toshibas (so far) */
dev
->
current_state
=
PCI_D3cold
;
pci_read_config_word
(
dev
,
PCI_CACHE_LINE_SIZE
,
&
toshiba_line_size
);
}
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_TI
,
0x8032
,
pci_pre_fixup_toshiba_ohci1394
);
static
void
__devinit
pci_post_fixup_toshiba_ohci1394
(
struct
pci_dev
*
dev
)
{
if
(
!
dmi_check_system
(
toshiba_ohci1394_dmi_table
))
return
;
/* only applies to certain Toshibas (so far) */
/* Restore config space on Toshiba laptops */
mdelay
(
10
);
pci_write_config_word
(
dev
,
PCI_CACHE_LINE_SIZE
,
toshiba_line_size
);
pci_write_config_word
(
dev
,
PCI_INTERRUPT_LINE
,
dev
->
irq
);
pci_write_config_dword
(
dev
,
PCI_BASE_ADDRESS_0
,
pci_resource_start
(
dev
,
0
));
pci_write_config_dword
(
dev
,
PCI_BASE_ADDRESS_1
,
pci_resource_start
(
dev
,
1
));
}
DECLARE_PCI_FIXUP_ENABLE
(
PCI_VENDOR_ID_TI
,
0x8032
,
pci_post_fixup_toshiba_ohci1394
);
drivers/pci/access.c
View file @
7efe5d7c
...
...
@@ -60,3 +60,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword);
EXPORT_SYMBOL
(
pci_bus_write_config_byte
);
EXPORT_SYMBOL
(
pci_bus_write_config_word
);
EXPORT_SYMBOL
(
pci_bus_write_config_dword
);
static
u32
pci_user_cached_config
(
struct
pci_dev
*
dev
,
int
pos
)
{
u32
data
;
data
=
dev
->
saved_config_space
[
pos
/
sizeof
(
dev
->
saved_config_space
[
0
])];
data
>>=
(
pos
%
sizeof
(
dev
->
saved_config_space
[
0
]))
*
8
;
return
data
;
}
#define PCI_USER_READ_CONFIG(size,type) \
int pci_user_read_config_##size \
(struct pci_dev *dev, int pos, type *val) \
{ \
unsigned long flags; \
int ret = 0; \
u32 data = -1; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
spin_lock_irqsave(&pci_lock, flags); \
if (likely(!dev->block_ucfg_access)) \
ret = dev->bus->ops->read(dev->bus, dev->devfn, \
pos, sizeof(type), &data); \
else if (pos < sizeof(dev->saved_config_space)) \
data = pci_user_cached_config(dev, pos); \
spin_unlock_irqrestore(&pci_lock, flags); \
*val = (type)data; \
return ret; \
}
#define PCI_USER_WRITE_CONFIG(size,type) \
int pci_user_write_config_##size \
(struct pci_dev *dev, int pos, type val) \
{ \
unsigned long flags; \
int ret = -EIO; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
spin_lock_irqsave(&pci_lock, flags); \
if (likely(!dev->block_ucfg_access)) \
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
pos, sizeof(type), val); \
spin_unlock_irqrestore(&pci_lock, flags); \
return ret; \
}
PCI_USER_READ_CONFIG
(
byte
,
u8
)
PCI_USER_READ_CONFIG
(
word
,
u16
)
PCI_USER_READ_CONFIG
(
dword
,
u32
)
PCI_USER_WRITE_CONFIG
(
byte
,
u8
)
PCI_USER_WRITE_CONFIG
(
word
,
u16
)
PCI_USER_WRITE_CONFIG
(
dword
,
u32
)
/**
* pci_block_user_cfg_access - Block userspace PCI config reads/writes
* @dev: pci device struct
*
* This function blocks any userspace PCI config accesses from occurring.
* When blocked, any writes will be bit bucketed and reads will return the
* data saved using pci_save_state for the first 64 bytes of config
* space and return 0xff for all other config reads.
**/
void
pci_block_user_cfg_access
(
struct
pci_dev
*
dev
)
{
unsigned
long
flags
;
pci_save_state
(
dev
);
/* spinlock to synchronize with anyone reading config space now */
spin_lock_irqsave
(
&
pci_lock
,
flags
);
dev
->
block_ucfg_access
=
1
;
spin_unlock_irqrestore
(
&
pci_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
pci_block_user_cfg_access
);
/**
* pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
* @dev: pci device struct
*
* This function allows userspace PCI config accesses to resume.
**/
void
pci_unblock_user_cfg_access
(
struct
pci_dev
*
dev
)
{
unsigned
long
flags
;
/* spinlock to synchronize with anyone reading saved config space */
spin_lock_irqsave
(
&
pci_lock
,
flags
);
dev
->
block_ucfg_access
=
0
;
spin_unlock_irqrestore
(
&
pci_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
pci_unblock_user_cfg_access
);
drivers/pci/hotplug/acpiphp_glue.c
View file @
7efe5d7c
...
...
@@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list);
static
void
handle_hotplug_event_bridge
(
acpi_handle
,
u32
,
void
*
);
static
void
handle_hotplug_event_func
(
acpi_handle
,
u32
,
void
*
);
static
void
acpiphp_sanitize_bus
(
struct
pci_bus
*
bus
);
static
void
acpiphp_set_hpp_values
(
acpi_handle
handle
,
struct
pci_bus
*
bus
);
/*
* initialization & terminatation routines
...
...
@@ -796,8 +799,13 @@ static int enable_device(struct acpiphp_slot *slot)
}
}
pci_bus_size_bridges
(
bus
);
pci_bus_assign_resources
(
bus
);
acpiphp_sanitize_bus
(
bus
);
pci_enable_bridges
(
bus
);
pci_bus_add_devices
(
bus
);
acpiphp_set_hpp_values
(
DEVICE_ACPI_HANDLE
(
&
bus
->
self
->
dev
),
bus
);
acpiphp_configure_ioapics
(
DEVICE_ACPI_HANDLE
(
&
bus
->
self
->
dev
));
/* associate pci_dev to our representation */
list_for_each
(
l
,
&
slot
->
funcs
)
{
...
...
drivers/pci/hotplug/cpcihp_zt5550.c
View file @
7efe5d7c
...
...
@@ -78,11 +78,20 @@ static void __iomem *csr_int_mask;
static
int
zt5550_hc_config
(
struct
pci_dev
*
pdev
)
{
int
ret
;
/* Since we know that no boards exist with two HC chips, treat it as an error */
if
(
hc_dev
)
{
err
(
"too many host controller devices?"
);
return
-
EBUSY
;
}
ret
=
pci_enable_device
(
pdev
);
if
(
ret
)
{
err
(
"cannot enable %s
\n
"
,
pci_name
(
pdev
));
return
ret
;
}
hc_dev
=
pdev
;
dbg
(
"hc_dev = %p"
,
hc_dev
);
dbg
(
"pci resource start %lx"
,
pci_resource_start
(
hc_dev
,
1
));
...
...
@@ -91,7 +100,8 @@ static int zt5550_hc_config(struct pci_dev *pdev)
if
(
!
request_mem_region
(
pci_resource_start
(
hc_dev
,
1
),
pci_resource_len
(
hc_dev
,
1
),
MY_NAME
))
{
err
(
"cannot reserve MMIO region"
);
return
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
exit_disable_device
;
}
hc_registers
=
...
...
@@ -99,9 +109,8 @@ static int zt5550_hc_config(struct pci_dev *pdev)
if
(
!
hc_registers
)
{
err
(
"cannot remap MMIO region %lx @ %lx"
,
pci_resource_len
(
hc_dev
,
1
),
pci_resource_start
(
hc_dev
,
1
));
release_mem_region
(
pci_resource_start
(
hc_dev
,
1
),
pci_resource_len
(
hc_dev
,
1
));
return
-
ENODEV
;
ret
=
-
ENODEV
;
goto
exit_release_region
;
}
csr_hc_index
=
hc_registers
+
CSR_HCINDEX
;
...
...
@@ -124,6 +133,13 @@ static int zt5550_hc_config(struct pci_dev *pdev)
writeb
((
u8
)
ALL_DIRECT_INTS_MASK
,
csr_int_mask
);
dbg
(
"disabled timer0, timer1 and ENUM interrupts"
);
return
0
;
exit_release_region:
release_mem_region
(
pci_resource_start
(
hc_dev
,
1
),
pci_resource_len
(
hc_dev
,
1
));
exit_disable_device:
pci_disable_device
(
hc_dev
);
return
ret
;
}
static
int
zt5550_hc_cleanup
(
void
)
...
...
@@ -134,6 +150,7 @@ static int zt5550_hc_cleanup(void)
iounmap
(
hc_registers
);
release_mem_region
(
pci_resource_start
(
hc_dev
,
1
),
pci_resource_len
(
hc_dev
,
1
));
pci_disable_device
(
hc_dev
);
return
0
;
}
...
...
drivers/pci/hotplug/cpqphp_core.c
View file @
7efe5d7c
...
...
@@ -794,12 +794,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u32
rc
;
struct
controller
*
ctrl
;
struct
pci_func
*
func
;
int
err
;
err
=
pci_enable_device
(
pdev
);
if
(
err
)
{
printk
(
KERN_ERR
MY_NAME
": cannot enable PCI device %s (%d)
\n
"
,
pci_name
(
pdev
),
err
);
return
err
;
}
// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
rc
=
pci_read_config_word
(
pdev
,
PCI_VENDOR_ID
,
&
vendor_id
);
if
(
rc
||
((
vendor_id
!=
PCI_VENDOR_ID_COMPAQ
)
&&
(
vendor_id
!=
PCI_VENDOR_ID_INTEL
)))
{
err
(
msg_HPC_non_compaq_or_intel
);
return
-
ENODEV
;
rc
=
-
ENODEV
;
goto
err_disable_device
;
}
dbg
(
"Vendor ID: %x
\n
"
,
vendor_id
);
...
...
@@ -807,7 +816,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dbg
(
"revision: %d
\n
"
,
rev
);
if
(
rc
||
((
vendor_id
==
PCI_VENDOR_ID_COMPAQ
)
&&
(
!
rev
)))
{
err
(
msg_HPC_rev_error
);
return
-
ENODEV
;
rc
=
-
ENODEV
;
goto
err_disable_device
;
}
/* Check for the proper subsytem ID's
...
...
@@ -820,18 +830,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc
=
pci_read_config_word
(
pdev
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
subsystem_vid
);
if
(
rc
)
{
err
(
"%s : pci_read_config_word failed
\n
"
,
__FUNCTION__
);
return
rc
;
goto
err_disable_device
;
}
dbg
(
"Subsystem Vendor ID: %x
\n
"
,
subsystem_vid
);
if
((
subsystem_vid
!=
PCI_VENDOR_ID_COMPAQ
)
&&
(
subsystem_vid
!=
PCI_VENDOR_ID_INTEL
))
{
err
(
msg_HPC_non_compaq_or_intel
);
return
-
ENODEV
;
rc
=
-
ENODEV
;
goto
err_disable_device
;
}
ctrl
=
(
struct
controller
*
)
kmalloc
(
sizeof
(
struct
controller
),
GFP_KERNEL
);
if
(
!
ctrl
)
{
err
(
"%s : out of memory
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
rc
=
-
ENOMEM
;
goto
err_disable_device
;
}
memset
(
ctrl
,
0
,
sizeof
(
struct
controller
));
...
...
@@ -1264,6 +1276,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
kfree
(
ctrl
->
pci_bus
);
err_free_ctrl:
kfree
(
ctrl
);
err_disable_device:
pci_disable_device
(
pdev
);
return
rc
;
}
...
...
drivers/pci/hotplug/rpaphp.h
View file @
7efe5d7c
...
...
@@ -92,9 +92,10 @@ extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
extern
int
rpaphp_claim_resource
(
struct
pci_dev
*
dev
,
int
resource
);
extern
int
rpaphp_enable_pci_slot
(
struct
slot
*
slot
);
extern
int
register_pci_slot
(
struct
slot
*
slot
);
extern
int
rpaphp_unconfig_pci_adapter
(
struct
slot
*
slot
);
extern
int
rpaphp_get_pci_adapter_status
(
struct
slot
*
slot
,
int
is_init
,
u8
*
value
);
extern
int
rpaphp_config_pci_adapter
(
struct
pci_bus
*
bus
);
extern
int
rpaphp_unconfig_pci_adapter
(
struct
pci_bus
*
bus
);
/* rpaphp_core.c */
extern
int
rpaphp_add_slot
(
struct
device_node
*
dn
);
...
...
drivers/pci/hotplug/rpaphp_core.c
View file @
7efe5d7c
...
...
@@ -426,8 +426,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
dbg
(
"DISABLING SLOT %s
\n
"
,
slot
->
name
);
down
(
&
rpaphp_sem
);
retval
=
rpaphp_unconfig_pci_adapter
(
slot
);
retval
=
rpaphp_unconfig_pci_adapter
(
slot
->
bus
);
up
(
&
rpaphp_sem
);
slot
->
state
=
NOT_CONFIGURED
;
info
(
"%s: devices in slot[%s] unconfigured.
\n
"
,
__FUNCTION__
,
slot
->
name
);
exit:
dbg
(
"%s - Exit: rc[%d]
\n
"
,
__FUNCTION__
,
retval
);
return
retval
;
...
...
drivers/pci/hotplug/rpaphp_pci.c
View file @
7efe5d7c
...
...
@@ -319,20 +319,15 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
return
;
}
int
rpaphp_unconfig_pci_adapter
(
struct
slot
*
slot
)
int
rpaphp_unconfig_pci_adapter
(
struct
pci_bus
*
bus
)
{
struct
pci_dev
*
dev
,
*
tmp
;
int
retval
=
0
;
list_for_each_entry_safe
(
dev
,
tmp
,
slot
->
pci_dev
s
,
bus_list
)
{
list_for_each_entry_safe
(
dev
,
tmp
,
&
bus
->
device
s
,
bus_list
)
{
rpaphp_eeh_remove_bus_device
(
dev
);
pci_remove_bus_device
(
dev
);
}
slot
->
state
=
NOT_CONFIGURED
;
info
(
"%s: devices in slot[%s] unconfigured.
\n
"
,
__FUNCTION__
,
slot
->
name
);
return
retval
;
return
0
;
}
static
int
setup_pci_hotplug_slot_info
(
struct
slot
*
slot
)
...
...
drivers/pci/hotplug/shpchp.h
View file @
7efe5d7c
...
...
@@ -32,8 +32,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include "pci_hotplug.h"
#if !defined(MODULE)
...
...
@@ -52,42 +50,18 @@ extern int shpchp_debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
struct
pci_func
{
struct
pci_func
*
next
;
u8
bus
;
u8
device
;
u8
function
;
u8
is_a_board
;
u16
status
;
u8
configured
;
u8
switch_save
;
u8
presence_save
;
u8
pwr_save
;
u32
base_length
[
0x06
];
u8
base_type
[
0x06
];
u16
reserved2
;
u32
config_space
[
0x20
];
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
struct
pci_dev
*
pci_dev
;
};
#define SLOT_MAGIC 0x67267321
struct
slot
{
u32
magic
;
struct
slot
*
next
;
u8
bus
;
u8
device
;
u16
status
;
u32
number
;
u8
is_a_board
;
u8
configured
;
u8
state
;
u8
switch_save
;
u8
presence_save
;
u32
capabilities
;
u16
reserved2
;
u8
pwr_save
;
struct
timer_list
task_event
;
u8
hp_slot
;
struct
controller
*
ctrl
;
...
...
@@ -96,12 +70,6 @@ struct slot {
struct
list_head
slot_list
;
};
struct
pci_resource
{
struct
pci_resource
*
next
;
u32
base
;
u32
length
;
};
struct
event_info
{
u32
event_type
;
u8
hp_slot
;
...
...
@@ -110,13 +78,9 @@ struct event_info {
struct
controller
{
struct
controller
*
next
;
struct
semaphore
crit_sect
;
/* critical section semaphore */
void
*
hpc_ctlr_handle
;
/* HPC controller handle */
struct
php_ctlr_state_s
*
hpc_ctlr_handle
;
/* HPC controller handle */
int
num_slots
;
/* Number of slots on ctlr */
int
slot_num_inc
;
/* 1 or -1 */
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
struct
pci_dev
*
pci_dev
;
struct
pci_bus
*
pci_bus
;
struct
event_info
event_queue
[
10
];
...
...
@@ -124,33 +88,21 @@ struct controller {
struct
hpc_ops
*
hpc_ops
;
wait_queue_head_t
queue
;
/* sleep & wake process */
u8
next_event
;
u8
seg
;
u8
bus
;
u8
device
;
u8
function
;
u8
rev
;
u8
slot_device_offset
;
u8
add_support
;
enum
pci_bus_speed
speed
;
u32
first_slot
;
/* First physical slot number */
u8
slot_bus
;
/* Bus where the slots handled by this controller sit */
u8
push_flag
;
u16
ctlrcap
;
u16
vendor_id
;
};
struct
irq_mapping
{
u8
barber_pole
;
u8
valid_INT
;
u8
interrupt
[
4
];
};
struct
resource_lists
{
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
struct
irq_mapping
*
irqs
;
struct
hotplug_params
{
u8
cache_line_size
;
u8
latency_timer
;
u8
enable_serr
;
u8
enable_perr
;
};
/* Define AMD SHPC ID */
...
...
@@ -194,24 +146,16 @@ struct resource_lists {
* error Messages
*/
#define msg_initialization_err "Initialization failure, error=%d\n"
#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
#define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n"
#define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n"
#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
/* sysfs functions for the hotplug controller info */
extern
void
shpchp_create_ctrl_files
(
struct
controller
*
ctrl
);
/* controller functions */
extern
int
shpchprm_find_available_resources
(
struct
controller
*
ctrl
);
extern
int
shpchp_event_start_thread
(
void
);
extern
void
shpchp_event_stop_thread
(
void
);
extern
struct
pci_func
*
shpchp_slot_create
(
unsigned
char
busnumber
);
extern
struct
pci_func
*
shpchp_slot_find
(
unsigned
char
bus
,
unsigned
char
device
,
unsigned
char
index
);
extern
int
shpchp_enable_slot
(
struct
slot
*
slot
);
extern
int
shpchp_disable_slot
(
struct
slot
*
slot
);
...
...
@@ -220,29 +164,20 @@ extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
extern
u8
shpchp_handle_presence_change
(
u8
hp_slot
,
void
*
inst_id
);
extern
u8
shpchp_handle_power_fault
(
u8
hp_slot
,
void
*
inst_id
);
/* resource functions */
extern
int
shpchp_resource_sort_and_combine
(
struct
pci_resource
**
head
);
/* pci functions */
extern
int
shpchp_set_irq
(
u8
bus_num
,
u8
dev_num
,
u8
int_pin
,
u8
irq_num
);
/*extern int shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
extern
int
shpchp_save_config
(
struct
controller
*
ctrl
,
int
busnumber
,
int
num_ctlr_slots
,
int
first_device_num
);
extern
int
shpchp_save_used_resources
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
int
flag
);
extern
int
shpchp_save_slot_config
(
struct
controller
*
ctrl
,
struct
pci_func
*
new_slot
);
extern
void
shpchp_destroy_board_resources
(
struct
pci_func
*
func
);
extern
int
shpchp_return_board_resources
(
struct
pci_func
*
func
,
struct
resource_lists
*
resources
);
extern
void
shpchp_destroy_resource_list
(
struct
resource_lists
*
resources
);
extern
int
shpchp_configure_device
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
);
extern
int
shpchp_unconfigure_device
(
struct
pci_func
*
func
);
extern
int
shpchp_configure_device
(
struct
slot
*
p_slot
);
extern
int
shpchp_unconfigure_device
(
struct
slot
*
p_slot
);
extern
void
get_hp_hw_control_from_firmware
(
struct
pci_dev
*
dev
);
extern
void
get_hp_params_from_firmware
(
struct
pci_dev
*
dev
,
struct
hotplug_params
*
hpp
);
extern
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
);
extern
void
shpchp_remove_ctrl_files
(
struct
controller
*
ctrl
);
/* Global variables */
extern
struct
controller
*
shpchp_ctrl_list
;
extern
struct
pci_func
*
shpchp_slot_list
[
256
];
/* These are added to support AMD shpc */
extern
u8
shpchp_nic_irq
;
extern
u8
shpchp_disk_irq
;
struct
ctrl_reg
{
volatile
u32
base_offset
;
...
...
@@ -298,7 +233,7 @@ enum ctrl_offsets {
SLOT11
=
offsetof
(
struct
ctrl_reg
,
slot11
),
SLOT12
=
offsetof
(
struct
ctrl_reg
,
slot12
),
};
typedef
u8
(
*
php_intr_callback_t
)
(
u
nsigned
int
change_id
,
void
*
instance_id
);
typedef
u8
(
*
php_intr_callback_t
)
(
u
8
hp_slot
,
void
*
instance_id
);
struct
php_ctlr_state_s
{
struct
php_ctlr_state_s
*
pnext
;
struct
pci_dev
*
pci_dev
;
...
...
@@ -359,12 +294,9 @@ static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
p_slot
=
ctrl
->
slot
;
dbg
(
"p_slot = %p
\n
"
,
p_slot
);
while
(
p_slot
&&
(
p_slot
->
device
!=
device
))
{
tmp_slot
=
p_slot
;
p_slot
=
p_slot
->
next
;
dbg
(
"In while loop, p_slot = %p
\n
"
,
p_slot
);
}
if
(
p_slot
==
NULL
)
{
err
(
"ERROR: shpchp_find_slot device=0x%x
\n
"
,
device
);
...
...
@@ -379,8 +311,6 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
DECLARE_WAITQUEUE
(
wait
,
current
);
int
retval
=
0
;
dbg
(
"%s : start
\n
"
,
__FUNCTION__
);
add_wait_queue
(
&
ctrl
->
queue
,
&
wait
);
if
(
!
shpchp_poll_mode
)
{
...
...
@@ -394,19 +324,9 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
if
(
signal_pending
(
current
))
retval
=
-
EINTR
;
dbg
(
"%s : end
\n
"
,
__FUNCTION__
);
return
retval
;
}
/* Puts node back in the resource list pointed to by head */
static
inline
void
return_resource
(
struct
pci_resource
**
head
,
struct
pci_resource
*
node
)
{
if
(
!
node
||
!
head
)
return
;
node
->
next
=
*
head
;
*
head
=
node
;
}
#define SLOT_NAME_SIZE 10
static
inline
void
make_slot_name
(
char
*
buffer
,
int
buffer_size
,
struct
slot
*
slot
)
...
...
@@ -420,11 +340,7 @@ enum php_ctlr_type {
ACPI
};
int
shpc_init
(
struct
controller
*
ctrl
,
struct
pci_dev
*
pdev
,
php_intr_callback_t
attention_button_callback
,
php_intr_callback_t
switch_change_callback
,
php_intr_callback_t
presence_change_callback
,
php_intr_callback_t
power_fault_callback
);
int
shpc_init
(
struct
controller
*
ctrl
,
struct
pci_dev
*
pdev
);
int
shpc_get_ctlr_slot_config
(
struct
controller
*
ctrl
,
int
*
num_ctlr_slots
,
...
...
@@ -437,8 +353,6 @@ struct hpc_ops {
int
(
*
power_on_slot
)
(
struct
slot
*
slot
);
int
(
*
slot_enable
)
(
struct
slot
*
slot
);
int
(
*
slot_disable
)
(
struct
slot
*
slot
);
int
(
*
enable_all_slots
)
(
struct
slot
*
slot
);
int
(
*
pwr_on_all_slots
)
(
struct
slot
*
slot
);
int
(
*
set_bus_speed_mode
)
(
struct
slot
*
slot
,
enum
pci_bus_speed
speed
);
int
(
*
get_power_status
)
(
struct
slot
*
slot
,
u8
*
status
);
int
(
*
get_attention_status
)
(
struct
slot
*
slot
,
u8
*
status
);
...
...
drivers/pci/hotplug/shpchp_core.c
View file @
7efe5d7c
...
...
@@ -27,26 +27,18 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include "shpchp.h"
#include "shpchprm.h"
/* Global variables */
int
shpchp_debug
;
int
shpchp_poll_mode
;
int
shpchp_poll_time
;
struct
controller
*
shpchp_ctrl_list
;
/* = NULL */
struct
pci_func
*
shpchp_slot_list
[
256
];
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
...
...
@@ -113,8 +105,6 @@ static int init_slots(struct controller *ctrl)
u32
slot_number
,
sun
;
int
result
=
-
ENOMEM
;
dbg
(
"%s
\n
"
,
__FUNCTION__
);
number_of_slots
=
ctrl
->
num_slots
;
slot_device
=
ctrl
->
slot_device_offset
;
slot_number
=
ctrl
->
first_slot
;
...
...
@@ -352,6 +342,17 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
return
0
;
}
static
int
is_shpc_capable
(
struct
pci_dev
*
dev
)
{
if
((
dev
->
vendor
==
PCI_VENDOR_ID_AMD
)
||
(
dev
->
device
==
PCI_DEVICE_ID_AMD_GOLAM_7450
))
return
1
;
if
(
pci_find_capability
(
dev
,
PCI_CAP_ID_SHPC
))
return
1
;
return
0
;
}
static
int
shpc_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
int
rc
;
...
...
@@ -360,6 +361,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int
first_device_num
;
/* first PCI device number supported by this SHPC */
int
num_ctlr_slots
;
/* number of slots supported by this SHPC */
if
(
!
is_shpc_capable
(
pdev
))
return
-
ENODEV
;
ctrl
=
(
struct
controller
*
)
kmalloc
(
sizeof
(
struct
controller
),
GFP_KERNEL
);
if
(
!
ctrl
)
{
err
(
"%s : out of memory
\n
"
,
__FUNCTION__
);
...
...
@@ -367,19 +371,12 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
memset
(
ctrl
,
0
,
sizeof
(
struct
controller
));
dbg
(
"DRV_thread pid = %d
\n
"
,
current
->
pid
);
rc
=
shpc_init
(
ctrl
,
pdev
,
(
php_intr_callback_t
)
shpchp_handle_attention_button
,
(
php_intr_callback_t
)
shpchp_handle_switch_change
,
(
php_intr_callback_t
)
shpchp_handle_presence_change
,
(
php_intr_callback_t
)
shpchp_handle_power_fault
);
rc
=
shpc_init
(
ctrl
,
pdev
);
if
(
rc
)
{
dbg
(
"%s: controller initialization failed
\n
"
,
SHPC_MODULE_NAME
);
goto
err_out_free_ctrl
;
}
dbg
(
"%s: controller initialization success
\n
"
,
__FUNCTION__
);
ctrl
->
pci_dev
=
pdev
;
/* pci_dev of the P2P bridge */
pci_set_drvdata
(
pdev
,
ctrl
);
...
...
@@ -411,22 +408,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
first_device_num
=
ctrl
->
slot_device_offset
;
num_ctlr_slots
=
ctrl
->
num_slots
;
/* Store PCI Config Space for all devices on this bus */
rc
=
shpchp_save_config
(
ctrl
,
ctrl
->
slot_bus
,
num_ctlr_slots
,
first_device_num
);
if
(
rc
)
{
err
(
"%s: unable to save PCI configuration data, error %d
\n
"
,
__FUNCTION__
,
rc
);
goto
err_out_free_ctrl_bus
;
}
/* Get IO, memory, and IRQ resources for new devices */
rc
=
shpchprm_find_available_resources
(
ctrl
);
ctrl
->
add_support
=
!
rc
;
if
(
rc
)
{
dbg
(
"shpchprm_find_available_resources = %#x
\n
"
,
rc
);
err
(
"unable to locate PCI configuration resources for hot plug add.
\n
"
);
goto
err_out_free_ctrl_bus
;
}
ctrl
->
add_support
=
1
;
/* Setup the slot information structures */
rc
=
init_slots
(
ctrl
);
...
...
@@ -477,7 +459,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static
int
shpc_start_thread
(
void
)
{
int
loop
;
int
retval
=
0
;
dbg
(
"Initialize + Start the notification/polling mechanism
\n
"
);
...
...
@@ -488,48 +469,21 @@ static int shpc_start_thread(void)
return
retval
;
}
dbg
(
"Initialize slot lists
\n
"
);
/* One slot list for each bus in the system */
for
(
loop
=
0
;
loop
<
256
;
loop
++
)
{
shpchp_slot_list
[
loop
]
=
NULL
;
}
return
retval
;
}
static
inline
void
__exit
free_shpchp_res
(
struct
pci_resource
*
res
)
{
struct
pci_resource
*
tres
;
while
(
res
)
{
tres
=
res
;
res
=
res
->
next
;
kfree
(
tres
);
}
}
static
void
__exit
unload_shpchpd
(
void
)
{
struct
pci_func
*
next
;
struct
pci_func
*
TempSlot
;
int
loop
;
struct
controller
*
ctrl
;
struct
controller
*
tctrl
;
ctrl
=
shpchp_ctrl_list
;
while
(
ctrl
)
{
shpchp_remove_ctrl_files
(
ctrl
);
cleanup_slots
(
ctrl
);
free_shpchp_res
(
ctrl
->
io_head
);
free_shpchp_res
(
ctrl
->
mem_head
);
free_shpchp_res
(
ctrl
->
p_mem_head
);
free_shpchp_res
(
ctrl
->
bus_head
);
kfree
(
ctrl
->
pci_bus
);
dbg
(
"%s: calling release_ctlr
\n
"
,
__FUNCTION__
);
ctrl
->
hpc_ops
->
release_ctlr
(
ctrl
);
tctrl
=
ctrl
;
...
...
@@ -538,20 +492,6 @@ static void __exit unload_shpchpd(void)
kfree
(
tctrl
);
}
for
(
loop
=
0
;
loop
<
256
;
loop
++
)
{
next
=
shpchp_slot_list
[
loop
];
while
(
next
!=
NULL
)
{
free_shpchp_res
(
next
->
io_head
);
free_shpchp_res
(
next
->
mem_head
);
free_shpchp_res
(
next
->
p_mem_head
);
free_shpchp_res
(
next
->
bus_head
);
TempSlot
=
next
;
next
=
next
->
next
;
kfree
(
TempSlot
);
}
}
/* Stop the notification mechanism */
shpchp_event_stop_thread
();
...
...
@@ -596,20 +536,14 @@ static int __init shpcd_init(void)
if
(
retval
)
goto
error_hpc_init
;
retval
=
shpchprm_init
(
PCI
);
if
(
!
retval
)
{
retval
=
pci_register_driver
(
&
shpc_driver
);
dbg
(
"%s: pci_register_driver = %d
\n
"
,
__FUNCTION__
,
retval
);
info
(
DRIVER_DESC
" version: "
DRIVER_VERSION
"
\n
"
);
}
error_hpc_init:
if
(
retval
)
{
shpchprm_cleanup
();
shpchp_event_stop_thread
();
}
else
shpchprm_print_pirt
();
}
return
retval
;
}
...
...
@@ -618,9 +552,6 @@ static void __exit shpcd_cleanup(void)
dbg
(
"unload_shpchpd()
\n
"
);
unload_shpchpd
();
shpchprm_cleanup
();
dbg
(
"pci_unregister_driver
\n
"
);
pci_unregister_driver
(
&
shpc_driver
);
info
(
DRIVER_DESC
" version: "
DRIVER_VERSION
" unloaded
\n
"
);
...
...
drivers/pci/hotplug/shpchp_ctrl.c
View file @
7efe5d7c
...
...
@@ -27,24 +27,14 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
#include "../pci.h"
#include "shpchp.h"
#include "shpchprm.h"
static
u32
configure_new_device
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
behind_bridge
,
struct
resource_lists
*
resources
,
u8
bridge_bus
,
u8
bridge_dev
);
static
int
configure_new_function
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
behind_bridge
,
struct
resource_lists
*
resources
,
u8
bridge_bus
,
u8
bridge_dev
);
static
void
interrupt_event_handler
(
struct
controller
*
ctrl
);
static
struct
semaphore
event_semaphore
;
/* mutex for process loop (up if something to process) */
...
...
@@ -52,28 +42,22 @@ static struct semaphore event_exit; /* guard ensure thread has exited before ca
static
int
event_finished
;
static
unsigned
long
pushbutton_pending
;
/* = 0 */
u8
shpchp_disk_irq
;
u8
shpchp_nic_irq
;
u8
shpchp_handle_attention_button
(
u8
hp_slot
,
void
*
inst_id
)
{
struct
controller
*
ctrl
=
(
struct
controller
*
)
inst_id
;
struct
slot
*
p_slot
;
u8
rc
=
0
;
u8
getstatus
;
struct
pci_func
*
func
;
struct
event_info
*
taskInfo
;
/* Attention Button Change */
dbg
(
"shpchp: Attention button interrupt received.
\n
"
);
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
(
hp_slot
+
ctrl
->
slot_device_offset
),
0
);
/* This is the structure that tells the worker thread what to do */
taskInfo
=
&
(
ctrl
->
event_queue
[
ctrl
->
next_event
]);
p_slot
=
shpchp_find_slot
(
ctrl
,
hp_slot
+
ctrl
->
slot_device_offset
);
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
func
->
presence_save
));
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
p_slot
->
presence_save
));
p_slot
->
hpc_ops
->
get_latch_status
(
p_slot
,
&
getstatus
);
ctrl
->
next_event
=
(
ctrl
->
next_event
+
1
)
%
10
;
...
...
@@ -118,14 +102,11 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
struct
slot
*
p_slot
;
u8
rc
=
0
;
u8
getstatus
;
struct
pci_func
*
func
;
struct
event_info
*
taskInfo
;
/* Switch Change */
dbg
(
"shpchp: Switch interrupt received.
\n
"
);
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
(
hp_slot
+
ctrl
->
slot_device_offset
),
0
);
/* This is the structure that tells the worker thread
* what to do
*/
...
...
@@ -135,19 +116,18 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
rc
++
;
p_slot
=
shpchp_find_slot
(
ctrl
,
hp_slot
+
ctrl
->
slot_device_offset
);
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
func
->
presence_save
));
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
p_slot
->
presence_save
));
p_slot
->
hpc_ops
->
get_latch_status
(
p_slot
,
&
getstatus
);
dbg
(
"%s: Card present %x Power status %x
\n
"
,
__FUNCTION__
,
func
->
presence_save
,
func
->
pwr_save
);
p_slot
->
presence_save
,
p_slot
->
pwr_save
);
if
(
getstatus
)
{
/*
* Switch opened
*/
info
(
"Latch open on Slot(%d)
\n
"
,
ctrl
->
first_slot
+
hp_slot
);
func
->
switch_save
=
0
;
taskInfo
->
event_type
=
INT_SWITCH_OPEN
;
if
(
func
->
pwr_save
&&
func
->
presence_save
)
{
if
(
p_slot
->
pwr_save
&&
p_slot
->
presence_save
)
{
taskInfo
->
event_type
=
INT_POWER_FAULT
;
err
(
"Surprise Removal of card
\n
"
);
}
...
...
@@ -156,7 +136,6 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
* Switch closed
*/
info
(
"Latch close on Slot(%d)
\n
"
,
ctrl
->
first_slot
+
hp_slot
);
func
->
switch_save
=
0x10
;
taskInfo
->
event_type
=
INT_SWITCH_CLOSE
;
}
...
...
@@ -172,14 +151,11 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
struct
slot
*
p_slot
;
u8
rc
=
0
;
/*u8 temp_byte;*/
struct
pci_func
*
func
;
struct
event_info
*
taskInfo
;
/* Presence Change */
dbg
(
"shpchp: Presence/Notify input change.
\n
"
);
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
(
hp_slot
+
ctrl
->
slot_device_offset
),
0
);
/* This is the structure that tells the worker thread
* what to do
*/
...
...
@@ -193,8 +169,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
/*
* Save the presence state
*/
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
func
->
presence_save
));
if
(
func
->
presence_save
)
{
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
p_slot
->
presence_save
));
if
(
p_slot
->
presence_save
)
{
/*
* Card Present
*/
...
...
@@ -219,14 +195,11 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
struct
controller
*
ctrl
=
(
struct
controller
*
)
inst_id
;
struct
slot
*
p_slot
;
u8
rc
=
0
;
struct
pci_func
*
func
;
struct
event_info
*
taskInfo
;
/* Power fault */
dbg
(
"shpchp: Power fault interrupt received.
\n
"
);
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
(
hp_slot
+
ctrl
->
slot_device_offset
),
0
);
/* This is the structure that tells the worker thread
* what to do
*/
...
...
@@ -242,7 +215,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
* Power fault Cleared
*/
info
(
"Power fault cleared on Slot(%d)
\n
"
,
ctrl
->
first_slot
+
hp_slot
);
func
->
status
=
0x00
;
p_slot
->
status
=
0x00
;
taskInfo
->
event_type
=
INT_POWER_FAULT_CLEAR
;
}
else
{
/*
...
...
@@ -251,7 +224,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
info
(
"Power fault on Slot(%d)
\n
"
,
ctrl
->
first_slot
+
hp_slot
);
taskInfo
->
event_type
=
INT_POWER_FAULT
;
/* set power fault status for this board */
func
->
status
=
0xFF
;
p_slot
->
status
=
0xFF
;
info
(
"power fault bit %x set
\n
"
,
hp_slot
);
}
if
(
rc
)
...
...
@@ -260,799 +233,13 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
return
rc
;
}
/*
* sort_by_size
*
* Sorts nodes on the list by their length.
* Smallest first.
*
*/
static
int
sort_by_size
(
struct
pci_resource
**
head
)
{
struct
pci_resource
*
current_res
;
struct
pci_resource
*
next_res
;
int
out_of_order
=
1
;
if
(
!
(
*
head
))
return
(
1
);
if
(
!
((
*
head
)
->
next
))
return
(
0
);
while
(
out_of_order
)
{
out_of_order
=
0
;
/* Special case for swapping list head */
if
(((
*
head
)
->
next
)
&&
((
*
head
)
->
length
>
(
*
head
)
->
next
->
length
))
{
out_of_order
++
;
current_res
=
*
head
;
*
head
=
(
*
head
)
->
next
;
current_res
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
current_res
;
}
current_res
=
*
head
;
while
(
current_res
->
next
&&
current_res
->
next
->
next
)
{
if
(
current_res
->
next
->
length
>
current_res
->
next
->
next
->
length
)
{
out_of_order
++
;
next_res
=
current_res
->
next
;
current_res
->
next
=
current_res
->
next
->
next
;
current_res
=
current_res
->
next
;
next_res
->
next
=
current_res
->
next
;
current_res
->
next
=
next_res
;
}
else
current_res
=
current_res
->
next
;
}
}
/* End of out_of_order loop */
return
(
0
);
}
/*
* sort_by_max_size
*
* Sorts nodes on the list by their length.
* Largest first.
*
*/
static
int
sort_by_max_size
(
struct
pci_resource
**
head
)
{
struct
pci_resource
*
current_res
;
struct
pci_resource
*
next_res
;
int
out_of_order
=
1
;
if
(
!
(
*
head
))
return
(
1
);
if
(
!
((
*
head
)
->
next
))
return
(
0
);
while
(
out_of_order
)
{
out_of_order
=
0
;
/* Special case for swapping list head */
if
(((
*
head
)
->
next
)
&&
((
*
head
)
->
length
<
(
*
head
)
->
next
->
length
))
{
out_of_order
++
;
current_res
=
*
head
;
*
head
=
(
*
head
)
->
next
;
current_res
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
current_res
;
}
current_res
=
*
head
;
while
(
current_res
->
next
&&
current_res
->
next
->
next
)
{
if
(
current_res
->
next
->
length
<
current_res
->
next
->
next
->
length
)
{
out_of_order
++
;
next_res
=
current_res
->
next
;
current_res
->
next
=
current_res
->
next
->
next
;
current_res
=
current_res
->
next
;
next_res
->
next
=
current_res
->
next
;
current_res
->
next
=
next_res
;
}
else
current_res
=
current_res
->
next
;
}
}
/* End of out_of_order loop */
return
(
0
);
}
/*
* do_pre_bridge_resource_split
*
* Returns zero or one node of resources that aren't in use
*
*/
static
struct
pci_resource
*
do_pre_bridge_resource_split
(
struct
pci_resource
**
head
,
struct
pci_resource
**
orig_head
,
u32
alignment
)
{
struct
pci_resource
*
prevnode
=
NULL
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
;
u32
rc
;
u32
temp_dword
;
dbg
(
"do_pre_bridge_resource_split
\n
"
);
if
(
!
(
*
head
)
||
!
(
*
orig_head
))
return
(
NULL
);
rc
=
shpchp_resource_sort_and_combine
(
head
);
if
(
rc
)
return
(
NULL
);
if
((
*
head
)
->
base
!=
(
*
orig_head
)
->
base
)
return
(
NULL
);
if
((
*
head
)
->
length
==
(
*
orig_head
)
->
length
)
return
(
NULL
);
/* If we got here, there the bridge requires some of the resource, but
* we may be able to split some off of the front
*/
node
=
*
head
;
if
(
node
->
length
&
(
alignment
-
1
))
{
/* This one isn't an aligned length, so we'll make a new entry
* and split it up.
*/
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
temp_dword
=
(
node
->
length
|
(
alignment
-
1
))
+
1
-
alignment
;
split_node
->
base
=
node
->
base
;
split_node
->
length
=
temp_dword
;
node
->
length
-=
temp_dword
;
node
->
base
+=
split_node
->
length
;
/* Put it in the list */
*
head
=
split_node
;
split_node
->
next
=
node
;
}
if
(
node
->
length
<
alignment
)
{
return
(
NULL
);
}
/* Now unlink it */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
node
->
next
=
NULL
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
node
->
next
=
NULL
;
}
return
(
node
);
}
/*
* do_bridge_resource_split
*
* Returns zero or one node of resources that aren't in use
*
*/
static
struct
pci_resource
*
do_bridge_resource_split
(
struct
pci_resource
**
head
,
u32
alignment
)
{
struct
pci_resource
*
prevnode
=
NULL
;
struct
pci_resource
*
node
;
u32
rc
;
u32
temp_dword
;
if
(
!
(
*
head
))
return
(
NULL
);
rc
=
shpchp_resource_sort_and_combine
(
head
);
if
(
rc
)
return
(
NULL
);
node
=
*
head
;
while
(
node
->
next
)
{
prevnode
=
node
;
node
=
node
->
next
;
kfree
(
prevnode
);
}
if
(
node
->
length
<
alignment
)
{
kfree
(
node
);
return
(
NULL
);
}
if
(
node
->
base
&
(
alignment
-
1
))
{
/* Short circuit if adjusted size is too small */
temp_dword
=
(
node
->
base
|
(
alignment
-
1
))
+
1
;
if
((
node
->
length
-
(
temp_dword
-
node
->
base
))
<
alignment
)
{
kfree
(
node
);
return
(
NULL
);
}
node
->
length
-=
(
temp_dword
-
node
->
base
);
node
->
base
=
temp_dword
;
}
if
(
node
->
length
&
(
alignment
-
1
))
{
/* There's stuff in use after this node */
kfree
(
node
);
return
(
NULL
);
}
return
(
node
);
}
/*
* get_io_resource
*
* this function sorts the resource list by size and then
* returns the first node of "size" length that is not in the
* ISA aliasing window. If it finds a node larger than "size"
* it will split it up.
*
* size must be a power of two.
*/
static
struct
pci_resource
*
get_io_resource
(
struct
pci_resource
**
head
,
u32
size
)
{
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
=
NULL
;
u32
temp_dword
;
if
(
!
(
*
head
))
return
(
NULL
);
if
(
shpchp_resource_sort_and_combine
(
head
)
)
return
(
NULL
);
if
(
sort_by_size
(
head
)
)
return
(
NULL
);
for
(
node
=
*
head
;
node
;
node
=
node
->
next
)
{
if
(
node
->
length
<
size
)
continue
;
if
(
node
->
base
&
(
size
-
1
))
{
/* This one isn't base aligned properly
so we'll make a new entry and split it up */
temp_dword
=
(
node
->
base
|
(
size
-
1
))
+
1
;
/*/ Short circuit if adjusted size is too small */
if
((
node
->
length
-
(
temp_dword
-
node
->
base
))
<
size
)
continue
;
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
split_node
->
base
=
node
->
base
;
split_node
->
length
=
temp_dword
-
node
->
base
;
node
->
base
=
temp_dword
;
node
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of non-aligned base */
/* Don't need to check if too small since we already did */
if
(
node
->
length
>
size
)
{
/* This one is longer than we need
so we'll make a new entry and split it up */
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
split_node
->
base
=
node
->
base
+
size
;
split_node
->
length
=
node
->
length
-
size
;
node
->
length
=
size
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of too big on top end */
/* For IO make sure it's not in the ISA aliasing space */
if
(
node
->
base
&
0x300L
)
continue
;
/* If we got here, then it is the right size
Now take it out of the list */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
}
node
->
next
=
NULL
;
/* Stop looping */
break
;
}
return
(
node
);
}
/*
* get_max_resource
*
* Gets the largest node that is at least "size" big from the
* list pointed to by head. It aligns the node on top and bottom
* to "size" alignment before returning it.
* J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
* This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
*/
static
struct
pci_resource
*
get_max_resource
(
struct
pci_resource
**
head
,
u32
size
)
{
struct
pci_resource
*
max
;
struct
pci_resource
*
temp
;
struct
pci_resource
*
split_node
;
u32
temp_dword
;
u32
max_size
[]
=
{
0x4000000
,
0x2000000
,
0x1000000
,
0x0800000
,
0x0400000
,
0x0200000
,
0x0100000
,
0x00
};
int
i
;
if
(
!
(
*
head
))
return
(
NULL
);
if
(
shpchp_resource_sort_and_combine
(
head
))
return
(
NULL
);
if
(
sort_by_max_size
(
head
))
return
(
NULL
);
for
(
max
=
*
head
;
max
;
max
=
max
->
next
)
{
/* If not big enough we could probably just bail,
instead we'll continue to the next. */
if
(
max
->
length
<
size
)
continue
;
if
(
max
->
base
&
(
size
-
1
))
{
/* This one isn't base aligned properly
so we'll make a new entry and split it up */
temp_dword
=
(
max
->
base
|
(
size
-
1
))
+
1
;
/* Short circuit if adjusted size is too small */
if
((
max
->
length
-
(
temp_dword
-
max
->
base
))
<
size
)
continue
;
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
split_node
->
base
=
max
->
base
;
split_node
->
length
=
temp_dword
-
max
->
base
;
max
->
base
=
temp_dword
;
max
->
length
-=
split_node
->
length
;
/* Put it next in the list */
split_node
->
next
=
max
->
next
;
max
->
next
=
split_node
;
}
if
((
max
->
base
+
max
->
length
)
&
(
size
-
1
))
{
/* This one isn't end aligned properly at the top
so we'll make a new entry and split it up */
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
temp_dword
=
((
max
->
base
+
max
->
length
)
&
~
(
size
-
1
));
split_node
->
base
=
temp_dword
;
split_node
->
length
=
max
->
length
+
max
->
base
-
split_node
->
base
;
max
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
max
->
next
;
max
->
next
=
split_node
;
}
/* Make sure it didn't shrink too much when we aligned it */
if
(
max
->
length
<
size
)
continue
;
for
(
i
=
0
;
max_size
[
i
]
>
size
;
i
++
)
{
if
(
max
->
length
>
max_size
[
i
])
{
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
break
;
/* return (NULL); */
split_node
->
base
=
max
->
base
+
max_size
[
i
];
split_node
->
length
=
max
->
length
-
max_size
[
i
];
max
->
length
=
max_size
[
i
];
/* Put it next in the list */
split_node
->
next
=
max
->
next
;
max
->
next
=
split_node
;
break
;
}
}
/* Now take it out of the list */
temp
=
(
struct
pci_resource
*
)
*
head
;
if
(
temp
==
max
)
{
*
head
=
max
->
next
;
}
else
{
while
(
temp
&&
temp
->
next
!=
max
)
{
temp
=
temp
->
next
;
}
temp
->
next
=
max
->
next
;
}
max
->
next
=
NULL
;
return
(
max
);
}
/* If we get here, we couldn't find one */
return
(
NULL
);
}
/*
* get_resource
*
* this function sorts the resource list by size and then
* returns the first node of "size" length. If it finds a node
* larger than "size" it will split it up.
*
* size must be a power of two.
*/
static
struct
pci_resource
*
get_resource
(
struct
pci_resource
**
head
,
u32
size
)
{
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
;
u32
temp_dword
;
if
(
!
(
*
head
))
return
(
NULL
);
if
(
shpchp_resource_sort_and_combine
(
head
)
)
return
(
NULL
);
if
(
sort_by_size
(
head
)
)
return
(
NULL
);
for
(
node
=
*
head
;
node
;
node
=
node
->
next
)
{
dbg
(
"%s: req_size =0x%x node=%p, base=0x%x, length=0x%x
\n
"
,
__FUNCTION__
,
size
,
node
,
node
->
base
,
node
->
length
);
if
(
node
->
length
<
size
)
continue
;
if
(
node
->
base
&
(
size
-
1
))
{
dbg
(
"%s: not aligned
\n
"
,
__FUNCTION__
);
/* this one isn't base aligned properly
so we'll make a new entry and split it up */
temp_dword
=
(
node
->
base
|
(
size
-
1
))
+
1
;
/* Short circuit if adjusted size is too small */
if
((
node
->
length
-
(
temp_dword
-
node
->
base
))
<
size
)
continue
;
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
split_node
->
base
=
node
->
base
;
split_node
->
length
=
temp_dword
-
node
->
base
;
node
->
base
=
temp_dword
;
node
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of non-aligned base */
/* Don't need to check if too small since we already did */
if
(
node
->
length
>
size
)
{
dbg
(
"%s: too big
\n
"
,
__FUNCTION__
);
/* this one is longer than we need
so we'll make a new entry and split it up */
split_node
=
kmalloc
(
sizeof
(
*
split_node
),
GFP_KERNEL
);
if
(
!
split_node
)
return
(
NULL
);
split_node
->
base
=
node
->
base
+
size
;
split_node
->
length
=
node
->
length
-
size
;
node
->
length
=
size
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of too big on top end */
dbg
(
"%s: got one!!!
\n
"
,
__FUNCTION__
);
/* If we got here, then it is the right size
Now take it out of the list */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
}
node
->
next
=
NULL
;
/* Stop looping */
break
;
}
return
(
node
);
}
/*
* shpchp_resource_sort_and_combine
*
* Sorts all of the nodes in the list in ascending order by
* their base addresses. Also does garbage collection by
* combining adjacent nodes.
*
* returns 0 if success
*/
int
shpchp_resource_sort_and_combine
(
struct
pci_resource
**
head
)
{
struct
pci_resource
*
node1
;
struct
pci_resource
*
node2
;
int
out_of_order
=
1
;
dbg
(
"%s: head = %p, *head = %p
\n
"
,
__FUNCTION__
,
head
,
*
head
);
if
(
!
(
*
head
))
return
(
1
);
dbg
(
"*head->next = %p
\n
"
,(
*
head
)
->
next
);
if
(
!
(
*
head
)
->
next
)
return
(
0
);
/* only one item on the list, already sorted! */
dbg
(
"*head->base = 0x%x
\n
"
,(
*
head
)
->
base
);
dbg
(
"*head->next->base = 0x%x
\n
"
,(
*
head
)
->
next
->
base
);
while
(
out_of_order
)
{
out_of_order
=
0
;
/* Special case for swapping list head */
if
(((
*
head
)
->
next
)
&&
((
*
head
)
->
base
>
(
*
head
)
->
next
->
base
))
{
node1
=
*
head
;
(
*
head
)
=
(
*
head
)
->
next
;
node1
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
node1
;
out_of_order
++
;
}
node1
=
(
*
head
);
while
(
node1
->
next
&&
node1
->
next
->
next
)
{
if
(
node1
->
next
->
base
>
node1
->
next
->
next
->
base
)
{
out_of_order
++
;
node2
=
node1
->
next
;
node1
->
next
=
node1
->
next
->
next
;
node1
=
node1
->
next
;
node2
->
next
=
node1
->
next
;
node1
->
next
=
node2
;
}
else
node1
=
node1
->
next
;
}
}
/* End of out_of_order loop */
node1
=
*
head
;
while
(
node1
&&
node1
->
next
)
{
if
((
node1
->
base
+
node1
->
length
)
==
node1
->
next
->
base
)
{
/* Combine */
dbg
(
"8..
\n
"
);
node1
->
length
+=
node1
->
next
->
length
;
node2
=
node1
->
next
;
node1
->
next
=
node1
->
next
->
next
;
kfree
(
node2
);
}
else
node1
=
node1
->
next
;
}
return
(
0
);
}
/**
* shpchp_slot_create - Creates a node and adds it to the proper bus.
* @busnumber - bus where new node is to be located
*
* Returns pointer to the new node or NULL if unsuccessful
*/
struct
pci_func
*
shpchp_slot_create
(
u8
busnumber
)
{
struct
pci_func
*
new_slot
;
struct
pci_func
*
next
;
new_slot
=
kmalloc
(
sizeof
(
*
new_slot
),
GFP_KERNEL
);
if
(
new_slot
==
NULL
)
{
return
(
new_slot
);
}
memset
(
new_slot
,
0
,
sizeof
(
struct
pci_func
));
new_slot
->
next
=
NULL
;
new_slot
->
configured
=
1
;
if
(
shpchp_slot_list
[
busnumber
]
==
NULL
)
{
shpchp_slot_list
[
busnumber
]
=
new_slot
;
}
else
{
next
=
shpchp_slot_list
[
busnumber
];
while
(
next
->
next
!=
NULL
)
next
=
next
->
next
;
next
->
next
=
new_slot
;
}
return
(
new_slot
);
}
/*
* slot_remove - Removes a node from the linked list of slots.
* @old_slot: slot to remove
*
* Returns 0 if successful, !0 otherwise.
*/
static
int
slot_remove
(
struct
pci_func
*
old_slot
)
{
struct
pci_func
*
next
;
if
(
old_slot
==
NULL
)
return
(
1
);
next
=
shpchp_slot_list
[
old_slot
->
bus
];
if
(
next
==
NULL
)
{
return
(
1
);
}
if
(
next
==
old_slot
)
{
shpchp_slot_list
[
old_slot
->
bus
]
=
old_slot
->
next
;
shpchp_destroy_board_resources
(
old_slot
);
kfree
(
old_slot
);
return
(
0
);
}
while
((
next
->
next
!=
old_slot
)
&&
(
next
->
next
!=
NULL
))
{
next
=
next
->
next
;
}
if
(
next
->
next
==
old_slot
)
{
next
->
next
=
old_slot
->
next
;
shpchp_destroy_board_resources
(
old_slot
);
kfree
(
old_slot
);
return
(
0
);
}
else
return
(
2
);
}
/**
* bridge_slot_remove - Removes a node from the linked list of slots.
* @bridge: bridge to remove
*
* Returns 0 if successful, !0 otherwise.
*/
static
int
bridge_slot_remove
(
struct
pci_func
*
bridge
)
{
u8
subordinateBus
,
secondaryBus
;
u8
tempBus
;
struct
pci_func
*
next
;
if
(
bridge
==
NULL
)
return
(
1
);
secondaryBus
=
(
bridge
->
config_space
[
0x06
]
>>
8
)
&
0xFF
;
subordinateBus
=
(
bridge
->
config_space
[
0x06
]
>>
16
)
&
0xFF
;
for
(
tempBus
=
secondaryBus
;
tempBus
<=
subordinateBus
;
tempBus
++
)
{
next
=
shpchp_slot_list
[
tempBus
];
while
(
!
slot_remove
(
next
))
{
next
=
shpchp_slot_list
[
tempBus
];
}
}
next
=
shpchp_slot_list
[
bridge
->
bus
];
if
(
next
==
NULL
)
{
return
(
1
);
}
if
(
next
==
bridge
)
{
shpchp_slot_list
[
bridge
->
bus
]
=
bridge
->
next
;
kfree
(
bridge
);
return
(
0
);
}
while
((
next
->
next
!=
bridge
)
&&
(
next
->
next
!=
NULL
))
{
next
=
next
->
next
;
}
if
(
next
->
next
==
bridge
)
{
next
->
next
=
bridge
->
next
;
kfree
(
bridge
);
return
(
0
);
}
else
return
(
2
);
}
/**
* shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed
* @bus: bus to find
* @device: device to find
* @index: is 0 for first function found, 1 for the second...
*
* Returns pointer to the node if successful, %NULL otherwise.
*/
struct
pci_func
*
shpchp_slot_find
(
u8
bus
,
u8
device
,
u8
index
)
{
int
found
=
-
1
;
struct
pci_func
*
func
;
func
=
shpchp_slot_list
[
bus
];
if
((
func
==
NULL
)
||
((
func
->
device
==
device
)
&&
(
index
==
0
)))
return
(
func
);
if
(
func
->
device
==
device
)
found
++
;
while
(
func
->
next
!=
NULL
)
{
func
=
func
->
next
;
if
(
func
->
device
==
device
)
found
++
;
if
(
found
==
index
)
return
(
func
);
}
return
(
NULL
);
}
static
int
is_bridge
(
struct
pci_func
*
func
)
{
/* Check the header type */
if
(((
func
->
config_space
[
0x03
]
>>
16
)
&
0xFF
)
==
0x01
)
return
1
;
else
return
0
;
}
/* The following routines constitute the bulk of the
hotplug controller logic
*/
static
u32
change_bus_speed
(
struct
controller
*
ctrl
,
struct
slot
*
p_slot
,
enum
pci_bus_speed
speed
)
static
int
change_bus_speed
(
struct
controller
*
ctrl
,
struct
slot
*
p_slot
,
enum
pci_bus_speed
speed
)
{
u32
rc
=
0
;
int
rc
=
0
;
dbg
(
"%s: change to speed %d
\n
"
,
__FUNCTION__
,
speed
);
down
(
&
ctrl
->
crit_sect
);
...
...
@@ -1074,10 +261,11 @@ static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum p
return
rc
;
}
static
u32
fix_bus_speed
(
struct
controller
*
ctrl
,
struct
slot
*
pslot
,
u8
flag
,
enum
pci_bus_speed
asp
,
enum
pci_bus_speed
bsp
,
enum
pci_bus_speed
msp
)
static
int
fix_bus_speed
(
struct
controller
*
ctrl
,
struct
slot
*
pslot
,
u8
flag
,
enum
pci_bus_speed
asp
,
enum
pci_bus_speed
bsp
,
enum
pci_bus_speed
msp
)
{
u32
rc
=
0
;
int
rc
=
0
;
if
(
flag
!=
0
)
{
/* Other slots on the same bus are occupied */
if
(
asp
<
bsp
)
{
...
...
@@ -1116,23 +304,20 @@ enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
* Configures board
*
*/
static
u32
board_added
(
struct
pci_func
*
func
,
struct
controller
*
ctrl
)
static
int
board_added
(
struct
slot
*
p_slot
)
{
u8
hp_slot
;
u8
slots_not_empty
=
0
;
int
index
;
u32
temp_register
=
0xFFFFFFFF
;
u32
retval
,
rc
=
0
;
struct
pci_func
*
new_func
=
NULL
;
struct
slot
*
p_slot
;
struct
resource_lists
res_lists
;
int
rc
=
0
;
enum
pci_bus_speed
adapter_speed
,
bus_speed
,
max_bus_speed
;
u8
pi
,
mode
;
struct
controller
*
ctrl
=
p_slot
->
ctrl
;
p_slot
=
shpchp_find_slot
(
ctrl
,
func
->
device
);
hp_slot
=
func
->
device
-
ctrl
->
slot_device_offset
;
hp_slot
=
p_slot
->
device
-
ctrl
->
slot_device_offset
;
dbg
(
"%s: func->device, slot_offset, hp_slot = %d, %d ,%d
\n
"
,
__FUNCTION__
,
func
->
device
,
ctrl
->
slot_device_offset
,
hp_slot
);
dbg
(
"%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d
\n
"
,
__FUNCTION__
,
p_slot
->
device
,
ctrl
->
slot_device_offset
,
hp_slot
);
/* Wait for exclusive access to hardware */
down
(
&
ctrl
->
crit_sect
);
...
...
@@ -1320,101 +505,27 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
up
(
&
ctrl
->
crit_sect
);
/* Wait for ~1 second */
dbg
(
"%s: before long_delay
\n
"
,
__FUNCTION__
);
wait_for_ctrl_irq
(
ctrl
);
dbg
(
"%s: after long_delay
\n
"
,
__FUNCTION__
);
dbg
(
"%s:
func status = %x
\n
"
,
__FUNCTION__
,
func
->
status
);
dbg
(
"%s:
slot status = %x
\n
"
,
__FUNCTION__
,
p_slot
->
status
);
/* Check for a power fault */
if
(
func
->
status
==
0xFF
)
{
if
(
p_slot
->
status
==
0xFF
)
{
/* power fault occurred, but it was benign */
temp_register
=
0xFFFFFFFF
;
dbg
(
"%s: temp register set to %x by power fault
\n
"
,
__FUNCTION__
,
temp_register
);
dbg
(
"%s: power fault
\n
"
,
__FUNCTION__
);
rc
=
POWER_FAILURE
;
func
->
status
=
0
;
}
else
{
/* Get vendor/device ID u32 */
rc
=
pci_bus_read_config_dword
(
ctrl
->
pci_dev
->
subordinate
,
PCI_DEVFN
(
func
->
device
,
func
->
function
),
PCI_VENDOR_ID
,
&
temp_register
);
dbg
(
"%s: pci_bus_read_config_dword returns %d
\n
"
,
__FUNCTION__
,
rc
);
dbg
(
"%s: temp_register is %x
\n
"
,
__FUNCTION__
,
temp_register
);
if
(
rc
!=
0
)
{
/* Something's wrong here */
temp_register
=
0xFFFFFFFF
;
dbg
(
"%s: temp register set to %x by error
\n
"
,
__FUNCTION__
,
temp_register
);
p_slot
->
status
=
0
;
goto
err_exit
;
}
/* Preset return code. It will be changed later if things go okay. */
rc
=
NO_ADAPTER_PRESENT
;
if
(
shpchp_configure_device
(
p_slot
))
{
err
(
"Cannot add device at 0x%x:0x%x
\n
"
,
p_slot
->
bus
,
p_slot
->
device
);
goto
err_exit
;
}
/* All F's is an empty slot or an invalid board */
if
(
temp_register
!=
0xFFFFFFFF
)
{
/* Check for a board in the slot */
res_lists
.
io_head
=
ctrl
->
io_head
;
res_lists
.
mem_head
=
ctrl
->
mem_head
;
res_lists
.
p_mem_head
=
ctrl
->
p_mem_head
;
res_lists
.
bus_head
=
ctrl
->
bus_head
;
res_lists
.
irqs
=
NULL
;
rc
=
configure_new_device
(
ctrl
,
func
,
0
,
&
res_lists
,
0
,
0
);
dbg
(
"%s: back from configure_new_device
\n
"
,
__FUNCTION__
);
ctrl
->
io_head
=
res_lists
.
io_head
;
ctrl
->
mem_head
=
res_lists
.
mem_head
;
ctrl
->
p_mem_head
=
res_lists
.
p_mem_head
;
ctrl
->
bus_head
=
res_lists
.
bus_head
;
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
mem_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
p_mem_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
io_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
bus_head
));
if
(
rc
)
{
/* Wait for exclusive access to hardware */
down
(
&
ctrl
->
crit_sect
);
/* turn off slot, turn on Amber LED, turn off Green LED */
retval
=
p_slot
->
hpc_ops
->
slot_disable
(
p_slot
);
if
(
retval
)
{
err
(
"%s: Issue of Slot Enable command failed
\n
"
,
__FUNCTION__
);
/* Done with exclusive hardware access */
up
(
&
ctrl
->
crit_sect
);
return
retval
;
}
/* Wait for the command to complete */
wait_for_ctrl_irq
(
ctrl
);
retval
=
p_slot
->
hpc_ops
->
check_cmd_status
(
ctrl
);
if
(
retval
)
{
err
(
"%s: Failed to disable slot, error code(%d)
\n
"
,
__FUNCTION__
,
retval
);
/* Done with exclusive hardware access */
up
(
&
ctrl
->
crit_sect
);
return
retval
;
}
/* Done with exclusive hardware access */
up
(
&
ctrl
->
crit_sect
);
return
(
rc
);
}
shpchp_save_slot_config
(
ctrl
,
func
);
func
->
status
=
0
;
func
->
switch_save
=
0x10
;
func
->
is_a_board
=
0x01
;
func
->
pwr_save
=
1
;
/* Next, we will instantiate the linux pci_dev structures
* (with appropriate driver notification, if already present)
*/
index
=
0
;
do
{
new_func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
func
->
device
,
index
++
);
if
(
new_func
&&
!
new_func
->
pci_dev
)
{
dbg
(
"%s:call pci_hp_configure_dev
\n
"
,
__FUNCTION__
);
shpchp_configure_device
(
ctrl
,
new_func
);
}
}
while
(
new_func
);
p_slot
->
status
=
0
;
p_slot
->
is_a_board
=
0x01
;
p_slot
->
pwr_save
=
1
;
/* Wait for exclusive access to hardware */
down
(
&
ctrl
->
crit_sect
);
...
...
@@ -1424,11 +535,12 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
/* Wait for the command to complete */
wait_for_ctrl_irq
(
ctrl
);
/* Done with exclusive hardware access */
up
(
&
ctrl
->
crit_sect
);
}
else
{
return
0
;
err_exit:
/* Wait for exclusive access to hardware */
down
(
&
ctrl
->
crit_sect
);
...
...
@@ -1455,8 +567,6 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
up
(
&
ctrl
->
crit_sect
);
return
(
rc
);
}
return
0
;
}
...
...
@@ -1464,55 +574,23 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
* remove_board - Turns off slot and LED's
*
*/
static
u32
remove_board
(
struct
pci_func
*
func
,
struct
controller
*
ctrl
)
static
int
remove_board
(
struct
slot
*
p_slot
)
{
int
index
;
u8
skip
=
0
;
u8
device
;
struct
controller
*
ctrl
=
p_slot
->
ctrl
;
u8
hp_slot
;
u32
rc
;
struct
resource_lists
res_lists
;
struct
pci_func
*
temp_func
;
struct
slot
*
p_slot
;
if
(
func
==
NULL
)
return
(
1
);
int
rc
;
if
(
shpchp_unconfigure_device
(
func
))
if
(
shpchp_unconfigure_device
(
p_slot
))
return
(
1
);
device
=
func
->
device
;
hp_slot
=
func
->
device
-
ctrl
->
slot_device_offset
;
hp_slot
=
p_slot
->
device
-
ctrl
->
slot_device_offset
;
p_slot
=
shpchp_find_slot
(
ctrl
,
hp_slot
+
ctrl
->
slot_device_offset
);
dbg
(
"In %s, hp_slot = %d
\n
"
,
__FUNCTION__
,
hp_slot
);
if
((
ctrl
->
add_support
)
&&
!
(
func
->
bus_head
||
func
->
mem_head
||
func
->
p_mem_head
||
func
->
io_head
))
{
/* Here we check to see if we've saved any of the board's
* resources already. If so, we'll skip the attempt to
* determine what's being used.
*/
index
=
0
;
temp_func
=
func
;
while
((
temp_func
=
shpchp_slot_find
(
temp_func
->
bus
,
temp_func
->
device
,
index
++
)))
{
if
(
temp_func
->
bus_head
||
temp_func
->
mem_head
||
temp_func
->
p_mem_head
||
temp_func
->
io_head
)
{
skip
=
1
;
break
;
}
}
if
(
!
skip
)
rc
=
shpchp_save_used_resources
(
ctrl
,
func
,
DISABLE_CARD
);
}
/* Change status to shutdown */
if
(
func
->
is_a_board
)
func
->
status
=
0x01
;
func
->
configured
=
0
;
if
(
p_slot
->
is_a_board
)
p_slot
->
status
=
0x01
;
/* Wait for exclusive access to hardware */
down
(
&
ctrl
->
crit_sect
);
...
...
@@ -1549,55 +627,8 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
/* Done with exclusive hardware access */
up
(
&
ctrl
->
crit_sect
);
if
(
ctrl
->
add_support
)
{
while
(
func
)
{
res_lists
.
io_head
=
ctrl
->
io_head
;
res_lists
.
mem_head
=
ctrl
->
mem_head
;
res_lists
.
p_mem_head
=
ctrl
->
p_mem_head
;
res_lists
.
bus_head
=
ctrl
->
bus_head
;
dbg
(
"Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)
\n
"
,
func
->
bus
,
func
->
device
,
func
->
function
);
shpchp_return_board_resources
(
func
,
&
res_lists
);
ctrl
->
io_head
=
res_lists
.
io_head
;
ctrl
->
mem_head
=
res_lists
.
mem_head
;
ctrl
->
p_mem_head
=
res_lists
.
p_mem_head
;
ctrl
->
bus_head
=
res_lists
.
bus_head
;
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
mem_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
p_mem_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
io_head
));
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
bus_head
));
if
(
is_bridge
(
func
))
{
dbg
(
"PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)
\n
"
,
ctrl
->
seg
,
func
->
bus
,
func
->
device
,
func
->
function
);
bridge_slot_remove
(
func
);
}
else
dbg
(
"PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)
\n
"
,
ctrl
->
seg
,
func
->
bus
,
func
->
device
,
func
->
function
);
slot_remove
(
func
);
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
device
,
0
);
}
/* Setup slot structure with entry for empty slot */
func
=
shpchp_slot_create
(
ctrl
->
slot_bus
);
if
(
func
==
NULL
)
{
return
(
1
);
}
func
->
bus
=
ctrl
->
slot_bus
;
func
->
device
=
device
;
func
->
function
=
0
;
func
->
configured
=
0
;
func
->
switch_save
=
0x10
;
func
->
pwr_save
=
0
;
func
->
is_a_board
=
0
;
}
p_slot
->
pwr_save
=
0
;
p_slot
->
is_a_board
=
0
;
return
0
;
}
...
...
@@ -1633,13 +664,11 @@ static void shpchp_pushbutton_thread (unsigned long slot)
p_slot
->
hpc_ops
->
get_power_status
(
p_slot
,
&
getstatus
);
if
(
getstatus
)
{
p_slot
->
state
=
POWEROFF_STATE
;
dbg
(
"In power_down_board, b:d(%x:%x)
\n
"
,
p_slot
->
bus
,
p_slot
->
device
);
shpchp_disable_slot
(
p_slot
);
p_slot
->
state
=
STATIC_STATE
;
}
else
{
p_slot
->
state
=
POWERON_STATE
;
dbg
(
"In add_board, b:d(%x:%x)
\n
"
,
p_slot
->
bus
,
p_slot
->
device
);
if
(
shpchp_enable_slot
(
p_slot
))
{
/* Wait for exclusive access to hardware */
...
...
@@ -1701,7 +730,6 @@ int shpchp_event_start_thread (void)
err
(
"Can't start up our event thread
\n
"
);
return
-
1
;
}
dbg
(
"Our event thread pid = %d
\n
"
,
pid
);
return
0
;
}
...
...
@@ -1709,9 +737,7 @@ int shpchp_event_start_thread (void)
void
shpchp_event_stop_thread
(
void
)
{
event_finished
=
1
;
dbg
(
"event_thread finish command given
\n
"
);
up
(
&
event_semaphore
);
dbg
(
"wait for event_thread to exit
\n
"
);
down
(
&
event_exit
);
}
...
...
@@ -1739,12 +765,10 @@ static void interrupt_event_handler(struct controller *ctrl)
{
int
loop
=
0
;
int
change
=
1
;
struct
pci_func
*
func
;
u8
hp_slot
;
u8
getstatus
;
struct
slot
*
p_slot
;
dbg
(
"%s:
\n
"
,
__FUNCTION__
);
while
(
change
)
{
change
=
0
;
...
...
@@ -1754,12 +778,8 @@ static void interrupt_event_handler(struct controller *ctrl)
ctrl
->
event_queue
[
loop
].
event_type
);
hp_slot
=
ctrl
->
event_queue
[
loop
].
hp_slot
;
func
=
shpchp_slot_find
(
ctrl
->
slot_bus
,
(
hp_slot
+
ctrl
->
slot_device_offset
),
0
);
p_slot
=
shpchp_find_slot
(
ctrl
,
hp_slot
+
ctrl
->
slot_device_offset
);
dbg
(
"%s: hp_slot %d, func %p, p_slot %p
\n
"
,
__FUNCTION__
,
hp_slot
,
func
,
p_slot
);
if
(
ctrl
->
event_queue
[
loop
].
event_type
==
INT_BUTTON_CANCEL
)
{
dbg
(
"%s: button cancel
\n
"
,
__FUNCTION__
);
del_timer
(
&
p_slot
->
task_event
);
...
...
@@ -1880,13 +900,6 @@ int shpchp_enable_slot (struct slot *p_slot)
{
u8
getstatus
=
0
;
int
rc
;
struct
pci_func
*
func
;
func
=
shpchp_slot_find
(
p_slot
->
bus
,
p_slot
->
device
,
0
);
if
(
!
func
)
{
dbg
(
"%s: Error! slot NULL
\n
"
,
__FUNCTION__
);
return
-
ENODEV
;
}
/* Check to see if (latch closed, card present, power off) */
down
(
&
p_slot
->
ctrl
->
crit_sect
);
...
...
@@ -1910,72 +923,34 @@ int shpchp_enable_slot (struct slot *p_slot)
}
up
(
&
p_slot
->
ctrl
->
crit_sect
);
slot_remove
(
func
);
func
=
shpchp_slot_create
(
p_slot
->
bus
);
if
(
func
==
NULL
)
return
-
ENOMEM
;
func
->
bus
=
p_slot
->
bus
;
func
->
device
=
p_slot
->
device
;
func
->
function
=
0
;
func
->
configured
=
0
;
func
->
is_a_board
=
1
;
p_slot
->
is_a_board
=
1
;
/* We have to save the presence info for these slots */
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
func
->
presence_save
));
p_slot
->
hpc_ops
->
get_power_status
(
p_slot
,
&
(
func
->
pwr_save
));
dbg
(
"%s:
func->pwr_save %x
\n
"
,
__FUNCTION__
,
func
->
pwr_save
);
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
p_slot
->
presence_save
));
p_slot
->
hpc_ops
->
get_power_status
(
p_slot
,
&
(
p_slot
->
pwr_save
));
dbg
(
"%s:
p_slot->pwr_save %x
\n
"
,
__FUNCTION__
,
p_slot
->
pwr_save
);
p_slot
->
hpc_ops
->
get_latch_status
(
p_slot
,
&
getstatus
);
func
->
switch_save
=
!
getstatus
?
0x10
:
0
;
rc
=
board_added
(
func
,
p_slot
->
ctrl
);
rc
=
board_added
(
p_slot
);
if
(
rc
)
{
if
(
is_bridge
(
func
))
bridge_slot_remove
(
func
);
else
slot_remove
(
func
);
/* Setup slot structure with entry for empty slot */
func
=
shpchp_slot_create
(
p_slot
->
bus
);
if
(
func
==
NULL
)
return
-
ENOMEM
;
/* Out of memory */
func
->
bus
=
p_slot
->
bus
;
func
->
device
=
p_slot
->
device
;
func
->
function
=
0
;
func
->
configured
=
0
;
func
->
is_a_board
=
1
;
/* We have to save the presence info for these slots */
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
func
->
presence_save
));
p_slot
->
hpc_ops
->
get_adapter_status
(
p_slot
,
&
(
p_slot
->
presence_save
));
p_slot
->
hpc_ops
->
get_latch_status
(
p_slot
,
&
getstatus
);
func
->
switch_save
=
!
getstatus
?
0x10
:
0
;
}
if
(
p_slot
)
update_slot_info
(
p_slot
);
return
rc
;
}
int
shpchp_disable_slot
(
struct
slot
*
p_slot
)
{
u8
class_code
,
header_type
,
BCR
;
u8
index
=
0
;
u8
getstatus
=
0
;
u32
rc
=
0
;
int
ret
=
0
;
unsigned
int
devfn
;
struct
pci_bus
*
pci_bus
;
struct
pci_func
*
func
;
if
(
!
p_slot
->
ctrl
)
return
-
ENODEV
;
pci_bus
=
p_slot
->
ctrl
->
pci_dev
->
subordinate
;
/* Check to see if (latch closed, card present, power on) */
down
(
&
p_slot
->
ctrl
->
crit_sect
);
...
...
@@ -1999,849 +974,8 @@ int shpchp_disable_slot (struct slot *p_slot)
}
up
(
&
p_slot
->
ctrl
->
crit_sect
);
func
=
shpchp_slot_find
(
p_slot
->
bus
,
p_slot
->
device
,
index
++
);
/* Make sure there are no video controllers here
* for all func of p_slot
*/
while
(
func
&&
!
rc
)
{
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
/* Check the Class Code */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
0x0B
,
&
class_code
);
if
(
rc
)
return
-
ENODEV
;
if
(
class_code
==
PCI_BASE_CLASS_DISPLAY
)
{
/* Display/Video adapter (not supported) */
rc
=
REMOVE_NOT_SUPPORTED
;
}
else
{
/* See if it's a bridge */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_HEADER_TYPE
,
&
header_type
);
if
(
rc
)
return
-
ENODEV
;
/* If it's a bridge, check the VGA Enable bit */
if
((
header_type
&
0x7F
)
==
PCI_HEADER_TYPE_BRIDGE
)
{
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
&
BCR
);
if
(
rc
)
return
-
ENODEV
;
/* If the VGA Enable bit is set, remove isn't supported */
if
(
BCR
&
PCI_BRIDGE_CTL_VGA
)
{
rc
=
REMOVE_NOT_SUPPORTED
;
}
}
}
func
=
shpchp_slot_find
(
p_slot
->
bus
,
p_slot
->
device
,
index
++
);
}
func
=
shpchp_slot_find
(
p_slot
->
bus
,
p_slot
->
device
,
0
);
if
((
func
!=
NULL
)
&&
!
rc
)
{
rc
=
remove_board
(
func
,
p_slot
->
ctrl
);
}
else
if
(
!
rc
)
rc
=
-
ENODEV
;
if
(
p_slot
)
ret
=
remove_board
(
p_slot
);
update_slot_info
(
p_slot
);
return
rc
;
}
/**
* configure_new_device - Configures the PCI header information of one board.
*
* @ctrl: pointer to controller structure
* @func: pointer to function structure
* @behind_bridge: 1 if this is a recursive call, 0 if not
* @resources: pointer to set of resource lists
*
* Returns 0 if success
*
*/
static
u32
configure_new_device
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
behind_bridge
,
struct
resource_lists
*
resources
,
u8
bridge_bus
,
u8
bridge_dev
)
{
u8
temp_byte
,
function
,
max_functions
,
stop_it
;
int
rc
;
u32
ID
;
struct
pci_func
*
new_slot
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
int
index
;
new_slot
=
func
;
dbg
(
"%s
\n
"
,
__FUNCTION__
);
memcpy
(
&
lpci_bus
,
ctrl
->
pci_dev
->
subordinate
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
/* Check for Multi-function device */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
func
->
device
,
func
->
function
),
0x0E
,
&
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: rc = %d
\n
"
,
__FUNCTION__
,
rc
);
return
rc
;
}
if
(
temp_byte
&
0x80
)
/* Multi-function device */
max_functions
=
8
;
else
max_functions
=
1
;
function
=
0
;
do
{
rc
=
configure_new_function
(
ctrl
,
new_slot
,
behind_bridge
,
resources
,
bridge_bus
,
bridge_dev
);
if
(
rc
)
{
dbg
(
"configure_new_function failed %d
\n
"
,
rc
);
index
=
0
;
while
(
new_slot
)
{
new_slot
=
shpchp_slot_find
(
new_slot
->
bus
,
new_slot
->
device
,
index
++
);
if
(
new_slot
)
shpchp_return_board_resources
(
new_slot
,
resources
);
}
return
(
rc
);
}
function
++
;
stop_it
=
0
;
/* The following loop skips to the next present function
* and creates a board structure
*/
while
((
function
<
max_functions
)
&&
(
!
stop_it
))
{
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
func
->
device
,
function
),
0x00
,
&
ID
);
if
(
ID
==
0xFFFFFFFF
)
{
/* There's nothing there. */
function
++
;
}
else
{
/* There's something there */
/* Setup slot structure. */
new_slot
=
shpchp_slot_create
(
func
->
bus
);
if
(
new_slot
==
NULL
)
{
/* Out of memory */
return
(
1
);
}
new_slot
->
bus
=
func
->
bus
;
new_slot
->
device
=
func
->
device
;
new_slot
->
function
=
function
;
new_slot
->
is_a_board
=
1
;
new_slot
->
status
=
0
;
stop_it
++
;
}
}
}
while
(
function
<
max_functions
);
dbg
(
"returning from configure_new_device
\n
"
);
return
0
;
}
/*
* Configuration logic that involves the hotplug data structures and
* their bookkeeping
*/
/**
* configure_new_function - Configures the PCI header information of one device
*
* @ctrl: pointer to controller structure
* @func: pointer to function structure
* @behind_bridge: 1 if this is a recursive call, 0 if not
* @resources: pointer to set of resource lists
*
* Calls itself recursively for bridged devices.
* Returns 0 if success
*
*/
static
int
configure_new_function
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
behind_bridge
,
struct
resource_lists
*
resources
,
u8
bridge_bus
,
u8
bridge_dev
)
{
int
cloop
;
u8
temp_byte
;
u8
device
;
u8
class_code
;
u16
temp_word
;
u32
rc
;
u32
temp_register
;
u32
base
;
u32
ID
;
unsigned
int
devfn
;
struct
pci_resource
*
mem_node
;
struct
pci_resource
*
p_mem_node
;
struct
pci_resource
*
io_node
;
struct
pci_resource
*
bus_node
;
struct
pci_resource
*
hold_mem_node
;
struct
pci_resource
*
hold_p_mem_node
;
struct
pci_resource
*
hold_IO_node
;
struct
pci_resource
*
hold_bus_node
;
struct
irq_mapping
irqs
;
struct
pci_func
*
new_slot
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
struct
resource_lists
temp_resources
;
#if defined(CONFIG_X86_64)
u8
IRQ
=
0
;
#endif
memcpy
(
&
lpci_bus
,
ctrl
->
pci_dev
->
subordinate
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
/* Check for Bridge */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_HEADER_TYPE
,
&
temp_byte
);
if
(
rc
)
return
rc
;
if
((
temp_byte
&
0x7F
)
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* PCI-PCI Bridge */
/* set Primary bus */
dbg
(
"set Primary bus = 0x%x
\n
"
,
func
->
bus
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_PRIMARY_BUS
,
func
->
bus
);
if
(
rc
)
return
rc
;
/* find range of busses to use */
bus_node
=
get_max_resource
(
&
resources
->
bus_head
,
1L
);
/* If we don't have any busses to allocate, we can't continue */
if
(
!
bus_node
)
{
err
(
"Got NO bus resource to use
\n
"
);
return
-
ENOMEM
;
}
dbg
(
"Got ranges of buses to use: base:len=0x%x:%x
\n
"
,
bus_node
->
base
,
bus_node
->
length
);
/* set Secondary bus */
temp_byte
=
(
u8
)
bus_node
->
base
;
dbg
(
"set Secondary bus = 0x%x
\n
"
,
temp_byte
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SECONDARY_BUS
,
temp_byte
);
if
(
rc
)
return
rc
;
/* set subordinate bus */
temp_byte
=
(
u8
)(
bus_node
->
base
+
bus_node
->
length
-
1
);
dbg
(
"set subordinate bus = 0x%x
\n
"
,
temp_byte
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SUBORDINATE_BUS
,
temp_byte
);
if
(
rc
)
return
rc
;
/* Set HP parameters (Cache Line Size, Latency Timer) */
rc
=
shpchprm_set_hpp
(
ctrl
,
func
,
PCI_HEADER_TYPE_BRIDGE
);
if
(
rc
)
return
rc
;
/* Setup the IO, memory, and prefetchable windows */
io_node
=
get_max_resource
(
&
(
resources
->
io_head
),
0x1000L
);
if
(
io_node
)
{
dbg
(
"io_node(base, len, next) (%x, %x, %p)
\n
"
,
io_node
->
base
,
io_node
->
length
,
io_node
->
next
);
}
mem_node
=
get_max_resource
(
&
(
resources
->
mem_head
),
0x100000L
);
if
(
mem_node
)
{
dbg
(
"mem_node(base, len, next) (%x, %x, %p)
\n
"
,
mem_node
->
base
,
mem_node
->
length
,
mem_node
->
next
);
}
if
(
resources
->
p_mem_head
)
p_mem_node
=
get_max_resource
(
&
(
resources
->
p_mem_head
),
0x100000L
);
else
{
/*
* In some platform implementation, MEM and PMEM are not
* distinguished, and hence ACPI _CRS has only MEM entries
* for both MEM and PMEM.
*/
dbg
(
"using MEM for PMEM
\n
"
);
p_mem_node
=
get_max_resource
(
&
(
resources
->
mem_head
),
0x100000L
);
}
if
(
p_mem_node
)
{
dbg
(
"p_mem_node(base, len, next) (%x, %x, %p)
\n
"
,
p_mem_node
->
base
,
p_mem_node
->
length
,
p_mem_node
->
next
);
}
/* set up the IRQ info */
if
(
!
resources
->
irqs
)
{
irqs
.
barber_pole
=
0
;
irqs
.
interrupt
[
0
]
=
0
;
irqs
.
interrupt
[
1
]
=
0
;
irqs
.
interrupt
[
2
]
=
0
;
irqs
.
interrupt
[
3
]
=
0
;
irqs
.
valid_INT
=
0
;
}
else
{
irqs
.
barber_pole
=
resources
->
irqs
->
barber_pole
;
irqs
.
interrupt
[
0
]
=
resources
->
irqs
->
interrupt
[
0
];
irqs
.
interrupt
[
1
]
=
resources
->
irqs
->
interrupt
[
1
];
irqs
.
interrupt
[
2
]
=
resources
->
irqs
->
interrupt
[
2
];
irqs
.
interrupt
[
3
]
=
resources
->
irqs
->
interrupt
[
3
];
irqs
.
valid_INT
=
resources
->
irqs
->
valid_INT
;
}
/* set up resource lists that are now aligned on top and bottom
* for anything behind the bridge.
*/
temp_resources
.
bus_head
=
bus_node
;
temp_resources
.
io_head
=
io_node
;
temp_resources
.
mem_head
=
mem_node
;
temp_resources
.
p_mem_head
=
p_mem_node
;
temp_resources
.
irqs
=
&
irqs
;
/* Make copies of the nodes we are going to pass down so that
* if there is a problem,we can just use these to free resources
*/
hold_bus_node
=
kmalloc
(
sizeof
(
*
hold_bus_node
),
GFP_KERNEL
);
hold_IO_node
=
kmalloc
(
sizeof
(
*
hold_IO_node
),
GFP_KERNEL
);
hold_mem_node
=
kmalloc
(
sizeof
(
*
hold_mem_node
),
GFP_KERNEL
);
hold_p_mem_node
=
kmalloc
(
sizeof
(
*
hold_p_mem_node
),
GFP_KERNEL
);
if
(
!
hold_bus_node
||
!
hold_IO_node
||
!
hold_mem_node
||
!
hold_p_mem_node
)
{
kfree
(
hold_bus_node
);
kfree
(
hold_IO_node
);
kfree
(
hold_mem_node
);
kfree
(
hold_p_mem_node
);
return
1
;
}
memcpy
(
hold_bus_node
,
bus_node
,
sizeof
(
struct
pci_resource
));
bus_node
->
base
+=
1
;
bus_node
->
length
-=
1
;
bus_node
->
next
=
NULL
;
/* If we have IO resources copy them and fill in the bridge's
* IO range registers
*/
if
(
io_node
)
{
memcpy
(
hold_IO_node
,
io_node
,
sizeof
(
struct
pci_resource
));
io_node
->
next
=
NULL
;
/* set IO base and Limit registers */
RES_CHECK
(
io_node
->
base
,
8
);
temp_byte
=
(
u8
)(
io_node
->
base
>>
8
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_IO_BASE
,
temp_byte
);
RES_CHECK
(
io_node
->
base
+
io_node
->
length
-
1
,
8
);
temp_byte
=
(
u8
)((
io_node
->
base
+
io_node
->
length
-
1
)
>>
8
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_IO_LIMIT
,
temp_byte
);
}
else
{
kfree
(
hold_IO_node
);
hold_IO_node
=
NULL
;
}
/* If we have memory resources copy them and fill in the bridge's
* memory range registers. Otherwise, fill in the range
* registers with values that disable them.
*/
if
(
mem_node
)
{
memcpy
(
hold_mem_node
,
mem_node
,
sizeof
(
struct
pci_resource
));
mem_node
->
next
=
NULL
;
/* set Mem base and Limit registers */
RES_CHECK
(
mem_node
->
base
,
16
);
temp_word
=
(
u32
)(
mem_node
->
base
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_BASE
,
temp_word
);
RES_CHECK
(
mem_node
->
base
+
mem_node
->
length
-
1
,
16
);
temp_word
=
(
u32
)((
mem_node
->
base
+
mem_node
->
length
-
1
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_LIMIT
,
temp_word
);
}
else
{
temp_word
=
0xFFFF
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_BASE
,
temp_word
);
temp_word
=
0x0000
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_LIMIT
,
temp_word
);
kfree
(
hold_mem_node
);
hold_mem_node
=
NULL
;
}
/* If we have prefetchable memory resources copy them and
* fill in the bridge's memory range registers. Otherwise,
* fill in the range registers with values that disable them.
*/
if
(
p_mem_node
)
{
memcpy
(
hold_p_mem_node
,
p_mem_node
,
sizeof
(
struct
pci_resource
));
p_mem_node
->
next
=
NULL
;
/* set Pre Mem base and Limit registers */
RES_CHECK
(
p_mem_node
->
base
,
16
);
temp_word
=
(
u32
)(
p_mem_node
->
base
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_BASE
,
temp_word
);
RES_CHECK
(
p_mem_node
->
base
+
p_mem_node
->
length
-
1
,
16
);
temp_word
=
(
u32
)((
p_mem_node
->
base
+
p_mem_node
->
length
-
1
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_LIMIT
,
temp_word
);
}
else
{
temp_word
=
0xFFFF
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_BASE
,
temp_word
);
temp_word
=
0x0000
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_LIMIT
,
temp_word
);
kfree
(
hold_p_mem_node
);
hold_p_mem_node
=
NULL
;
}
/* Adjust this to compensate for extra adjustment in first loop */
irqs
.
barber_pole
--
;
rc
=
0
;
/* Here we actually find the devices and configure them */
for
(
device
=
0
;
(
device
<=
0x1F
)
&&
!
rc
;
device
++
)
{
irqs
.
barber_pole
=
(
irqs
.
barber_pole
+
1
)
&
0x03
;
ID
=
0xFFFFFFFF
;
pci_bus
->
number
=
hold_bus_node
->
base
;
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
device
,
0
),
PCI_VENDOR_ID
,
&
ID
);
pci_bus
->
number
=
func
->
bus
;
if
(
ID
!=
0xFFFFFFFF
)
{
/* device Present */
/* Setup slot structure. */
new_slot
=
shpchp_slot_create
(
hold_bus_node
->
base
);
if
(
new_slot
==
NULL
)
{
/* Out of memory */
rc
=
-
ENOMEM
;
continue
;
}
new_slot
->
bus
=
hold_bus_node
->
base
;
new_slot
->
device
=
device
;
new_slot
->
function
=
0
;
new_slot
->
is_a_board
=
1
;
new_slot
->
status
=
0
;
rc
=
configure_new_device
(
ctrl
,
new_slot
,
1
,
&
temp_resources
,
func
->
bus
,
func
->
device
);
dbg
(
"configure_new_device rc=0x%x
\n
"
,
rc
);
}
/* End of IF (device in slot?) */
}
/* End of FOR loop */
if
(
rc
)
{
shpchp_destroy_resource_list
(
&
temp_resources
);
return_resource
(
&
(
resources
->
bus_head
),
hold_bus_node
);
return_resource
(
&
(
resources
->
io_head
),
hold_IO_node
);
return_resource
(
&
(
resources
->
mem_head
),
hold_mem_node
);
return_resource
(
&
(
resources
->
p_mem_head
),
hold_p_mem_node
);
return
(
rc
);
}
/* save the interrupt routing information */
if
(
resources
->
irqs
)
{
resources
->
irqs
->
interrupt
[
0
]
=
irqs
.
interrupt
[
0
];
resources
->
irqs
->
interrupt
[
1
]
=
irqs
.
interrupt
[
1
];
resources
->
irqs
->
interrupt
[
2
]
=
irqs
.
interrupt
[
2
];
resources
->
irqs
->
interrupt
[
3
]
=
irqs
.
interrupt
[
3
];
resources
->
irqs
->
valid_INT
=
irqs
.
valid_INT
;
}
else
if
(
!
behind_bridge
)
{
/* We need to hook up the interrupts here */
for
(
cloop
=
0
;
cloop
<
4
;
cloop
++
)
{
if
(
irqs
.
valid_INT
&
(
0x01
<<
cloop
))
{
rc
=
shpchp_set_irq
(
func
->
bus
,
func
->
device
,
0x0A
+
cloop
,
irqs
.
interrupt
[
cloop
]);
if
(
rc
)
{
shpchp_destroy_resource_list
(
&
temp_resources
);
return_resource
(
&
(
resources
->
bus_head
),
hold_bus_node
);
return_resource
(
&
(
resources
->
io_head
),
hold_IO_node
);
return_resource
(
&
(
resources
->
mem_head
),
hold_mem_node
);
return_resource
(
&
(
resources
->
p_mem_head
),
hold_p_mem_node
);
return
rc
;
}
}
}
/* end of for loop */
}
/* Return unused bus resources
* First use the temporary node to store information for the board
*/
if
(
hold_bus_node
&&
bus_node
&&
temp_resources
.
bus_head
)
{
hold_bus_node
->
length
=
bus_node
->
base
-
hold_bus_node
->
base
;
hold_bus_node
->
next
=
func
->
bus_head
;
func
->
bus_head
=
hold_bus_node
;
temp_byte
=
(
u8
)(
temp_resources
.
bus_head
->
base
-
1
);
/* set subordinate bus */
dbg
(
"re-set subordinate bus = 0x%x
\n
"
,
temp_byte
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SUBORDINATE_BUS
,
temp_byte
);
if
(
temp_resources
.
bus_head
->
length
==
0
)
{
kfree
(
temp_resources
.
bus_head
);
temp_resources
.
bus_head
=
NULL
;
}
else
{
dbg
(
"return bus res of b:d(0x%x:%x) base:len(0x%x:%x)
\n
"
,
func
->
bus
,
func
->
device
,
temp_resources
.
bus_head
->
base
,
temp_resources
.
bus_head
->
length
);
return_resource
(
&
(
resources
->
bus_head
),
temp_resources
.
bus_head
);
}
}
/* If we have IO space available and there is some left,
* return the unused portion
*/
if
(
hold_IO_node
&&
temp_resources
.
io_head
)
{
io_node
=
do_pre_bridge_resource_split
(
&
(
temp_resources
.
io_head
),
&
hold_IO_node
,
0x1000
);
/* Check if we were able to split something off */
if
(
io_node
)
{
hold_IO_node
->
base
=
io_node
->
base
+
io_node
->
length
;
RES_CHECK
(
hold_IO_node
->
base
,
8
);
temp_byte
=
(
u8
)((
hold_IO_node
->
base
)
>>
8
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_IO_BASE
,
temp_byte
);
return_resource
(
&
(
resources
->
io_head
),
io_node
);
}
io_node
=
do_bridge_resource_split
(
&
(
temp_resources
.
io_head
),
0x1000
);
/* Check if we were able to split something off */
if
(
io_node
)
{
/* First use the temporary node to store information for the board */
hold_IO_node
->
length
=
io_node
->
base
-
hold_IO_node
->
base
;
/* If we used any, add it to the board's list */
if
(
hold_IO_node
->
length
)
{
hold_IO_node
->
next
=
func
->
io_head
;
func
->
io_head
=
hold_IO_node
;
RES_CHECK
(
io_node
->
base
-
1
,
8
);
temp_byte
=
(
u8
)((
io_node
->
base
-
1
)
>>
8
);
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_IO_LIMIT
,
temp_byte
);
return_resource
(
&
(
resources
->
io_head
),
io_node
);
}
else
{
/* it doesn't need any IO */
temp_byte
=
0x00
;
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_IO_LIMIT
,
temp_byte
);
return_resource
(
&
(
resources
->
io_head
),
io_node
);
kfree
(
hold_IO_node
);
}
}
else
{
/* it used most of the range */
hold_IO_node
->
next
=
func
->
io_head
;
func
->
io_head
=
hold_IO_node
;
}
}
else
if
(
hold_IO_node
)
{
/* it used the whole range */
hold_IO_node
->
next
=
func
->
io_head
;
func
->
io_head
=
hold_IO_node
;
}
/* If we have memory space available and there is some left,
* return the unused portion
*/
if
(
hold_mem_node
&&
temp_resources
.
mem_head
)
{
mem_node
=
do_pre_bridge_resource_split
(
&
(
temp_resources
.
mem_head
),
&
hold_mem_node
,
0x100000L
);
/* Check if we were able to split something off */
if
(
mem_node
)
{
hold_mem_node
->
base
=
mem_node
->
base
+
mem_node
->
length
;
RES_CHECK
(
hold_mem_node
->
base
,
16
);
temp_word
=
(
u32
)((
hold_mem_node
->
base
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_BASE
,
temp_word
);
return_resource
(
&
(
resources
->
mem_head
),
mem_node
);
}
mem_node
=
do_bridge_resource_split
(
&
(
temp_resources
.
mem_head
),
0x100000L
);
/* Check if we were able to split something off */
if
(
mem_node
)
{
/* First use the temporary node to store information for the board */
hold_mem_node
->
length
=
mem_node
->
base
-
hold_mem_node
->
base
;
if
(
hold_mem_node
->
length
)
{
hold_mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
hold_mem_node
;
/* configure end address */
RES_CHECK
(
mem_node
->
base
-
1
,
16
);
temp_word
=
(
u32
)((
mem_node
->
base
-
1
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_LIMIT
,
temp_word
);
/* Return unused resources to the pool */
return_resource
(
&
(
resources
->
mem_head
),
mem_node
);
}
else
{
/* it doesn't need any Mem */
temp_word
=
0x0000
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_LIMIT
,
temp_word
);
return_resource
(
&
(
resources
->
mem_head
),
mem_node
);
kfree
(
hold_mem_node
);
}
}
else
{
/* it used most of the range */
hold_mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
hold_mem_node
;
}
}
else
if
(
hold_mem_node
)
{
/* it used the whole range */
hold_mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
hold_mem_node
;
}
/* If we have prefetchable memory space available and there is some
* left at the end, return the unused portion
*/
if
(
hold_p_mem_node
&&
temp_resources
.
p_mem_head
)
{
p_mem_node
=
do_pre_bridge_resource_split
(
&
(
temp_resources
.
p_mem_head
),
&
hold_p_mem_node
,
0x100000L
);
/* Check if we were able to split something off */
if
(
p_mem_node
)
{
hold_p_mem_node
->
base
=
p_mem_node
->
base
+
p_mem_node
->
length
;
RES_CHECK
(
hold_p_mem_node
->
base
,
16
);
temp_word
=
(
u32
)((
hold_p_mem_node
->
base
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_BASE
,
temp_word
);
return_resource
(
&
(
resources
->
p_mem_head
),
p_mem_node
);
}
p_mem_node
=
do_bridge_resource_split
(
&
(
temp_resources
.
p_mem_head
),
0x100000L
);
/* Check if we were able to split something off */
if
(
p_mem_node
)
{
/* First use the temporary node to store information for the board */
hold_p_mem_node
->
length
=
p_mem_node
->
base
-
hold_p_mem_node
->
base
;
/* If we used any, add it to the board's list */
if
(
hold_p_mem_node
->
length
)
{
hold_p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
hold_p_mem_node
;
RES_CHECK
(
p_mem_node
->
base
-
1
,
16
);
temp_word
=
(
u32
)((
p_mem_node
->
base
-
1
)
>>
16
);
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_LIMIT
,
temp_word
);
return_resource
(
&
(
resources
->
p_mem_head
),
p_mem_node
);
}
else
{
/* it doesn't need any PMem */
temp_word
=
0x0000
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_LIMIT
,
temp_word
);
return_resource
(
&
(
resources
->
p_mem_head
),
p_mem_node
);
kfree
(
hold_p_mem_node
);
}
}
else
{
/* it used the most of the range */
hold_p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
hold_p_mem_node
;
}
}
else
if
(
hold_p_mem_node
)
{
/* it used the whole range */
hold_p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
hold_p_mem_node
;
}
/* We should be configuring an IRQ and the bridge's base address
* registers if it needs them. Although we have never seen such
* a device
*/
shpchprm_enable_card
(
ctrl
,
func
,
PCI_HEADER_TYPE_BRIDGE
);
dbg
(
"PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)
\n
"
,
ctrl
->
seg
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
else
if
((
temp_byte
&
0x7F
)
==
PCI_HEADER_TYPE_NORMAL
)
{
/* Standard device */
u64
base64
;
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
0x0B
,
&
class_code
);
if
(
class_code
==
PCI_BASE_CLASS_DISPLAY
)
return
(
DEVICE_TYPE_NOT_SUPPORTED
);
/* Figure out IO and memory needs */
for
(
cloop
=
PCI_BASE_ADDRESS_0
;
cloop
<=
PCI_BASE_ADDRESS_5
;
cloop
+=
4
)
{
temp_register
=
0xFFFFFFFF
;
rc
=
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
temp_register
);
rc
=
pci_bus_read_config_dword
(
pci_bus
,
devfn
,
cloop
,
&
temp_register
);
dbg
(
"Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)
\n
"
,
cloop
,
temp_register
,
func
->
bus
,
func
->
device
,
func
->
function
);
if
(
!
temp_register
)
continue
;
base64
=
0L
;
if
(
temp_register
&
PCI_BASE_ADDRESS_SPACE_IO
)
{
/* Map IO */
/* set base = amount of IO space */
base
=
temp_register
&
0xFFFFFFFC
;
base
=
~
base
+
1
;
dbg
(
"NEED IO length(0x%x)
\n
"
,
base
);
io_node
=
get_io_resource
(
&
(
resources
->
io_head
),(
ulong
)
base
);
/* allocate the resource to the board */
if
(
io_node
)
{
dbg
(
"Got IO base=0x%x(length=0x%x)
\n
"
,
io_node
->
base
,
io_node
->
length
);
base
=
(
u32
)
io_node
->
base
;
io_node
->
next
=
func
->
io_head
;
func
->
io_head
=
io_node
;
}
else
{
err
(
"Got NO IO resource(length=0x%x)
\n
"
,
base
);
return
-
ENOMEM
;
}
}
else
{
/* map MEM */
int
prefetchable
=
1
;
struct
pci_resource
**
res_node
=
&
func
->
p_mem_head
;
char
*
res_type_str
=
"PMEM"
;
u32
temp_register2
;
if
(
!
(
temp_register
&
PCI_BASE_ADDRESS_MEM_PREFETCH
))
{
prefetchable
=
0
;
res_node
=
&
func
->
mem_head
;
res_type_str
++
;
}
base
=
temp_register
&
0xFFFFFFF0
;
base
=
~
base
+
1
;
switch
(
temp_register
&
PCI_BASE_ADDRESS_MEM_TYPE_MASK
)
{
case
PCI_BASE_ADDRESS_MEM_TYPE_32
:
dbg
(
"NEED 32 %s bar=0x%x(length=0x%x)
\n
"
,
res_type_str
,
temp_register
,
base
);
if
(
prefetchable
&&
resources
->
p_mem_head
)
mem_node
=
get_resource
(
&
(
resources
->
p_mem_head
),
(
ulong
)
base
);
else
{
if
(
prefetchable
)
dbg
(
"using MEM for PMEM
\n
"
);
mem_node
=
get_resource
(
&
(
resources
->
mem_head
),
(
ulong
)
base
);
}
/* allocate the resource to the board */
if
(
mem_node
)
{
base
=
(
u32
)
mem_node
->
base
;
mem_node
->
next
=
*
res_node
;
*
res_node
=
mem_node
;
dbg
(
"Got 32 %s base=0x%x(length=0x%x)
\n
"
,
res_type_str
,
mem_node
->
base
,
mem_node
->
length
);
}
else
{
err
(
"Got NO 32 %s resource(length=0x%x)
\n
"
,
res_type_str
,
base
);
return
-
ENOMEM
;
}
break
;
case
PCI_BASE_ADDRESS_MEM_TYPE_64
:
rc
=
pci_bus_read_config_dword
(
pci_bus
,
devfn
,
cloop
+
4
,
&
temp_register2
);
dbg
(
"NEED 64 %s bar=0x%x:%x(length=0x%x)
\n
"
,
res_type_str
,
temp_register2
,
temp_register
,
base
);
if
(
prefetchable
&&
resources
->
p_mem_head
)
mem_node
=
get_resource
(
&
(
resources
->
p_mem_head
),
(
ulong
)
base
);
else
{
if
(
prefetchable
)
dbg
(
"using MEM for PMEM
\n
"
);
mem_node
=
get_resource
(
&
(
resources
->
mem_head
),
(
ulong
)
base
);
}
/* allocate the resource to the board */
if
(
mem_node
)
{
base64
=
mem_node
->
base
;
mem_node
->
next
=
*
res_node
;
*
res_node
=
mem_node
;
dbg
(
"Got 64 %s base=0x%x:%x(length=%x)
\n
"
,
res_type_str
,
(
u32
)(
base64
>>
32
),
(
u32
)
base64
,
mem_node
->
length
);
}
else
{
err
(
"Got NO 64 %s resource(length=0x%x)
\n
"
,
res_type_str
,
base
);
return
-
ENOMEM
;
}
break
;
default:
dbg
(
"reserved BAR type=0x%x
\n
"
,
temp_register
);
break
;
}
}
if
(
base64
)
{
rc
=
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
(
u32
)
base64
);
cloop
+=
4
;
base64
>>=
32
;
if
(
base64
)
{
dbg
(
"%s: high dword of base64(0x%x) set to 0
\n
"
,
__FUNCTION__
,
(
u32
)
base64
);
base64
=
0x0L
;
}
rc
=
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
(
u32
)
base64
);
}
else
{
rc
=
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
base
);
}
}
/* End of base register loop */
#if defined(CONFIG_X86_64)
/* Figure out which interrupt pin this function uses */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_INTERRUPT_PIN
,
&
temp_byte
);
/* If this function needs an interrupt and we are behind a bridge
and the pin is tied to something that's alread mapped,
set this one the same
*/
if
(
temp_byte
&&
resources
->
irqs
&&
(
resources
->
irqs
->
valid_INT
&
(
0x01
<<
((
temp_byte
+
resources
->
irqs
->
barber_pole
-
1
)
&
0x03
))))
{
/* We have to share with something already set up */
IRQ
=
resources
->
irqs
->
interrupt
[(
temp_byte
+
resources
->
irqs
->
barber_pole
-
1
)
&
0x03
];
}
else
{
/* Program IRQ based on card type */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
0x0B
,
&
class_code
);
if
(
class_code
==
PCI_BASE_CLASS_STORAGE
)
{
IRQ
=
shpchp_disk_irq
;
}
else
{
IRQ
=
shpchp_nic_irq
;
}
}
/* IRQ Line */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_INTERRUPT_LINE
,
IRQ
);
if
(
!
behind_bridge
)
{
rc
=
shpchp_set_irq
(
func
->
bus
,
func
->
device
,
temp_byte
+
0x09
,
IRQ
);
if
(
rc
)
return
(
1
);
}
else
{
/* TBD - this code may also belong in the other clause of this If statement */
resources
->
irqs
->
interrupt
[(
temp_byte
+
resources
->
irqs
->
barber_pole
-
1
)
&
0x03
]
=
IRQ
;
resources
->
irqs
->
valid_INT
|=
0x01
<<
(
temp_byte
+
resources
->
irqs
->
barber_pole
-
1
)
&
0x03
;
}
#endif
/* Disable ROM base Address */
rc
=
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
PCI_ROM_ADDRESS
,
0x00
);
/* Set HP parameters (Cache Line Size, Latency Timer) */
rc
=
shpchprm_set_hpp
(
ctrl
,
func
,
PCI_HEADER_TYPE_NORMAL
);
if
(
rc
)
return
rc
;
shpchprm_enable_card
(
ctrl
,
func
,
PCI_HEADER_TYPE_NORMAL
);
dbg
(
"PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)
\n
"
,
ctrl
->
seg
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
/* End of Not-A-Bridge else */
else
{
/* It's some strange type of PCI adapter (Cardbus?) */
return
(
DEVICE_TYPE_NOT_SUPPORTED
);
}
func
->
configured
=
1
;
return
0
;
return
ret
;
}
drivers/pci/hotplug/shpchp_hpc.c
View file @
7efe5d7c
...
...
@@ -27,17 +27,10 @@
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <asm/system.h>
#include "shpchp.h"
#ifdef DEBUG
...
...
@@ -282,7 +275,7 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
static
int
shpc_write_cmd
(
struct
slot
*
slot
,
u8
t_slot
,
u8
cmd
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u16
cmd_status
;
int
retval
=
0
;
u16
temp_word
;
...
...
@@ -320,7 +313,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
* command.
*/
writew
(
temp_word
,
php_ctlr
->
creg
+
CMD
);
dbg
(
"%s: temp_word written %x
\n
"
,
__FUNCTION__
,
temp_word
);
DBG_LEAVE_ROUTINE
return
retval
;
...
...
@@ -328,7 +320,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
static
int
hpc_check_cmd_status
(
struct
controller
*
ctrl
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
ctrl
->
hpc_ctlr_handle
;
u16
cmd_status
;
int
retval
=
0
;
...
...
@@ -368,7 +360,7 @@ static int hpc_check_cmd_status(struct controller *ctrl)
static
int
hpc_get_attention_status
(
struct
slot
*
slot
,
u8
*
status
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
;
u8
atten_led_state
;
...
...
@@ -408,7 +400,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
static
int
hpc_get_power_status
(
struct
slot
*
slot
,
u8
*
status
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
;
u8
slot_state
;
...
...
@@ -450,7 +442,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
static
int
hpc_get_latch_status
(
struct
slot
*
slot
,
u8
*
status
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
;
...
...
@@ -473,7 +465,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
static
int
hpc_get_adapter_status
(
struct
slot
*
slot
,
u8
*
status
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
;
u8
card_state
;
...
...
@@ -496,7 +488,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
static
int
hpc_get_prog_int
(
struct
slot
*
slot
,
u8
*
prog_int
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
DBG_ENTER_ROUTINE
...
...
@@ -513,7 +505,7 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
static
int
hpc_get_adapter_speed
(
struct
slot
*
slot
,
enum
pci_bus_speed
*
value
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
,
sec_bus_status
;
u8
m66_cap
,
pcix_cap
,
pi
;
...
...
@@ -594,7 +586,7 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
static
int
hpc_get_mode1_ECC_cap
(
struct
slot
*
slot
,
u8
*
mode
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u16
sec_bus_status
;
u8
pi
;
int
retval
=
0
;
...
...
@@ -623,7 +615,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
static
int
hpc_query_power_fault
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u32
slot_reg
;
u16
slot_status
;
u8
pwr_fault_state
,
status
;
...
...
@@ -647,7 +639,7 @@ static int hpc_query_power_fault(struct slot * slot)
static
int
hpc_set_attention_status
(
struct
slot
*
slot
,
u8
value
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
=
0
;
int
rc
=
0
;
...
...
@@ -683,7 +675,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
static
void
hpc_set_green_led_on
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
if
(
!
slot
->
ctrl
->
hpc_ctlr_handle
)
{
...
...
@@ -705,7 +697,7 @@ static void hpc_set_green_led_on(struct slot *slot)
static
void
hpc_set_green_led_off
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
if
(
!
slot
->
ctrl
->
hpc_ctlr_handle
)
{
...
...
@@ -727,7 +719,7 @@ static void hpc_set_green_led_off(struct slot *slot)
static
void
hpc_set_green_led_blink
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
if
(
!
slot
->
ctrl
->
hpc_ctlr_handle
)
{
...
...
@@ -754,7 +746,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl,
int
*
updown
,
/* physical_slot_num increament: 1 or -1 */
int
*
flags
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
ctrl
->
hpc_ctlr_handle
;
DBG_ENTER_ROUTINE
...
...
@@ -776,7 +768,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl,
static
void
hpc_release_ctlr
(
struct
controller
*
ctrl
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
p
,
*
p_prev
;
DBG_ENTER_ROUTINE
...
...
@@ -796,10 +788,8 @@ static void hpc_release_ctlr(struct controller *ctrl)
}
}
if
(
php_ctlr
->
pci_dev
)
{
dbg
(
"%s: before calling iounmap & release_mem_region
\n
"
,
__FUNCTION__
);
iounmap
(
php_ctlr
->
creg
);
release_mem_region
(
pci_resource_start
(
php_ctlr
->
pci_dev
,
0
),
pci_resource_len
(
php_ctlr
->
pci_dev
,
0
));
dbg
(
"%s: before calling iounmap & release_mem_region
\n
"
,
__FUNCTION__
);
php_ctlr
->
pci_dev
=
NULL
;
}
...
...
@@ -828,7 +818,7 @@ DBG_LEAVE_ROUTINE
static
int
hpc_power_on_slot
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
int
retval
=
0
;
...
...
@@ -859,7 +849,7 @@ static int hpc_power_on_slot(struct slot * slot)
static
int
hpc_slot_enable
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
int
retval
=
0
;
...
...
@@ -890,7 +880,7 @@ static int hpc_slot_enable(struct slot * slot)
static
int
hpc_slot_disable
(
struct
slot
*
slot
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
u8
slot_cmd
;
int
retval
=
0
;
...
...
@@ -920,51 +910,12 @@ static int hpc_slot_disable(struct slot * slot)
return
retval
;
}
static
int
hpc_enable_all_slots
(
struct
slot
*
slot
)
{
int
retval
=
0
;
DBG_ENTER_ROUTINE
if
(
!
slot
->
ctrl
->
hpc_ctlr_handle
)
{
err
(
"%s: Invalid HPC controller handle!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
retval
=
shpc_write_cmd
(
slot
,
0
,
SET_ENABLE_ALL
);
if
(
retval
)
{
err
(
"%s: Write command failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
DBG_LEAVE_ROUTINE
return
retval
;
}
static
int
hpc_pwr_on_all_slots
(
struct
slot
*
slot
)
{
int
retval
=
0
;
DBG_ENTER_ROUTINE
retval
=
shpc_write_cmd
(
slot
,
0
,
SET_PWR_ON_ALL
);
if
(
retval
)
{
err
(
"%s: Write command failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
DBG_LEAVE_ROUTINE
return
retval
;
}
static
int
hpc_set_bus_speed_mode
(
struct
slot
*
slot
,
enum
pci_bus_speed
value
)
{
u8
slot_cmd
;
u8
pi
;
int
retval
=
0
;
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
DBG_ENTER_ROUTINE
...
...
@@ -1089,18 +1040,13 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if
(
!
intr_loc
)
return
IRQ_NONE
;
dbg
(
"%s: shpc_isr proceeds
\n
"
,
__FUNCTION__
);
dbg
(
"%s: intr_loc = %x
\n
"
,
__FUNCTION__
,
intr_loc
);
if
(
!
shpchp_poll_mode
)
{
/* Mask Global Interrupt Mask - see implementation note on p. 139 */
/* of SHPC spec rev 1.0*/
temp_dword
=
readl
(
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
dbg
(
"%s: Before masking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
temp_dword
|=
0x00000001
;
dbg
(
"%s: After masking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
writel
(
temp_dword
,
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
intr_loc2
=
readl
(
php_ctlr
->
creg
+
INTR_LOC
);
...
...
@@ -1114,11 +1060,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
* Detect bit in Controller SERR-INT register
*/
temp_dword
=
readl
(
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
dbg
(
"%s: Before clearing CCIP, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
temp_dword
&=
0xfffeffff
;
dbg
(
"%s: After clearing CCIP, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
writel
(
temp_dword
,
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
wake_up_interruptible
(
&
ctrl
->
queue
);
}
...
...
@@ -1126,11 +1068,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if
((
intr_loc
=
(
intr_loc
>>
1
))
==
0
)
{
/* Unmask Global Interrupt Mask */
temp_dword
=
readl
(
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
dbg
(
"%s: 1-Before unmasking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
temp_dword
&=
0xfffffffe
;
dbg
(
"%s: 1-After unmasking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
writel
(
temp_dword
,
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
return
IRQ_NONE
;
...
...
@@ -1140,11 +1078,9 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* To find out which slot has interrupt pending */
if
((
intr_loc
>>
hp_slot
)
&
0x01
)
{
temp_dword
=
readl
(
php_ctlr
->
creg
+
SLOT1
+
(
4
*
hp_slot
));
dbg
(
"%s: Slot %x with intr,
temp_dword
= %x
\n
"
,
dbg
(
"%s: Slot %x with intr,
slot register
= %x
\n
"
,
__FUNCTION__
,
hp_slot
,
temp_dword
);
temp_byte
=
(
temp_dword
>>
16
)
&
0xFF
;
dbg
(
"%s: Slot with intr, temp_byte = %x
\n
"
,
__FUNCTION__
,
temp_byte
);
if
((
php_ctlr
->
switch_change_callback
)
&&
(
temp_byte
&
0x08
))
schedule_flag
+=
php_ctlr
->
switch_change_callback
(
hp_slot
,
php_ctlr
->
callback_instance_id
);
...
...
@@ -1160,8 +1096,6 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear all slot events */
temp_dword
=
0xe01f3fff
;
dbg
(
"%s: Clearing slot events, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
writel
(
temp_dword
,
php_ctlr
->
creg
+
SLOT1
+
(
4
*
hp_slot
));
intr_loc2
=
readl
(
php_ctlr
->
creg
+
INTR_LOC
);
...
...
@@ -1171,11 +1105,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if
(
!
shpchp_poll_mode
)
{
/* Unmask Global Interrupt Mask */
temp_dword
=
readl
(
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
dbg
(
"%s: 2-Before unmasking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
temp_dword
&=
0xfffffffe
;
dbg
(
"%s: 2-After unmasking global interrupt, temp_dword = %x
\n
"
,
__FUNCTION__
,
temp_dword
);
writel
(
temp_dword
,
php_ctlr
->
creg
+
SERR_INTR_ENABLE
);
}
...
...
@@ -1184,7 +1114,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
static
int
hpc_get_max_bus_speed
(
struct
slot
*
slot
,
enum
pci_bus_speed
*
value
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
enum
pci_bus_speed
bus_speed
=
PCI_SPEED_UNKNOWN
;
int
retval
=
0
;
u8
pi
;
...
...
@@ -1253,7 +1183,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
static
int
hpc_get_cur_bus_speed
(
struct
slot
*
slot
,
enum
pci_bus_speed
*
value
)
{
struct
php_ctlr_state_s
*
php_ctlr
=
(
struct
php_ctlr_state_s
*
)
slot
->
ctrl
->
hpc_ctlr_handle
;
struct
php_ctlr_state_s
*
php_ctlr
=
slot
->
ctrl
->
hpc_ctlr_handle
;
enum
pci_bus_speed
bus_speed
=
PCI_SPEED_UNKNOWN
;
u16
sec_bus_status
;
int
retval
=
0
;
...
...
@@ -1367,8 +1297,6 @@ static struct hpc_ops shpchp_hpc_ops = {
.
power_on_slot
=
hpc_power_on_slot
,
.
slot_enable
=
hpc_slot_enable
,
.
slot_disable
=
hpc_slot_disable
,
.
enable_all_slots
=
hpc_enable_all_slots
,
.
pwr_on_all_slots
=
hpc_pwr_on_all_slots
,
.
set_bus_speed_mode
=
hpc_set_bus_speed_mode
,
.
set_attention_status
=
hpc_set_attention_status
,
.
get_power_status
=
hpc_get_power_status
,
...
...
@@ -1391,12 +1319,7 @@ static struct hpc_ops shpchp_hpc_ops = {
.
check_cmd_status
=
hpc_check_cmd_status
,
};
int
shpc_init
(
struct
controller
*
ctrl
,
struct
pci_dev
*
pdev
,
php_intr_callback_t
attention_button_callback
,
php_intr_callback_t
switch_change_callback
,
php_intr_callback_t
presence_change_callback
,
php_intr_callback_t
power_fault_callback
)
int
shpc_init
(
struct
controller
*
ctrl
,
struct
pci_dev
*
pdev
)
{
struct
php_ctlr_state_s
*
php_ctlr
,
*
p
;
void
*
instance_id
=
ctrl
;
...
...
@@ -1405,7 +1328,6 @@ int shpc_init(struct controller * ctrl,
static
int
first
=
1
;
u32
shpc_cap_offset
,
shpc_base_offset
;
u32
tempdword
,
slot_reg
;
u16
vendor_id
,
device_id
;
u8
i
;
DBG_ENTER_ROUTINE
...
...
@@ -1422,21 +1344,8 @@ int shpc_init(struct controller * ctrl,
php_ctlr
->
pci_dev
=
pdev
;
/* save pci_dev in context */
rc
=
pci_read_config_word
(
pdev
,
PCI_VENDOR_ID
,
&
vendor_id
);
dbg
(
"%s: Vendor ID: %x
\n
"
,
__FUNCTION__
,
vendor_id
);
if
(
rc
)
{
err
(
"%s: unable to read PCI configuration data
\n
"
,
__FUNCTION__
);
goto
abort_free_ctlr
;
}
rc
=
pci_read_config_word
(
pdev
,
PCI_DEVICE_ID
,
&
device_id
);
dbg
(
"%s: Device ID: %x
\n
"
,
__FUNCTION__
,
device_id
);
if
(
rc
)
{
err
(
"%s: unable to read PCI configuration data
\n
"
,
__FUNCTION__
);
goto
abort_free_ctlr
;
}
if
((
vendor_id
==
PCI_VENDOR_ID_AMD
)
||
(
device_id
==
PCI_DEVICE_ID_AMD_GOLAM_7450
))
{
if
((
pdev
->
vendor
==
PCI_VENDOR_ID_AMD
)
||
(
pdev
->
device
==
PCI_DEVICE_ID_AMD_GOLAM_7450
))
{
shpc_base_offset
=
0
;
/* amd shpc driver doesn't use this; assume 0 */
}
else
{
if
((
shpc_cap_offset
=
pci_find_capability
(
pdev
,
PCI_CAP_ID_SHPC
))
==
0
)
{
...
...
@@ -1469,7 +1378,8 @@ int shpc_init(struct controller * ctrl,
err
(
"%s : pci_read_config_dword failed
\n
"
,
__FUNCTION__
);
goto
abort_free_ctlr
;
}
dbg
(
"%s: offset %d: tempdword %x
\n
"
,
__FUNCTION__
,
i
,
tempdword
);
dbg
(
"%s: offset %d: value %x
\n
"
,
__FUNCTION__
,
i
,
tempdword
);
}
}
...
...
@@ -1478,13 +1388,6 @@ int shpc_init(struct controller * ctrl,
first
=
0
;
}
dbg
(
"pdev = %p: b:d:f:irq=0x%x:%x:%x:%x
\n
"
,
pdev
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
),
pdev
->
irq
);
for
(
rc
=
0
;
rc
<
DEVICE_COUNT_RESOURCE
;
rc
++
)
if
(
pci_resource_len
(
pdev
,
rc
)
>
0
)
dbg
(
"pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x
\n
"
,
rc
,
pci_resource_start
(
pdev
,
rc
),
pci_resource_len
(
pdev
,
rc
),
shpc_base_offset
);
info
(
"HPC vendor_id %x device_id %x ss_vid %x ss_did %x
\n
"
,
pdev
->
vendor
,
pdev
->
device
,
pdev
->
subsystem_vendor
,
pdev
->
subsystem_device
);
...
...
@@ -1504,7 +1407,6 @@ int shpc_init(struct controller * ctrl,
goto
abort_free_ctlr
;
}
dbg
(
"%s: php_ctlr->creg %p
\n
"
,
__FUNCTION__
,
php_ctlr
->
creg
);
dbg
(
"%s: physical addr %p
\n
"
,
__FUNCTION__
,
(
void
*
)
pci_resource_start
(
pdev
,
0
));
init_MUTEX
(
&
ctrl
->
crit_sect
);
/* Setup wait queue */
...
...
@@ -1512,13 +1414,10 @@ int shpc_init(struct controller * ctrl,
/* Find the IRQ */
php_ctlr
->
irq
=
pdev
->
irq
;
dbg
(
"HPC interrupt = %d
\n
"
,
php_ctlr
->
irq
);
/* Save interrupt callback info */
php_ctlr
->
attention_button_callback
=
attention_button_callback
;
php_ctlr
->
switch_change_callback
=
switch_change_callback
;
php_ctlr
->
presence_change_callback
=
presence_change_callback
;
php_ctlr
->
power_fault_callback
=
power_fault_callback
;
php_ctlr
->
attention_button_callback
=
shpchp_handle_attention_button
,
php_ctlr
->
switch_change_callback
=
shpchp_handle_switch_change
;
php_ctlr
->
presence_change_callback
=
shpchp_handle_presence_change
;
php_ctlr
->
power_fault_callback
=
shpchp_handle_power_fault
;
php_ctlr
->
callback_instance_id
=
instance_id
;
/* Return PCI Controller Info */
...
...
@@ -1556,7 +1455,6 @@ int shpc_init(struct controller * ctrl,
if
(
rc
)
{
info
(
"Can't get msi for the hotplug controller
\n
"
);
info
(
"Use INTx for the hotplug controller
\n
"
);
dbg
(
"%s: rc = %x
\n
"
,
__FUNCTION__
,
rc
);
}
else
php_ctlr
->
irq
=
pdev
->
irq
;
...
...
@@ -1566,9 +1464,11 @@ int shpc_init(struct controller * ctrl,
err
(
"Can't get irq %d for the hotplug controller
\n
"
,
php_ctlr
->
irq
);
goto
abort_free_ctlr
;
}
/* Execute OSHP method here */
}
dbg
(
"%s: Before adding HPC to HPC list
\n
"
,
__FUNCTION__
);
dbg
(
"%s: HPC at b:d:f:irq=0x%x:%x:%x:%x
\n
"
,
__FUNCTION__
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
),
pdev
->
irq
);
get_hp_hw_control_from_firmware
(
pdev
);
/* Add this HPC instance into the HPC list */
spin_lock
(
&
list_lock
);
...
...
@@ -1607,7 +1507,6 @@ int shpc_init(struct controller * ctrl,
dbg
(
"%s: SERR_INTR_ENABLE = %x
\n
"
,
__FUNCTION__
,
tempdword
);
}
dbg
(
"%s: Leaving shpc_init
\n
"
,
__FUNCTION__
);
DBG_LEAVE_ROUTINE
return
0
;
...
...
drivers/pci/hotplug/shpchp_pci.c
View file @
7efe5d7c
...
...
@@ -27,784 +27,151 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include "../pci.h"
#include "shpchp.h"
#ifndef CONFIG_IA64
#include "../../../arch/i386/pci/pci.h"
/* horrible hack showing how processor dependant we are... */
#endif
int
shpchp_configure_device
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
)
void
program_fw_provided_values
(
struct
pci_dev
*
dev
)
{
unsigned
char
bus
;
struct
pci_bus
*
child
;
int
num
;
if
(
func
->
pci_dev
==
NULL
)
func
->
pci_dev
=
pci_find_slot
(
func
->
bus
,
PCI_DEVFN
(
func
->
device
,
func
->
function
));
/* Still NULL ? Well then scan for it ! */
if
(
func
->
pci_dev
==
NULL
)
{
num
=
pci_scan_slot
(
ctrl
->
pci_dev
->
subordinate
,
PCI_DEVFN
(
func
->
device
,
func
->
function
));
if
(
num
)
{
dbg
(
"%s: subordiante %p number %x
\n
"
,
__FUNCTION__
,
ctrl
->
pci_dev
->
subordinate
,
ctrl
->
pci_dev
->
subordinate
->
number
);
pci_bus_add_devices
(
ctrl
->
pci_dev
->
subordinate
);
}
func
->
pci_dev
=
pci_find_slot
(
func
->
bus
,
PCI_DEVFN
(
func
->
device
,
func
->
function
));
if
(
func
->
pci_dev
==
NULL
)
{
dbg
(
"ERROR: pci_dev still null
\n
"
);
return
0
;
}
}
if
(
func
->
pci_dev
->
hdr_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
pci_read_config_byte
(
func
->
pci_dev
,
PCI_SECONDARY_BUS
,
&
bus
);
child
=
pci_add_new_bus
(
func
->
pci_dev
->
bus
,
(
func
->
pci_dev
),
bus
);
pci_do_scan_bus
(
child
);
}
return
0
;
}
int
shpchp_unconfigure_device
(
struct
pci_func
*
func
)
{
int
rc
=
0
;
int
j
;
dbg
(
"%s: bus/dev/func = %x/%x/%x
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
for
(
j
=
0
;
j
<
8
;
j
++
)
{
struct
pci_dev
*
temp
=
pci_find_slot
(
func
->
bus
,
(
func
->
device
<<
3
)
|
j
);
if
(
temp
)
{
pci_remove_bus_device
(
temp
);
u16
pci_cmd
,
pci_bctl
;
struct
pci_dev
*
cdev
;
struct
hotplug_params
hpp
=
{
0x8
,
0x40
,
0
,
0
};
/* defaults */
/* Program hpp values for this device */
if
(
!
(
dev
->
hdr_type
==
PCI_HEADER_TYPE_NORMAL
||
(
dev
->
hdr_type
==
PCI_HEADER_TYPE_BRIDGE
&&
(
dev
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)))
return
;
get_hp_params_from_firmware
(
dev
,
&
hpp
);
pci_write_config_byte
(
dev
,
PCI_CACHE_LINE_SIZE
,
hpp
.
cache_line_size
);
pci_write_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
hpp
.
latency_timer
);
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
pci_cmd
);
if
(
hpp
.
enable_serr
)
pci_cmd
|=
PCI_COMMAND_SERR
;
else
pci_cmd
&=
~
PCI_COMMAND_SERR
;
if
(
hpp
.
enable_perr
)
pci_cmd
|=
PCI_COMMAND_PARITY
;
else
pci_cmd
&=
~
PCI_COMMAND_PARITY
;
pci_write_config_word
(
dev
,
PCI_COMMAND
,
pci_cmd
);
/* Program bridge control value and child devices */
if
((
dev
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)
{
pci_write_config_byte
(
dev
,
PCI_SEC_LATENCY_TIMER
,
hpp
.
latency_timer
);
pci_read_config_word
(
dev
,
PCI_BRIDGE_CONTROL
,
&
pci_bctl
);
if
(
hpp
.
enable_serr
)
pci_bctl
|=
PCI_BRIDGE_CTL_SERR
;
else
pci_bctl
&=
~
PCI_BRIDGE_CTL_SERR
;
if
(
hpp
.
enable_perr
)
pci_bctl
|=
PCI_BRIDGE_CTL_PARITY
;
else
pci_bctl
&=
~
PCI_BRIDGE_CTL_PARITY
;
pci_write_config_word
(
dev
,
PCI_BRIDGE_CONTROL
,
pci_bctl
);
if
(
dev
->
subordinate
)
{
list_for_each_entry
(
cdev
,
&
dev
->
subordinate
->
devices
,
bus_list
)
program_fw_provided_values
(
cdev
);
}
}
return
rc
;
}
/*
* shpchp_set_irq
*
* @bus_num: bus number of PCI device
* @dev_num: device number of PCI device
* @slot: pointer to u8 where slot number will be returned
*/
int
shpchp_set_irq
(
u8
bus_num
,
u8
dev_num
,
u8
int_pin
,
u8
irq_num
)
{
#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
int
rc
;
u16
temp_word
;
struct
pci_dev
fakedev
;
struct
pci_bus
fakebus
;
fakedev
.
devfn
=
dev_num
<<
3
;
fakedev
.
bus
=
&
fakebus
;
fakebus
.
number
=
bus_num
;
dbg
(
"%s: dev %d, bus %d, pin %d, num %d
\n
"
,
__FUNCTION__
,
dev_num
,
bus_num
,
int_pin
,
irq_num
);
rc
=
pcibios_set_irq_routing
(
&
fakedev
,
int_pin
-
0x0a
,
irq_num
);
dbg
(
"%s: rc %d
\n
"
,
__FUNCTION__
,
rc
);
if
(
!
rc
)
return
!
rc
;
/* set the Edge Level Control Register (ELCR) */
temp_word
=
inb
(
0x4d0
);
temp_word
|=
inb
(
0x4d1
)
<<
8
;
temp_word
|=
0x01
<<
irq_num
;
/* This should only be for x86 as it sets the Edge Level Control Register */
outb
((
u8
)
(
temp_word
&
0xFF
),
0x4d0
);
outb
((
u8
)
((
temp_word
&
0xFF00
)
>>
8
),
0x4d1
);
#endif
return
0
;
}
/* More PCI configuration routines; this time centered around hotplug controller */
/*
* shpchp_save_config
*
* Reads configuration for all slots in a PCI bus and saves info.
*
* Note: For non-hot plug busses, the slot # saved is the device #
*
* returns 0 if success
*/
int
shpchp_save_config
(
struct
controller
*
ctrl
,
int
busnumber
,
int
num_ctlr_slots
,
int
first_device_num
)
int
shpchp_configure_device
(
struct
slot
*
p_slot
)
{
int
rc
;
u8
class_code
;
u8
header_type
;
u32
ID
;
u8
secondary_bus
;
struct
pci_func
*
new_slot
;
int
sub_bus
;
int
FirstSupported
;
int
LastSupported
;
int
max_functions
;
int
function
;
u8
DevError
;
int
device
=
0
;
int
cloop
=
0
;
int
stop_it
;
int
index
;
int
is_hot_plug
=
num_ctlr_slots
||
first_device_num
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
dbg
(
"%s: num_ctlr_slots = %d, first_device_num = %d
\n
"
,
__FUNCTION__
,
num_ctlr_slots
,
first_device_num
);
memcpy
(
&
lpci_bus
,
ctrl
->
pci_dev
->
subordinate
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
dbg
(
"%s: num_ctlr_slots = %d, first_device_num = %d
\n
"
,
__FUNCTION__
,
num_ctlr_slots
,
first_device_num
);
/* Decide which slots are supported */
if
(
is_hot_plug
)
{
/*********************************
* is_hot_plug is the slot mask
*********************************/
FirstSupported
=
first_device_num
;
LastSupported
=
FirstSupported
+
num_ctlr_slots
-
1
;
}
else
{
FirstSupported
=
0
;
LastSupported
=
0x1F
;
}
dbg
(
"FirstSupported = %d, LastSupported = %d
\n
"
,
FirstSupported
,
LastSupported
);
/* Save PCI configuration space for all devices in supported slots */
pci_bus
->
number
=
busnumber
;
for
(
device
=
FirstSupported
;
device
<=
LastSupported
;
device
++
)
{
ID
=
0xFFFFFFFF
;
rc
=
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
device
,
0
),
PCI_VENDOR_ID
,
&
ID
);
if
(
ID
!=
0xFFFFFFFF
)
{
/* device in slot */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
device
,
0
),
0x0B
,
&
class_code
);
if
(
rc
)
return
rc
;
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
device
,
0
),
PCI_HEADER_TYPE
,
&
header_type
);
if
(
rc
)
return
rc
;
dbg
(
"class_code = %x, header_type = %x
\n
"
,
class_code
,
header_type
);
/* If multi-function device, set max_functions to 8 */
if
(
header_type
&
0x80
)
max_functions
=
8
;
else
max_functions
=
1
;
function
=
0
;
do
{
DevError
=
0
;
if
((
header_type
&
0x7F
)
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* P-P Bridge */
/* Recurse the subordinate bus
* get the subordinate bus number
*/
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
device
,
function
),
PCI_SECONDARY_BUS
,
&
secondary_bus
);
if
(
rc
)
{
return
rc
;
}
else
{
sub_bus
=
(
int
)
secondary_bus
;
/* Save secondary bus cfg spc with this recursive call. */
rc
=
shpchp_save_config
(
ctrl
,
sub_bus
,
0
,
0
);
if
(
rc
)
return
rc
;
}
}
index
=
0
;
new_slot
=
shpchp_slot_find
(
busnumber
,
device
,
index
++
);
struct
pci_dev
*
dev
;
struct
pci_bus
*
parent
=
p_slot
->
ctrl
->
pci_dev
->
subordinate
;
int
num
,
fn
;
dbg
(
"new_slot = %p
\n
"
,
new_slot
);
while
(
new_slot
&&
(
new_slot
->
function
!=
(
u8
)
function
))
{
new_slot
=
shpchp_slot_find
(
busnumber
,
device
,
index
++
);
dbg
(
"new_slot = %p
\n
"
,
new_slot
);
}
if
(
!
new_slot
)
{
/* Setup slot structure. */
new_slot
=
shpchp_slot_create
(
busnumber
);
dbg
(
"new_slot = %p
\n
"
,
new_slot
);
if
(
new_slot
==
NULL
)
return
(
1
);
}
new_slot
->
bus
=
(
u8
)
busnumber
;
new_slot
->
device
=
(
u8
)
device
;
new_slot
->
function
=
(
u8
)
function
;
new_slot
->
is_a_board
=
1
;
new_slot
->
switch_save
=
0x10
;
new_slot
->
pwr_save
=
1
;
/* In case of unsupported board */
new_slot
->
status
=
DevError
;
new_slot
->
pci_dev
=
pci_find_slot
(
new_slot
->
bus
,
(
new_slot
->
device
<<
3
)
|
new_slot
->
function
);
dbg
(
"new_slot->pci_dev = %p
\n
"
,
new_slot
->
pci_dev
);
for
(
cloop
=
0
;
cloop
<
0x20
;
cloop
++
)
{
rc
=
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
device
,
function
),
cloop
<<
2
,
(
u32
*
)
&
(
new_slot
->
config_space
[
cloop
]));
/* dbg("new_slot->config_space[%x] = %x\n",
cloop, new_slot->config_space[cloop]); */
if
(
rc
)
return
rc
;
dev
=
pci_find_slot
(
p_slot
->
bus
,
PCI_DEVFN
(
p_slot
->
device
,
0
));
if
(
dev
)
{
err
(
"Device %s already exists at %x:%x, cannot hot-add
\n
"
,
pci_name
(
dev
),
p_slot
->
bus
,
p_slot
->
device
);
return
-
EINVAL
;
}
function
++
;
stop_it
=
0
;
/* this loop skips to the next present function
* reading in Class Code and Header type.
*/
while
((
function
<
max_functions
)
&&
(
!
stop_it
))
{
rc
=
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
device
,
function
),
PCI_VENDOR_ID
,
&
ID
);
if
(
ID
==
0xFFFFFFFF
)
{
/* nothing there. */
function
++
;
dbg
(
"Nothing there
\n
"
);
}
else
{
/* Something there */
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
device
,
function
),
0x0B
,
&
class_code
);
if
(
rc
)
return
rc
;
rc
=
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
device
,
function
),
PCI_HEADER_TYPE
,
&
header_type
);
if
(
rc
)
return
rc
;
dbg
(
"class_code = %x, header_type = %x
\n
"
,
class_code
,
header_type
);
stop_it
++
;
num
=
pci_scan_slot
(
parent
,
PCI_DEVFN
(
p_slot
->
device
,
0
));
if
(
num
==
0
)
{
err
(
"No new device found
\n
"
);
return
-
ENODEV
;
}
}
}
while
(
function
<
max_functions
);
/* End of IF (device in slot?) */
}
else
if
(
is_hot_plug
)
{
/* Setup slot structure with entry for empty slot */
new_slot
=
shpchp_slot_create
(
busnumber
);
if
(
new_slot
==
NULL
)
{
return
(
1
);
for
(
fn
=
0
;
fn
<
8
;
fn
++
)
{
if
(
!
(
dev
=
pci_find_slot
(
p_slot
->
bus
,
PCI_DEVFN
(
p_slot
->
device
,
fn
))))
continue
;
if
((
dev
->
class
>>
16
)
==
PCI_BASE_CLASS_DISPLAY
)
{
err
(
"Cannot hot-add display device %s
\n
"
,
pci_name
(
dev
));
continue
;
}
dbg
(
"new_slot = %p
\n
"
,
new_slot
);
new_slot
->
bus
=
(
u8
)
busnumber
;
new_slot
->
device
=
(
u8
)
device
;
new_slot
->
function
=
0
;
new_slot
->
is_a_board
=
0
;
new_slot
->
presence_save
=
0
;
new_slot
->
switch_save
=
0
;
if
((
dev
->
hdr_type
==
PCI_HEADER_TYPE_BRIDGE
)
||
(
dev
->
hdr_type
==
PCI_HEADER_TYPE_CARDBUS
))
{
/* Find an unused bus number for the new bridge */
struct
pci_bus
*
child
;
unsigned
char
busnr
,
start
=
parent
->
secondary
;
unsigned
char
end
=
parent
->
subordinate
;
for
(
busnr
=
start
;
busnr
<=
end
;
busnr
++
)
{
if
(
!
pci_find_bus
(
pci_domain_nr
(
parent
),
busnr
))
break
;
}
}
/* End of FOR loop */
return
(
0
);
}
/*
* shpchp_save_slot_config
*
* Saves configuration info for all PCI devices in a given slot
* including subordinate busses.
*
* returns 0 if success
*/
int
shpchp_save_slot_config
(
struct
controller
*
ctrl
,
struct
pci_func
*
new_slot
)
{
int
rc
;
u8
class_code
;
u8
header_type
;
u32
ID
;
u8
secondary_bus
;
int
sub_bus
;
int
max_functions
;
int
function
;
int
cloop
=
0
;
int
stop_it
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_dev
->
subordinate
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
new_slot
->
bus
;
ID
=
0xFFFFFFFF
;
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
0
),
PCI_VENDOR_ID
,
&
ID
);
if
(
ID
!=
0xFFFFFFFF
)
{
/* device in slot */
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
0
),
0x0B
,
&
class_code
);
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
0
),
PCI_HEADER_TYPE
,
&
header_type
);
if
(
header_type
&
0x80
)
/* Multi-function device */
max_functions
=
8
;
else
max_functions
=
1
;
function
=
0
;
do
{
if
((
header_type
&
0x7F
)
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* PCI-PCI Bridge */
/* Recurse the subordinate bus */
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
function
),
PCI_SECONDARY_BUS
,
&
secondary_bus
);
sub_bus
=
(
int
)
secondary_bus
;
/* Save the config headers for the secondary bus. */
rc
=
shpchp_save_config
(
ctrl
,
sub_bus
,
0
,
0
);
if
(
rc
)
return
rc
;
}
/* End of IF */
new_slot
->
status
=
0
;
for
(
cloop
=
0
;
cloop
<
0x20
;
cloop
++
)
{
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
function
),
cloop
<<
2
,
(
u32
*
)
&
(
new_slot
->
config_space
[
cloop
]));
if
(
busnr
>=
end
)
{
err
(
"No free bus for hot-added bridge
\n
"
);
continue
;
}
function
++
;
stop_it
=
0
;
/* this loop skips to the next present function
* reading in the Class Code and the Header type.
*/
while
((
function
<
max_functions
)
&&
(
!
stop_it
))
{
pci_bus_read_config_dword
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
function
),
PCI_VENDOR_ID
,
&
ID
);
if
(
ID
==
0xFFFFFFFF
)
{
/* nothing there. */
function
++
;
}
else
{
/* Something there */
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
function
),
0x0B
,
&
class_code
);
pci_bus_read_config_byte
(
pci_bus
,
PCI_DEVFN
(
new_slot
->
device
,
function
),
PCI_HEADER_TYPE
,
&
header_type
);
stop_it
++
;
child
=
pci_add_new_bus
(
parent
,
dev
,
busnr
);
if
(
!
child
)
{
err
(
"Cannot add new bus for %s
\n
"
,
pci_name
(
dev
));
continue
;
}
child
->
subordinate
=
pci_do_scan_bus
(
child
);
pci_bus_size_bridges
(
child
);
}
}
while
(
function
<
max_functions
);
}
/* End of IF (device in slot?) */
else
{
return
2
;
program_fw_provided_values
(
dev
);
}
pci_bus_assign_resources
(
parent
);
pci_bus_add_devices
(
parent
);
pci_enable_bridges
(
parent
);
return
0
;
}
/*
* shpchp_save_used_resources
*
* Stores used resource information for existing boards. this is
* for boards that were in the system when this driver was loaded.
* this function is for hot plug ADD
*
* returns 0 if success
* if disable == 1(DISABLE_CARD),
* it loops for all functions of the slot and disables them.
* else, it just get resources of the function and return.
*/
int
shpchp_save_used_resources
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
int
disable
)
int
shpchp_unconfigure_device
(
struct
slot
*
p_slot
)
{
u8
cloop
;
u8
header_type
;
u8
secondary_bus
;
u8
temp_byte
;
u16
command
;
u16
save_command
;
u16
w_base
,
w_length
;
u32
temp_register
;
u32
save_base
;
u32
base
,
length
;
u64
base64
=
0
;
int
index
=
0
;
unsigned
int
devfn
;
struct
pci_resource
*
mem_node
=
NULL
;
struct
pci_resource
*
p_mem_node
=
NULL
;
struct
pci_resource
*
t_mem_node
;
struct
pci_resource
*
io_node
;
struct
pci_resource
*
bus_node
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_dev
->
subordinate
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
if
(
disable
)
func
=
shpchp_slot_find
(
func
->
bus
,
func
->
device
,
index
++
);
while
((
func
!=
NULL
)
&&
func
->
is_a_board
)
{
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
/* Save the command register */
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
&
save_command
);
if
(
disable
)
{
/* disable card */
command
=
0x00
;
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
command
);
}
/* Check for Bridge */
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_HEADER_TYPE
,
&
header_type
);
if
((
header_type
&
0x7F
)
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* PCI-PCI Bridge */
dbg
(
"Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x
\n
"
,
func
->
bus
,
func
->
device
,
save_command
);
if
(
disable
)
{
/* Clear Bridge Control Register */
command
=
0x00
;
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
command
);
}
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_SECONDARY_BUS
,
&
secondary_bus
);
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_SUBORDINATE_BUS
,
&
temp_byte
);
bus_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
bus_node
)
return
-
ENOMEM
;
bus_node
->
base
=
(
ulong
)
secondary_bus
;
bus_node
->
length
=
(
ulong
)(
temp_byte
-
secondary_bus
+
1
);
bus_node
->
next
=
func
->
bus_head
;
func
->
bus_head
=
bus_node
;
/* Save IO base and Limit registers */
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_IO_BASE
,
&
temp_byte
);
base
=
temp_byte
;
pci_bus_read_config_byte
(
pci_bus
,
devfn
,
PCI_IO_LIMIT
,
&
temp_byte
);
length
=
temp_byte
;
if
((
base
<=
length
)
&&
(
!
disable
||
(
save_command
&
PCI_COMMAND_IO
)))
{
io_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
io_node
)
return
-
ENOMEM
;
io_node
->
base
=
(
ulong
)(
base
&
PCI_IO_RANGE_MASK
)
<<
8
;
io_node
->
length
=
(
ulong
)(
length
-
base
+
0x10
)
<<
8
;
io_node
->
next
=
func
->
io_head
;
func
->
io_head
=
io_node
;
}
/* Save memory base and Limit registers */
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_BASE
,
&
w_base
);
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_MEMORY_LIMIT
,
&
w_length
);
if
((
w_base
<=
w_length
)
&&
(
!
disable
||
(
save_command
&
PCI_COMMAND_MEMORY
)))
{
mem_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
mem_node
)
return
-
ENOMEM
;
mem_node
->
base
=
(
ulong
)
w_base
<<
16
;
mem_node
->
length
=
(
ulong
)(
w_length
-
w_base
+
0x10
)
<<
16
;
mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
mem_node
;
}
/* Save prefetchable memory base and Limit registers */
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_BASE
,
&
w_base
);
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_PREF_MEMORY_LIMIT
,
&
w_length
);
if
((
w_base
<=
w_length
)
&&
(
!
disable
||
(
save_command
&
PCI_COMMAND_MEMORY
)))
{
p_mem_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
p_mem_node
)
return
-
ENOMEM
;
p_mem_node
->
base
=
(
ulong
)
w_base
<<
16
;
p_mem_node
->
length
=
(
ulong
)(
w_length
-
w_base
+
0x10
)
<<
16
;
p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
p_mem_node
;
}
}
else
if
((
header_type
&
0x7F
)
==
PCI_HEADER_TYPE_NORMAL
)
{
dbg
(
"Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x
\n
"
,
func
->
bus
,
func
->
device
,
save_command
);
/* Figure out IO and memory base lengths */
for
(
cloop
=
PCI_BASE_ADDRESS_0
;
cloop
<=
PCI_BASE_ADDRESS_5
;
cloop
+=
4
)
{
pci_bus_read_config_dword
(
pci_bus
,
devfn
,
cloop
,
&
save_base
);
temp_register
=
0xFFFFFFFF
;
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
temp_register
);
pci_bus_read_config_dword
(
pci_bus
,
devfn
,
cloop
,
&
temp_register
);
int
rc
=
0
;
int
j
;
u8
bctl
=
0
;
if
(
!
disable
)
pci_bus_write_config_dword
(
pci_bus
,
devfn
,
cloop
,
save_base
);
dbg
(
"%s: bus/dev = %x/%x
\n
"
,
__FUNCTION__
,
p_slot
->
bus
,
p_slot
->
device
);
if
(
!
temp_register
)
for
(
j
=
0
;
j
<
8
;
j
++
)
{
struct
pci_dev
*
temp
=
pci_find_slot
(
p_slot
->
bus
,
(
p_slot
->
device
<<
3
)
|
j
);
if
(
!
temp
)
continue
;
if
((
temp
->
class
>>
16
)
==
PCI_BASE_CLASS_DISPLAY
)
{
err
(
"Cannot remove display device %s
\n
"
,
pci_name
(
temp
));
continue
;
base
=
temp_register
;
if
((
base
&
PCI_BASE_ADDRESS_SPACE_IO
)
&&
(
!
disable
||
(
save_command
&
PCI_COMMAND_IO
)))
{
/* IO base */
/* set temp_register = amount of IO space requested */
base
=
base
&
0xFFFFFFFCL
;
base
=
(
~
base
)
+
1
;
io_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
io_node
)
return
-
ENOMEM
;
io_node
->
base
=
(
ulong
)
save_base
&
PCI_BASE_ADDRESS_IO_MASK
;
io_node
->
length
=
(
ulong
)
base
;
dbg
(
"sur adapter: IO bar=0x%x(length=0x%x)
\n
"
,
io_node
->
base
,
io_node
->
length
);
io_node
->
next
=
func
->
io_head
;
func
->
io_head
=
io_node
;
}
else
{
/* map Memory */
int
prefetchable
=
1
;
/* struct pci_resources **res_node; */
char
*
res_type_str
=
"PMEM"
;
u32
temp_register2
;
t_mem_node
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
t_mem_node
)
return
-
ENOMEM
;
if
(
!
(
base
&
PCI_BASE_ADDRESS_MEM_PREFETCH
)
&&
(
!
disable
||
(
save_command
&
PCI_COMMAND_MEMORY
)))
{
prefetchable
=
0
;
mem_node
=
t_mem_node
;
res_type_str
++
;
}
else
p_mem_node
=
t_mem_node
;
base
=
base
&
0xFFFFFFF0L
;
base
=
(
~
base
)
+
1
;
switch
(
temp_register
&
PCI_BASE_ADDRESS_MEM_TYPE_MASK
)
{
case
PCI_BASE_ADDRESS_MEM_TYPE_32
:
if
(
prefetchable
)
{
p_mem_node
->
base
=
(
ulong
)
save_base
&
PCI_BASE_ADDRESS_MEM_MASK
;
p_mem_node
->
length
=
(
ulong
)
base
;
dbg
(
"sur adapter: 32 %s bar=0x%x(length=0x%x)
\n
"
,
res_type_str
,
p_mem_node
->
base
,
p_mem_node
->
length
);
p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
p_mem_node
;
}
else
{
mem_node
->
base
=
(
ulong
)
save_base
&
PCI_BASE_ADDRESS_MEM_MASK
;
mem_node
->
length
=
(
ulong
)
base
;
dbg
(
"sur adapter: 32 %s bar=0x%x(length=0x%x)
\n
"
,
res_type_str
,
mem_node
->
base
,
mem_node
->
length
);
mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
mem_node
;
}
break
;
case
PCI_BASE_ADDRESS_MEM_TYPE_64
:
pci_bus_read_config_dword
(
pci_bus
,
devfn
,
cloop
+
4
,
&
temp_register2
);
base64
=
temp_register2
;
base64
=
(
base64
<<
32
)
|
save_base
;
if
(
temp_register2
)
{
dbg
(
"sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0
\n
"
,
res_type_str
,
temp_register2
,
(
u32
)
base64
);
base64
&=
0x00000000FFFFFFFFL
;
}
if
(
prefetchable
)
{
p_mem_node
->
base
=
base64
&
PCI_BASE_ADDRESS_MEM_MASK
;
p_mem_node
->
length
=
base
;
dbg
(
"sur adapter: 64 %s base=0x%x(len=0x%x)
\n
"
,
res_type_str
,
p_mem_node
->
base
,
p_mem_node
->
length
);
p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
p_mem_node
;
}
else
{
mem_node
->
base
=
base64
&
PCI_BASE_ADDRESS_MEM_MASK
;
mem_node
->
length
=
base
;
dbg
(
"sur adapter: 64 %s base=0x%x(len=0x%x)
\n
"
,
res_type_str
,
mem_node
->
base
,
mem_node
->
length
);
mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
mem_node
;
}
cloop
+=
4
;
break
;
default:
dbg
(
"asur: reserved BAR type=0x%x
\n
"
,
temp_register
);
break
;
}
}
}
/* End of base register loop */
}
else
{
/* Some other unknown header type */
dbg
(
"Save_used_res of PCI unknown type b:d=0x%x:%x. skip.
\n
"
,
func
->
bus
,
func
->
device
);
if
(
temp
->
hdr_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
pci_read_config_byte
(
temp
,
PCI_BRIDGE_CONTROL
,
&
bctl
);
if
(
bctl
&
PCI_BRIDGE_CTL_VGA
)
{
err
(
"Cannot remove display device %s
\n
"
,
pci_name
(
temp
));
continue
;
}
/* find the next device in this slot */
if
(
!
disable
)
break
;
func
=
shpchp_slot_find
(
func
->
bus
,
func
->
device
,
index
++
);
}
return
0
;
}
/**
* kfree_resource_list: release memory of all list members
* @res: resource list to free
*/
static
inline
void
return_resource_list
(
struct
pci_resource
**
func
,
struct
pci_resource
**
res
)
{
struct
pci_resource
*
node
;
struct
pci_resource
*
t_node
;
node
=
*
func
;
*
func
=
NULL
;
while
(
node
)
{
t_node
=
node
->
next
;
return_resource
(
res
,
node
);
node
=
t_node
;
pci_remove_bus_device
(
temp
);
}
}
/*
* shpchp_return_board_resources
*
* this routine returns all resources allocated to a board to
* the available pool.
*
* returns 0 if success
*/
int
shpchp_return_board_resources
(
struct
pci_func
*
func
,
struct
resource_lists
*
resources
)
{
int
rc
;
dbg
(
"%s
\n
"
,
__FUNCTION__
);
if
(
!
func
)
return
1
;
return_resource_list
(
&
(
func
->
io_head
),
&
(
resources
->
io_head
));
return_resource_list
(
&
(
func
->
mem_head
),
&
(
resources
->
mem_head
));
return_resource_list
(
&
(
func
->
p_mem_head
),
&
(
resources
->
p_mem_head
));
return_resource_list
(
&
(
func
->
bus_head
),
&
(
resources
->
bus_head
));
rc
=
shpchp_resource_sort_and_combine
(
&
(
resources
->
mem_head
));
rc
|=
shpchp_resource_sort_and_combine
(
&
(
resources
->
p_mem_head
));
rc
|=
shpchp_resource_sort_and_combine
(
&
(
resources
->
io_head
));
rc
|=
shpchp_resource_sort_and_combine
(
&
(
resources
->
bus_head
));
return
rc
;
}
/**
* kfree_resource_list: release memory of all list members
* @res: resource list to free
*/
static
inline
void
kfree_resource_list
(
struct
pci_resource
**
r
)
{
struct
pci_resource
*
res
,
*
tres
;
res
=
*
r
;
*
r
=
NULL
;
while
(
res
)
{
tres
=
res
;
res
=
res
->
next
;
kfree
(
tres
);
}
}
/**
* shpchp_destroy_resource_list: put node back in the resource list
* @resources: list to put nodes back
*/
void
shpchp_destroy_resource_list
(
struct
resource_lists
*
resources
)
{
kfree_resource_list
(
&
(
resources
->
io_head
));
kfree_resource_list
(
&
(
resources
->
mem_head
));
kfree_resource_list
(
&
(
resources
->
p_mem_head
));
kfree_resource_list
(
&
(
resources
->
bus_head
));
}
/**
* shpchp_destroy_board_resources: put node back in the resource list
* @resources: list to put nodes back
*/
void
shpchp_destroy_board_resources
(
struct
pci_func
*
func
)
{
kfree_resource_list
(
&
(
func
->
io_head
));
kfree_resource_list
(
&
(
func
->
mem_head
));
kfree_resource_list
(
&
(
func
->
p_mem_head
));
kfree_resource_list
(
&
(
func
->
bus_head
));
}
drivers/pci/hotplug/shpchp_sysfs.c
View file @
7efe5d7c
...
...
@@ -26,12 +26,9 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
#include "shpchp.h"
...
...
@@ -40,104 +37,60 @@
static
ssize_t
show_ctrl
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
pci_dev
*
pci_dev
;
struct
controller
*
ctrl
;
struct
pci_dev
*
pdev
;
char
*
out
=
buf
;
int
index
;
struct
pci_resource
*
res
;
int
index
,
busnr
;
struct
resource
*
res
;
struct
pci_bus
*
bus
;
p
ci_
dev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
ctrl
=
pci_get_drvdata
(
pci_dev
)
;
pdev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
bus
=
pdev
->
subordinate
;
out
+=
sprintf
(
buf
,
"Free resources: memory
\n
"
);
index
=
11
;
res
=
ctrl
->
mem_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
for
(
index
=
0
;
index
<
PCI_BUS_NUM_RESOURCES
;
index
++
)
{
res
=
bus
->
resource
[
index
];
if
(
res
&&
(
res
->
flags
&
IORESOURCE_MEM
)
&&
!
(
res
->
flags
&
IORESOURCE_PREFETCH
))
{
out
+=
sprintf
(
out
,
"start = %8.8lx, length = %8.8lx
\n
"
,
res
->
start
,
(
res
->
end
-
res
->
start
));
}
}
out
+=
sprintf
(
out
,
"Free resources: prefetchable memory
\n
"
);
index
=
11
;
res
=
ctrl
->
p_mem_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
for
(
index
=
0
;
index
<
PCI_BUS_NUM_RESOURCES
;
index
++
)
{
res
=
bus
->
resource
[
index
];
if
(
res
&&
(
res
->
flags
&
IORESOURCE_MEM
)
&&
(
res
->
flags
&
IORESOURCE_PREFETCH
))
{
out
+=
sprintf
(
out
,
"start = %8.8lx, length = %8.8lx
\n
"
,
res
->
start
,
(
res
->
end
-
res
->
start
));
}
}
out
+=
sprintf
(
out
,
"Free resources: IO
\n
"
);
index
=
11
;
res
=
ctrl
->
io_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
for
(
index
=
0
;
index
<
PCI_BUS_NUM_RESOURCES
;
index
++
)
{
res
=
bus
->
resource
[
index
];
if
(
res
&&
(
res
->
flags
&
IORESOURCE_IO
))
{
out
+=
sprintf
(
out
,
"start = %8.8lx, length = %8.8lx
\n
"
,
res
->
start
,
(
res
->
end
-
res
->
start
));
}
}
out
+=
sprintf
(
out
,
"Free resources: bus numbers
\n
"
);
index
=
11
;
res
=
ctrl
->
bus_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
for
(
busnr
=
bus
->
secondary
;
busnr
<=
bus
->
subordinate
;
busnr
++
)
{
if
(
!
pci_find_bus
(
pci_domain_nr
(
bus
),
busnr
))
break
;
}
if
(
busnr
<
bus
->
subordinate
)
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
busnr
,
(
bus
->
subordinate
-
busnr
));
return
out
-
buf
;
}
static
DEVICE_ATTR
(
ctrl
,
S_IRUGO
,
show_ctrl
,
NULL
);
static
ssize_t
show_dev
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
void
shpchp_create_ctrl_files
(
struct
controller
*
ctrl
)
{
struct
pci_dev
*
pci_dev
;
struct
controller
*
ctrl
;
char
*
out
=
buf
;
int
index
;
struct
pci_resource
*
res
;
struct
pci_func
*
new_slot
;
struct
slot
*
slot
;
pci_dev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
ctrl
=
pci_get_drvdata
(
pci_dev
);
slot
=
ctrl
->
slot
;
while
(
slot
)
{
new_slot
=
shpchp_slot_find
(
slot
->
bus
,
slot
->
device
,
0
);
if
(
!
new_slot
)
break
;
out
+=
sprintf
(
out
,
"assigned resources: memory
\n
"
);
index
=
11
;
res
=
new_slot
->
mem_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
}
out
+=
sprintf
(
out
,
"assigned resources: prefetchable memory
\n
"
);
index
=
11
;
res
=
new_slot
->
p_mem_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
}
out
+=
sprintf
(
out
,
"assigned resources: IO
\n
"
);
index
=
11
;
res
=
new_slot
->
io_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
}
out
+=
sprintf
(
out
,
"assigned resources: bus numbers
\n
"
);
index
=
11
;
res
=
new_slot
->
bus_head
;
while
(
res
&&
index
--
)
{
out
+=
sprintf
(
out
,
"start = %8.8x, length = %8.8x
\n
"
,
res
->
base
,
res
->
length
);
res
=
res
->
next
;
}
slot
=
slot
->
next
;
}
return
out
-
buf
;
device_create_file
(
&
ctrl
->
pci_dev
->
dev
,
&
dev_attr_ctrl
);
}
static
DEVICE_ATTR
(
dev
,
S_IRUGO
,
show_dev
,
NULL
);
void
shpchp_
create_ctrl_files
(
struct
controller
*
ctrl
)
void
shpchp_
remove_ctrl_files
(
struct
controller
*
ctrl
)
{
device_create_file
(
&
ctrl
->
pci_dev
->
dev
,
&
dev_attr_ctrl
);
device_create_file
(
&
ctrl
->
pci_dev
->
dev
,
&
dev_attr_dev
);
device_remove_file
(
&
ctrl
->
pci_dev
->
dev
,
&
dev_attr_ctrl
);
}
drivers/pci/hotplug/shpchprm.h
deleted
100644 → 0
View file @
dbe0580d
/*
* SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2003-2004 Intel Corporation
*
* All rights reserved.
*
* 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 of the License, 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
#ifndef _SHPCHPRM_H_
#define _SHPCHPRM_H_
#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
#include "shpchprm_legacy.h"
#else
#include "shpchprm_nonacpi.h"
#endif
int
shpchprm_init
(
enum
php_ctlr_type
ct
);
void
shpchprm_cleanup
(
void
);
int
shpchprm_print_pirt
(
void
);
int
shpchprm_find_available_resources
(
struct
controller
*
ctrl
);
int
shpchprm_set_hpp
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
);
void
shpchprm_enable_card
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
);
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
);
#ifdef DEBUG
#define RES_CHECK(this, bits) \
{ if (((this) & (bits - 1))) \
printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
#else
#define RES_CHECK(this, bits)
#endif
#endif
/* _SHPCHPRM_H_ */
drivers/pci/hotplug/shpchprm_acpi.c
View file @
7efe5d7c
...
...
@@ -24,91 +24,19 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/efi.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_IA64
#include <asm/iosapic.h>
#endif
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "shpchp.h"
#include "shpchprm.h"
#define PCI_MAX_BUS 0x100
#define ACPI_STA_DEVICE_PRESENT 0x01
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
#define PHP_RES_BUS 0xA0
#define PHP_RES_IO 0xA1
#define PHP_RES_MEM 0xA2
#define PHP_RES_PMEM 0xA3
#define BRIDGE_TYPE_P2P 0x00
#define BRIDGE_TYPE_HOST 0x01
/* this should go to drivers/acpi/include/ */
struct
acpi__hpp
{
u8
cache_line_size
;
u8
latency_timer
;
u8
enable_serr
;
u8
enable_perr
;
};
struct
acpi_php_slot
{
struct
acpi_php_slot
*
next
;
struct
acpi_bridge
*
bridge
;
acpi_handle
handle
;
int
seg
;
int
bus
;
int
dev
;
int
fun
;
u32
sun
;
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
void
*
slot_ops
;
/* _STA, _EJx, etc */
struct
slot
*
slot
;
};
/* per func */
struct
acpi_bridge
{
struct
acpi_bridge
*
parent
;
struct
acpi_bridge
*
next
;
struct
acpi_bridge
*
child
;
acpi_handle
handle
;
int
seg
;
int
pbus
;
/* pdev->bus->number */
int
pdevice
;
/* PCI_SLOT(pdev->devfn) */
int
pfunction
;
/* PCI_DEVFN(pdev->devfn) */
int
bus
;
/* pdev->subordinate->number */
struct
acpi__hpp
*
_hpp
;
struct
acpi_php_slot
*
slots
;
struct
pci_resource
*
tmem_head
;
/* total from crs */
struct
pci_resource
*
tp_mem_head
;
/* total from crs */
struct
pci_resource
*
tio_head
;
/* total from crs */
struct
pci_resource
*
tbus_head
;
/* total from crs */
struct
pci_resource
*
mem_head
;
/* available */
struct
pci_resource
*
p_mem_head
;
/* available */
struct
pci_resource
*
io_head
;
/* available */
struct
pci_resource
*
bus_head
;
/* available */
int
scanned
;
int
type
;
};
static
struct
acpi_bridge
*
acpi_bridges_head
;
static
u8
*
acpi_path_name
(
acpi_handle
handle
)
{
acpi_status
status
;
...
...
@@ -124,82 +52,43 @@ static u8 * acpi_path_name( acpi_handle handle)
return
path_name
;
}
static
void
acpi_get__hpp
(
struct
acpi_bridge
*
ab
);
static
void
acpi_run_oshp
(
struct
acpi_bridge
*
ab
);
static
int
acpi_add_slot_to_php_slots
(
struct
acpi_bridge
*
ab
,
int
bus_num
,
acpi_handle
handle
,
u32
adr
,
u32
sun
)
{
struct
acpi_php_slot
*
aps
;
static
long
samesun
=
-
1
;
aps
=
(
struct
acpi_php_slot
*
)
kmalloc
(
sizeof
(
struct
acpi_php_slot
),
GFP_KERNEL
);
if
(
!
aps
)
{
err
(
"acpi_shpchprm: alloc for aps fail
\n
"
);
return
-
1
;
}
memset
(
aps
,
0
,
sizeof
(
struct
acpi_php_slot
));
aps
->
handle
=
handle
;
aps
->
bus
=
bus_num
;
aps
->
dev
=
(
adr
>>
16
)
&
0xffff
;
aps
->
fun
=
adr
&
0xffff
;
aps
->
sun
=
sun
;
aps
->
next
=
ab
->
slots
;
/* cling to the bridge */
aps
->
bridge
=
ab
;
ab
->
slots
=
aps
;
ab
->
scanned
+=
1
;
if
(
!
ab
->
_hpp
)
acpi_get__hpp
(
ab
);
acpi_run_oshp
(
ab
);
if
(
sun
!=
samesun
)
{
info
(
"acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x
\n
"
,
aps
->
sun
,
ab
->
seg
,
aps
->
bus
,
aps
->
dev
,
aps
->
fun
);
samesun
=
sun
;
}
return
0
;
}
static
void
acpi_get__hpp
(
struct
acpi_bridge
*
ab
)
static
acpi_status
acpi_run_hpp
(
acpi_handle
handle
,
struct
hotplug_params
*
hpp
)
{
acpi_status
status
;
u8
nui
[
4
];
struct
acpi_buffer
ret_buf
=
{
0
,
NULL
};
union
acpi_object
*
ext_obj
,
*
package
;
u8
*
path_name
=
acpi_path_name
(
ab
->
handle
);
u8
*
path_name
=
acpi_path_name
(
handle
);
int
i
,
len
=
0
;
/* get _hpp */
status
=
acpi_evaluate_object
(
ab
->
handle
,
METHOD_NAME__HPP
,
NULL
,
&
ret_buf
);
status
=
acpi_evaluate_object
(
handle
,
METHOD_NAME__HPP
,
NULL
,
&
ret_buf
);
switch
(
status
)
{
case
AE_BUFFER_OVERFLOW
:
ret_buf
.
pointer
=
kmalloc
(
ret_buf
.
length
,
GFP_KERNEL
);
if
(
!
ret_buf
.
pointer
)
{
err
(
"acpi_shpchprm:%s alloc for _HPP fail
\n
"
,
path_name
);
return
;
err
(
"%s:%s alloc for _HPP fail
\n
"
,
__FUNCTION__
,
path_name
);
return
AE_NO_MEMORY
;
}
status
=
acpi_evaluate_object
(
ab
->
handle
,
METHOD_NAME__HPP
,
NULL
,
&
ret_buf
);
status
=
acpi_evaluate_object
(
handle
,
METHOD_NAME__HPP
,
NULL
,
&
ret_buf
);
if
(
ACPI_SUCCESS
(
status
))
break
;
default:
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s _HPP fail=0x%x
\n
"
,
path_name
,
status
);
return
;
dbg
(
"%s:%s _HPP fail=0x%x
\n
"
,
__FUNCTION__
,
path_name
,
status
);
return
status
;
}
}
ext_obj
=
(
union
acpi_object
*
)
ret_buf
.
pointer
;
if
(
ext_obj
->
type
!=
ACPI_TYPE_PACKAGE
)
{
err
(
"acpi_shpchprm:%s _HPP obj not a package
\n
"
,
path_name
);
err
(
"%s:%s _HPP obj not a package
\n
"
,
__FUNCTION__
,
path_name
);
status
=
AE_ERROR
;
goto
free_and_return
;
}
...
...
@@ -212,1502 +101,86 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
nui
[
i
]
=
(
u8
)
ext_obj
->
integer
.
value
;
break
;
default:
err
(
"acpi_shpchprm:%s _HPP obj type incorrect
\n
"
,
path_name
);
err
(
"%s:%s _HPP obj type incorrect
\n
"
,
__FUNCTION__
,
path_name
);
status
=
AE_ERROR
;
goto
free_and_return
;
}
}
ab
->
_hpp
=
kmalloc
(
sizeof
(
struct
acpi__hpp
),
GFP_KERNEL
);
if
(
!
ab
->
_hpp
)
{
err
(
"acpi_shpchprm:%s alloc for _HPP failed
\n
"
,
path_name
);
goto
free_and_return
;
}
memset
(
ab
->
_hpp
,
0
,
sizeof
(
struct
acpi__hpp
));
ab
->
_hpp
->
cache_line_size
=
nui
[
0
];
ab
->
_hpp
->
latency_timer
=
nui
[
1
];
ab
->
_hpp
->
enable_serr
=
nui
[
2
];
ab
->
_hpp
->
enable_perr
=
nui
[
3
];
hpp
->
cache_line_size
=
nui
[
0
];
hpp
->
latency_timer
=
nui
[
1
];
hpp
->
enable_serr
=
nui
[
2
];
hpp
->
enable_perr
=
nui
[
3
];
dbg
(
" _HPP: cache_line_size=0x%x
\n
"
,
ab
->
_
hpp
->
cache_line_size
);
dbg
(
" _HPP: latency timer =0x%x
\n
"
,
ab
->
_
hpp
->
latency_timer
);
dbg
(
" _HPP: enable SERR =0x%x
\n
"
,
ab
->
_
hpp
->
enable_serr
);
dbg
(
" _HPP: enable PERR =0x%x
\n
"
,
ab
->
_
hpp
->
enable_perr
);
dbg
(
" _HPP: cache_line_size=0x%x
\n
"
,
hpp
->
cache_line_size
);
dbg
(
" _HPP: latency timer =0x%x
\n
"
,
hpp
->
latency_timer
);
dbg
(
" _HPP: enable SERR =0x%x
\n
"
,
hpp
->
enable_serr
);
dbg
(
" _HPP: enable PERR =0x%x
\n
"
,
hpp
->
enable_perr
);
free_and_return:
kfree
(
ret_buf
.
pointer
);
return
status
;
}
static
void
acpi_run_oshp
(
struct
acpi_bridge
*
ab
)
{
acpi_status
status
;
u8
*
path_name
=
acpi_path_name
(
ab
->
handle
);
/* run OSHP */
status
=
acpi_evaluate_object
(
ab
->
handle
,
METHOD_NAME_OSHP
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_pciehprm:%s OSHP fails=0x%x
\n
"
,
path_name
,
status
);
}
else
dbg
(
"acpi_pciehprm:%s OSHP passes =0x%x
\n
"
,
path_name
,
status
);
return
;
}
static
acpi_status
acpi_evaluate_crs
(
acpi_handle
handle
,
struct
acpi_resource
**
retbuf
)
static
void
acpi_run_oshp
(
acpi_handle
handle
)
{
acpi_status
status
;
struct
acpi_buffer
crsbuf
;
u8
*
path_name
=
acpi_path_name
(
handle
);
crsbuf
.
length
=
0
;
crsbuf
.
pointer
=
NULL
;
status
=
acpi_get_current_resources
(
handle
,
&
crsbuf
);
switch
(
status
)
{
case
AE_BUFFER_OVERFLOW
:
break
;
/* found */
case
AE_NOT_FOUND
:
dbg
(
"acpi_shpchprm:%s _CRS not found
\n
"
,
path_name
);
return
status
;
default:
err
(
"acpi_shpchprm:%s _CRS fail=0x%x
\n
"
,
path_name
,
status
);
return
status
;
}
crsbuf
.
pointer
=
kmalloc
(
crsbuf
.
length
,
GFP_KERNEL
);
if
(
!
crsbuf
.
pointer
)
{
err
(
"acpi_shpchprm: alloc %ld bytes for %s _CRS fail
\n
"
,
(
ulong
)
crsbuf
.
length
,
path_name
);
return
AE_NO_MEMORY
;
}
status
=
acpi_get_current_resources
(
handle
,
&
crsbuf
);
/* run OSHP */
status
=
acpi_evaluate_object
(
handle
,
METHOD_NAME_OSHP
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm: %s _CRS fail=0x%x.
\n
"
,
path_name
,
status
);
kfree
(
crsbuf
.
pointer
);
return
status
;
}
*
retbuf
=
crsbuf
.
pointer
;
return
status
;
}
static
void
free_pci_resource
(
struct
pci_resource
*
aprh
)
{
struct
pci_resource
*
res
,
*
next
;
for
(
res
=
aprh
;
res
;
res
=
next
)
{
next
=
res
->
next
;
kfree
(
res
);
}
}
static
void
print_pci_resource
(
struct
pci_resource
*
aprh
)
{
struct
pci_resource
*
res
;
for
(
res
=
aprh
;
res
;
res
=
res
->
next
)
dbg
(
" base= 0x%x length= 0x%x
\n
"
,
res
->
base
,
res
->
length
);
}
static
void
print_slot_resources
(
struct
acpi_php_slot
*
aps
)
{
if
(
aps
->
bus_head
)
{
dbg
(
" BUS Resources:
\n
"
);
print_pci_resource
(
aps
->
bus_head
);
}
if
(
aps
->
io_head
)
{
dbg
(
" IO Resources:
\n
"
);
print_pci_resource
(
aps
->
io_head
);
}
if
(
aps
->
mem_head
)
{
dbg
(
" MEM Resources:
\n
"
);
print_pci_resource
(
aps
->
mem_head
);
}
if
(
aps
->
p_mem_head
)
{
dbg
(
" PMEM Resources:
\n
"
);
print_pci_resource
(
aps
->
p_mem_head
);
}
}
static
void
print_pci_resources
(
struct
acpi_bridge
*
ab
)
{
if
(
ab
->
tbus_head
)
{
dbg
(
" Total BUS Resources:
\n
"
);
print_pci_resource
(
ab
->
tbus_head
);
}
if
(
ab
->
bus_head
)
{
dbg
(
" BUS Resources:
\n
"
);
print_pci_resource
(
ab
->
bus_head
);
}
if
(
ab
->
tio_head
)
{
dbg
(
" Total IO Resources:
\n
"
);
print_pci_resource
(
ab
->
tio_head
);
}
if
(
ab
->
io_head
)
{
dbg
(
" IO Resources:
\n
"
);
print_pci_resource
(
ab
->
io_head
);
}
if
(
ab
->
tmem_head
)
{
dbg
(
" Total MEM Resources:
\n
"
);
print_pci_resource
(
ab
->
tmem_head
);
}
if
(
ab
->
mem_head
)
{
dbg
(
" MEM Resources:
\n
"
);
print_pci_resource
(
ab
->
mem_head
);
}
if
(
ab
->
tp_mem_head
)
{
dbg
(
" Total PMEM Resources:
\n
"
);
print_pci_resource
(
ab
->
tp_mem_head
);
}
if
(
ab
->
p_mem_head
)
{
dbg
(
" PMEM Resources:
\n
"
);
print_pci_resource
(
ab
->
p_mem_head
);
}
if
(
ab
->
_hpp
)
{
dbg
(
" _HPP: cache_line_size=0x%x
\n
"
,
ab
->
_hpp
->
cache_line_size
);
dbg
(
" _HPP: latency timer =0x%x
\n
"
,
ab
->
_hpp
->
latency_timer
);
dbg
(
" _HPP: enable SERR =0x%x
\n
"
,
ab
->
_hpp
->
enable_serr
);
dbg
(
" _HPP: enable PERR =0x%x
\n
"
,
ab
->
_hpp
->
enable_perr
);
}
}
static
int
shpchprm_delete_resource
(
struct
pci_resource
**
aprh
,
ulong
base
,
ulong
size
)
{
struct
pci_resource
*
res
;
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
split_node
;
ulong
tbase
;
shpchp_resource_sort_and_combine
(
aprh
);
for
(
res
=
*
aprh
;
res
;
res
=
res
->
next
)
{
if
(
res
->
base
>
base
)
continue
;
if
((
res
->
base
+
res
->
length
)
<
(
base
+
size
))
continue
;
if
(
res
->
base
<
base
)
{
tbase
=
base
;
if
((
res
->
length
-
(
tbase
-
res
->
base
))
<
size
)
continue
;
split_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
split_node
)
return
-
ENOMEM
;
split_node
->
base
=
res
->
base
;
split_node
->
length
=
tbase
-
res
->
base
;
res
->
base
=
tbase
;
res
->
length
-=
split_node
->
length
;
split_node
->
next
=
res
->
next
;
res
->
next
=
split_node
;
}
if
(
res
->
length
>=
size
)
{
split_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
split_node
)
return
-
ENOMEM
;
split_node
->
base
=
res
->
base
+
size
;
split_node
->
length
=
res
->
length
-
size
;
res
->
length
=
size
;
split_node
->
next
=
res
->
next
;
res
->
next
=
split_node
;
}
if
(
*
aprh
==
res
)
{
*
aprh
=
res
->
next
;
err
(
"%s:%s OSHP fails=0x%x
\n
"
,
__FUNCTION__
,
path_name
,
status
);
}
else
{
prevnode
=
*
aprh
;
while
(
prevnode
->
next
!=
res
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
res
->
next
;
}
res
->
next
=
NULL
;
kfree
(
res
);
break
;
dbg
(
"%s:%s OSHP passes
\n
"
,
__FUNCTION__
,
path_name
);
}
return
0
;
}
static
int
shpchprm_delete_resources
(
struct
pci_resource
**
aprh
,
struct
pci_resource
*
this
)
{
struct
pci_resource
*
res
;
for
(
res
=
this
;
res
;
res
=
res
->
next
)
shpchprm_delete_resource
(
aprh
,
res
->
base
,
res
->
length
);
return
0
;
}
static
int
shpchprm_add_resource
(
struct
pci_resource
**
aprh
,
ulong
base
,
ulong
size
)
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
)
{
struct
pci_resource
*
res
;
for
(
res
=
*
aprh
;
res
;
res
=
res
->
next
)
{
if
((
res
->
base
+
res
->
length
)
==
base
)
{
res
->
length
+=
size
;
size
=
0L
;
break
;
}
if
(
res
->
next
==
*
aprh
)
break
;
}
if
(
size
)
{
res
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
res
)
{
err
(
"acpi_shpchprm: alloc for res fail
\n
"
);
return
-
ENOMEM
;
}
memset
(
res
,
0
,
sizeof
(
struct
pci_resource
));
res
->
base
=
base
;
res
->
length
=
size
;
res
->
next
=
*
aprh
;
*
aprh
=
res
;
}
int
offset
=
devnum
-
ctrl
->
slot_device_offset
;
dbg
(
"%s: ctrl->slot_num_inc %d, offset %d
\n
"
,
__FUNCTION__
,
ctrl
->
slot_num_inc
,
offset
);
*
sun
=
(
u8
)
(
ctrl
->
first_slot
+
ctrl
->
slot_num_inc
*
offset
);
return
0
;
}
static
int
shpchprm_add_resources
(
struct
pci_resource
**
aprh
,
struct
pci_resource
*
this
)
{
struct
pci_resource
*
res
;
int
rc
=
0
;
for
(
res
=
this
;
res
&&
!
rc
;
res
=
res
->
next
)
rc
=
shpchprm_add_resource
(
aprh
,
res
->
base
,
res
->
length
);
return
rc
;
}
static
void
acpi_parse_io
(
struct
acpi_bridge
*
ab
,
union
acpi_resource_data
*
data
)
{
struct
acpi_resource_io
*
dataio
;
dataio
=
(
struct
acpi_resource_io
*
)
data
;
dbg
(
"Io Resource
\n
"
);
dbg
(
" %d bit decode
\n
"
,
ACPI_DECODE_16
==
dataio
->
io_decode
?
16
:
10
);
dbg
(
" Range minimum base: %08X
\n
"
,
dataio
->
min_base_address
);
dbg
(
" Range maximum base: %08X
\n
"
,
dataio
->
max_base_address
);
dbg
(
" Alignment: %08X
\n
"
,
dataio
->
alignment
);
dbg
(
" Range Length: %08X
\n
"
,
dataio
->
range_length
);
}
static
void
acpi_parse_fixed_io
(
struct
acpi_bridge
*
ab
,
union
acpi_resource_data
*
data
)
{
struct
acpi_resource_fixed_io
*
datafio
;
datafio
=
(
struct
acpi_resource_fixed_io
*
)
data
;
dbg
(
"Fixed Io Resource
\n
"
);
dbg
(
" Range base address: %08X"
,
datafio
->
base_address
);
dbg
(
" Range length: %08X"
,
datafio
->
range_length
);
}
static
void
acpi_parse_address16_32
(
struct
acpi_bridge
*
ab
,
union
acpi_resource_data
*
data
,
acpi_resource_type
id
)
void
get_hp_hw_control_from_firmware
(
struct
pci_dev
*
dev
)
{
/*
* acpi_resource_address16 == acpi_resource_address32
* acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
* OSHP is an optional ACPI firmware control method. If present,
* we need to run it to inform BIOS that we will control SHPC
* hardware from now on.
*/
struct
acpi_resource_address32
*
data32
=
(
struct
acpi_resource_address32
*
)
data
;
struct
pci_resource
**
aprh
,
**
tprh
;
if
(
id
==
ACPI_RSTYPE_ADDRESS16
)
dbg
(
"acpi_shpchprm:16-Bit Address Space Resource
\n
"
);
else
dbg
(
"acpi_shpchprm:32-Bit Address Space Resource
\n
"
);
switch
(
data32
->
resource_type
)
{
case
ACPI_MEMORY_RANGE
:
dbg
(
" Resource Type: Memory Range
\n
"
);
aprh
=
&
ab
->
mem_head
;
tprh
=
&
ab
->
tmem_head
;
switch
(
data32
->
attribute
.
memory
.
cache_attribute
)
{
case
ACPI_NON_CACHEABLE_MEMORY
:
dbg
(
" Type Specific: Noncacheable memory
\n
"
);
break
;
case
ACPI_CACHABLE_MEMORY
:
dbg
(
" Type Specific: Cacheable memory
\n
"
);
break
;
case
ACPI_WRITE_COMBINING_MEMORY
:
dbg
(
" Type Specific: Write-combining memory
\n
"
);
break
;
case
ACPI_PREFETCHABLE_MEMORY
:
aprh
=
&
ab
->
p_mem_head
;
dbg
(
" Type Specific: Prefetchable memory
\n
"
);
break
;
default:
dbg
(
" Type Specific: Invalid cache attribute
\n
"
);
break
;
}
dbg
(
" Type Specific: Read%s
\n
"
,
ACPI_READ_WRITE_MEMORY
==
data32
->
attribute
.
memory
.
read_write_attribute
?
"/Write"
:
" Only"
);
break
;
case
ACPI_IO_RANGE
:
dbg
(
" Resource Type: I/O Range
\n
"
);
aprh
=
&
ab
->
io_head
;
tprh
=
&
ab
->
tio_head
;
switch
(
data32
->
attribute
.
io
.
range_attribute
)
{
case
ACPI_NON_ISA_ONLY_RANGES
:
dbg
(
" Type Specific: Non-ISA Io Addresses
\n
"
);
break
;
case
ACPI_ISA_ONLY_RANGES
:
dbg
(
" Type Specific: ISA Io Addresses
\n
"
);
break
;
case
ACPI_ENTIRE_RANGE
:
dbg
(
" Type Specific: ISA and non-ISA Io Addresses
\n
"
);
break
;
default:
dbg
(
" Type Specific: Invalid range attribute
\n
"
);
break
;
}
break
;
case
ACPI_BUS_NUMBER_RANGE
:
dbg
(
" Resource Type: Bus Number Range(fixed)
\n
"
);
/* fixup to be compatible with the rest of php driver */
data32
->
min_address_range
++
;
data32
->
address_length
--
;
aprh
=
&
ab
->
bus_head
;
tprh
=
&
ab
->
tbus_head
;
break
;
default:
dbg
(
" Resource Type: Invalid resource type. Exiting.
\n
"
);
acpi_handle
handle
=
DEVICE_ACPI_HANDLE
(
&
(
dev
->
dev
));
if
(
!
handle
)
return
;
}
dbg
(
" Resource %s
\n
"
,
ACPI_CONSUMER
==
data32
->
producer_consumer
?
"Consumer"
:
"Producer"
);
dbg
(
" %s decode
\n
"
,
ACPI_SUB_DECODE
==
data32
->
decode
?
"Subtractive"
:
"Positive"
);
dbg
(
" Min address is %s fixed
\n
"
,
ACPI_ADDRESS_FIXED
==
data32
->
min_address_fixed
?
""
:
"not"
);
dbg
(
" Max address is %s fixed
\n
"
,
ACPI_ADDRESS_FIXED
==
data32
->
max_address_fixed
?
""
:
"not"
);
dbg
(
" Granularity: %08X
\n
"
,
data32
->
granularity
);
dbg
(
" Address range min: %08X
\n
"
,
data32
->
min_address_range
);
dbg
(
" Address range max: %08X
\n
"
,
data32
->
max_address_range
);
dbg
(
" Address translation offset: %08X
\n
"
,
data32
->
address_translation_offset
);
dbg
(
" Address Length: %08X
\n
"
,
data32
->
address_length
);
if
(
0xFF
!=
data32
->
resource_source
.
index
)
{
dbg
(
" Resource Source Index: %X
\n
"
,
data32
->
resource_source
.
index
);
/* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
}
shpchprm_add_resource
(
aprh
,
data32
->
min_address_range
,
data32
->
address_length
);
acpi_run_oshp
(
handle
);
}
static
acpi_status
acpi_parse_crs
(
struct
acpi_bridge
*
ab
,
struct
acpi_resource
*
crsbuf
)
void
get_hp_params_from_firmware
(
struct
pci_dev
*
dev
,
struct
hotplug_params
*
hpp
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_resource
*
resource
=
crsbuf
;
u8
count
=
0
;
u8
done
=
0
;
acpi_status
status
=
AE_NOT_FOUND
;
struct
pci_dev
*
pdev
=
dev
;
while
(
!
done
)
{
dbg
(
"acpi_shpchprm: PCI bus 0x%x Resource structure %x.
\n
"
,
ab
->
bus
,
count
++
);
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_IRQ
:
dbg
(
"Irq -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_DMA
:
dbg
(
"DMA -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_START_DPF
:
dbg
(
"Start DPF -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_END_DPF
:
dbg
(
"End DPF -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_IO
:
acpi_parse_io
(
ab
,
&
resource
->
data
);
break
;
case
ACPI_RSTYPE_FIXED_IO
:
acpi_parse_fixed_io
(
ab
,
&
resource
->
data
);
break
;
case
ACPI_RSTYPE_VENDOR
:
dbg
(
"Vendor -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_END_TAG
:
dbg
(
"End_tag -------- Resource
\n
"
);
done
=
1
;
break
;
case
ACPI_RSTYPE_MEM24
:
dbg
(
"Mem24 -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_MEM32
:
dbg
(
"Mem32 -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_FIXED_MEM32
:
dbg
(
"Fixed Mem32 -------- Resource
\n
"
);
break
;
case
ACPI_RSTYPE_ADDRESS16
:
acpi_parse_address16_32
(
ab
,
&
resource
->
data
,
ACPI_RSTYPE_ADDRESS16
);
break
;
case
ACPI_RSTYPE_ADDRESS32
:
acpi_parse_address16_32
(
ab
,
&
resource
->
data
,
ACPI_RSTYPE_ADDRESS32
);
break
;
case
ACPI_RSTYPE_ADDRESS64
:
info
(
"Address64 -------- Resource unparsed
\n
"
);
break
;
case
ACPI_RSTYPE_EXT_IRQ
:
dbg
(
"Ext Irq -------- Resource
\n
"
);
/*
* _HPP settings apply to all child buses, until another _HPP is
* encountered. If we don't find an _HPP for the input pci dev,
* look for it in the parent device scope since that would apply to
* this pci dev. If we don't find any _HPP, use hardcoded defaults
*/
while
(
pdev
&&
(
ACPI_FAILURE
(
status
)))
{
acpi_handle
handle
=
DEVICE_ACPI_HANDLE
(
&
(
pdev
->
dev
));
if
(
!
handle
)
break
;
default:
dbg
(
"Invalid -------- resource type 0x%x
\n
"
,
resource
->
id
);
status
=
acpi_run_hpp
(
handle
,
hpp
);
if
(
!
(
pdev
->
bus
->
parent
))
break
;
}
resource
=
(
struct
acpi_resource
*
)
((
char
*
)
resource
+
resource
->
length
);
}
return
status
;
}
static
acpi_status
acpi_get_crs
(
struct
acpi_bridge
*
ab
)
{
acpi_status
status
;
struct
acpi_resource
*
crsbuf
;
status
=
acpi_evaluate_crs
(
ab
->
handle
,
&
crsbuf
);
if
(
ACPI_SUCCESS
(
status
))
{
status
=
acpi_parse_crs
(
ab
,
crsbuf
);
kfree
(
crsbuf
);
shpchp_resource_sort_and_combine
(
&
ab
->
bus_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
io_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
mem_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
p_mem_head
);
shpchprm_add_resources
(
&
ab
->
tbus_head
,
ab
->
bus_head
);
shpchprm_add_resources
(
&
ab
->
tio_head
,
ab
->
io_head
);
shpchprm_add_resources
(
&
ab
->
tmem_head
,
ab
->
mem_head
);
shpchprm_add_resources
(
&
ab
->
tp_mem_head
,
ab
->
p_mem_head
);
}
return
status
;
}
/* find acpi_bridge downword from ab. */
static
struct
acpi_bridge
*
find_acpi_bridge_by_bus
(
struct
acpi_bridge
*
ab
,
int
seg
,
int
bus
/* pdev->subordinate->number */
)
{
struct
acpi_bridge
*
lab
=
NULL
;
if
(
!
ab
)
return
NULL
;
if
((
ab
->
bus
==
bus
)
&&
(
ab
->
seg
==
seg
))
return
ab
;
if
(
ab
->
child
)
lab
=
find_acpi_bridge_by_bus
(
ab
->
child
,
seg
,
bus
);
if
(
!
lab
)
if
(
ab
->
next
)
lab
=
find_acpi_bridge_by_bus
(
ab
->
next
,
seg
,
bus
);
return
lab
;
}
/*
* Build a device tree of ACPI PCI Bridges
*/
static
void
shpchprm_acpi_register_a_bridge
(
struct
acpi_bridge
**
head
,
struct
acpi_bridge
*
pab
,
/* parent bridge to which child bridge is added */
struct
acpi_bridge
*
cab
/* child bridge to add */
)
{
struct
acpi_bridge
*
lpab
;
struct
acpi_bridge
*
lcab
;
lpab
=
find_acpi_bridge_by_bus
(
*
head
,
pab
->
seg
,
pab
->
bus
);
if
(
!
lpab
)
{
if
(
!
(
pab
->
type
&
BRIDGE_TYPE_HOST
))
warn
(
"PCI parent bridge s:b(%x:%x) not in list.
\n
"
,
pab
->
seg
,
pab
->
bus
);
pab
->
next
=
*
head
;
*
head
=
pab
;
lpab
=
pab
;
}
if
((
cab
->
type
&
BRIDGE_TYPE_HOST
)
&&
(
pab
==
cab
))
return
;
lcab
=
find_acpi_bridge_by_bus
(
*
head
,
cab
->
seg
,
cab
->
bus
);
if
(
lcab
)
{
if
((
pab
->
bus
!=
lcab
->
parent
->
bus
)
||
(
lcab
->
bus
!=
cab
->
bus
))
err
(
"PCI child bridge s:b(%x:%x) in list with diff parent.
\n
"
,
cab
->
seg
,
cab
->
bus
);
return
;
}
else
lcab
=
cab
;
lcab
->
parent
=
lpab
;
lcab
->
next
=
lpab
->
child
;
lpab
->
child
=
lcab
;
}
static
acpi_status
shpchprm_acpi_build_php_slots_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
ulong
bus_num
;
ulong
seg_num
;
ulong
sun
,
adr
;
ulong
padr
=
0
;
acpi_handle
phandle
=
NULL
;
struct
acpi_bridge
*
pab
=
(
struct
acpi_bridge
*
)
context
;
struct
acpi_bridge
*
lab
;
acpi_status
status
;
u8
*
path_name
=
acpi_path_name
(
handle
);
/* get _SUN */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__SUN
,
NULL
,
&
sun
);
switch
(
status
)
{
case
AE_NOT_FOUND
:
return
AE_OK
;
default:
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s _SUN fail=0x%x
\n
"
,
path_name
,
status
);
return
status
;
}
}
/* get _ADR. _ADR must exist if _SUN exists */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__ADR
,
NULL
,
&
adr
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s _ADR fail=0x%x
\n
"
,
path_name
,
status
);
return
status
;
}
dbg
(
"acpi_shpchprm:%s sun=0x%08x adr=0x%08x
\n
"
,
path_name
,
(
u32
)
sun
,
(
u32
)
adr
);
status
=
acpi_get_parent
(
handle
,
&
phandle
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s get_parent fail=0x%x
\n
"
,
path_name
,
status
);
return
(
status
);
}
bus_num
=
pab
->
bus
;
seg_num
=
pab
->
seg
;
if
(
pab
->
bus
==
bus_num
)
{
lab
=
pab
;
}
else
{
dbg
(
"WARN: pab is not parent
\n
"
);
lab
=
find_acpi_bridge_by_bus
(
pab
,
seg_num
,
bus_num
);
if
(
!
lab
)
{
dbg
(
"acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)
\n
"
,
(
u32
)
bus_num
,
(
u32
)
sun
);
lab
=
(
struct
acpi_bridge
*
)
kmalloc
(
sizeof
(
struct
acpi_bridge
),
GFP_KERNEL
);
if
(
!
lab
)
{
err
(
"acpi_shpchprm: alloc for ab fail
\n
"
);
return
AE_NO_MEMORY
;
}
memset
(
lab
,
0
,
sizeof
(
struct
acpi_bridge
));
lab
->
handle
=
phandle
;
lab
->
pbus
=
pab
->
bus
;
lab
->
pdevice
=
(
int
)(
padr
>>
16
)
&
0xffff
;
lab
->
pfunction
=
(
int
)(
padr
&
0xffff
);
lab
->
bus
=
(
int
)
bus_num
;
lab
->
scanned
=
0
;
lab
->
type
=
BRIDGE_TYPE_P2P
;
shpchprm_acpi_register_a_bridge
(
&
acpi_bridges_head
,
pab
,
lab
);
}
else
dbg
(
"acpi_shpchprm: found P2P bridge(%x) for sun(%08x)
\n
"
,
(
u32
)
bus_num
,
(
u32
)
sun
);
}
acpi_add_slot_to_php_slots
(
lab
,
(
int
)
bus_num
,
handle
,
(
u32
)
adr
,
(
u32
)
sun
);
return
(
status
);
}
static
int
shpchprm_acpi_build_php_slots
(
struct
acpi_bridge
*
ab
,
u32
depth
)
{
acpi_status
status
;
u8
*
path_name
=
acpi_path_name
(
ab
->
handle
);
/* Walk down this pci bridge to get _SUNs if any behind P2P */
status
=
acpi_walk_namespace
(
ACPI_TYPE_DEVICE
,
ab
->
handle
,
depth
,
shpchprm_acpi_build_php_slots_callback
,
ab
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
dbg
(
"acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x
\n
"
,
path_name
,
ab
->
seg
,
ab
->
bus
,
status
);
return
-
1
;
}
return
0
;
}
static
void
build_a_bridge
(
struct
acpi_bridge
*
pab
,
struct
acpi_bridge
*
ab
)
{
u8
*
path_name
=
acpi_path_name
(
ab
->
handle
);
shpchprm_acpi_register_a_bridge
(
&
acpi_bridges_head
,
pab
,
ab
);
switch
(
ab
->
type
)
{
case
BRIDGE_TYPE_HOST
:
dbg
(
"acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]
\n
"
,
ab
->
bus
,
ab
->
seg
,
ab
->
pbus
,
ab
->
pdevice
,
ab
->
pfunction
,
path_name
);
break
;
case
BRIDGE_TYPE_P2P
:
dbg
(
"acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]
\n
"
,
ab
->
pbus
,
ab
->
bus
,
ab
->
seg
,
ab
->
pbus
,
ab
->
pdevice
,
ab
->
pfunction
,
path_name
);
break
;
};
/* build any immediate PHP slots under this pci bridge */
shpchprm_acpi_build_php_slots
(
ab
,
1
);
}
static
struct
acpi_bridge
*
add_p2p_bridge
(
acpi_handle
handle
,
struct
acpi_bridge
*
pab
,
/* parent */
ulong
adr
)
{
struct
acpi_bridge
*
ab
;
struct
pci_dev
*
pdev
;
ulong
devnum
,
funcnum
;
u8
*
path_name
=
acpi_path_name
(
handle
);
ab
=
(
struct
acpi_bridge
*
)
kmalloc
(
sizeof
(
struct
acpi_bridge
),
GFP_KERNEL
);
if
(
!
ab
)
{
err
(
"acpi_shpchprm: alloc for ab fail
\n
"
);
return
NULL
;
}
memset
(
ab
,
0
,
sizeof
(
struct
acpi_bridge
));
devnum
=
(
adr
>>
16
)
&
0xffff
;
funcnum
=
adr
&
0xffff
;
pdev
=
pci_find_slot
(
pab
->
bus
,
PCI_DEVFN
(
devnum
,
funcnum
));
if
(
!
pdev
||
!
pdev
->
subordinate
)
{
err
(
"acpi_shpchprm:%s is not a P2P Bridge
\n
"
,
path_name
);
kfree
(
ab
);
return
NULL
;
}
ab
->
handle
=
handle
;
ab
->
seg
=
pab
->
seg
;
ab
->
pbus
=
pab
->
bus
;
/* or pdev->bus->number */
ab
->
pdevice
=
devnum
;
/* or PCI_SLOT(pdev->devfn) */
ab
->
pfunction
=
funcnum
;
/* or PCI_FUNC(pdev->devfn) */
ab
->
bus
=
pdev
->
subordinate
->
number
;
ab
->
scanned
=
0
;
ab
->
type
=
BRIDGE_TYPE_P2P
;
dbg
(
"acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]
\n
"
,
pab
->
bus
,
ab
->
bus
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
),
pab
->
bus
,
(
u32
)
devnum
,
(
u32
)
funcnum
,
path_name
);
build_a_bridge
(
pab
,
ab
);
return
ab
;
}
static
acpi_status
scan_p2p_bridge
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
struct
acpi_bridge
*
pab
=
(
struct
acpi_bridge
*
)
context
;
struct
acpi_bridge
*
ab
;
acpi_status
status
;
ulong
adr
=
0
;
u8
*
path_name
=
acpi_path_name
(
handle
);
ulong
devnum
,
funcnum
;
struct
pci_dev
*
pdev
;
/* get device, function */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__ADR
,
NULL
,
&
adr
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
status
!=
AE_NOT_FOUND
)
err
(
"acpi_shpchprm:%s _ADR fail=0x%x
\n
"
,
path_name
,
status
);
return
AE_OK
;
}
devnum
=
(
adr
>>
16
)
&
0xffff
;
funcnum
=
adr
&
0xffff
;
pdev
=
pci_find_slot
(
pab
->
bus
,
PCI_DEVFN
(
devnum
,
funcnum
));
if
(
!
pdev
)
return
AE_OK
;
if
(
!
pdev
->
subordinate
)
return
AE_OK
;
ab
=
add_p2p_bridge
(
handle
,
pab
,
adr
);
if
(
ab
)
{
status
=
acpi_walk_namespace
(
ACPI_TYPE_DEVICE
,
handle
,
(
u32
)
1
,
scan_p2p_bridge
,
ab
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
dbg
(
"acpi_shpchprm:%s find_p2p fail=0x%x
\n
"
,
path_name
,
status
);
}
return
AE_OK
;
}
static
struct
acpi_bridge
*
add_host_bridge
(
acpi_handle
handle
,
ulong
segnum
,
ulong
busnum
)
{
ulong
adr
=
0
;
acpi_status
status
;
struct
acpi_bridge
*
ab
;
u8
*
path_name
=
acpi_path_name
(
handle
);
/* get device, function: host br adr is always 0000 though. */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__ADR
,
NULL
,
&
adr
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s _ADR fail=0x%x
\n
"
,
path_name
,
status
);
return
NULL
;
}
dbg
(
"acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]
\n
"
,
(
u32
)
segnum
,
(
u32
)
busnum
,
(
u32
)(
adr
>>
16
)
&
0xffff
,
(
u32
)
adr
&
0xffff
,
path_name
);
ab
=
(
struct
acpi_bridge
*
)
kmalloc
(
sizeof
(
struct
acpi_bridge
),
GFP_KERNEL
);
if
(
!
ab
)
{
err
(
"acpi_shpchprm: alloc for ab fail
\n
"
);
return
NULL
;
}
memset
(
ab
,
0
,
sizeof
(
struct
acpi_bridge
));
ab
->
handle
=
handle
;
ab
->
seg
=
(
int
)
segnum
;
ab
->
bus
=
ab
->
pbus
=
(
int
)
busnum
;
ab
->
pdevice
=
(
int
)(
adr
>>
16
)
&
0xffff
;
ab
->
pfunction
=
(
int
)(
adr
&
0xffff
);
ab
->
scanned
=
0
;
ab
->
type
=
BRIDGE_TYPE_HOST
;
/* get root pci bridge's current resources */
status
=
acpi_get_crs
(
ab
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s evaluate _CRS fail=0x%x
\n
"
,
path_name
,
status
);
kfree
(
ab
);
return
NULL
;
}
build_a_bridge
(
ab
,
ab
);
return
ab
;
}
static
acpi_status
acpi_scan_from_root_pci_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
ulong
segnum
=
0
;
ulong
busnum
=
0
;
acpi_status
status
;
struct
acpi_bridge
*
ab
;
u8
*
path_name
=
acpi_path_name
(
handle
);
/* get bus number of this pci root bridge */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__SEG
,
NULL
,
&
segnum
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
status
!=
AE_NOT_FOUND
)
{
err
(
"acpi_shpchprm:%s evaluate _SEG fail=0x%x
\n
"
,
path_name
,
status
);
return
status
;
}
segnum
=
0
;
}
/* get bus number of this pci root bridge */
status
=
acpi_evaluate_integer
(
handle
,
METHOD_NAME__BBN
,
NULL
,
&
busnum
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:%s evaluate _BBN fail=0x%x
\n
"
,
path_name
,
status
);
return
(
status
);
}
ab
=
add_host_bridge
(
handle
,
segnum
,
busnum
);
if
(
ab
)
{
status
=
acpi_walk_namespace
(
ACPI_TYPE_DEVICE
,
handle
,
1
,
scan_p2p_bridge
,
ab
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
dbg
(
"acpi_shpchprm:%s find_p2p fail=0x%x
\n
"
,
path_name
,
status
);
}
return
AE_OK
;
}
static
int
shpchprm_acpi_scan_pci
(
void
)
{
acpi_status
status
;
/*
* TBD: traverse LDM device tree with the help of
* unified ACPI augmented for php device population.
*/
status
=
acpi_get_devices
(
PCI_ROOT_HID_STRING
,
acpi_scan_from_root_pci_callback
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"acpi_shpchprm:get_device PCI ROOT HID fail=0x%x
\n
"
,
status
);
return
-
1
;
}
return
0
;
}
int
shpchprm_init
(
enum
php_ctlr_type
ctlr_type
)
{
int
rc
;
if
(
ctlr_type
!=
PCI
)
return
-
ENODEV
;
dbg
(
"shpchprm ACPI init <enter>
\n
"
);
acpi_bridges_head
=
NULL
;
/* construct PCI bus:device tree of acpi_handles */
rc
=
shpchprm_acpi_scan_pci
();
if
(
rc
)
return
rc
;
dbg
(
"shpchprm ACPI init %s
\n
"
,
(
rc
)
?
"fail"
:
"success"
);
return
rc
;
}
static
void
free_a_slot
(
struct
acpi_php_slot
*
aps
)
{
dbg
(
" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x
\n
"
,
aps
->
sun
,
aps
->
bus
,
aps
->
dev
,
aps
->
fun
);
free_pci_resource
(
aps
->
io_head
);
free_pci_resource
(
aps
->
bus_head
);
free_pci_resource
(
aps
->
mem_head
);
free_pci_resource
(
aps
->
p_mem_head
);
kfree
(
aps
);
}
static
void
free_a_bridge
(
struct
acpi_bridge
*
ab
)
{
struct
acpi_php_slot
*
aps
,
*
next
;
switch
(
ab
->
type
)
{
case
BRIDGE_TYPE_HOST
:
dbg
(
"Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)
\n
"
,
ab
->
bus
,
acpi_path_name
(
ab
->
handle
),
ab
->
seg
,
ab
->
pbus
,
ab
->
pdevice
,
ab
->
pfunction
);
break
;
case
BRIDGE_TYPE_P2P
:
dbg
(
"Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)
\n
"
,
ab
->
pbus
,
ab
->
bus
,
acpi_path_name
(
ab
->
handle
),
ab
->
seg
,
ab
->
pbus
,
ab
->
pdevice
,
ab
->
pfunction
);
break
;
};
/* free slots first */
for
(
aps
=
ab
->
slots
;
aps
;
aps
=
next
)
{
next
=
aps
->
next
;
free_a_slot
(
aps
);
}
free_pci_resource
(
ab
->
io_head
);
free_pci_resource
(
ab
->
tio_head
);
free_pci_resource
(
ab
->
bus_head
);
free_pci_resource
(
ab
->
tbus_head
);
free_pci_resource
(
ab
->
mem_head
);
free_pci_resource
(
ab
->
tmem_head
);
free_pci_resource
(
ab
->
p_mem_head
);
free_pci_resource
(
ab
->
tp_mem_head
);
kfree
(
ab
);
}
static
void
shpchprm_free_bridges
(
struct
acpi_bridge
*
ab
)
{
if
(
!
ab
)
return
;
if
(
ab
->
child
)
shpchprm_free_bridges
(
ab
->
child
);
if
(
ab
->
next
)
shpchprm_free_bridges
(
ab
->
next
);
free_a_bridge
(
ab
);
}
void
shpchprm_cleanup
(
void
)
{
shpchprm_free_bridges
(
acpi_bridges_head
);
}
static
int
get_number_of_slots
(
struct
acpi_bridge
*
ab
,
int
selfonly
)
{
struct
acpi_php_slot
*
aps
;
int
prev_slot
=
-
1
;
int
slot_num
=
0
;
for
(
aps
=
ab
->
slots
;
aps
;
aps
=
aps
->
next
)
if
(
aps
->
dev
!=
prev_slot
)
{
prev_slot
=
aps
->
dev
;
slot_num
++
;
}
if
(
ab
->
child
)
slot_num
+=
get_number_of_slots
(
ab
->
child
,
0
);
if
(
selfonly
)
return
slot_num
;
if
(
ab
->
next
)
slot_num
+=
get_number_of_slots
(
ab
->
next
,
0
);
return
slot_num
;
}
static
int
print_acpi_resources
(
struct
acpi_bridge
*
ab
)
{
struct
acpi_php_slot
*
aps
;
int
i
;
switch
(
ab
->
type
)
{
case
BRIDGE_TYPE_HOST
:
dbg
(
"PCI HOST Bridge (%x) [%s]
\n
"
,
ab
->
bus
,
acpi_path_name
(
ab
->
handle
));
break
;
case
BRIDGE_TYPE_P2P
:
dbg
(
"PCI P2P Bridge (%x-%x) [%s]
\n
"
,
ab
->
pbus
,
ab
->
bus
,
acpi_path_name
(
ab
->
handle
));
break
;
};
print_pci_resources
(
ab
);
for
(
i
=
-
1
,
aps
=
ab
->
slots
;
aps
;
aps
=
aps
->
next
)
{
if
(
aps
->
dev
==
i
)
continue
;
dbg
(
" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)
\n
"
,
aps
->
sun
,
aps
->
seg
,
aps
->
bus
,
aps
->
dev
,
aps
->
fun
);
print_slot_resources
(
aps
);
i
=
aps
->
dev
;
}
if
(
ab
->
child
)
print_acpi_resources
(
ab
->
child
);
if
(
ab
->
next
)
print_acpi_resources
(
ab
->
next
);
return
0
;
}
int
shpchprm_print_pirt
(
void
)
{
dbg
(
"SHPCHPRM ACPI Slots
\n
"
);
if
(
acpi_bridges_head
)
print_acpi_resources
(
acpi_bridges_head
);
return
0
;
}
static
struct
acpi_php_slot
*
get_acpi_slot
(
struct
acpi_bridge
*
ab
,
u32
sun
)
{
struct
acpi_php_slot
*
aps
=
NULL
;
for
(
aps
=
ab
->
slots
;
aps
;
aps
=
aps
->
next
)
if
(
aps
->
sun
==
sun
)
return
aps
;
if
(
!
aps
&&
ab
->
child
)
{
aps
=
(
struct
acpi_php_slot
*
)
get_acpi_slot
(
ab
->
child
,
sun
);
if
(
aps
)
return
aps
;
}
if
(
!
aps
&&
ab
->
next
)
{
aps
=
(
struct
acpi_php_slot
*
)
get_acpi_slot
(
ab
->
next
,
sun
);
if
(
aps
)
return
aps
;
}
return
aps
;
}
#if 0
static void * shpchprm_get_slot(struct slot *slot)
{
struct acpi_bridge *ab = acpi_bridges_head;
struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
aps->slot = slot;
dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
return (void *)aps;
}
#endif
static
void
shpchprm_dump_func_res
(
struct
pci_func
*
fun
)
{
struct
pci_func
*
func
=
fun
;
if
(
func
->
bus_head
)
{
dbg
(
": BUS Resources:
\n
"
);
print_pci_resource
(
func
->
bus_head
);
}
if
(
func
->
io_head
)
{
dbg
(
": IO Resources:
\n
"
);
print_pci_resource
(
func
->
io_head
);
}
if
(
func
->
mem_head
)
{
dbg
(
": MEM Resources:
\n
"
);
print_pci_resource
(
func
->
mem_head
);
}
if
(
func
->
p_mem_head
)
{
dbg
(
": PMEM Resources:
\n
"
);
print_pci_resource
(
func
->
p_mem_head
);
}
}
static
void
shpchprm_dump_ctrl_res
(
struct
controller
*
ctlr
)
{
struct
controller
*
ctrl
=
ctlr
;
if
(
ctrl
->
bus_head
)
{
dbg
(
": BUS Resources:
\n
"
);
print_pci_resource
(
ctrl
->
bus_head
);
}
if
(
ctrl
->
io_head
)
{
dbg
(
": IO Resources:
\n
"
);
print_pci_resource
(
ctrl
->
io_head
);
}
if
(
ctrl
->
mem_head
)
{
dbg
(
": MEM Resources:
\n
"
);
print_pci_resource
(
ctrl
->
mem_head
);
}
if
(
ctrl
->
p_mem_head
)
{
dbg
(
": PMEM Resources:
\n
"
);
print_pci_resource
(
ctrl
->
p_mem_head
);
}
}
static
int
shpchprm_get_used_resources
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
)
{
return
shpchp_save_used_resources
(
ctrl
,
func
,
!
DISABLE_CARD
);
}
static
int
configure_existing_function
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
)
{
int
rc
;
/* see how much resources the func has used. */
rc
=
shpchprm_get_used_resources
(
ctrl
,
func
);
if
(
!
rc
)
{
/* subtract the resources used by the func from ctrl resources */
rc
=
shpchprm_delete_resources
(
&
ctrl
->
bus_head
,
func
->
bus_head
);
rc
|=
shpchprm_delete_resources
(
&
ctrl
->
io_head
,
func
->
io_head
);
rc
|=
shpchprm_delete_resources
(
&
ctrl
->
mem_head
,
func
->
mem_head
);
rc
|=
shpchprm_delete_resources
(
&
ctrl
->
p_mem_head
,
func
->
p_mem_head
);
if
(
rc
)
warn
(
"aCEF: cannot del used resources
\n
"
);
}
else
err
(
"aCEF: cannot get used resources
\n
"
);
return
rc
;
}
static
int
bind_pci_resources_to_slots
(
struct
controller
*
ctrl
)
{
struct
pci_func
*
func
,
new_func
;
int
busn
=
ctrl
->
slot_bus
;
int
devn
,
funn
;
u32
vid
;
for
(
devn
=
0
;
devn
<
32
;
devn
++
)
{
for
(
funn
=
0
;
funn
<
8
;
funn
++
)
{
/*
if (devn == ctrl->device && funn == ctrl->function)
continue;
*/
/* find out if this entry is for an occupied slot */
vid
=
0xFFFFFFFF
;
pci_bus_read_config_dword
(
ctrl
->
pci_dev
->
subordinate
,
PCI_DEVFN
(
devn
,
funn
),
PCI_VENDOR_ID
,
&
vid
);
if
(
vid
!=
0xFFFFFFFF
)
{
func
=
shpchp_slot_find
(
busn
,
devn
,
funn
);
if
(
!
func
)
{
memset
(
&
new_func
,
0
,
sizeof
(
struct
pci_func
));
new_func
.
bus
=
busn
;
new_func
.
device
=
devn
;
new_func
.
function
=
funn
;
new_func
.
is_a_board
=
1
;
configure_existing_function
(
ctrl
,
&
new_func
);
shpchprm_dump_func_res
(
&
new_func
);
}
else
{
configure_existing_function
(
ctrl
,
func
);
shpchprm_dump_func_res
(
func
);
}
dbg
(
"aCCF:existing PCI 0x%x Func ResourceDump
\n
"
,
ctrl
->
bus
);
}
}
}
return
0
;
}
static
int
bind_pci_resources
(
struct
controller
*
ctrl
,
struct
acpi_bridge
*
ab
)
{
int
status
=
0
;
if
(
ab
->
bus_head
)
{
dbg
(
"bapr: BUS Resources add on PCI 0x%x
\n
"
,
ab
->
bus
);
status
=
shpchprm_add_resources
(
&
ctrl
->
bus_head
,
ab
->
bus_head
);
if
(
shpchprm_delete_resources
(
&
ab
->
bus_head
,
ctrl
->
bus_head
))
warn
(
"bapr: cannot sub BUS Resource on PCI 0x%x
\n
"
,
ab
->
bus
);
if
(
status
)
{
err
(
"bapr: BUS Resource add on PCI 0x%x: fail=0x%x
\n
"
,
ab
->
bus
,
status
);
return
status
;
}
}
else
info
(
"bapr: No BUS Resource on PCI 0x%x.
\n
"
,
ab
->
bus
);
if
(
ab
->
io_head
)
{
dbg
(
"bapr: IO Resources add on PCI 0x%x
\n
"
,
ab
->
bus
);
status
=
shpchprm_add_resources
(
&
ctrl
->
io_head
,
ab
->
io_head
);
if
(
shpchprm_delete_resources
(
&
ab
->
io_head
,
ctrl
->
io_head
))
warn
(
"bapr: cannot sub IO Resource on PCI 0x%x
\n
"
,
ab
->
bus
);
if
(
status
)
{
err
(
"bapr: IO Resource add on PCI 0x%x: fail=0x%x
\n
"
,
ab
->
bus
,
status
);
return
status
;
}
}
else
info
(
"bapr: No IO Resource on PCI 0x%x.
\n
"
,
ab
->
bus
);
if
(
ab
->
mem_head
)
{
dbg
(
"bapr: MEM Resources add on PCI 0x%x
\n
"
,
ab
->
bus
);
status
=
shpchprm_add_resources
(
&
ctrl
->
mem_head
,
ab
->
mem_head
);
if
(
shpchprm_delete_resources
(
&
ab
->
mem_head
,
ctrl
->
mem_head
))
warn
(
"bapr: cannot sub MEM Resource on PCI 0x%x
\n
"
,
ab
->
bus
);
if
(
status
)
{
err
(
"bapr: MEM Resource add on PCI 0x%x: fail=0x%x
\n
"
,
ab
->
bus
,
status
);
return
status
;
}
}
else
info
(
"bapr: No MEM Resource on PCI 0x%x.
\n
"
,
ab
->
bus
);
if
(
ab
->
p_mem_head
)
{
dbg
(
"bapr: PMEM Resources add on PCI 0x%x
\n
"
,
ab
->
bus
);
status
=
shpchprm_add_resources
(
&
ctrl
->
p_mem_head
,
ab
->
p_mem_head
);
if
(
shpchprm_delete_resources
(
&
ab
->
p_mem_head
,
ctrl
->
p_mem_head
))
warn
(
"bapr: cannot sub PMEM Resource on PCI 0x%x
\n
"
,
ab
->
bus
);
if
(
status
)
{
err
(
"bapr: PMEM Resource add on PCI 0x%x: fail=0x%x
\n
"
,
ab
->
bus
,
status
);
return
status
;
}
}
else
info
(
"bapr: No PMEM Resource on PCI 0x%x.
\n
"
,
ab
->
bus
);
return
status
;
}
static
int
no_pci_resources
(
struct
acpi_bridge
*
ab
)
{
return
!
(
ab
->
p_mem_head
||
ab
->
mem_head
||
ab
->
io_head
||
ab
->
bus_head
);
}
static
int
find_pci_bridge_resources
(
struct
controller
*
ctrl
,
struct
acpi_bridge
*
ab
)
{
int
rc
=
0
;
struct
pci_func
func
;
memset
(
&
func
,
0
,
sizeof
(
struct
pci_func
));
func
.
bus
=
ab
->
pbus
;
func
.
device
=
ab
->
pdevice
;
func
.
function
=
ab
->
pfunction
;
func
.
is_a_board
=
1
;
/* Get used resources for this PCI bridge */
rc
=
shpchp_save_used_resources
(
ctrl
,
&
func
,
!
DISABLE_CARD
);
ab
->
io_head
=
func
.
io_head
;
ab
->
mem_head
=
func
.
mem_head
;
ab
->
p_mem_head
=
func
.
p_mem_head
;
ab
->
bus_head
=
func
.
bus_head
;
if
(
ab
->
bus_head
)
shpchprm_delete_resource
(
&
ab
->
bus_head
,
ctrl
->
bus
,
1
);
return
rc
;
}
static
int
get_pci_resources_from_bridge
(
struct
controller
*
ctrl
,
struct
acpi_bridge
*
ab
)
{
int
rc
=
0
;
dbg
(
"grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.
\n
"
,
ctrl
->
bus
,
ab
->
bus
);
rc
=
find_pci_bridge_resources
(
ctrl
,
ab
);
shpchp_resource_sort_and_combine
(
&
ab
->
bus_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
io_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
mem_head
);
shpchp_resource_sort_and_combine
(
&
ab
->
p_mem_head
);
shpchprm_add_resources
(
&
ab
->
tbus_head
,
ab
->
bus_head
);
shpchprm_add_resources
(
&
ab
->
tio_head
,
ab
->
io_head
);
shpchprm_add_resources
(
&
ab
->
tmem_head
,
ab
->
mem_head
);
shpchprm_add_resources
(
&
ab
->
tp_mem_head
,
ab
->
p_mem_head
);
return
rc
;
}
static
int
get_pci_resources
(
struct
controller
*
ctrl
,
struct
acpi_bridge
*
ab
)
{
int
rc
=
0
;
if
(
no_pci_resources
(
ab
))
{
dbg
(
"spbr:PCI 0x%x has no resources. Get parent resources.
\n
"
,
ab
->
bus
);
rc
=
get_pci_resources_from_bridge
(
ctrl
,
ab
);
}
return
rc
;
}
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
)
{
int
offset
=
devnum
-
ctrl
->
slot_device_offset
;
dbg
(
"%s: ctrl->slot_num_inc %d, offset %d
\n
"
,
__FUNCTION__
,
ctrl
->
slot_num_inc
,
offset
);
*
sun
=
(
u8
)
(
ctrl
->
first_slot
+
ctrl
->
slot_num_inc
*
offset
);
return
0
;
}
/*
* Get resources for this ctrl.
* 1. get total resources from ACPI _CRS or bridge (this ctrl)
* 2. find used resources of existing adapters
* 3. subtract used resources from total resources
*/
int
shpchprm_find_available_resources
(
struct
controller
*
ctrl
)
{
int
rc
=
0
;
struct
acpi_bridge
*
ab
;
ab
=
find_acpi_bridge_by_bus
(
acpi_bridges_head
,
ctrl
->
seg
,
ctrl
->
pci_dev
->
subordinate
->
number
);
if
(
!
ab
)
{
err
(
"pfar:cannot locate acpi bridge of PCI 0x%x.
\n
"
,
ctrl
->
pci_dev
->
subordinate
->
number
);
return
-
1
;
}
if
(
no_pci_resources
(
ab
))
{
rc
=
get_pci_resources
(
ctrl
,
ab
);
if
(
rc
)
{
err
(
"pfar:cannot get pci resources of PCI 0x%x.
\n
"
,
ctrl
->
pci_dev
->
subordinate
->
number
);
return
-
1
;
}
}
rc
=
bind_pci_resources
(
ctrl
,
ab
);
dbg
(
"pfar:pre-Bind PCI 0x%x Ctrl Resource Dump
\n
"
,
ctrl
->
pci_dev
->
subordinate
->
number
);
shpchprm_dump_ctrl_res
(
ctrl
);
bind_pci_resources_to_slots
(
ctrl
);
dbg
(
"pfar:post-Bind PCI 0x%x Ctrl Resource Dump
\n
"
,
ctrl
->
pci_dev
->
subordinate
->
number
);
shpchprm_dump_ctrl_res
(
ctrl
);
return
rc
;
}
int
shpchprm_set_hpp
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
{
struct
acpi_bridge
*
ab
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
int
rc
=
0
;
unsigned
int
devfn
;
u8
cls
=
0x08
;
/* default cache line size */
u8
lt
=
0x40
;
/* default latency timer */
u8
ep
=
0
;
u8
es
=
0
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
ab
=
find_acpi_bridge_by_bus
(
acpi_bridges_head
,
ctrl
->
seg
,
ctrl
->
slot_bus
);
if
(
ab
)
{
if
(
ab
->
_hpp
)
{
lt
=
(
u8
)
ab
->
_hpp
->
latency_timer
;
cls
=
(
u8
)
ab
->
_hpp
->
cache_line_size
;
ep
=
(
u8
)
ab
->
_hpp
->
enable_perr
;
es
=
(
u8
)
ab
->
_hpp
->
enable_serr
;
}
else
dbg
(
"_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value
\n
"
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
else
dbg
(
"_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value
\n
"
,
func
->
bus
,
func
->
device
,
func
->
function
);
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* set subordinate Latency Timer */
rc
|=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SEC_LATENCY_TIMER
,
lt
);
}
/* set base Latency Timer */
rc
|=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_LATENCY_TIMER
,
lt
);
dbg
(
" set latency timer =0x%02x: %x
\n
"
,
lt
,
rc
);
rc
|=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_CACHE_LINE_SIZE
,
cls
);
dbg
(
" set cache_line_size=0x%02x: %x
\n
"
,
cls
,
rc
);
return
rc
;
}
void
shpchprm_enable_card
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
{
u16
command
,
cmd
,
bcommand
,
bcmd
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
struct
acpi_bridge
*
ab
;
unsigned
int
devfn
;
int
rc
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
&
command
);
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
&
bcommand
);
}
cmd
=
command
=
command
|
PCI_COMMAND_MASTER
|
PCI_COMMAND_INVALIDATE
|
PCI_COMMAND_IO
|
PCI_COMMAND_MEMORY
;
bcmd
=
bcommand
=
bcommand
|
PCI_BRIDGE_CTL_NO_ISA
;
ab
=
find_acpi_bridge_by_bus
(
acpi_bridges_head
,
ctrl
->
seg
,
ctrl
->
slot_bus
);
if
(
ab
)
{
if
(
ab
->
_hpp
)
{
if
(
ab
->
_hpp
->
enable_perr
)
{
command
|=
PCI_COMMAND_PARITY
;
bcommand
|=
PCI_BRIDGE_CTL_PARITY
;
}
else
{
command
&=
~
PCI_COMMAND_PARITY
;
bcommand
&=
~
PCI_BRIDGE_CTL_PARITY
;
}
if
(
ab
->
_hpp
->
enable_serr
)
{
command
|=
PCI_COMMAND_SERR
;
bcommand
|=
PCI_BRIDGE_CTL_SERR
;
}
else
{
command
&=
~
PCI_COMMAND_SERR
;
bcommand
&=
~
PCI_BRIDGE_CTL_SERR
;
}
}
else
dbg
(
"no _hpp for B/D/F = %#x/%#x/%#x.
\n
"
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
else
dbg
(
"no acpi bridge for B/D/F = %#x/%#x/%#x.
\n
"
,
func
->
bus
,
func
->
device
,
func
->
function
);
if
(
command
!=
cmd
)
{
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
command
);
}
if
((
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
&&
(
bcommand
!=
bcmd
))
{
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
bcommand
);
/* Check if a parent object supports _HPP */
pdev
=
pdev
->
bus
->
parent
->
self
;
}
}
drivers/pci/hotplug/shpchprm_legacy.c
View file @
7efe5d7c
...
...
@@ -27,33 +27,11 @@
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#ifdef CONFIG_IA64
#include <asm/iosapic.h>
#endif
#include "shpchp.h"
#include "shpchprm.h"
#include "shpchprm_legacy.h"
static
void
__iomem
*
shpchp_rom_start
;
static
u16
unused_IRQ
;
void
shpchprm_cleanup
(
void
)
{
if
(
shpchp_rom_start
)
iounmap
(
shpchp_rom_start
);
}
int
shpchprm_print_pirt
(
void
)
{
return
0
;
}
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
)
{
...
...
@@ -63,377 +41,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
return
0
;
}
/* Find the Hot Plug Resource Table in the specified region of memory */
static
void
__iomem
*
detect_HRT_floating_pointer
(
void
__iomem
*
begin
,
void
__iomem
*
end
)
void
get_hp_params_from_firmware
(
struct
pci_dev
*
dev
,
struct
hotplug_params
*
hpp
)
{
void
__iomem
*
fp
;
void
__iomem
*
endp
;
u8
temp1
,
temp2
,
temp3
,
temp4
;
int
status
=
0
;
endp
=
(
end
-
sizeof
(
struct
hrt
)
+
1
);
for
(
fp
=
begin
;
fp
<=
endp
;
fp
+=
16
)
{
temp1
=
readb
(
fp
+
SIG0
);
temp2
=
readb
(
fp
+
SIG1
);
temp3
=
readb
(
fp
+
SIG2
);
temp4
=
readb
(
fp
+
SIG3
);
if
(
temp1
==
'$'
&&
temp2
==
'H'
&&
temp3
==
'R'
&&
temp4
==
'T'
)
{
status
=
1
;
break
;
}
}
if
(
!
status
)
fp
=
NULL
;
dbg
(
"Discovered Hotplug Resource Table at %p
\n
"
,
fp
);
return
fp
;
return
;
}
/*
* shpchprm_find_available_resources
*
* Finds available memory, IO, and IRQ resources for programming
* devices which may be added to the system
* this function is for hot plug ADD!
*
* returns 0 if success
*/
int
shpchprm_find_available_resources
(
struct
controller
*
ctrl
)
void
get_hp_hw_control_from_firmware
(
struct
pci_dev
*
dev
)
{
u8
populated_slot
;
u8
bridged_slot
;
void
__iomem
*
one_slot
;
struct
pci_func
*
func
=
NULL
;
int
i
=
10
,
index
=
0
;
u32
temp_dword
,
rc
;
ulong
temp_ulong
;
struct
pci_resource
*
mem_node
;
struct
pci_resource
*
p_mem_node
;
struct
pci_resource
*
io_node
;
struct
pci_resource
*
bus_node
;
void
__iomem
*
rom_resource_table
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
u8
cfgspc_irq
,
temp
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
rom_resource_table
=
detect_HRT_floating_pointer
(
shpchp_rom_start
,
shpchp_rom_start
+
0xffff
);
dbg
(
"rom_resource_table = %p
\n
"
,
rom_resource_table
);
if
(
rom_resource_table
==
NULL
)
return
-
ENODEV
;
/* Sum all resources and setup resource maps */
unused_IRQ
=
readl
(
rom_resource_table
+
UNUSED_IRQ
);
dbg
(
"unused_IRQ = %x
\n
"
,
unused_IRQ
);
temp
=
0
;
while
(
unused_IRQ
)
{
if
(
unused_IRQ
&
1
)
{
shpchp_disk_irq
=
temp
;
break
;
}
unused_IRQ
=
unused_IRQ
>>
1
;
temp
++
;
}
dbg
(
"shpchp_disk_irq= %d
\n
"
,
shpchp_disk_irq
);
unused_IRQ
=
unused_IRQ
>>
1
;
temp
++
;
while
(
unused_IRQ
)
{
if
(
unused_IRQ
&
1
)
{
shpchp_nic_irq
=
temp
;
break
;
}
unused_IRQ
=
unused_IRQ
>>
1
;
temp
++
;
}
dbg
(
"shpchp_nic_irq= %d
\n
"
,
shpchp_nic_irq
);
unused_IRQ
=
readl
(
rom_resource_table
+
PCIIRQ
);
temp
=
0
;
pci_read_config_byte
(
ctrl
->
pci_dev
,
PCI_INTERRUPT_LINE
,
&
cfgspc_irq
);
if
(
!
shpchp_nic_irq
)
{
shpchp_nic_irq
=
cfgspc_irq
;
}
if
(
!
shpchp_disk_irq
)
{
shpchp_disk_irq
=
cfgspc_irq
;
}
dbg
(
"shpchp_disk_irq, shpchp_nic_irq= %d, %d
\n
"
,
shpchp_disk_irq
,
shpchp_nic_irq
);
one_slot
=
rom_resource_table
+
sizeof
(
struct
hrt
);
i
=
readb
(
rom_resource_table
+
NUMBER_OF_ENTRIES
);
dbg
(
"number_of_entries = %d
\n
"
,
i
);
if
(
!
readb
(
one_slot
+
SECONDARY_BUS
))
return
(
1
);
dbg
(
"dev|IO base|length|MEMbase|length|PM base|length|PB SB MB
\n
"
);
while
(
i
&&
readb
(
one_slot
+
SECONDARY_BUS
))
{
u8
dev_func
=
readb
(
one_slot
+
DEV_FUNC
);
u8
primary_bus
=
readb
(
one_slot
+
PRIMARY_BUS
);
u8
secondary_bus
=
readb
(
one_slot
+
SECONDARY_BUS
);
u8
max_bus
=
readb
(
one_slot
+
MAX_BUS
);
u16
io_base
=
readw
(
one_slot
+
IO_BASE
);
u16
io_length
=
readw
(
one_slot
+
IO_LENGTH
);
u16
mem_base
=
readw
(
one_slot
+
MEM_BASE
);
u16
mem_length
=
readw
(
one_slot
+
MEM_LENGTH
);
u16
pre_mem_base
=
readw
(
one_slot
+
PRE_MEM_BASE
);
u16
pre_mem_length
=
readw
(
one_slot
+
PRE_MEM_LENGTH
);
dbg
(
"%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x
\n
"
,
dev_func
,
io_base
,
io_length
,
mem_base
,
mem_length
,
pre_mem_base
,
pre_mem_length
,
primary_bus
,
secondary_bus
,
max_bus
);
/* If this entry isn't for our controller's bus, ignore it */
if
(
primary_bus
!=
ctrl
->
slot_bus
)
{
i
--
;
one_slot
+=
sizeof
(
struct
slot_rt
);
continue
;
}
/* find out if this entry is for an occupied slot */
temp_dword
=
0xFFFFFFFF
;
pci_bus
->
number
=
primary_bus
;
pci_bus_read_config_dword
(
pci_bus
,
dev_func
,
PCI_VENDOR_ID
,
&
temp_dword
);
dbg
(
"temp_D_word = %x
\n
"
,
temp_dword
);
if
(
temp_dword
!=
0xFFFFFFFF
)
{
index
=
0
;
func
=
shpchp_slot_find
(
primary_bus
,
dev_func
>>
3
,
0
);
while
(
func
&&
(
func
->
function
!=
(
dev_func
&
0x07
)))
{
dbg
(
"func = %p b:d:f(%x:%x:%x)
\n
"
,
func
,
primary_bus
,
dev_func
>>
3
,
index
);
func
=
shpchp_slot_find
(
primary_bus
,
dev_func
>>
3
,
index
++
);
}
/* If we can't find a match, skip this table entry */
if
(
!
func
)
{
i
--
;
one_slot
+=
sizeof
(
struct
slot_rt
);
continue
;
}
/* this may not work and shouldn't be used */
if
(
secondary_bus
!=
primary_bus
)
bridged_slot
=
1
;
else
bridged_slot
=
0
;
populated_slot
=
1
;
}
else
{
populated_slot
=
0
;
bridged_slot
=
0
;
}
dbg
(
"slot populated =%s
\n
"
,
populated_slot
?
"yes"
:
"no"
);
/* If we've got a valid IO base, use it */
temp_ulong
=
io_base
+
io_length
;
if
((
io_base
)
&&
(
temp_ulong
<=
0x10000
))
{
io_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
io_node
)
return
-
ENOMEM
;
io_node
->
base
=
(
ulong
)
io_base
;
io_node
->
length
=
(
ulong
)
io_length
;
dbg
(
"found io_node(base, length) = %x, %x
\n
"
,
io_node
->
base
,
io_node
->
length
);
if
(
!
populated_slot
)
{
io_node
->
next
=
ctrl
->
io_head
;
ctrl
->
io_head
=
io_node
;
}
else
{
io_node
->
next
=
func
->
io_head
;
func
->
io_head
=
io_node
;
}
}
/* If we've got a valid memory base, use it */
temp_ulong
=
mem_base
+
mem_length
;
if
((
mem_base
)
&&
(
temp_ulong
<=
0x10000
))
{
mem_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
mem_node
)
return
-
ENOMEM
;
mem_node
->
base
=
(
ulong
)
mem_base
<<
16
;
mem_node
->
length
=
(
ulong
)(
mem_length
<<
16
);
dbg
(
"found mem_node(base, length) = %x, %x
\n
"
,
mem_node
->
base
,
mem_node
->
length
);
if
(
!
populated_slot
)
{
mem_node
->
next
=
ctrl
->
mem_head
;
ctrl
->
mem_head
=
mem_node
;
}
else
{
mem_node
->
next
=
func
->
mem_head
;
func
->
mem_head
=
mem_node
;
}
}
/*
* If we've got a valid prefetchable memory base, and
* the base + length isn't greater than 0xFFFF
*/
temp_ulong
=
pre_mem_base
+
pre_mem_length
;
if
((
pre_mem_base
)
&&
(
temp_ulong
<=
0x10000
))
{
p_mem_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
p_mem_node
)
return
-
ENOMEM
;
p_mem_node
->
base
=
(
ulong
)
pre_mem_base
<<
16
;
p_mem_node
->
length
=
(
ulong
)
pre_mem_length
<<
16
;
dbg
(
"found p_mem_node(base, length) = %x, %x
\n
"
,
p_mem_node
->
base
,
p_mem_node
->
length
);
if
(
!
populated_slot
)
{
p_mem_node
->
next
=
ctrl
->
p_mem_head
;
ctrl
->
p_mem_head
=
p_mem_node
;
}
else
{
p_mem_node
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
p_mem_node
;
}
}
/*
* If we've got a valid bus number, use it
* The second condition is to ignore bus numbers on
* populated slots that don't have PCI-PCI bridges
*/
if
(
secondary_bus
&&
(
secondary_bus
!=
primary_bus
))
{
bus_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
bus_node
)
return
-
ENOMEM
;
bus_node
->
base
=
(
ulong
)
secondary_bus
;
bus_node
->
length
=
(
ulong
)(
max_bus
-
secondary_bus
+
1
);
dbg
(
"found bus_node(base, length) = %x, %x
\n
"
,
bus_node
->
base
,
bus_node
->
length
);
if
(
!
populated_slot
)
{
bus_node
->
next
=
ctrl
->
bus_head
;
ctrl
->
bus_head
=
bus_node
;
}
else
{
bus_node
->
next
=
func
->
bus_head
;
func
->
bus_head
=
bus_node
;
}
}
i
--
;
one_slot
+=
sizeof
(
struct
slot_rt
);
}
/* If all of the following fail, we don't have any resources for hot plug add */
rc
=
1
;
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
mem_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
p_mem_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
io_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
bus_head
));
return
(
rc
);
}
int
shpchprm_set_hpp
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
{
u32
rc
;
u8
temp_byte
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
unsigned
int
devfn
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
temp_byte
=
0x40
;
/* hard coded value for LT */
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* set subordinate Latency Timer */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SEC_LATENCY_TIMER
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set secondary LT error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
return
rc
;
}
}
/* set base Latency Timer */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_LATENCY_TIMER
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set LT error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
return
rc
;
}
/* set Cache Line size */
temp_byte
=
0x08
;
/* hard coded value for CLS */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_CACHE_LINE_SIZE
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set CLS error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
/* set enable_perr */
/* set enable_serr */
return
rc
;
}
void
shpchprm_enable_card
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
{
u16
command
,
bcommand
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
unsigned
int
devfn
;
int
rc
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
&
command
);
command
|=
PCI_COMMAND_PARITY
|
PCI_COMMAND_SERR
|
PCI_COMMAND_MASTER
|
PCI_COMMAND_INVALIDATE
|
PCI_COMMAND_IO
|
PCI_COMMAND_MEMORY
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
command
);
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
&
bcommand
);
bcommand
|=
PCI_BRIDGE_CTL_PARITY
|
PCI_BRIDGE_CTL_SERR
|
PCI_BRIDGE_CTL_NO_ISA
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
bcommand
);
}
}
static
int
legacy_shpchprm_init_pci
(
void
)
{
shpchp_rom_start
=
ioremap
(
ROM_PHY_ADDR
,
ROM_PHY_LEN
);
if
(
!
shpchp_rom_start
)
{
err
(
"Could not ioremap memory region for ROM
\n
"
);
return
-
EIO
;
}
return
0
;
return
;
}
int
shpchprm_init
(
enum
php_ctlr_type
ctrl_type
)
{
int
retval
;
switch
(
ctrl_type
)
{
case
PCI
:
retval
=
legacy_shpchprm_init_pci
();
break
;
default:
retval
=
-
ENODEV
;
break
;
}
return
retval
;
}
drivers/pci/hotplug/shpchprm_legacy.h
deleted
100644 → 0
View file @
dbe0580d
/*
* SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2003-2004 Intel Corporation
*
* All rights reserved.
*
* 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 of the License, 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
#ifndef _SHPCHPRM_LEGACY_H_
#define _SHPCHPRM_LEGACY_H_
#define ROM_PHY_ADDR 0x0F0000
#define ROM_PHY_LEN 0x00FFFF
struct
slot_rt
{
u8
dev_func
;
u8
primary_bus
;
u8
secondary_bus
;
u8
max_bus
;
u16
io_base
;
u16
io_length
;
u16
mem_base
;
u16
mem_length
;
u16
pre_mem_base
;
u16
pre_mem_length
;
}
__attribute__
((
packed
));
/* offsets to the hotplug slot resource table registers based on the above structure layout */
enum
slot_rt_offsets
{
DEV_FUNC
=
offsetof
(
struct
slot_rt
,
dev_func
),
PRIMARY_BUS
=
offsetof
(
struct
slot_rt
,
primary_bus
),
SECONDARY_BUS
=
offsetof
(
struct
slot_rt
,
secondary_bus
),
MAX_BUS
=
offsetof
(
struct
slot_rt
,
max_bus
),
IO_BASE
=
offsetof
(
struct
slot_rt
,
io_base
),
IO_LENGTH
=
offsetof
(
struct
slot_rt
,
io_length
),
MEM_BASE
=
offsetof
(
struct
slot_rt
,
mem_base
),
MEM_LENGTH
=
offsetof
(
struct
slot_rt
,
mem_length
),
PRE_MEM_BASE
=
offsetof
(
struct
slot_rt
,
pre_mem_base
),
PRE_MEM_LENGTH
=
offsetof
(
struct
slot_rt
,
pre_mem_length
),
};
struct
hrt
{
char
sig0
;
char
sig1
;
char
sig2
;
char
sig3
;
u16
unused_IRQ
;
u16
PCIIRQ
;
u8
number_of_entries
;
u8
revision
;
u16
reserved1
;
u32
reserved2
;
}
__attribute__
((
packed
));
/* offsets to the hotplug resource table registers based on the above structure layout */
enum
hrt_offsets
{
SIG0
=
offsetof
(
struct
hrt
,
sig0
),
SIG1
=
offsetof
(
struct
hrt
,
sig1
),
SIG2
=
offsetof
(
struct
hrt
,
sig2
),
SIG3
=
offsetof
(
struct
hrt
,
sig3
),
UNUSED_IRQ
=
offsetof
(
struct
hrt
,
unused_IRQ
),
PCIIRQ
=
offsetof
(
struct
hrt
,
PCIIRQ
),
NUMBER_OF_ENTRIES
=
offsetof
(
struct
hrt
,
number_of_entries
),
REVISION
=
offsetof
(
struct
hrt
,
revision
),
HRT_RESERVED1
=
offsetof
(
struct
hrt
,
reserved1
),
HRT_RESERVED2
=
offsetof
(
struct
hrt
,
reserved2
),
};
struct
irq_info
{
u8
bus
,
devfn
;
/* bus, device and function */
struct
{
u8
link
;
/* IRQ line ID, chipset dependent, 0=not routed */
u16
bitmap
;
/* Available IRQs */
}
__attribute__
((
packed
))
irq
[
4
];
u8
slot
;
/* slot number, 0=onboard */
u8
rfu
;
}
__attribute__
((
packed
));
struct
irq_routing_table
{
u32
signature
;
/* PIRQ_SIGNATURE should be here */
u16
version
;
/* PIRQ_VERSION */
u16
size
;
/* Table size in bytes */
u8
rtr_bus
,
rtr_devfn
;
/* Where the interrupt router lies */
u16
exclusive_irqs
;
/* IRQs devoted exclusively to PCI usage */
u16
rtr_vendor
,
rtr_device
;
/* Vendor and device ID of interrupt router */
u32
miniport_data
;
/* Crap */
u8
rfu
[
11
];
u8
checksum
;
/* Modulo 256 checksum must give zero */
struct
irq_info
slots
[
0
];
}
__attribute__
((
packed
));
#endif
/* _SHPCHPRM_LEGACY_H_ */
drivers/pci/hotplug/shpchprm_nonacpi.c
View file @
7efe5d7c
...
...
@@ -32,24 +32,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#ifdef CONFIG_IA64
#include <asm/iosapic.h>
#endif
#include "shpchp.h"
#include "shpchprm.h"
#include "shpchprm_nonacpi.h"
void
shpchprm_cleanup
(
void
)
{
return
;
}
int
shpchprm_print_pirt
(
void
)
{
return
0
;
}
int
shpchprm_get_physical_slot_number
(
struct
controller
*
ctrl
,
u32
*
sun
,
u8
busnum
,
u8
devnum
)
{
...
...
@@ -60,375 +43,13 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
return
0
;
}
static
void
print_pci_resource
(
struct
pci_resource
*
aprh
)
{
struct
pci_resource
*
res
;
for
(
res
=
aprh
;
res
;
res
=
res
->
next
)
dbg
(
" base= 0x%x length= 0x%x
\n
"
,
res
->
base
,
res
->
length
);
}
static
void
phprm_dump_func_res
(
struct
pci_func
*
fun
)
{
struct
pci_func
*
func
=
fun
;
if
(
func
->
bus_head
)
{
dbg
(
": BUS Resources:
\n
"
);
print_pci_resource
(
func
->
bus_head
);
}
if
(
func
->
io_head
)
{
dbg
(
": IO Resources:
\n
"
);
print_pci_resource
(
func
->
io_head
);
}
if
(
func
->
mem_head
)
{
dbg
(
": MEM Resources:
\n
"
);
print_pci_resource
(
func
->
mem_head
);
}
if
(
func
->
p_mem_head
)
{
dbg
(
": PMEM Resources:
\n
"
);
print_pci_resource
(
func
->
p_mem_head
);
}
}
static
int
phprm_get_used_resources
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
)
{
return
shpchp_save_used_resources
(
ctrl
,
func
,
!
DISABLE_CARD
);
}
static
int
phprm_delete_resource
(
struct
pci_resource
**
aprh
,
ulong
base
,
ulong
size
)
{
struct
pci_resource
*
res
;
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
split_node
;
ulong
tbase
;
shpchp_resource_sort_and_combine
(
aprh
);
for
(
res
=
*
aprh
;
res
;
res
=
res
->
next
)
{
if
(
res
->
base
>
base
)
continue
;
if
((
res
->
base
+
res
->
length
)
<
(
base
+
size
))
continue
;
if
(
res
->
base
<
base
)
{
tbase
=
base
;
if
((
res
->
length
-
(
tbase
-
res
->
base
))
<
size
)
continue
;
split_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
split_node
)
return
-
ENOMEM
;
split_node
->
base
=
res
->
base
;
split_node
->
length
=
tbase
-
res
->
base
;
res
->
base
=
tbase
;
res
->
length
-=
split_node
->
length
;
split_node
->
next
=
res
->
next
;
res
->
next
=
split_node
;
}
if
(
res
->
length
>=
size
)
{
split_node
=
(
struct
pci_resource
*
)
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
!
split_node
)
return
-
ENOMEM
;
split_node
->
base
=
res
->
base
+
size
;
split_node
->
length
=
res
->
length
-
size
;
res
->
length
=
size
;
split_node
->
next
=
res
->
next
;
res
->
next
=
split_node
;
}
if
(
*
aprh
==
res
)
{
*
aprh
=
res
->
next
;
}
else
{
prevnode
=
*
aprh
;
while
(
prevnode
->
next
!=
res
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
res
->
next
;
}
res
->
next
=
NULL
;
kfree
(
res
);
break
;
}
return
0
;
}
static
int
phprm_delete_resources
(
struct
pci_resource
**
aprh
,
struct
pci_resource
*
this
)
{
struct
pci_resource
*
res
;
for
(
res
=
this
;
res
;
res
=
res
->
next
)
phprm_delete_resource
(
aprh
,
res
->
base
,
res
->
length
);
return
0
;
}
static
int
configure_existing_function
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
)
{
int
rc
;
/* see how much resources the func has used. */
rc
=
phprm_get_used_resources
(
ctrl
,
func
);
if
(
!
rc
)
{
/* subtract the resources used by the func from ctrl resources */
rc
=
phprm_delete_resources
(
&
ctrl
->
bus_head
,
func
->
bus_head
);
rc
|=
phprm_delete_resources
(
&
ctrl
->
io_head
,
func
->
io_head
);
rc
|=
phprm_delete_resources
(
&
ctrl
->
mem_head
,
func
->
mem_head
);
rc
|=
phprm_delete_resources
(
&
ctrl
->
p_mem_head
,
func
->
p_mem_head
);
if
(
rc
)
warn
(
"aCEF: cannot del used resources
\n
"
);
}
else
err
(
"aCEF: cannot get used resources
\n
"
);
return
rc
;
}
static
int
bind_pci_resources_to_slots
(
struct
controller
*
ctrl
)
{
struct
pci_func
*
func
,
new_func
;
int
busn
=
ctrl
->
slot_bus
;
int
devn
,
funn
;
u32
vid
;
for
(
devn
=
0
;
devn
<
32
;
devn
++
)
{
for
(
funn
=
0
;
funn
<
8
;
funn
++
)
{
/*
if (devn == ctrl->device && funn == ctrl->function)
continue;
*/
/* find out if this entry is for an occupied slot */
vid
=
0xFFFFFFFF
;
pci_bus_read_config_dword
(
ctrl
->
pci_dev
->
subordinate
,
PCI_DEVFN
(
devn
,
funn
),
PCI_VENDOR_ID
,
&
vid
);
if
(
vid
!=
0xFFFFFFFF
)
{
func
=
shpchp_slot_find
(
busn
,
devn
,
funn
);
if
(
!
func
)
{
memset
(
&
new_func
,
0
,
sizeof
(
struct
pci_func
));
new_func
.
bus
=
busn
;
new_func
.
device
=
devn
;
new_func
.
function
=
funn
;
new_func
.
is_a_board
=
1
;
configure_existing_function
(
ctrl
,
&
new_func
);
phprm_dump_func_res
(
&
new_func
);
}
else
{
configure_existing_function
(
ctrl
,
func
);
phprm_dump_func_res
(
func
);
}
dbg
(
"aCCF:existing PCI 0x%x Func ResourceDump
\n
"
,
ctrl
->
bus
);
}
}
}
return
0
;
}
static
void
phprm_dump_ctrl_res
(
struct
controller
*
ctlr
)
{
struct
controller
*
ctrl
=
ctlr
;
if
(
ctrl
->
bus_head
)
{
dbg
(
": BUS Resources:
\n
"
);
print_pci_resource
(
ctrl
->
bus_head
);
}
if
(
ctrl
->
io_head
)
{
dbg
(
": IO Resources:
\n
"
);
print_pci_resource
(
ctrl
->
io_head
);
}
if
(
ctrl
->
mem_head
)
{
dbg
(
": MEM Resources:
\n
"
);
print_pci_resource
(
ctrl
->
mem_head
);
}
if
(
ctrl
->
p_mem_head
)
{
dbg
(
": PMEM Resources:
\n
"
);
print_pci_resource
(
ctrl
->
p_mem_head
);
}
}
/*
* phprm_find_available_resources
*
* Finds available memory, IO, and IRQ resources for programming
* devices which may be added to the system
* this function is for hot plug ADD!
*
* returns 0 if success
*/
int
shpchprm_find_available_resources
(
struct
controller
*
ctrl
)
{
struct
pci_func
func
;
u32
rc
;
memset
(
&
func
,
0
,
sizeof
(
struct
pci_func
));
func
.
bus
=
ctrl
->
bus
;
func
.
device
=
ctrl
->
device
;
func
.
function
=
ctrl
->
function
;
func
.
is_a_board
=
1
;
/* Get resources for this PCI bridge */
rc
=
shpchp_save_used_resources
(
ctrl
,
&
func
,
!
DISABLE_CARD
);
dbg
(
"%s: shpchp_save_used_resources rc = %d
\n
"
,
__FUNCTION__
,
rc
);
if
(
func
.
mem_head
)
func
.
mem_head
->
next
=
ctrl
->
mem_head
;
ctrl
->
mem_head
=
func
.
mem_head
;
if
(
func
.
p_mem_head
)
func
.
p_mem_head
->
next
=
ctrl
->
p_mem_head
;
ctrl
->
p_mem_head
=
func
.
p_mem_head
;
if
(
func
.
io_head
)
func
.
io_head
->
next
=
ctrl
->
io_head
;
ctrl
->
io_head
=
func
.
io_head
;
if
(
func
.
bus_head
)
func
.
bus_head
->
next
=
ctrl
->
bus_head
;
ctrl
->
bus_head
=
func
.
bus_head
;
if
(
ctrl
->
bus_head
)
phprm_delete_resource
(
&
ctrl
->
bus_head
,
ctrl
->
pci_dev
->
subordinate
->
number
,
1
);
dbg
(
"%s:pre-Bind PCI 0x%x Ctrl Resource Dump
\n
"
,
__FUNCTION__
,
ctrl
->
bus
);
phprm_dump_ctrl_res
(
ctrl
);
bind_pci_resources_to_slots
(
ctrl
);
dbg
(
"%s:post-Bind PCI 0x%x Ctrl Resource Dump
\n
"
,
__FUNCTION__
,
ctrl
->
bus
);
phprm_dump_ctrl_res
(
ctrl
);
/* If all of the following fail, we don't have any resources for hot plug add */
rc
=
1
;
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
mem_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
p_mem_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
io_head
));
rc
&=
shpchp_resource_sort_and_combine
(
&
(
ctrl
->
bus_head
));
return
(
rc
);
}
int
shpchprm_set_hpp
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
void
get_hp_params_from_firmware
(
struct
pci_dev
*
dev
,
struct
hotplug_params
*
hpp
)
{
u32
rc
;
u8
temp_byte
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
unsigned
int
devfn
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
temp_byte
=
0x40
;
/* hard coded value for LT */
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
/* set subordinate Latency Timer */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_SEC_LATENCY_TIMER
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set secondary LT error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
return
rc
;
}
}
/* set base Latency Timer */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_LATENCY_TIMER
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set LT error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
return
rc
;
}
/* set Cache Line size */
temp_byte
=
0x08
;
/* hard coded value for CLS */
rc
=
pci_bus_write_config_byte
(
pci_bus
,
devfn
,
PCI_CACHE_LINE_SIZE
,
temp_byte
);
if
(
rc
)
{
dbg
(
"%s: set CLS error. b:d:f(%02x:%02x:%02x)
\n
"
,
__FUNCTION__
,
func
->
bus
,
func
->
device
,
func
->
function
);
}
/* set enable_perr */
/* set enable_serr */
return
rc
;
}
void
shpchprm_enable_card
(
struct
controller
*
ctrl
,
struct
pci_func
*
func
,
u8
card_type
)
{
u16
command
,
bcommand
;
struct
pci_bus
lpci_bus
,
*
pci_bus
;
unsigned
int
devfn
;
int
rc
;
memcpy
(
&
lpci_bus
,
ctrl
->
pci_bus
,
sizeof
(
lpci_bus
));
pci_bus
=
&
lpci_bus
;
pci_bus
->
number
=
func
->
bus
;
devfn
=
PCI_DEVFN
(
func
->
device
,
func
->
function
);
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
&
command
);
command
|=
PCI_COMMAND_PARITY
|
PCI_COMMAND_SERR
|
PCI_COMMAND_MASTER
|
PCI_COMMAND_INVALIDATE
|
PCI_COMMAND_IO
|
PCI_COMMAND_MEMORY
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_COMMAND
,
command
);
if
(
card_type
==
PCI_HEADER_TYPE_BRIDGE
)
{
rc
=
pci_bus_read_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
&
bcommand
);
bcommand
|=
PCI_BRIDGE_CTL_PARITY
|
PCI_BRIDGE_CTL_SERR
|
PCI_BRIDGE_CTL_NO_ISA
;
rc
=
pci_bus_write_config_word
(
pci_bus
,
devfn
,
PCI_BRIDGE_CONTROL
,
bcommand
);
}
}
static
int
legacy_shpchprm_init_pci
(
void
)
{
return
0
;
return
;
}
int
shpchprm_init
(
enum
php_ctlr_type
ctrl_type
)
void
get_hp_hw_control_from_firmware
(
struct
pci_dev
*
dev
)
{
int
retval
;
switch
(
ctrl_type
)
{
case
PCI
:
retval
=
legacy_shpchprm_init_pci
();
break
;
default:
retval
=
-
ENODEV
;
break
;
}
return
retval
;
return
;
}
drivers/pci/hotplug/shpchprm_nonacpi.h
deleted
100644 → 0
View file @
dbe0580d
/*
* SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2003-2004 Intel Corporation
*
* All rights reserved.
*
* 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 of the License, 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
#ifndef _SHPCHPRM_NONACPI_H_
#define _SHPCHPRM_NONACPI_H_
struct
irq_info
{
u8
bus
,
devfn
;
/* bus, device and function */
struct
{
u8
link
;
/* IRQ line ID, chipset dependent, 0=not routed */
u16
bitmap
;
/* Available IRQs */
}
__attribute__
((
packed
))
irq
[
4
];
u8
slot
;
/* slot number, 0=onboard */
u8
rfu
;
}
__attribute__
((
packed
));
struct
irq_routing_table
{
u32
signature
;
/* PIRQ_SIGNATURE should be here */
u16
version
;
/* PIRQ_VERSION */
u16
size
;
/* Table size in bytes */
u8
rtr_bus
,
rtr_devfn
;
/* Where the interrupt router lies */
u16
exclusive_irqs
;
/* IRQs devoted exclusively to PCI usage */
u16
rtr_vendor
,
rtr_device
;
/* Vendor and device ID of interrupt router */
u32
miniport_data
;
/* Crap */
u8
rfu
[
11
];
u8
checksum
;
/* Modulo 256 checksum must give zero */
struct
irq_info
slots
[
0
];
}
__attribute__
((
packed
));
#endif
/* _SHPCHPRM_NONACPI_H_ */
drivers/pci/msi.c
View file @
7efe5d7c
...
...
@@ -575,6 +575,8 @@ static int msi_capability_init(struct pci_dev *dev)
/**
* msix_capability_init - configure device's MSI-X capability
* @dev: pointer to the pci_dev data structure of MSI-X device function
* @entries: pointer to an array of struct msix_entry entries
* @nvec: number of @entries
*
* Setup the MSI-X capability structure of device function with a
* single MSI-X vector. A return of zero indicates the successful setup of
...
...
drivers/pci/pci-driver.c
View file @
7efe5d7c
...
...
@@ -26,7 +26,10 @@ struct pci_dynid {
#ifdef CONFIG_HOTPLUG
/**
* store_new_id
* store_new_id - add a new PCI device ID to this driver and re-probe devices
* @driver: target device driver
* @buf: buffer for scanning device ID data
* @count: input size
*
* Adds a new dynamic pci device ID to this driver,
* and causes the driver to probe for all devices again.
...
...
@@ -194,6 +197,8 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
/**
* __pci_device_probe()
* @drv: driver to call to check if it wants the PCI device
* @pci_dev: PCI device being probed
*
* returns 0 on success, else error.
* side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
...
...
@@ -377,6 +382,10 @@ int pci_register_driver(struct pci_driver *drv)
* the pci shutdown function, this test can go away. */
if
(
!
drv
->
driver
.
shutdown
)
drv
->
driver
.
shutdown
=
pci_device_shutdown
;
else
printk
(
KERN_WARNING
"Warning: PCI driver %s has a struct "
"device_driver shutdown method, please update!
\n
"
,
drv
->
name
);
drv
->
driver
.
owner
=
drv
->
owner
;
drv
->
driver
.
kobj
.
ktype
=
&
pci_driver_kobj_type
;
...
...
@@ -436,11 +445,11 @@ pci_dev_driver(const struct pci_dev *dev)
/**
* pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
* @ids: array of PCI device id structures to search in
* @dev: the PCI device structure to match against
* @drv: the device driver to search for matching PCI device id structures
*
* Used by a driver to check whether a PCI device present in the
* system is in its list of supported devices.Returns the matching
* system is in its list of supported devices.
Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
static
int
pci_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
...
...
drivers/pci/pci-sysfs.c
View file @
7efe5d7c
...
...
@@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
((
off
&
1
)
&&
size
)
{
u8
val
;
pci_read_config_byte
(
dev
,
off
,
&
val
);
pci_
user_
read_config_byte
(
dev
,
off
,
&
val
);
data
[
off
-
init_off
]
=
val
;
off
++
;
size
--
;
...
...
@@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
((
off
&
3
)
&&
size
>
2
)
{
u16
val
;
pci_read_config_word
(
dev
,
off
,
&
val
);
pci_
user_
read_config_word
(
dev
,
off
,
&
val
);
data
[
off
-
init_off
]
=
val
&
0xff
;
data
[
off
-
init_off
+
1
]
=
(
val
>>
8
)
&
0xff
;
off
+=
2
;
...
...
@@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
while
(
size
>
3
)
{
u32
val
;
pci_read_config_dword
(
dev
,
off
,
&
val
);
pci_
user_
read_config_dword
(
dev
,
off
,
&
val
);
data
[
off
-
init_off
]
=
val
&
0xff
;
data
[
off
-
init_off
+
1
]
=
(
val
>>
8
)
&
0xff
;
data
[
off
-
init_off
+
2
]
=
(
val
>>
16
)
&
0xff
;
...
...
@@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
(
size
>=
2
)
{
u16
val
;
pci_read_config_word
(
dev
,
off
,
&
val
);
pci_
user_
read_config_word
(
dev
,
off
,
&
val
);
data
[
off
-
init_off
]
=
val
&
0xff
;
data
[
off
-
init_off
+
1
]
=
(
val
>>
8
)
&
0xff
;
off
+=
2
;
...
...
@@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
(
size
>
0
)
{
u8
val
;
pci_read_config_byte
(
dev
,
off
,
&
val
);
pci_
user_
read_config_byte
(
dev
,
off
,
&
val
);
data
[
off
-
init_off
]
=
val
;
off
++
;
--
size
;
...
...
@@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
}
if
((
off
&
1
)
&&
size
)
{
pci_write_config_byte
(
dev
,
off
,
data
[
off
-
init_off
]);
pci_
user_
write_config_byte
(
dev
,
off
,
data
[
off
-
init_off
]);
off
++
;
size
--
;
}
...
...
@@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
((
off
&
3
)
&&
size
>
2
)
{
u16
val
=
data
[
off
-
init_off
];
val
|=
(
u16
)
data
[
off
-
init_off
+
1
]
<<
8
;
pci_write_config_word
(
dev
,
off
,
val
);
pci_
user_
write_config_word
(
dev
,
off
,
val
);
off
+=
2
;
size
-=
2
;
}
...
...
@@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
val
|=
(
u32
)
data
[
off
-
init_off
+
1
]
<<
8
;
val
|=
(
u32
)
data
[
off
-
init_off
+
2
]
<<
16
;
val
|=
(
u32
)
data
[
off
-
init_off
+
3
]
<<
24
;
pci_write_config_dword
(
dev
,
off
,
val
);
pci_
user_
write_config_dword
(
dev
,
off
,
val
);
off
+=
4
;
size
-=
4
;
}
...
...
@@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if
(
size
>=
2
)
{
u16
val
=
data
[
off
-
init_off
];
val
|=
(
u16
)
data
[
off
-
init_off
+
1
]
<<
8
;
pci_write_config_word
(
dev
,
off
,
val
);
pci_
user_
write_config_word
(
dev
,
off
,
val
);
off
+=
2
;
size
-=
2
;
}
if
(
size
)
{
pci_write_config_byte
(
dev
,
off
,
data
[
off
-
init_off
]);
pci_
user_
write_config_byte
(
dev
,
off
,
data
[
off
-
init_off
]);
off
++
;
--
size
;
}
...
...
drivers/pci/pci.c
View file @
7efe5d7c
...
...
@@ -252,6 +252,8 @@ pci_restore_bars(struct pci_dev *dev)
pci_update_resource
(
dev
,
&
dev
->
resource
[
i
],
i
);
}
int
(
*
platform_pci_set_power_state
)(
struct
pci_dev
*
dev
,
pci_power_t
t
);
/**
* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to be suspended
...
...
@@ -266,7 +268,6 @@ pci_restore_bars(struct pci_dev *dev)
* -EIO if device does not support PCI PM.
* 0 if we can successfully change the power state.
*/
int
(
*
platform_pci_set_power_state
)(
struct
pci_dev
*
dev
,
pci_power_t
t
);
int
pci_set_power_state
(
struct
pci_dev
*
dev
,
pci_power_t
state
)
{
...
...
@@ -314,19 +315,19 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
* sets PowerState to 0.
*/
switch
(
dev
->
current_state
)
{
case
PCI_D0
:
case
PCI_D1
:
case
PCI_D2
:
pmcsr
&=
~
PCI_PM_CTRL_STATE_MASK
;
pmcsr
|=
state
;
break
;
case
PCI_UNKNOWN
:
/* Boot-up */
if
((
pmcsr
&
PCI_PM_CTRL_STATE_MASK
)
==
PCI_D3hot
&&
!
(
pmcsr
&
PCI_PM_CTRL_NO_SOFT_RESET
))
need_restore
=
1
;
/* Fall-through: force to D0 */
case
PCI_D3hot
:
case
PCI_D3cold
:
case
PCI_POWER_ERROR
:
pmcsr
=
0
;
break
;
default:
pmcsr
&=
~
PCI_PM_CTRL_STATE_MASK
;
pmcsr
|=
state
;
pmcsr
=
0
;
break
;
}
...
...
@@ -808,8 +809,8 @@ pci_clear_mwi(struct pci_dev *dev)
/**
* pci_intx - enables/disables PCI INTx for device dev
* @dev: the PCI device to operate on
* @enable: boolean
* @
p
dev: the PCI device to operate on
* @enable: boolean
: whether to enable or disable PCI INTx
*
* Enables/disables PCI INTx for device dev
*/
...
...
drivers/pci/pci.h
View file @
7efe5d7c
...
...
@@ -15,6 +15,13 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
extern
int
(
*
platform_pci_choose_state
)(
struct
pci_dev
*
dev
,
pm_message_t
state
);
extern
int
(
*
platform_pci_set_power_state
)(
struct
pci_dev
*
dev
,
pci_power_t
state
);
extern
int
pci_user_read_config_byte
(
struct
pci_dev
*
dev
,
int
where
,
u8
*
val
);
extern
int
pci_user_read_config_word
(
struct
pci_dev
*
dev
,
int
where
,
u16
*
val
);
extern
int
pci_user_read_config_dword
(
struct
pci_dev
*
dev
,
int
where
,
u32
*
val
);
extern
int
pci_user_write_config_byte
(
struct
pci_dev
*
dev
,
int
where
,
u8
val
);
extern
int
pci_user_write_config_word
(
struct
pci_dev
*
dev
,
int
where
,
u16
val
);
extern
int
pci_user_write_config_dword
(
struct
pci_dev
*
dev
,
int
where
,
u32
val
);
/* PCI /proc functions */
#ifdef CONFIG_PROC_FS
extern
int
pci_proc_attach_device
(
struct
pci_dev
*
dev
);
...
...
drivers/pci/probe.c
View file @
7efe5d7c
...
...
@@ -669,6 +669,7 @@ static void pci_release_dev(struct device *dev)
/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device
*
* Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
* have 4096 bytes. Even if the device is capable, that doesn't mean we can
...
...
drivers/pci/proc.c
View file @
7efe5d7c
...
...
@@ -80,7 +80,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if
((
pos
&
1
)
&&
cnt
)
{
unsigned
char
val
;
pci_read_config_byte
(
dev
,
pos
,
&
val
);
pci_
user_
read_config_byte
(
dev
,
pos
,
&
val
);
__put_user
(
val
,
buf
);
buf
++
;
pos
++
;
...
...
@@ -89,7 +89,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if
((
pos
&
3
)
&&
cnt
>
2
)
{
unsigned
short
val
;
pci_read_config_word
(
dev
,
pos
,
&
val
);
pci_
user_
read_config_word
(
dev
,
pos
,
&
val
);
__put_user
(
cpu_to_le16
(
val
),
(
unsigned
short
__user
*
)
buf
);
buf
+=
2
;
pos
+=
2
;
...
...
@@ -98,7 +98,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
while
(
cnt
>=
4
)
{
unsigned
int
val
;
pci_read_config_dword
(
dev
,
pos
,
&
val
);
pci_
user_
read_config_dword
(
dev
,
pos
,
&
val
);
__put_user
(
cpu_to_le32
(
val
),
(
unsigned
int
__user
*
)
buf
);
buf
+=
4
;
pos
+=
4
;
...
...
@@ -107,7 +107,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if
(
cnt
>=
2
)
{
unsigned
short
val
;
pci_read_config_word
(
dev
,
pos
,
&
val
);
pci_
user_
read_config_word
(
dev
,
pos
,
&
val
);
__put_user
(
cpu_to_le16
(
val
),
(
unsigned
short
__user
*
)
buf
);
buf
+=
2
;
pos
+=
2
;
...
...
@@ -116,7 +116,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if
(
cnt
)
{
unsigned
char
val
;
pci_read_config_byte
(
dev
,
pos
,
&
val
);
pci_
user_
read_config_byte
(
dev
,
pos
,
&
val
);
__put_user
(
val
,
buf
);
buf
++
;
pos
++
;
...
...
@@ -151,7 +151,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if
((
pos
&
1
)
&&
cnt
)
{
unsigned
char
val
;
__get_user
(
val
,
buf
);
pci_write_config_byte
(
dev
,
pos
,
val
);
pci_
user_
write_config_byte
(
dev
,
pos
,
val
);
buf
++
;
pos
++
;
cnt
--
;
...
...
@@ -160,7 +160,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if
((
pos
&
3
)
&&
cnt
>
2
)
{
unsigned
short
val
;
__get_user
(
val
,
(
unsigned
short
__user
*
)
buf
);
pci_write_config_word
(
dev
,
pos
,
le16_to_cpu
(
val
));
pci_
user_
write_config_word
(
dev
,
pos
,
le16_to_cpu
(
val
));
buf
+=
2
;
pos
+=
2
;
cnt
-=
2
;
...
...
@@ -169,7 +169,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
while
(
cnt
>=
4
)
{
unsigned
int
val
;
__get_user
(
val
,
(
unsigned
int
__user
*
)
buf
);
pci_write_config_dword
(
dev
,
pos
,
le32_to_cpu
(
val
));
pci_
user_
write_config_dword
(
dev
,
pos
,
le32_to_cpu
(
val
));
buf
+=
4
;
pos
+=
4
;
cnt
-=
4
;
...
...
@@ -178,7 +178,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if
(
cnt
>=
2
)
{
unsigned
short
val
;
__get_user
(
val
,
(
unsigned
short
__user
*
)
buf
);
pci_write_config_word
(
dev
,
pos
,
le16_to_cpu
(
val
));
pci_
user_
write_config_word
(
dev
,
pos
,
le16_to_cpu
(
val
));
buf
+=
2
;
pos
+=
2
;
cnt
-=
2
;
...
...
@@ -187,7 +187,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if
(
cnt
)
{
unsigned
char
val
;
__get_user
(
val
,
buf
);
pci_write_config_byte
(
dev
,
pos
,
val
);
pci_
user_
write_config_byte
(
dev
,
pos
,
val
);
buf
++
;
pos
++
;
cnt
--
;
...
...
@@ -484,10 +484,10 @@ static int show_dev_config(struct seq_file *m, void *v)
drv
=
pci_dev_driver
(
dev
);
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
pci_read_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
&
latency
);
pci_read_config_byte
(
dev
,
PCI_MIN_GNT
,
&
min_gnt
);
pci_read_config_byte
(
dev
,
PCI_MAX_LAT
,
&
max_lat
);
pci_
user_
read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
pci_
user_
read_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
&
latency
);
pci_
user_
read_config_byte
(
dev
,
PCI_MIN_GNT
,
&
min_gnt
);
pci_
user_
read_config_byte
(
dev
,
PCI_MAX_LAT
,
&
max_lat
);
seq_printf
(
m
,
" Bus %2d, device %3d, function %2d:
\n
"
,
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
PCI_FUNC
(
dev
->
devfn
));
seq_printf
(
m
,
" Class %04x"
,
class_rev
>>
16
);
...
...
drivers/pci/quirks.c
View file @
7efe5d7c
...
...
@@ -414,6 +414,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82801EB_0
,
quirk_ich4_lpc_acpi
);
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ESB_1
,
quirk_ich4_lpc_acpi
);
static
void
__devinit
quirk_ich6_lpc_acpi
(
struct
pci_dev
*
dev
)
{
u32
region
;
pci_read_config_dword
(
dev
,
0x40
,
&
region
);
quirk_io_region
(
dev
,
region
,
128
,
PCI_BRIDGE_RESOURCES
,
"ICH6 ACPI/GPIO/TCO"
);
pci_read_config_dword
(
dev
,
0x48
,
&
region
);
quirk_io_region
(
dev
,
region
,
64
,
PCI_BRIDGE_RESOURCES
+
1
,
"ICH6 GPIO"
);
}
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ICH6_1
,
quirk_ich6_lpc_acpi
);
/*
* VIA ACPI: One IO region pointed to by longword at
* 0x48 or 0x20 (256 bytes of ACPI registers)
...
...
@@ -922,6 +934,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
case
0x186a
:
/* M6Ne notebook */
asus_hides_smbus
=
1
;
}
if
(
dev
->
device
==
PCI_DEVICE_ID_INTEL_82915GM_HB
)
{
switch
(
dev
->
subsystem_device
)
{
case
0x1882
:
/* M6V notebook */
asus_hides_smbus
=
1
;
}
}
}
else
if
(
unlikely
(
dev
->
subsystem_vendor
==
PCI_VENDOR_ID_HP
))
{
if
(
dev
->
device
==
PCI_DEVICE_ID_INTEL_82855PM_HB
)
switch
(
dev
->
subsystem_device
)
{
...
...
@@ -932,6 +950,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if
(
dev
->
device
==
PCI_DEVICE_ID_INTEL_82865_HB
)
switch
(
dev
->
subsystem_device
)
{
case
0x12bc
:
/* HP D330L */
case
0x12bd
:
/* HP D530 */
asus_hides_smbus
=
1
;
}
}
else
if
(
unlikely
(
dev
->
subsystem_vendor
==
PCI_VENDOR_ID_TOSHIBA
))
{
...
...
@@ -966,6 +985,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_7205_0
,
asus_hides_smbus_hostbridge
);
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82855PM_HB
,
asus_hides_smbus_hostbridge
);
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82855GM_HB
,
asus_hides_smbus_hostbridge
);
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82915GM_HB
,
asus_hides_smbus_hostbridge
);
static
void
__init
asus_hides_smbus_lpc
(
struct
pci_dev
*
dev
)
{
...
...
@@ -990,6 +1010,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, as
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82801DB_12
,
asus_hides_smbus_lpc
);
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82801EB_0
,
asus_hides_smbus_lpc
);
static
void
__init
asus_hides_smbus_lpc_ich6
(
struct
pci_dev
*
dev
)
{
u32
val
,
rcba
;
void
__iomem
*
base
;
if
(
likely
(
!
asus_hides_smbus
))
return
;
pci_read_config_dword
(
dev
,
0xF0
,
&
rcba
);
base
=
ioremap_nocache
(
rcba
&
0xFFFFC000
,
0x4000
);
/* use bits 31:14, 16 kB aligned */
if
(
base
==
NULL
)
return
;
val
=
readl
(
base
+
0x3418
);
/* read the Function Disable register, dword mode only */
writel
(
val
&
0xFFFFFFF7
,
base
+
0x3418
);
/* enable the SMBus device */
iounmap
(
base
);
printk
(
KERN_INFO
"PCI: Enabled ICH6/i801 SMBus device
\n
"
);
}
DECLARE_PCI_FIXUP_HEADER
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_ICH6_1
,
asus_hides_smbus_lpc_ich6
);
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
*/
...
...
drivers/pci/syscall.c
View file @
7efe5d7c
...
...
@@ -13,7 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>
#include "pci.h"
asmlinkage
long
sys_pciconfig_read
(
unsigned
long
bus
,
unsigned
long
dfn
,
...
...
@@ -38,13 +38,13 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
lock_kernel
();
switch
(
len
)
{
case
1
:
cfg_ret
=
pci_read_config_byte
(
dev
,
off
,
&
byte
);
cfg_ret
=
pci_
user_
read_config_byte
(
dev
,
off
,
&
byte
);
break
;
case
2
:
cfg_ret
=
pci_read_config_word
(
dev
,
off
,
&
word
);
cfg_ret
=
pci_
user_
read_config_word
(
dev
,
off
,
&
word
);
break
;
case
4
:
cfg_ret
=
pci_read_config_dword
(
dev
,
off
,
&
dword
);
cfg_ret
=
pci_
user_
read_config_dword
(
dev
,
off
,
&
dword
);
break
;
default:
err
=
-
EINVAL
;
...
...
@@ -112,7 +112,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err
=
get_user
(
byte
,
(
u8
__user
*
)
buf
);
if
(
err
)
break
;
err
=
pci_write_config_byte
(
dev
,
off
,
byte
);
err
=
pci_
user_
write_config_byte
(
dev
,
off
,
byte
);
if
(
err
!=
PCIBIOS_SUCCESSFUL
)
err
=
-
EIO
;
break
;
...
...
@@ -121,7 +121,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err
=
get_user
(
word
,
(
u16
__user
*
)
buf
);
if
(
err
)
break
;
err
=
pci_write_config_word
(
dev
,
off
,
word
);
err
=
pci_
user_
write_config_word
(
dev
,
off
,
word
);
if
(
err
!=
PCIBIOS_SUCCESSFUL
)
err
=
-
EIO
;
break
;
...
...
@@ -130,7 +130,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err
=
get_user
(
dword
,
(
u32
__user
*
)
buf
);
if
(
err
)
break
;
err
=
pci_write_config_dword
(
dev
,
off
,
dword
);
err
=
pci_
user_
write_config_dword
(
dev
,
off
,
dword
);
if
(
err
!=
PCIBIOS_SUCCESSFUL
)
err
=
-
EIO
;
break
;
...
...
drivers/scsi/ipr.c
View file @
7efe5d7c
...
...
@@ -4944,6 +4944,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
int
rc
;
ENTER
;
pci_unblock_user_cfg_access
(
ioa_cfg
->
pdev
);
rc
=
pci_restore_state
(
ioa_cfg
->
pdev
);
if
(
rc
!=
PCIBIOS_SUCCESSFUL
)
{
...
...
@@ -4998,6 +4999,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
int
rc
;
ENTER
;
pci_block_user_cfg_access
(
ioa_cfg
->
pdev
);
rc
=
pci_write_config_byte
(
ioa_cfg
->
pdev
,
PCI_BIST
,
PCI_BIST_START
);
if
(
rc
!=
PCIBIOS_SUCCESSFUL
)
{
...
...
drivers/scsi/megaraid/megaraid_mbox.c
View file @
7efe5d7c
...
...
@@ -76,7 +76,7 @@ static void megaraid_exit(void);
static
int
megaraid_probe_one
(
struct
pci_dev
*
,
const
struct
pci_device_id
*
);
static
void
megaraid_detach_one
(
struct
pci_dev
*
);
static
void
megaraid_mbox_shutdown
(
struct
device
*
);
static
void
megaraid_mbox_shutdown
(
struct
pci_dev
*
);
static
int
megaraid_io_attach
(
adapter_t
*
);
static
void
megaraid_io_detach
(
adapter_t
*
);
...
...
@@ -369,9 +369,7 @@ static struct pci_driver megaraid_pci_driver_g = {
.
id_table
=
pci_id_table_g
,
.
probe
=
megaraid_probe_one
,
.
remove
=
__devexit_p
(
megaraid_detach_one
),
.
driver
=
{
.
shutdown
=
megaraid_mbox_shutdown
,
}
};
...
...
@@ -673,9 +671,9 @@ megaraid_detach_one(struct pci_dev *pdev)
* Shutdown notification, perform flush cache
*/
static
void
megaraid_mbox_shutdown
(
struct
device
*
device
)
megaraid_mbox_shutdown
(
struct
pci_dev
*
pdev
)
{
adapter_t
*
adapter
=
pci_get_drvdata
(
to_pci_dev
(
device
)
);
adapter_t
*
adapter
=
pci_get_drvdata
(
pdev
);
static
int
counter
;
if
(
!
adapter
)
{
...
...
drivers/video/cirrusfb.c
View file @
7efe5d7c
...
...
@@ -275,20 +275,20 @@ static const struct cirrusfb_board_info_rec {
#ifdef CONFIG_PCI
#define CHIP(id, btype) \
{ PCI_VENDOR_ID_CIRRUS,
PCI_DEVICE_ID_##
id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
{ PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
static
struct
pci_device_id
cirrusfb_pci_table
[]
=
{
CHIP
(
CIRRUS_5436
,
BT_ALPINE
),
CHIP
(
CIRRUS_5434_8
,
BT_ALPINE
),
CHIP
(
CIRRUS_5434_4
,
BT_ALPINE
),
CHIP
(
CIRRUS_5430
,
BT_ALPINE
),
/* GD-5440 has identical
id */
CHIP
(
CIRRUS_7543
,
BT_ALPINE
),
CHIP
(
CIRRUS_7548
,
BT_ALPINE
),
CHIP
(
CIRRUS_5480
,
BT_GD5480
),
/* MacPicasso probab
ly */
CHIP
(
CIRRUS_5446
,
BT_PICASSO4
),
/* Picasso 4 is a GD
5446 */
CHIP
(
CIRRUS_5462
,
BT_LAGUNA
),
/* CL Laguna */
CHIP
(
CIRRUS_5464
,
BT_LAGUNA
),
/* CL Laguna 3D */
CHIP
(
CIRRUS_5465
,
BT_LAGUNA
),
/* CL Laguna 3DA*/
CHIP
(
PCI_DEVICE_ID_CIRRUS_5436
,
BT_ALPINE
),
CHIP
(
PCI_DEVICE_ID_CIRRUS_5434_8
,
BT_ALPINE
),
CHIP
(
PCI_DEVICE_ID_CIRRUS_5434_4
,
BT_ALPINE
),
CHIP
(
PCI_DEVICE_ID_CIRRUS_5430
,
BT_ALPINE
),
/* GD-5440 is same
id */
CHIP
(
PCI_DEVICE_ID_CIRRUS_7543
,
BT_ALPINE
),
CHIP
(
PCI_DEVICE_ID_CIRRUS_7548
,
BT_ALPINE
),
CHIP
(
PCI_DEVICE_ID_CIRRUS_5480
,
BT_GD5480
),
/* MacPicasso like
ly */
CHIP
(
PCI_DEVICE_ID_CIRRUS_5446
,
BT_PICASSO4
),
/* Picasso 4 is
5446 */
CHIP
(
PCI_DEVICE_ID_CIRRUS_5462
,
BT_LAGUNA
),
/* CL Laguna */
CHIP
(
PCI_DEVICE_ID_CIRRUS_5464
,
BT_LAGUNA
),
/* CL Laguna 3D */
CHIP
(
PCI_DEVICE_ID_CIRRUS_5465
,
BT_LAGUNA
),
/* CL Laguna 3DA*/
{
0
,
}
};
MODULE_DEVICE_TABLE
(
pci
,
cirrusfb_pci_table
);
...
...
include/linux/pci.h
View file @
7efe5d7c
...
...
@@ -132,6 +132,7 @@ struct pci_dev {
unsigned
int
is_enabled
:
1
;
/* pci_enable_device has been called */
unsigned
int
is_busmaster
:
1
;
/* device is busmaster */
unsigned
int
no_msi
:
1
;
/* device may not use msi */
unsigned
int
block_ucfg_access
:
1
;
/* userspace config space access is blocked */
u32
saved_config_space
[
16
];
/* config space saved at suspend time */
struct
bin_attribute
*
rom_attr
;
/* attribute descriptor for sysfs ROM entry */
...
...
@@ -490,6 +491,9 @@ extern void pci_disable_msix(struct pci_dev *dev);
extern
void
msi_remove_pci_irq_vectors
(
struct
pci_dev
*
dev
);
#endif
extern
void
pci_block_user_cfg_access
(
struct
pci_dev
*
dev
);
extern
void
pci_unblock_user_cfg_access
(
struct
pci_dev
*
dev
);
/*
* PCI domain support. Sometimes called PCI segment (eg by ACPI),
* a PCI domain is defined to be a set of PCI busses which share
...
...
@@ -560,6 +564,9 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
static
inline
void
pci_block_user_cfg_access
(
struct
pci_dev
*
dev
)
{
}
static
inline
void
pci_unblock_user_cfg_access
(
struct
pci_dev
*
dev
)
{
}
#endif
/* CONFIG_PCI */
/* Include architecture-dependent settings and functions */
...
...
include/linux/pci_ids.h
View file @
7efe5d7c
...
...
@@ -132,9 +132,6 @@
#define PCI_VENDOR_ID_COMPAQ 0x0e11
#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
#define PCI_DEVICE_ID_COMPAQ_6010 0x6010
#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
...
...
@@ -274,7 +271,6 @@
#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050
#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051
#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052
#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452
#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053
#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054
#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055
...
...
@@ -282,8 +278,6 @@
#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057
#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058
/* Rage128 M4 */
#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45
#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46
/* Radeon R100 */
#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144
#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145
...
...
@@ -304,32 +298,22 @@
#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157
#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158
/* Radeon NV-100 */
#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159
#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a
/* Radeon RV250 (9000) */
#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964
#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965
#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966
#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967
/* Radeon RV280 (9200) */
#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960
#define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961
#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964
/* Radeon R300 (9500) */
#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144
/* Radeon R300 (9700) */
#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44
#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45
#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46
#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47
#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145
#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146
/* Radeon R350 (9800) */
#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48
#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49
/* Radeon RV350 (9600) */
#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150
#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152
/* Radeon M6 */
#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59
#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a
...
...
@@ -342,10 +326,6 @@
#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66
#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67
/* Radeon */
#define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144
#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145
#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146
#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147
/* RadeonIGP */
#define PCI_DEVICE_ID_ATI_RS100 0xcab0
#define PCI_DEVICE_ID_ATI_RS200 0xcab2
...
...
@@ -446,45 +426,28 @@
#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
#define PCI_DEVICE_ID_CIRRUS_4281 0x6005
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
#define PCI_DEVICE_ID_IBM_TR 0x0018
#define PCI_DEVICE_ID_IBM_82G2675 0x001d
#define PCI_DEVICE_ID_IBM_MCA 0x0020
#define PCI_DEVICE_ID_IBM_82351 0x0022
#define PCI_DEVICE_ID_IBM_PYTHON 0x002d
#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
#define PCI_DEVICE_ID_IBM_MPIC 0x0046
#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096
#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc
#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105
#define PCI_DEVICE_ID_IBM_405GP 0x0156
#define PCI_DEVICE_ID_IBM_SNIPE 0x0180
#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd
#define PCI_DEVICE_ID_IBM_CITRINE 0x028C
#define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166
#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031
#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219
#define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A
#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251
#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252
#define PCI_VENDOR_ID_COMPEX2 0x101a /
/ pci.ids says "AT&T GIS (NCR)"
#define PCI_VENDOR_ID_COMPEX2 0x101a
/
* pci.ids says "AT&T GIS (NCR)" */
#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
#define PCI_VENDOR_ID_WD 0x101c
#define PCI_DEVICE_ID_WD_7197 0x3296
#define PCI_DEVICE_ID_WD_90C 0xc24a
#define PCI_VENDOR_ID_AMI 0x101e
...
...
@@ -501,33 +464,18 @@
#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006
#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007
#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C
#define PCI_DEVICE_ID_AMD_FE_GATE_700D 0x700D
#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E
#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F
#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400
#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401
#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403
#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404
#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408
#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409
#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B
#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C
#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410
#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411
#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413
#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414
#define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440
# define PCI_DEVICE_ID_AMD_VIPER_7440 PCI_DEVICE_ID_AMD_OPUS_7440
#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440
#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441
# define PCI_DEVICE_ID_AMD_VIPER_7441 PCI_DEVICE_ID_AMD_OPUS_7441
#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443
#
define PCI_DEVICE_ID_AMD_VIPER_7443 PCI_DEVICE_ID_AMD_OPUS_
7443
#
define PCI_DEVICE_ID_AMD_VIPER_7443 0x
7443
#define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445
#define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448
# define PCI_DEVICE_ID_AMD_VIPER_7448 PCI_DEVICE_ID_AMD_OPUS_7448
#define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449
# define PCI_DEVICE_ID_AMD_VIPER_7449 PCI_DEVICE_ID_AMD_OPUS_7449
#define PCI_DEVICE_ID_AMD_8111_LAN 0x7462
#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468
#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469
#define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a
...
...
@@ -585,7 +533,6 @@
#define PCI_DEVICE_ID_CT_65550 0x00e0
#define PCI_DEVICE_ID_CT_65554 0x00e4
#define PCI_DEVICE_ID_CT_65555 0x00e5
#define PCI_DEVICE_ID_CT_69000 0x00c0
#define PCI_VENDOR_ID_MIRO 0x1031
#define PCI_DEVICE_ID_MIRO_36050 0x5601
...
...
@@ -639,7 +586,6 @@
#define PCI_DEVICE_ID_SI_550 0x0550
#define PCI_DEVICE_ID_SI_540_VGA 0x5300
#define PCI_DEVICE_ID_SI_550_VGA 0x5315
#define PCI_DEVICE_ID_SI_601 0x0601
#define PCI_DEVICE_ID_SI_620 0x0620
#define PCI_DEVICE_ID_SI_630 0x0630
#define PCI_DEVICE_ID_SI_633 0x0633
...
...
@@ -650,30 +596,22 @@
#define PCI_DEVICE_ID_SI_648 0x0648
#define PCI_DEVICE_ID_SI_650 0x0650
#define PCI_DEVICE_ID_SI_651 0x0651
#define PCI_DEVICE_ID_SI_652 0x0652
#define PCI_DEVICE_ID_SI_655 0x0655
#define PCI_DEVICE_ID_SI_661 0x0661
#define PCI_DEVICE_ID_SI_730 0x0730
#define PCI_DEVICE_ID_SI_733 0x0733
#define PCI_DEVICE_ID_SI_630_VGA 0x6300
#define PCI_DEVICE_ID_SI_730_VGA 0x7300
#define PCI_DEVICE_ID_SI_735 0x0735
#define PCI_DEVICE_ID_SI_740 0x0740
#define PCI_DEVICE_ID_SI_741 0x0741
#define PCI_DEVICE_ID_SI_745 0x0745
#define PCI_DEVICE_ID_SI_746 0x0746
#define PCI_DEVICE_ID_SI_748 0x0748
#define PCI_DEVICE_ID_SI_750 0x0750
#define PCI_DEVICE_ID_SI_751 0x0751
#define PCI_DEVICE_ID_SI_752 0x0752
#define PCI_DEVICE_ID_SI_755 0x0755
#define PCI_DEVICE_ID_SI_760 0x0760
#define PCI_DEVICE_ID_SI_900 0x0900
#define PCI_DEVICE_ID_SI_961 0x0961
#define PCI_DEVICE_ID_SI_962 0x0962
#define PCI_DEVICE_ID_SI_963 0x0963
#define PCI_DEVICE_ID_SI_5107 0x5107
#define PCI_DEVICE_ID_SI_5300 0x5300
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5518 0x5518
...
...
@@ -685,10 +623,6 @@
#define PCI_DEVICE_ID_SI_5597 0x5597
#define PCI_DEVICE_ID_SI_5598 0x5598
#define PCI_DEVICE_ID_SI_5600 0x5600
#define PCI_DEVICE_ID_SI_6300 0x6300
#define PCI_DEVICE_ID_SI_6306 0x6306
#define PCI_DEVICE_ID_SI_6326 0x6326
#define PCI_DEVICE_ID_SI_7001 0x7001
#define PCI_DEVICE_ID_SI_7012 0x7012
#define PCI_DEVICE_ID_SI_7013 0x7013
#define PCI_DEVICE_ID_SI_7016 0x7016
...
...
@@ -709,14 +643,11 @@
#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
#define PCI_DEVICE_ID_HP_PCI_LBA 0x1054
#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0
#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1
#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227
#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229
#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a
#define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e
#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c
...
...
@@ -724,9 +655,7 @@
#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290
#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301
#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a
#define PCI_DEVICE_ID_HP_CISS 0x3210
#define PCI_DEVICE_ID_HP_CISSA 0x3220
#define PCI_DEVICE_ID_HP_CISSB 0x3222
#define PCI_DEVICE_ID_HP_CISSC 0x3230
#define PCI_DEVICE_ID_HP_CISSD 0x3238
#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
...
...
@@ -734,8 +663,6 @@
#define PCI_VENDOR_ID_PCTECH 0x1042
#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000
#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
#define PCI_VENDOR_ID_ASUSTEK 0x1043
...
...
@@ -745,24 +672,15 @@
#define PCI_DEVICE_ID_DPT 0xa400
#define PCI_VENDOR_ID_OPTI 0x1045
#define PCI_DEVICE_ID_OPTI_92C178 0xc178
#define PCI_DEVICE_ID_OPTI_82C557 0xc557
#define PCI_DEVICE_ID_OPTI_82C558 0xc558
#define PCI_DEVICE_ID_OPTI_82C621 0xc621
#define PCI_DEVICE_ID_OPTI_82C700 0xc700
#define PCI_DEVICE_ID_OPTI_82C701 0xc701
#define PCI_DEVICE_ID_OPTI_82C814 0xc814
#define PCI_DEVICE_ID_OPTI_82C822 0xc822
#define PCI_DEVICE_ID_OPTI_82C861 0xc861
#define PCI_DEVICE_ID_OPTI_82C825 0xd568
#define PCI_VENDOR_ID_ELSA 0x1048
#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000
#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
#define PCI_VENDOR_ID_SGS 0x104a
#define PCI_DEVICE_ID_SGS_2000 0x0008
#define PCI_DEVICE_ID_SGS_1764 0x0009
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
...
...
@@ -770,7 +688,6 @@
#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
#define PCI_VENDOR_ID_TI 0x104c
#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
#define PCI_DEVICE_ID_TI_4450 0x8011
#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031
...
...
@@ -804,14 +721,10 @@
#define PCI_DEVICE_ID_TI_X420 0xac8e
#define PCI_VENDOR_ID_SONY 0x104d
#define PCI_DEVICE_ID_SONY_CXD3222 0x8039
#define PCI_VENDOR_ID_OAK 0x104e
#define PCI_DEVICE_ID_OAK_OTI107 0x0107
/* Winbond have two vendor IDs! See 0x10ad as well */
#define PCI_VENDOR_ID_WINBOND2 0x1050
#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
#define PCI_DEVICE_ID_WINBOND2_6692 0x6692
...
...
@@ -820,19 +733,15 @@
#define PCI_VENDOR_ID_EFAR 0x1055
#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130
#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462
#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463
#define PCI_VENDOR_ID_MOTOROLA 0x1057
#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507
#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
#define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004
#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802
#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803
#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806
#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b
#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803
...
...
@@ -843,33 +752,19 @@
#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
#define PCI_DEVICE_ID_PROMISE_20263 0x0D38
#define PCI_DEVICE_ID_PROMISE_20268 0x4d68
#define PCI_DEVICE_ID_PROMISE_20268R 0x6268
#define PCI_DEVICE_ID_PROMISE_20269 0x4d69
#define PCI_DEVICE_ID_PROMISE_20270 0x6268
#define PCI_DEVICE_ID_PROMISE_20271 0x6269
#define PCI_DEVICE_ID_PROMISE_20275 0x1275
#define PCI_DEVICE_ID_PROMISE_20276 0x5275
#define PCI_DEVICE_ID_PROMISE_20277 0x7275
#define PCI_DEVICE_ID_PROMISE_5300 0x5300
#define PCI_VENDOR_ID_N9 0x105d
#define PCI_DEVICE_ID_N9_I128 0x2309
#define PCI_DEVICE_ID_N9_I128_2 0x2339
#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
#define PCI_VENDOR_ID_UMC 0x1060
#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
#define PCI_VENDOR_ID_X 0x1061
#define PCI_DEVICE_ID_X_AGX016 0x0001
#define PCI_VENDOR_ID_MYLEX 0x1069
#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001
...
...
@@ -880,37 +775,26 @@
#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56
#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166
#define PCI_VENDOR_ID_PICOP 0x1066
#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
#define PCI_DEVICE_ID_APPLE_GC 0x0002
#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018
#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
#define PCI_DEVICE_ID_APPLE_KEYLARGO 0x0022
#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024
#define PCI_DEVICE_ID_APPLE_KEYLARGO_P 0x0025
#define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d
#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e
#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032
#define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034
#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b
#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e
#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c
#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050
#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051
#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052
#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058
#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059
#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
...
...
@@ -923,12 +807,9 @@
#define PCI_DEVICE_ID_YAMAHA_744 0x0010
#define PCI_DEVICE_ID_YAMAHA_754 0x0012
#define PCI_VENDOR_ID_NEXGEN 0x1074
#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
#define PCI_VENDOR_ID_QLOGIC 0x1077
#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100
#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200
#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300
...
...
@@ -946,32 +827,20 @@
#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
#define PCI_DEVICE_ID_CYRIX_5520 0x0002
#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101
#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
#define PCI_VENDOR_ID_LEADTEK 0x107d
#define PCI_DEVICE_ID_LEADTEK_805 0x0000
#define PCI_VENDOR_ID_INTERPHASE 0x107e
#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008
#define PCI_VENDOR_ID_CONTAQ 0x1080
#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
#define PCI_VENDOR_ID_FOREX 0x1083
#define PCI_VENDOR_ID_OLICOM 0x108d
#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
...
...
@@ -990,49 +859,31 @@
#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_640 0x0640
#define PCI_DEVICE_ID_CMD_643 0x0643
#define PCI_DEVICE_ID_CMD_646 0x0646
#define PCI_DEVICE_ID_CMD_647 0x0647
#define PCI_DEVICE_ID_CMD_648 0x0648
#define PCI_DEVICE_ID_CMD_649 0x0649
#define PCI_DEVICE_ID_CMD_670 0x0670
#define PCI_DEVICE_ID_CMD_680 0x0680
#define PCI_DEVICE_ID_SII_680 0x0680
#define PCI_DEVICE_ID_SII_3112 0x3112
#define PCI_DEVICE_ID_SII_1210SA 0x0240
#define PCI_VENDOR_ID_VISION 0x1098
#define PCI_DEVICE_ID_VISION_QD8500 0x0001
#define PCI_DEVICE_ID_VISION_QD8580 0x0002
#define PCI_VENDOR_ID_BROOKTREE 0x109e
#define PCI_DEVICE_ID_BROOKTREE_848 0x0350
#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e
#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
#define PCI_VENDOR_ID_SIERRA 0x10a8
#define PCI_DEVICE_ID_SIERRA_STB 0x0000
#define PCI_VENDOR_ID_SGI 0x10a9
#define PCI_DEVICE_ID_SGI_IOC3 0x0003
#define PCI_DEVICE_ID_SGI_IOC4 0x100a
#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002
#define PCI_VENDOR_ID_ACC 0x10aa
#define PCI_DEVICE_ID_ACC_2056 0x0000
#define PCI_VENDOR_ID_WINBOND 0x10ad
#define PCI_DEVICE_ID_WINBOND_83769 0x0001
#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
#define PCI_VENDOR_ID_DATABOOK 0x10b3
#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
#define PCI_VENDOR_ID_PLX 0x10b5
#define PCI_DEVICE_ID_PLX_R685 0x1030
...
...
@@ -1043,33 +894,19 @@
#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151
#define PCI_DEVICE_ID_PLX_R753 0x1152
#define PCI_DEVICE_ID_PLX_OLITEC 0x1187
#define PCI_DEVICE_ID_PLX_9030 0x9030
#define PCI_DEVICE_ID_PLX_9050 0x9050
#define PCI_DEVICE_ID_PLX_9060 0x9060
#define PCI_DEVICE_ID_PLX_9060ES 0x906E
#define PCI_DEVICE_ID_PLX_9060SD 0x906D
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
#define PCI_VENDOR_ID_MADGE 0x10b6
#define PCI_DEVICE_ID_MADGE_MK2 0x0002
#define PCI_DEVICE_ID_MADGE_C155S 0x1001
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C985 0x0001
#define PCI_DEVICE_ID_3COM_3C940 0x1700
#define PCI_DEVICE_ID_3COM_3C339 0x3390
#define PCI_DEVICE_ID_3COM_3C359 0x3590
#define PCI_DEVICE_ID_3COM_3C590 0x5900
#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
#define PCI_DEVICE_ID_3COM_3C940B 0x80eb
#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_DEVICE_ID_3COM_3CR990 0x9900
#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902
#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903
...
...
@@ -1079,24 +916,11 @@
#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909
#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a
#define PCI_VENDOR_ID_SMC 0x10b8
#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
#define PCI_VENDOR_ID_AL 0x10b9
#define PCI_DEVICE_ID_AL_M1445 0x1445
#define PCI_DEVICE_ID_AL_M1449 0x1449
#define PCI_DEVICE_ID_AL_M1451 0x1451
#define PCI_DEVICE_ID_AL_M1461 0x1461
#define PCI_DEVICE_ID_AL_M1489 0x1489
#define PCI_DEVICE_ID_AL_M1511 0x1511
#define PCI_DEVICE_ID_AL_M1513 0x1513
#define PCI_DEVICE_ID_AL_M1521 0x1521
#define PCI_DEVICE_ID_AL_M1523 0x1523
#define PCI_DEVICE_ID_AL_M1531 0x1531
#define PCI_DEVICE_ID_AL_M1533 0x1533
#define PCI_DEVICE_ID_AL_M1535 0x1535
#define PCI_DEVICE_ID_AL_M1541 0x1541
#define PCI_DEVICE_ID_AL_M1543 0x1543
#define PCI_DEVICE_ID_AL_M1563 0x1563
#define PCI_DEVICE_ID_AL_M1621 0x1621
#define PCI_DEVICE_ID_AL_M1631 0x1631
...
...
@@ -1109,49 +933,23 @@
#define PCI_DEVICE_ID_AL_M1681 0x1681
#define PCI_DEVICE_ID_AL_M1683 0x1683
#define PCI_DEVICE_ID_AL_M1689 0x1689
#define PCI_DEVICE_ID_AL_M3307 0x3307
#define PCI_DEVICE_ID_AL_M4803 0x5215
#define PCI_DEVICE_ID_AL_M5219 0x5219
#define PCI_DEVICE_ID_AL_M5228 0x5228
#define PCI_DEVICE_ID_AL_M5229 0x5229
#define PCI_DEVICE_ID_AL_M5237 0x5237
#define PCI_DEVICE_ID_AL_M5243 0x5243
#define PCI_DEVICE_ID_AL_M5451 0x5451
#define PCI_DEVICE_ID_AL_M7101 0x7101
#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
#define PCI_VENDOR_ID_SURECOM 0x10bd
#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083
#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
#define PCI_VENDOR_ID_ASP 0x10cd
#define PCI_DEVICE_ID_ASP_ABP940 0x1200
#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
#define PCI_VENDOR_ID_MACRONIX 0x10d9
#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
#define PCI_VENDOR_ID_TCONRAD 0x10da
#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
...
...
@@ -1197,7 +995,6 @@
#define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc
#define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce
#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1
#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5
#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6
...
...
@@ -1284,7 +1081,6 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F
#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268
#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269
#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282
...
...
@@ -1335,24 +1131,13 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
#define PCI_DEVICE_ID_IMS_TT128 0x9128
#define PCI_DEVICE_ID_IMS_TT3D 0x9135
#define PCI_VENDOR_ID_TEKRAM2 0x10e1
#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
#define PCI_VENDOR_ID_TUNDRA 0x10e3
#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
#define PCI_VENDOR_ID_AMCC 0x10e8
#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
#define PCI_DEVICE_ID_AMCC_S5933 0x807d
#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
#define PCI_VENDOR_ID_INTERG 0x10ea
#define PCI_DEVICE_ID_INTERG_1680 0x1680
#define PCI_DEVICE_ID_INTERG_1682 0x1682
#define PCI_DEVICE_ID_INTERG_2000 0x2000
#define PCI_DEVICE_ID_INTERG_2010 0x2010
...
...
@@ -1360,32 +1145,23 @@
#define PCI_DEVICE_ID_INTERG_5050 0x5050
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
#define PCI_DEVICE_ID_REALTEK_8129 0x8129
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_DEVICE_ID_REALTEK_8169 0x8169
#define PCI_VENDOR_ID_XILINX 0x10ee
#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0
#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1
#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2
#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3
#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4
#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
#define PCI_DEVICE_ID_TURBOPAM 0x4020
#define PCI_VENDOR_ID_TRUEVISION 0x10fa
#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
#define PCI_VENDOR_ID_INIT 0x1101
#define PCI_DEVICE_ID_INIT_320P 0x9100
#define PCI_DEVICE_ID_INIT_360P 0x9500
#define PCI_VENDOR_ID_CREATIVE 0x1102 /
/ duplicate: ECTIVA
#define PCI_VENDOR_ID_CREATIVE 0x1102
/
* duplicate: ECTIVA */
#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
#define PCI_VENDOR_ID_ECTIVA 0x1102 /
/ duplicate: CREATIVE
#define PCI_VENDOR_ID_ECTIVA 0x1102
/
* duplicate: CREATIVE */
#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
#define PCI_VENDOR_ID_TTI 0x1103
...
...
@@ -1395,7 +1171,7 @@
#define PCI_DEVICE_ID_TTI_HPT302 0x0006
#define PCI_DEVICE_ID_TTI_HPT371 0x0007
#define PCI_DEVICE_ID_TTI_HPT374 0x0008
#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /
/ apparently a 372N variant?
#define PCI_DEVICE_ID_TTI_HPT372N 0x0009
/
* apparently a 372N variant? */
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_8763_0 0x0198
...
...
@@ -1408,36 +1184,25 @@
#define PCI_DEVICE_ID_VIA_8363_0 0x0305
#define PCI_DEVICE_ID_VIA_8371_0 0x0391
#define PCI_DEVICE_ID_VIA_8501_0 0x0501
#define PCI_DEVICE_ID_VIA_82C505 0x0505
#define PCI_DEVICE_ID_VIA_82C561 0x0561
#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
#define PCI_DEVICE_ID_VIA_82C576 0x0576
#define PCI_DEVICE_ID_VIA_82C585 0x0585
#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
#define PCI_DEVICE_ID_VIA_82C595 0x0595
#define PCI_DEVICE_ID_VIA_82C596 0x0596
#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
#define PCI_DEVICE_ID_VIA_82C598_0 0x0598
#define PCI_DEVICE_ID_VIA_8601_0 0x0601
#define PCI_DEVICE_ID_VIA_8605_0 0x0605
#define PCI_DEVICE_ID_VIA_82C680 0x0680
#define PCI_DEVICE_ID_VIA_82C686 0x0686
#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
#define PCI_DEVICE_ID_VIA_82C693 0x0693
#define PCI_DEVICE_ID_VIA_82C693_1 0x0698
#define PCI_DEVICE_ID_VIA_82C926 0x0926
#define PCI_DEVICE_ID_VIA_82C576_1 0x1571
#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
#define PCI_DEVICE_ID_VIA_6305 0x3044
#define PCI_DEVICE_ID_VIA_82C596_3 0x3050
#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051
#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
#define PCI_DEVICE_ID_VIA_8233_5 0x3059
#define PCI_DEVICE_ID_VIA_8233_7 0x3065
#define PCI_DEVICE_ID_VIA_82C686_6 0x3068
#define PCI_DEVICE_ID_VIA_8233_0 0x3074
#define PCI_DEVICE_ID_VIA_8633_0 0x3091
#define PCI_DEVICE_ID_VIA_8367_0 0x3099
...
...
@@ -1455,38 +1220,23 @@
#define PCI_DEVICE_ID_VIA_XN266 0x3156
#define PCI_DEVICE_ID_VIA_8754C_0 0x3168
#define PCI_DEVICE_ID_VIA_8235 0x3177
#define PCI_DEVICE_ID_VIA_P4N333 0x3178
#define PCI_DEVICE_ID_VIA_8385_0 0x3188
#define PCI_DEVICE_ID_VIA_8377_0 0x3189
#define PCI_DEVICE_ID_VIA_8378_0 0x3205
#define PCI_DEVICE_ID_VIA_8783_0 0x3208
#define PCI_DEVICE_ID_VIA_P4M400 0x3209
#define PCI_DEVICE_ID_VIA_8237 0x3227
#define PCI_DEVICE_ID_VIA_3296_0 0x0296
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_8231 0x8231
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
#define PCI_DEVICE_ID_VIA_8365_1 0x8305
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_8501_1 0x8501
#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_8601_1 0x8601
#define PCI_DEVICE_ID_VIA_8505_1 0x8605
#define PCI_DEVICE_ID_VIA_8633_1 0xB091
#define PCI_DEVICE_ID_VIA_8367_1 0xB099
#define PCI_DEVICE_ID_VIA_P4X266_1 0xB101
#define PCI_DEVICE_ID_VIA_8615_1 0xB103
#define PCI_DEVICE_ID_VIA_8361_1 0xB112
#define PCI_DEVICE_ID_VIA_8235_1 0xB168
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198
#define PCI_VENDOR_ID_SIEMENS 0x110A
#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
#define PCI_VENDOR_ID_SMC2 0x1113
#define PCI_DEVICE_ID_SMC2_1211TX 0x1211
#define PCI_VENDOR_ID_VORTEX 0x1119
#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
...
...
@@ -1509,18 +1259,6 @@
#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111
#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112
#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121
#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122
#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125
#define PCI_VENDOR_ID_EF 0x111a
#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
...
...
@@ -1532,21 +1270,15 @@
#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
#define PCI_VENDOR_ID_FORE 0x1127
#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
#define PCI_VENDOR_ID_PHILIPS 0x1131
#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730
#define PCI_VENDOR_ID_EICON 0x1133
#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001
#define PCI_DEVICE_ID_EICON_DIVA20 0xe002
#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003
#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004
#define PCI_DEVICE_ID_EICON_DIVA201 0xe005
#define PCI_DEVICE_ID_EICON_DIVA202 0xe00b
...
...
@@ -1558,35 +1290,17 @@
#define PCI_VENDOR_ID_ZIATECH 0x1138
#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550
#define PCI_VENDOR_ID_CYCLONE 0x113c
#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001
#define PCI_VENDOR_ID_ALLIANCE 0x1142
#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424
#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d
#define PCI_VENDOR_ID_SYSKONNECT 0x1148
#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000
#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300
#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320
#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400
#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500
#define PCI_VENDOR_ID_VMIC 0x114a
#define PCI_DEVICE_ID_VMIC_VME 0x7587
#define PCI_VENDOR_ID_DIGI 0x114f
#define PCI_DEVICE_ID_DIGI_EPC 0x0002
#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003
#define PCI_DEVICE_ID_DIGI_XEM 0x0004
#define PCI_DEVICE_ID_DIGI_XR 0x0005
#define PCI_DEVICE_ID_DIGI_CX 0x0006
#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070
#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071
#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072
...
...
@@ -1596,23 +1310,15 @@
#define PCI_DEVICE_ID_NEO_2RJ45 0x00CA
#define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB
#define PCI_VENDOR_ID_MUTECH 0x1159
#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
#define PCI_VENDOR_ID_XIRCOM 0x115d
#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003
#define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101
#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103
#define PCI_VENDOR_ID_RENDITION 0x1163
#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001
#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
#define PCI_VENDOR_ID_SERVERWORKS 0x1166
#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008
#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009
#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010
#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
...
...
@@ -1622,13 +1328,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225
#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227
#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
#define PCI_VENDOR_ID_SBE 0x1176
#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
...
...
@@ -1639,17 +1339,12 @@
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105
#define PCI_DEVICE_ID_TOSHIBA_601 0x0601
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617
#define PCI_VENDOR_ID_TOSHIBA_2 0x102f
#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a
#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030
#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180
#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108
#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
...
...
@@ -1664,7 +1359,6 @@
#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00
#define PCI_VENDOR_ID_ARTOP 0x1191
#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004
#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006
#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007
...
...
@@ -1677,16 +1371,11 @@
#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040
#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050
#define PCI_DEVICE_ID_ARTOP_8060 0x8060
#define PCI_DEVICE_ID_ARTOP_AEC67160 0x8080
#define PCI_DEVICE_ID_ARTOP_AEC67160_2 0x8081
#define PCI_DEVICE_ID_ARTOP_AEC67162 0x808a
#define PCI_VENDOR_ID_ZEITNET 0x1193
#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
#define PCI_VENDOR_ID_OMEGA 0x119b
#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001
...
...
@@ -1696,61 +1385,41 @@
#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
#define PCI_VENDOR_ID_MARVELL 0x11ab
#define PCI_DEVICE_ID_MARVELL_GT64011 0x4146
#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146
#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480
#define PCI_DEVICE_ID_MARVELL_GT96100 0x9652
#define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653
#define PCI_VENDOR_ID_LITEON 0x11ad
#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002
#define PCI_VENDOR_ID_V3 0x11b0
#define PCI_DEVICE_ID_V3_V960 0x0001
#define PCI_DEVICE_ID_V3_V350 0x0001
#define PCI_DEVICE_ID_V3_V961 0x0002
#define PCI_DEVICE_ID_V3_V351 0x0002
#define PCI_VENDOR_ID_NP 0x11bc
#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001
#define PCI_VENDOR_ID_ATT 0x11c1
#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
#define PCI_VENDOR_ID_NEC2 0x11c3
/* NEC (2nd) */
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
#define PCI_VENDOR_ID_AURAVISION 0x11d1
#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
#define PCI_DEVICE_ID_AD1889JS 0x1889
#define PCI_VENDOR_ID_IKON 0x11d5
#define PCI_DEVICE_ID_IKON_10115 0x0115
#define PCI_DEVICE_ID_IKON_10117 0x0117
#define PCI_VENDOR_ID_SEGA 0x11db
#define PCI_DEVICE_ID_SEGA_BBA 0x1234
#define PCI_VENDOR_ID_ZORAN 0x11de
#define PCI_DEVICE_ID_ZORAN_36057 0x6057
#define PCI_DEVICE_ID_ZORAN_36120 0x6120
#define PCI_VENDOR_ID_KINETIC 0x11f4
#define PCI_DEVICE_ID_KINETIC_2915 0x2915
#define PCI_VENDOR_ID_COMPEX 0x11f6
#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
#define PCI_VENDOR_ID_RP 0x11fe
#define PCI_DEVICE_ID_RP32INTF 0x0001
...
...
@@ -1764,7 +1433,6 @@
#define PCI_DEVICE_ID_RP16SNI 0x0009
#define PCI_DEVICE_ID_RPP4 0x000A
#define PCI_DEVICE_ID_RPP8 0x000B
#define PCI_DEVICE_ID_RP8M 0x000C
#define PCI_DEVICE_ID_RP4M 0x000D
#define PCI_DEVICE_ID_RP2_232 0x000E
#define PCI_DEVICE_ID_RP2_422 0x000F
...
...
@@ -1792,10 +1460,6 @@
#define PCI_DEVICE_ID_PC300_TE_M_2 0x0320
#define PCI_DEVICE_ID_PC300_TE_M_1 0x0321
/* Allied Telesyn */
#define PCI_VENDOR_ID_AT 0x1259
#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703
#define PCI_VENDOR_ID_ESSENTIAL 0x120f
#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
...
...
@@ -1812,10 +1476,7 @@
#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
#define PCI_VENDOR_ID_SIGMADES 0x1236
#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
#define PCI_VENDOR_ID_CCUBE 0x123f
#define PCI_VENDOR_ID_AVM 0x1244
#define PCI_DEVICE_ID_AVM_B1 0x0700
...
...
@@ -1825,19 +1486,8 @@
#define PCI_DEVICE_ID_AVM_C2 0x1100
#define PCI_DEVICE_ID_AVM_T1 0x1200
#define PCI_VENDOR_ID_DIPIX 0x1246
#define PCI_VENDOR_ID_STALLION 0x124d
#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003
#define PCI_VENDOR_ID_OPTIBASE 0x1255
#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110
#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210
#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110
#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
/* Allied Telesyn */
#define PCI_VENDOR_ID_AT 0x1259
...
...
@@ -1846,7 +1496,6 @@
#define PCI_VENDOR_ID_ESS 0x125d
#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969
#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
...
...
@@ -1859,11 +1508,7 @@
#define PCI_VENDOR_ID_SATSAGEM 0x1267
#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016
#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
#define PCI_VENDOR_ID_HUGHES 0x1273
#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
#define PCI_VENDOR_ID_ENSONIQ 0x1274
#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
...
...
@@ -1884,13 +1529,10 @@
#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886
/* formerly Platform Tech */
#define PCI_VENDOR_ID_ESS_OLD 0x1285
#define PCI_DEVICE_ID_ESS_ESS0100 0x0100
#define PCI_VENDOR_ID_ALTEON 0x12ae
#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
#define PCI_VENDOR_ID_USR 0x12B9
#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
...
...
@@ -1905,8 +1547,6 @@
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B
#define PCI_VENDOR_ID_PICTUREL 0x12c5
#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
...
...
@@ -1928,8 +1568,6 @@
#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8
#define PCI_DEVICE_ID_LML_33R10 0x8a02
#define PCI_VENDOR_ID_CBOARDS 0x1307
#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
#define PCI_VENDOR_ID_SIIG 0x131f
#define PCI_SUBVENDOR_ID_SIIG 0x131f
...
...
@@ -1973,7 +1611,6 @@
#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050
#define PCI_VENDOR_ID_RADISYS 0x1331
#define PCI_DEVICE_ID_RADISYS_ENP2611 0x0030
#define PCI_VENDOR_ID_DOMEX 0x134a
#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001
...
...
@@ -1981,8 +1618,6 @@
#define PCI_VENDOR_ID_QUATECH 0x135C
#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030
#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040
#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
...
...
@@ -2001,7 +1636,6 @@
#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106
#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109
#define PCI_VENDOR_ID_KAWASAKI 0x136b
#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
...
...
@@ -2015,12 +1649,9 @@
#define PCI_DEVICE_ID_LMC_SSI 0x0005
#define PCI_DEVICE_ID_LMC_T1 0x0006
#define PCI_VENDOR_ID_MARIAN 0x1382
#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048
#define PCI_VENDOR_ID_NETGEAR 0x1385
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a
#define PCI_VENDOR_ID_APPLICOM 0x1389
#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
...
...
@@ -2043,9 +1674,6 @@
#define PCI_DEVICE_ID_MOXA_CP134U 0x1340
#define PCI_DEVICE_ID_MOXA_C168 0x1680
#define PCI_DEVICE_ID_MOXA_CP168U 0x1681
#define PCI_DEVICE_ID_MOXA_CP204J 0x2040
#define PCI_DEVICE_ID_MOXA_C218 0x2180
#define PCI_DEVICE_ID_MOXA_C320 0x3200
#define PCI_VENDOR_ID_CCD 0x1397
#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0
...
...
@@ -2066,9 +1694,7 @@
#define PCI_VENDOR_ID_MICROGATE 0x13c0
#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020
#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030
#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210
#define PCI_VENDOR_ID_3WARE 0x13C1
#define PCI_DEVICE_ID_3WARE_1000 0x1000
...
...
@@ -2119,10 +1745,6 @@
#define PCI_VENDOR_ID_SAMSUNG 0x144d
#define PCI_VENDOR_ID_AIRONET 0x14b9
#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001
#define PCI_DEVICE_ID_AIRONET_4800 0x4500 // values switched? see
#define PCI_DEVICE_ID_AIRONET_4500 0x4800 // drivers/net/aironet4500_card.c
#define PCI_VENDOR_ID_TITAN 0x14D2
#define PCI_DEVICE_ID_TITAN_010L 0x8001
...
...
@@ -2141,8 +1763,6 @@
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
#define PCI_VENDOR_ID_SIPACKETS 0x14d9
#define PCI_DEVICE_ID_SP_HT 0x0010
#define PCI_VENDOR_ID_AFAVLAB 0x14db
#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180
...
...
@@ -2207,8 +1827,6 @@
#define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_MIPS 0x153f
#define PCI_DEVICE_ID_SOC_IT 0x0001
#define PCI_VENDOR_ID_SYBA 0x1592
#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
...
...
@@ -2228,15 +1846,7 @@
#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
#define PCI_VENDOR_ID_PDC 0x15e9
#define PCI_DEVICE_ID_PDC_1841 0x1841
#define PCI_VENDOR_ID_MACROLINK 0x15ed
#define PCI_DEVICE_ID_MACROLINK_MCCS8 0x1000
#define PCI_DEVICE_ID_MACROLINK_MCCS 0x1001
#define PCI_DEVICE_ID_MACROLINK_MCCS8H 0x1002
#define PCI_DEVICE_ID_MACROLINK_MCCSH 0x1003
#define PCI_DEVICE_ID_MACROLINK_MCCR8 0x2000
#define PCI_DEVICE_ID_MACROLINK_MCCR 0x2001
#define PCI_VENDOR_ID_FARSITE 0x1619
#define PCI_DEVICE_ID_FARSITE_T2P 0x0400
...
...
@@ -2254,7 +1864,6 @@
#define PCI_DEVICE_ID_REVOLUTION 0x0044
#define PCI_VENDOR_ID_LINKSYS 0x1737
#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032
#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064
#define PCI_VENDOR_ID_ALTIMA 0x173b
...
...
@@ -2269,7 +1878,6 @@
#define PCI_DEVICE_ID_HERC_WIN 0x5732
#define PCI_DEVICE_ID_HERC_UNI 0x5832
#define PCI_VENDOR_ID_INFINICON 0x1820
#define PCI_VENDOR_ID_SITECOM 0x182d
#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069
...
...
@@ -2279,8 +1887,6 @@
#define PCI_VENDOR_ID_TDI 0x192E
#define PCI_DEVICE_ID_TDI_EHCI 0x0101
#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
...
...
@@ -2289,70 +1895,33 @@
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
#define PCI_VENDOR_ID_3DLABS 0x3d3d
#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
#define PCI_DEVICE_ID_3DLABS_MX 0x0006
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
#define PCI_VENDOR_ID_AVANCE 0x4005
#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
#define PCI_DEVICE_ID_AVANCE_2302 0x2302
#define PCI_VENDOR_ID_AKS 0x416c
#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
#define PCI_DEVICE_ID_AKS_CPC 0x0200
#define PCI_VENDOR_ID_REDCREEK 0x4916
#define PCI_DEVICE_ID_RC45 0x1960
#define PCI_VENDOR_ID_NETVIN 0x4a14
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551
#define PCI_DEVICE_ID_S3_ViRGE 0x5631
#define PCI_DEVICE_ID_S3_TRIO 0x8811
#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
#define PCI_DEVICE_ID_S3_868 0x8880
#define PCI_DEVICE_ID_S3_928 0x88b0
#define PCI_DEVICE_ID_S3_864_1 0x88c0
#define PCI_DEVICE_ID_S3_864_2 0x88c1
#define PCI_DEVICE_ID_S3_964_1 0x88d0
#define PCI_DEVICE_ID_S3_964_2 0x88d1
#define PCI_DEVICE_ID_S3_968 0x88f0
#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901
#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902
#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01
#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10
#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25
#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01
#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02
#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03
#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04
#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
#define PCI_VENDOR_ID_DUNORD 0x5544
#define PCI_DEVICE_ID_DUNORD_I3000 0x0001
#define PCI_VENDOR_ID_DCI 0x6666
#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001
#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002
#define PCI_VENDOR_ID_DUNORD 0x5544
#define PCI_DEVICE_ID_DUNORD_I3000 0x0001
#define PCI_VENDOR_ID_GENROCO 0x5555
#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
#define PCI_DEVICE_ID_INTEL_21145 0x0039
#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321
#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
...
...
@@ -2361,30 +1930,17 @@
#define PCI_DEVICE_ID_INTEL_82375 0x0482
#define PCI_DEVICE_ID_INTEL_82424 0x0483
#define PCI_DEVICE_ID_INTEL_82378 0x0484
#define PCI_DEVICE_ID_INTEL_82430 0x0486
#define PCI_DEVICE_ID_INTEL_82434 0x04a3
#define PCI_DEVICE_ID_INTEL_I960 0x0960
#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
#define PCI_DEVICE_ID_INTEL_82562ET 0x1031
#define PCI_DEVICE_ID_INTEL_82801CAM 0x1038
#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
#define PCI_DEVICE_ID_INTEL_82815_AB 0x1131
#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
#define PCI_DEVICE_ID_INTEL_7116 0x1223
#define PCI_DEVICE_ID_INTEL_7505_0 0x2550
#define PCI_DEVICE_ID_INTEL_7505_1 0x2552
#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
#define PCI_DEVICE_ID_INTEL_82596 0x1226
#define PCI_DEVICE_ID_INTEL_82865 0x1227
#define PCI_DEVICE_ID_INTEL_82557 0x1229
#define PCI_DEVICE_ID_INTEL_82437 0x122d
#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
#define PCI_DEVICE_ID_INTEL_82439 0x1250
...
...
@@ -2393,83 +1949,53 @@
#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412
#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416
#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418
#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420
#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421
#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422
#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423
#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425
#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426
#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428
#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440
#define PCI_DEVICE_ID_INTEL_82801BA_1 0x2442
#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443
#define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444
#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445
#define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446
#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448
#define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449
#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a
#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b
#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450
#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452
#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453
#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459
#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b
#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d
#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e
#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484
#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487
#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0
#define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1
#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2
#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3
#define PCI_DEVICE_ID_INTEL_82801DB_4 0x24c4
#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5
#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6
#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7
#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9
#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca
#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb
#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc
#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd
#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0
#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1
#define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2
#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3
#define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4
#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5
#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6
#define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7
#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db
#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd
#define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1
#define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2
#define PCI_DEVICE_ID_INTEL_ESB_3 0x25a3
#define PCI_DEVICE_ID_INTEL_ESB_31 0x25b0
#define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4
#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
#define PCI_DEVICE_ID_INTEL_ESB_6 0x25a7
#define PCI_DEVICE_ID_INTEL_ESB_7 0x25a9
#define PCI_DEVICE_ID_INTEL_ESB_8 0x25aa
#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
#define PCI_DEVICE_ID_INTEL_ESB_11 0x25ac
#define PCI_DEVICE_ID_INTEL_ESB_12 0x25ad
#define PCI_DEVICE_ID_INTEL_ESB_13 0x25ae
#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500
#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501
#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530
...
...
@@ -2479,7 +2005,6 @@
#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572
#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578
#define PCI_DEVICE_ID_INTEL_82875_IG 0x257b
#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580
#define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582
#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590
...
...
@@ -2489,80 +2014,23 @@
#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640
#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641
#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642
#define PCI_DEVICE_ID_INTEL_ICH6_3 0x2651
#define PCI_DEVICE_ID_INTEL_ICH6_4 0x2652
#define PCI_DEVICE_ID_INTEL_ICH6_5 0x2653
#define PCI_DEVICE_ID_INTEL_ICH6_6 0x2658
#define PCI_DEVICE_ID_INTEL_ICH6_7 0x2659
#define PCI_DEVICE_ID_INTEL_ICH6_8 0x265a
#define PCI_DEVICE_ID_INTEL_ICH6_9 0x265b
#define PCI_DEVICE_ID_INTEL_ICH6_10 0x265c
#define PCI_DEVICE_ID_INTEL_ICH6_11 0x2660
#define PCI_DEVICE_ID_INTEL_ICH6_12 0x2662
#define PCI_DEVICE_ID_INTEL_ICH6_13 0x2664
#define PCI_DEVICE_ID_INTEL_ICH6_14 0x2666
#define PCI_DEVICE_ID_INTEL_ICH6_15 0x2668
#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a
#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d
#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f
#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670
#define PCI_DEVICE_ID_INTEL_ESB2_1 0x2680
#define PCI_DEVICE_ID_INTEL_ESB2_2 0x2681
#define PCI_DEVICE_ID_INTEL_ESB2_3 0x2682
#define PCI_DEVICE_ID_INTEL_ESB2_4 0x2683
#define PCI_DEVICE_ID_INTEL_ESB2_5 0x2688
#define PCI_DEVICE_ID_INTEL_ESB2_6 0x2689
#define PCI_DEVICE_ID_INTEL_ESB2_7 0x268a
#define PCI_DEVICE_ID_INTEL_ESB2_8 0x268b
#define PCI_DEVICE_ID_INTEL_ESB2_9 0x268c
#define PCI_DEVICE_ID_INTEL_ESB2_10 0x2690
#define PCI_DEVICE_ID_INTEL_ESB2_11 0x2692
#define PCI_DEVICE_ID_INTEL_ESB2_12 0x2694
#define PCI_DEVICE_ID_INTEL_ESB2_13 0x2696
#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
#define PCI_DEVICE_ID_INTEL_ESB2_15 0x2699
#define PCI_DEVICE_ID_INTEL_ESB2_16 0x269a
#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b
#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e
#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
#define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0
#define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1
#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
#define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4
#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5
#define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8
#define PCI_DEVICE_ID_INTEL_ICH7_8 0x27c9
#define PCI_DEVICE_ID_INTEL_ICH7_9 0x27ca
#define PCI_DEVICE_ID_INTEL_ICH7_10 0x27cb
#define PCI_DEVICE_ID_INTEL_ICH7_11 0x27cc
#define PCI_DEVICE_ID_INTEL_ICH7_12 0x27d0
#define PCI_DEVICE_ID_INTEL_ICH7_13 0x27d2
#define PCI_DEVICE_ID_INTEL_ICH7_14 0x27d4
#define PCI_DEVICE_ID_INTEL_ICH7_15 0x27d6
#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8
#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da
#define PCI_DEVICE_ID_INTEL_ICH7_18 0x27dc
#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
#define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df
#define PCI_DEVICE_ID_INTEL_ICH7_22 0x27e0
#define PCI_DEVICE_ID_INTEL_ICH7_23 0x27e2
#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
#define PCI_DEVICE_ID_INTEL_ESB2_19 0x3500
#define PCI_DEVICE_ID_INTEL_ESB2_20 0x3501
#define PCI_DEVICE_ID_INTEL_ESB2_21 0x3504
#define PCI_DEVICE_ID_INTEL_ESB2_22 0x3505
#define PCI_DEVICE_ID_INTEL_ESB2_23 0x350c
#define PCI_DEVICE_ID_INTEL_ESB2_24 0x350d
#define PCI_DEVICE_ID_INTEL_ESB2_25 0x3510
#define PCI_DEVICE_ID_INTEL_ESB2_26 0x3511
#define PCI_DEVICE_ID_INTEL_ESB2_27 0x3514
#define PCI_DEVICE_ID_INTEL_ESB2_28 0x3515
#define PCI_DEVICE_ID_INTEL_ESB2_29 0x3518
#define PCI_DEVICE_ID_INTEL_ESB2_30 0x3519
#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
...
...
@@ -2576,7 +2044,6 @@
#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
...
...
@@ -2601,22 +2068,15 @@
#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198
#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199
#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a
#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602
#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea
#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
#define PCI_DEVICE_ID_INTEL_IXP2400 0x9001
#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
...
...
@@ -2629,7 +2089,6 @@
#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
#define PCI_VENDOR_ID_KTI 0x8e2e
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
#define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
...
...
@@ -2637,7 +2096,6 @@
#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860
#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800
#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038
#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
...
...
@@ -2657,7 +2115,6 @@
#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678
#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778
#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878
#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
#define PCI_VENDOR_ID_ADAPTEC2 0x9005
#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
...
...
@@ -2677,8 +2134,6 @@
#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf
#define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503
#define PCI_VENDOR_ID_ATRONICS 0x907f
#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
#define PCI_VENDOR_ID_HOLTEK 0x9412
#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
...
...
@@ -2711,7 +2166,3 @@
#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
#define PCI_VENDOR_ID_ARK 0xedd8
#define PCI_DEVICE_ID_ARK_STING 0xa091
#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1
sound/oss/ymfpci.c
View file @
7efe5d7c
...
...
@@ -107,14 +107,15 @@ static LIST_HEAD(ymf_devs);
*/
static
struct
pci_device_id
ymf_id_tbl
[]
=
{
#define DEV(v, d, data) \
{ PCI_VENDOR_ID_##v, PCI_DEVICE_ID_##v##_##d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)data }
DEV
(
YAMAHA
,
724
,
"YMF724"
),
DEV
(
YAMAHA
,
724
F
,
"YMF724F"
),
DEV
(
YAMAHA
,
740
,
"YMF740"
),
DEV
(
YAMAHA
,
740
C
,
"YMF740C"
),
DEV
(
YAMAHA
,
744
,
"YMF744"
),
DEV
(
YAMAHA
,
754
,
"YMF754"
),
#define DEV(dev, data) \
{ PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
(unsigned long)data }
DEV
(
PCI_DEVICE_ID_YAMAHA_724
,
"YMF724"
),
DEV
(
PCI_DEVICE_ID_YAMAHA_724F
,
"YMF724F"
),
DEV
(
PCI_DEVICE_ID_YAMAHA_740
,
"YMF740"
),
DEV
(
PCI_DEVICE_ID_YAMAHA_740C
,
"YMF740C"
),
DEV
(
PCI_DEVICE_ID_YAMAHA_744
,
"YMF744"
),
DEV
(
PCI_DEVICE_ID_YAMAHA_754
,
"YMF754"
),
#undef DEV
{
}
};
...
...
sound/pci/bt87x.c
View file @
7efe5d7c
...
...
@@ -761,15 +761,18 @@ static int __devinit snd_bt87x_create(snd_card_t *card,
#define BT_DEVICE(chip, subvend, subdev, rate) \
{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
.device =
PCI_DEVICE_ID_BROOKTREE_##
chip, \
.device = chip, \
.subvendor = subvend, .subdevice = subdev, \
.driver_data = rate }
/* driver_data is the default digital_rate value for that device */
static
struct
pci_device_id
snd_bt87x_ids
[]
=
{
BT_DEVICE
(
878
,
0x0070
,
0x13eb
,
32000
),
/* Hauppauge WinTV series */
BT_DEVICE
(
879
,
0x0070
,
0x13eb
,
32000
),
/* Hauppauge WinTV series */
BT_DEVICE
(
878
,
0x0070
,
0xff01
,
44100
),
/* Viewcast Osprey 200 */
/* Hauppauge WinTV series */
BT_DEVICE
(
PCI_DEVICE_ID_BROOKTREE_878
,
0x0070
,
0x13eb
,
32000
),
/* Hauppauge WinTV series */
BT_DEVICE
(
PCI_DEVICE_ID_BROOKTREE_879
,
0x0070
,
0x13eb
,
32000
),
/* Viewcast Osprey 200 */
BT_DEVICE
(
PCI_DEVICE_ID_BROOKTREE_878
,
0x0070
,
0xff01
,
44100
),
{
}
};
MODULE_DEVICE_TABLE
(
pci
,
snd_bt87x_ids
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment