Commit a3ea9b58 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (49 commits)
  [PATCH] acpiphp: fix acpi_path_name
  [PATCH] ibmphp: remove TRUE and FALSE
  [PATCH] PCI Hotplug: add common acpi functions to core
  [PATCH] PCI: kzalloc() conversion in drivers/pci
  [PATCH] acpiphp: Scan slots under the nested P2P bridge
  [PATCH] PCI Hotplug: SN: Fix cleanup on hotplug removal of PPB
  [PATCH] shpchp: cleanup bus speed handling
  [PATCH] PCI: fix pci_request_region[s] arg
  [PATCH] PCI: Provide a boot parameter to disable MSI
  [PATCH] PCI: the scheduled removal of PCI_LEGACY_PROC
  [PATCH] PCI: cpqphp_ctrl.c: board_replaced(): remove dead code
  [PATCH] acpiphp: fix bridge handle
  [PATCH] acpiphp - slot management fix - V4
  [PATCH] acpi: remove dock event handling from ibm_acpi
  [PATCH] acpiphp: add dock event handling
  [PATCH] acpi: export acpi_bus_trim
  [PATCH] acpiphp: add new bus to acpi
  [PATCH] PCI: Move pci_dev_put outside a spinlock
  [PATCH] PCI: PCI/Cardbus cards hidden, needs pci=assign-busses to fix
  [PATCH] PCI: fix problems with MSI-X on ia64
  ...
parents 554f593d b2e6e3ba
......@@ -158,13 +158,6 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: Legacy /proc/pci interface (PCI_LEGACY_PROC)
When: March 2006
Why: deprecated since 2.5.53 in favor of lspci(8)
Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: pci_module_init(driver)
When: January 2007
Why: Is replaced by pci_register_driver(pci_driver).
......
......@@ -49,6 +49,7 @@ restrictions referred to are that the relevant option is valid if:
MCA MCA bus support is enabled.
MDA MDA console support is enabled.
MOUSE Appropriate mouse support is enabled.
MSI Message Signaled Interrupts (PCI).
MTD MTD support is enabled.
NET Appropriate network support is enabled.
NUMA NUMA support is enabled.
......@@ -1152,6 +1153,9 @@ running once the system is up.
Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration
nomsi [MSI] If the PCI_MSI kernel config parameter is
enabled, this kernel boot option can be used to
disable the use of MSI interrupts system-wide.
nosort [IA-32] Don't sort PCI devices according to
order given by the PCI BIOS. This sorting is
done to get a device order compatible with
......
......@@ -543,7 +543,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
0x100000000ULL)
continue;
res = alloc_bootmem_low(sizeof(struct resource));
res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
switch (md->type) {
case EFI_RESERVED_TYPE:
res->name = "Reserved Memory";
......
......@@ -1288,7 +1288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
struct resource *res;
if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
continue;
res = alloc_bootmem_low(sizeof(struct resource));
res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
switch (e820.map[i].type) {
case E820_RAM: res->name = "System RAM"; break;
case E820_ACPI: res->name = "ACPI Tables"; break;
......@@ -1316,13 +1316,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
/*
* Request address space for all standard resources
*
* This is called just before pcibios_assign_resources(), which is also
* an fs_initcall, but is linked in later (in arch/i386/pci/i386.c).
*/
static void __init register_memory(void)
static int __init request_standard_resources(void)
{
unsigned long gapstart, gapsize, round;
unsigned long long last;
int i;
int i;
printk("Setting up standard PCI resources\n");
if (efi_enabled)
efi_initialize_iomem_resources(&code_resource, &data_resource);
else
......@@ -1334,6 +1336,16 @@ static void __init register_memory(void)
/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, &standard_io_resources[i]);
return 0;
}
fs_initcall(request_standard_resources);
static void __init register_memory(void)
{
unsigned long gapstart, gapsize, round;
unsigned long long last;
int i;
/*
* Search for the bigest gap in the low 32 bits of the e820
......
obj-y := i386.o
obj-y := i386.o init.o
obj-$(CONFIG_PCI_BIOS) += pcbios.o
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
......
......@@ -8,6 +8,7 @@
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/dmi.h>
#include <asm/acpi.h>
#include <asm/segment.h>
......@@ -120,11 +121,42 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b)
pci_read_bridge_bases(b);
}
/*
* Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
*/
#ifdef __i386__
static int __devinit assign_all_busses(struct dmi_system_id *d)
{
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
" (pci=assign-busses)\n", d->ident);
return 0;
}
#endif
/*
* Laptops which need pci=assign-busses to see Cardbus cards
*/
static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
#ifdef __i386__
{
.callback = assign_all_busses,
.ident = "Samsung X20 Laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
},
},
#endif /* __i386__ */
{}
};
struct pci_bus * __devinit pcibios_scan_root(int busnum)
{
struct pci_bus *bus = NULL;
dmi_check_system(pciprobe_dmi_table);
while ((bus = pci_find_next_bus(bus)) != NULL) {
if (bus->number == busnum) {
/* Already scanned */
......
......@@ -245,7 +245,7 @@ static int __init pci_check_type2(void)
return works;
}
static int __init pci_direct_init(void)
void __init pci_direct_init(void)
{
struct resource *region, *region2;
......@@ -258,16 +258,16 @@ static int __init pci_direct_init(void)
if (pci_check_type1()) {
printk(KERN_INFO "PCI: Using configuration type 1\n");
raw_pci_ops = &pci_direct_conf1;
return 0;
return;
}
release_resource(region);
type2:
if ((pci_probe & PCI_PROBE_CONF2) == 0)
goto out;
return;
region = request_region(0xCF8, 4, "PCI conf2");
if (!region)
goto out;
return;
region2 = request_region(0xC000, 0x1000, "PCI conf2");
if (!region2)
goto fail2;
......@@ -275,15 +275,10 @@ static int __init pci_direct_init(void)
if (pci_check_type2()) {
printk(KERN_INFO "PCI: Using configuration type 2\n");
raw_pci_ops = &pci_direct_conf2;
return 0;
return;
}
release_resource(region2);
fail2:
release_resource(region);
out:
return 0;
}
arch_initcall(pci_direct_init);
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
/* arch_initcall has too random ordering, so call the initializers
in the right sequence from here. */
static __init int pci_access_init(void)
{
#ifdef CONFIG_PCI_MMCONFIG
pci_mmcfg_init();
#endif
if (raw_pci_ops)
return 0;
#ifdef CONFIG_PCI_BIOS
pci_pcbios_init();
#endif
if (raw_pci_ops)
return 0;
#ifdef CONFIG_PCI_DIRECT
pci_direct_init();
#endif
return 0;
}
arch_initcall(pci_access_init);
......@@ -172,25 +172,20 @@ static __init void unreachable_devices(void)
}
}
static int __init pci_mmcfg_init(void)
void __init pci_mmcfg_init(void)
{
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
goto out;
return;
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
(pci_mmcfg_config[0].base_address == 0))
goto out;
return;
printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
unreachable_devices();
out:
return 0;
}
arch_initcall(pci_mmcfg_init);
......@@ -476,14 +476,12 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
}
EXPORT_SYMBOL(pcibios_set_irq_routing);
static int __init pci_pcbios_init(void)
void __init pci_pcbios_init(void)
{
if ((pci_probe & PCI_PROBE_BIOS)
&& ((raw_pci_ops = pci_find_bios()))) {
pci_probe |= PCI_BIOS_SORT;
pci_bios_present = 1;
}
return 0;
}
arch_initcall(pci_pcbios_init);
......@@ -80,4 +80,7 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus,
extern int pci_conf1_read(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *value);
extern void pci_direct_init(void);
extern void pci_pcbios_init(void);
extern void pci_mmcfg_init(void);
......@@ -7,7 +7,7 @@ CFLAGS += -Iarch/i386/pci
obj-y := i386.o
obj-$(CONFIG_PCI_DIRECT)+= direct.o
obj-y += fixup.o
obj-y += fixup.o init.o
obj-$(CONFIG_ACPI) += acpi.o
obj-y += legacy.o irq.o common.o
# mmconfig has a 64bit special
......@@ -22,3 +22,4 @@ irq-y += ../../i386/pci/irq.o
common-y += ../../i386/pci/common.o
fixup-y += ../../i386/pci/fixup.o
i386-y += ../../i386/pci/i386.o
init-y += ../../i386/pci/init.o
......@@ -205,6 +205,18 @@ config ACPI_IBM
If you have an IBM ThinkPad laptop, say Y or M here.
config ACPI_IBM_DOCK
bool "Legacy Docking Station Support"
depends on ACPI_IBM
default n
---help---
Allows the ibm_acpi driver to handle docking station events.
This support is obsoleted by CONFIG_HOTPLUG_PCI_ACPI. It will
allow locking and removing the laptop from the docking station,
but will not properly connect PCI devices.
If you are not sure, say N here.
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
......
......@@ -160,13 +160,13 @@ IBM_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, T4x, X31, X40 */
"\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */
"\\CMS", /* R40, R40e */
); /* all others */
#ifdef CONFIG_ACPI_IBM_DOCK
IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
"\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
"\\_SB.PCI0.PCI1.DOCK", /* all others */
"\\_SB.PCI.ISA.SLCE", /* 570 */
); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
#endif
IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
"\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
"\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
......@@ -844,7 +844,7 @@ static int _sta(acpi_handle handle)
return status;
}
#ifdef CONFIG_ACPI_IBM_DOCK
#define dock_docked() (_sta(dock_handle) & 1)
static int dock_read(char *p)
......@@ -907,6 +907,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
acpi_bus_generate_event(ibm->device, event, 0); /* unknown */
}
}
#endif
static int bay_status_supported;
static int bay_status2_supported;
......@@ -1574,6 +1575,7 @@ static struct ibm_struct ibms[] = {
.read = light_read,
.write = light_write,
},
#ifdef CONFIG_ACPI_IBM_DOCK
{
.name = "dock",
.read = dock_read,
......@@ -1589,6 +1591,7 @@ static struct ibm_struct ibms[] = {
.handle = &pci_handle,
.type = ACPI_SYSTEM_NOTIFY,
},
#endif
{
.name = "bay",
.init = bay_init,
......@@ -1880,7 +1883,9 @@ IBM_PARAM(hotkey);
IBM_PARAM(bluetooth);
IBM_PARAM(video);
IBM_PARAM(light);
#ifdef CONFIG_ACPI_IBM_DOCK
IBM_PARAM(dock);
#endif
IBM_PARAM(bay);
IBM_PARAM(cmos);
IBM_PARAM(led);
......@@ -1927,7 +1932,9 @@ static int __init acpi_ibm_init(void)
IBM_HANDLE_INIT(hkey);
IBM_HANDLE_INIT(lght);
IBM_HANDLE_INIT(cmos);
#ifdef CONFIG_ACPI_IBM_DOCK
IBM_HANDLE_INIT(dock);
#endif
IBM_HANDLE_INIT(pci);
IBM_HANDLE_INIT(bay);
if (bay_handle)
......
......@@ -23,7 +23,6 @@ static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
static void acpi_device_release(struct kobject *kobj)
{
......@@ -1284,7 +1283,7 @@ int acpi_bus_start(struct acpi_device *device)
EXPORT_SYMBOL(acpi_bus_start);
static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
int acpi_bus_trim(struct acpi_device *start, int rmdevice)
{
acpi_status status;
struct acpi_device *parent, *child;
......@@ -1337,6 +1336,8 @@ static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
}
return err;
}
EXPORT_SYMBOL_GPL(acpi_bus_trim);
static int acpi_bus_scan_fixed(struct acpi_device *root)
{
......
......@@ -11,24 +11,11 @@ config PCI_MSI
generate an interrupt using an inbound Memory Write on its
PCI bus instead of asserting a device IRQ pin.
If you don't know what to do here, say N.
config PCI_LEGACY_PROC
bool "Legacy /proc/pci interface"
depends on PCI
---help---
This feature enables a procfs file -- /proc/pci -- that provides a
summary of PCI devices in the system.
This feature has been deprecated as of v2.5.53, in favor of using the
tool lspci(8). This feature may be removed at a future date.
Use of PCI MSI interrupts can be disabled at kernel boot time
by using the 'pci=nomsi' option. This disables MSI for the
entire system.
lspci can provide the same data, as well as much more. lspci is a part of
the pci-utils package, which should be installed by your distribution.
See <file:Documentation/Changes> for information on where to get the latest
version.
When in doubt, say N.
If you don't know what to do here, say N.
config PCI_DEBUG
bool "PCI Debugging"
......
......@@ -22,6 +22,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI
pci_hotplug-objs += cpci_hotplug_core.o \
cpci_hotplug_pci.o
endif
ifdef CONFIG_ACPI
pci_hotplug-objs += acpi_pcihp.o
endif
cpqphp-objs := cpqphp_core.o \
cpqphp_ctrl.o \
......@@ -37,7 +40,8 @@ ibmphp-objs := ibmphp_core.o \
ibmphp_hpc.o
acpiphp-objs := acpiphp_core.o \
acpiphp_glue.o
acpiphp_glue.o \
acpiphp_dock.o
rpaphp-objs := rpaphp_core.o \
rpaphp_pci.o \
......@@ -50,23 +54,9 @@ pciehp-objs := pciehp_core.o \
pciehp_ctrl.o \
pciehp_pci.o \
pciehp_hpc.o
ifdef CONFIG_ACPI
pciehp-objs += pciehprm_acpi.o
else
pciehp-objs += pciehprm_nonacpi.o
endif
shpchp-objs := shpchp_core.o \
shpchp_ctrl.o \
shpchp_pci.o \
shpchp_sysfs.o \
shpchp_hpc.o
ifdef CONFIG_ACPI
shpchp-objs += shpchprm_acpi.o
else
ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
shpchp-objs += shpchprm_legacy.o
else
shpchp-objs += shpchprm_nonacpi.o
endif
endif
/*
* SHPCHPRM ACPI: PHP Resource Manager for ACPI platform
* Common ACPI functions for hot plug platforms
*
* Copyright (C) 2003-2004 Intel Corporation
* Copyright (C) 2006 Intel Corporation
*
* All rights reserved.
*
......@@ -31,26 +31,12 @@
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "shpchp.h"
#include "pci_hotplug.h"
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
static u8 * acpi_path_name( acpi_handle handle)
{
acpi_status status;
static u8 path_name[ACPI_PATHNAME_MAX];
struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
memset(path_name, 0, sizeof (path_name));
status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
if (ACPI_FAILURE(status))
return NULL;
else
return path_name;
}
static acpi_status
acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
......@@ -58,18 +44,21 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
acpi_status status;
u8 nui[4];
struct acpi_buffer ret_buf = { 0, NULL};
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *ext_obj, *package;
u8 *path_name = acpi_path_name(handle);
int i, len = 0;
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
/* get _hpp */
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 ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
path_name);
printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
__FUNCTION__, (char *)string.pointer);
acpi_os_free(string.pointer);
return AE_NO_MEMORY;
}
status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
......@@ -78,16 +67,17 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
break;
default:
if (ACPI_FAILURE(status)) {
dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
path_name, status);
pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
(char *)string.pointer, status);
acpi_os_free(string.pointer);
return status;
}
}
ext_obj = (union acpi_object *) ret_buf.pointer;
if (ext_obj->type != ACPI_TYPE_PACKAGE) {
err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
path_name);
printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__,
(char *)string.pointer);
status = AE_ERROR;
goto free_and_return;
}
......@@ -101,8 +91,8 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
nui[i] = (u8)ext_obj->integer.value;
break;
default:
err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
path_name);
printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
__FUNCTION__, (char *)string.pointer);
status = AE_ERROR;
goto free_and_return;
}
......@@ -113,54 +103,52 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
hpp->enable_serr = nui[2];
hpp->enable_perr = nui[3];
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);
pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
free_and_return:
kfree(ret_buf.pointer);
acpi_os_free(string.pointer);
acpi_os_free(ret_buf.pointer);
return status;
}
static void acpi_run_oshp(acpi_handle handle)
/* acpi_run_oshp - get control of hotplug from the firmware
*
* @handle - the handle of the hotplug controller.
*/
acpi_status acpi_run_oshp(acpi_handle handle)
{
acpi_status status;
u8 *path_name = acpi_path_name(handle);
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
/* run OSHP */
status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
if (ACPI_FAILURE(status)) {
err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
status);
} else {
dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
}
}
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
{
int offset = devnum - ctrl->slot_device_offset;
if (ACPI_FAILURE(status))
printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__,
(char *)string.pointer, status);
else
pr_debug("%s:%s OSHP passes\n", __FUNCTION__,
(char *)string.pointer);
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;
acpi_os_free(string.pointer);
return status;
}
EXPORT_SYMBOL_GPL(acpi_run_oshp);
void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
/*
* 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.
*/
acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
if (!handle)
return;
acpi_run_oshp(handle);
}
void get_hp_params_from_firmware(struct pci_dev *dev,
/* acpi_get_hp_params_from_firmware
*
* @dev - the pci_dev of the newly added device
* @hpp - allocated by the caller
*/
acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
acpi_status status = AE_NOT_FOUND;
......@@ -182,5 +170,42 @@ void get_hp_params_from_firmware(struct pci_dev *dev,
/* Check if a parent object supports _HPP */
pdev = pdev->bus->parent->self;
}
return status;
}
EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
/* acpi_root_bridge - check to see if this acpi object is a root bridge
*
* @handle - the acpi object in question.
*/
int acpi_root_bridge(acpi_handle handle)
{
acpi_status status;
struct acpi_device_info *info;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
int i;
status = acpi_get_object_info(handle, &buffer);
if (ACPI_SUCCESS(status)) {
info = buffer.pointer;
if ((info->valid & ACPI_VALID_HID) &&
!strcmp(PCI_ROOT_HID_STRING,
info->hardware_id.value)) {
acpi_os_free(buffer.pointer);
return 1;
}
if (info->valid & ACPI_VALID_CID) {
for (i=0; i < info->compatibility_id.count; i++) {
if (!strcmp(PCI_ROOT_HID_STRING,
info->compatibility_id.id[i].value)) {
acpi_os_free(buffer.pointer);
return 1;
}
}
}
acpi_os_free(buffer.pointer);
}
return 0;
}
EXPORT_SYMBOL_GPL(acpi_root_bridge);
......@@ -37,6 +37,7 @@
#include <linux/acpi.h>
#include <linux/kobject.h> /* for KOBJ_NAME_LEN */
#include <linux/mutex.h>
#include "pci_hotplug.h"
#define dbg(format, arg...) \
......@@ -59,26 +60,10 @@ struct acpiphp_slot;
* struct slot - slot information for each *physical* slot
*/
struct slot {
u8 number;
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
struct acpiphp_slot *acpi_slot;
};
/**
* struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
* @cache_line_size in DWORD
* @latency_timer in PCI clock
* @enable_SERR 0 or 1
* @enable_PERR 0 or 1
*/
struct hpp_param {
u8 cache_line_size;
u8 latency_timer;
u8 enable_SERR;
u8 enable_PERR;
};
/**
......@@ -102,7 +87,7 @@ struct acpiphp_bridge {
struct pci_dev *pci_dev;
/* ACPI 2.0 _HPP parameters */
struct hpp_param hpp;
struct hotplug_params hpp;
spinlock_t res_lock;
};
......@@ -118,9 +103,9 @@ struct acpiphp_slot {
struct acpiphp_bridge *bridge; /* parent */
struct list_head funcs; /* one slot may have different
objects (i.e. for each function) */
struct semaphore crit_sect;
struct slot *slot;
struct mutex crit_sect;
u32 id; /* slot id (serial #) for hotplug core */
u8 device; /* pci device# */
u32 sun; /* ACPI _SUN (slot unique number) */
......@@ -160,6 +145,25 @@ struct acpiphp_attention_info
struct module *owner;
};
struct dependent_device {
struct list_head device_list;
struct list_head pci_list;
acpi_handle handle;
struct acpiphp_func *func;
};
struct acpiphp_dock_station {
acpi_handle handle;
u32 last_dock_time;
u32 flags;
struct acpiphp_func *dock_bridge;
struct list_head dependent_devices;
struct list_head pci_dependent_devices;
};
/* PCI bus bridge HID */
#define ACPI_PCI_HOST_HID "PNP0A03"
......@@ -197,19 +201,27 @@ struct acpiphp_attention_info
#define FUNC_HAS_PS1 (0x00000020)
#define FUNC_HAS_PS2 (0x00000040)
#define FUNC_HAS_PS3 (0x00000080)
#define FUNC_HAS_DCK (0x00000100)
#define FUNC_IS_DD (0x00000200)
/* dock station flags */
#define DOCK_DOCKING (0x00000001)
#define DOCK_HAS_BRIDGE (0x00000002)
/* function prototypes */
/* acpiphp_core.c */
extern int acpiphp_register_attention(struct acpiphp_attention_info*info);
extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot);
extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
/* acpiphp_glue.c */
extern int acpiphp_glue_init (void);
extern void acpiphp_glue_exit (void);
extern int acpiphp_get_num_slots (void);
extern struct acpiphp_slot *get_slot_from_id (int id);
typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
void handle_hotplug_event_func(acpi_handle, u32, void*);
extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
......@@ -219,6 +231,16 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
/* acpiphp_dock.c */
extern int find_dock_station(void);
extern void remove_dock_station(void);
extern void add_dependent_device(struct dependent_device *new_dd);
extern void add_pci_dependent_device(struct dependent_device *new_dd);
extern struct dependent_device *get_dependent_device(acpi_handle handle);
extern int is_dependent_device(acpi_handle handle);
extern int detect_dependent_devices(acpi_handle *bridge_handle);
extern struct dependent_device *alloc_dependent_device(acpi_handle handle);
/* variables */
extern int acpiphp_debug;
......
......@@ -44,8 +44,6 @@
#include "pci_hotplug.h"
#include "acpiphp.h"
static LIST_HEAD(slot_list);
#define MY_NAME "acpiphp"
static int debug;
......@@ -341,62 +339,53 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
kfree(slot);
}
/**
* init_slots - initialize 'struct slot' structures for each slot
*
*/
static int __init init_slots(void)
/* callback routine to initialize 'struct slot' for each slot */
int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
{
struct slot *slot;
struct hotplug_slot *hotplug_slot;
struct hotplug_slot_info *hotplug_slot_info;
int retval = -ENOMEM;
int i;
for (i = 0; i < num_slots; ++i) {
slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof(struct slot));
slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
if (!slot->hotplug_slot)
goto error_slot;
memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
if (!slot->hotplug_slot->info)
goto error_hpslot;
memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
if (!slot->hotplug_slot->name)
goto error_info;
slot->number = i;
slot->hotplug_slot->private = slot;
slot->hotplug_slot->release = &release_slot;
slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
slot->acpi_slot = get_slot_from_id(i);
slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
slot->hotplug_slot->info->attention_status = 0;
slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
make_slot_name(slot);
retval = pci_hp_register(slot->hotplug_slot);
if (retval) {
err("pci_hp_register failed with error %d\n", retval);
goto error_name;
}
/* add slot to our internal list */
list_add(&slot->slot_list, &slot_list);
info("Slot [%s] registered\n", slot->hotplug_slot->name);
}
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
goto error;
slot->hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
if (!slot->hotplug_slot)
goto error_slot;
slot->hotplug_slot->info = kzalloc(sizeof(*hotplug_slot_info),
GFP_KERNEL);
if (!slot->hotplug_slot->info)
goto error_hpslot;
slot->hotplug_slot->name = kzalloc(SLOT_NAME_SIZE, GFP_KERNEL);
if (!slot->hotplug_slot->name)
goto error_info;
slot->hotplug_slot->private = slot;
slot->hotplug_slot->release = &release_slot;
slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
slot->acpi_slot = acpiphp_slot;
slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
slot->hotplug_slot->info->attention_status = 0;
slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
acpiphp_slot->slot = slot;
make_slot_name(slot);
retval = pci_hp_register(slot->hotplug_slot);
if (retval) {
err("pci_hp_register failed with error %d\n", retval);
goto error_name;
}
info("Slot [%s] registered\n", slot->hotplug_slot->name);
return 0;
error_name:
......@@ -412,42 +401,51 @@ static int __init init_slots(void)
}
static void __exit cleanup_slots (void)
void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
{
struct list_head *tmp, *n;
struct slot *slot;
struct slot *slot = acpiphp_slot->slot;
int retval = 0;
list_for_each_safe (tmp, n, &slot_list) {
/* memory will be freed in release_slot callback */
slot = list_entry(tmp, struct slot, slot_list);
list_del(&slot->slot_list);
pci_hp_deregister(slot->hotplug_slot);
}
info ("Slot [%s] unregistered\n", slot->hotplug_slot->name);
retval = pci_hp_deregister(slot->hotplug_slot);
if (retval)
err("pci_hp_deregister failed with error %d\n", retval);
}
static int __init acpiphp_init(void)
{
int retval;
int docking_station;
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
acpiphp_debug = debug;
docking_station = find_dock_station();
/* read all the ACPI info from the system */
retval = init_acpi();
if (retval)
return retval;
return init_slots();
/* if we have found a docking station, we should
* go ahead and load even if init_acpi has found
* no slots. This handles the case when the _DCK
* method not defined under the actual dock bridge
*/
if (docking_station)
return 0;
else
return retval;
}
static void __exit acpiphp_exit(void)
{
cleanup_slots();
/* deallocate internal data structures etc. */
acpiphp_glue_exit();
remove_dock_station();
}
module_init(acpiphp_init);
......
/*
* ACPI PCI HotPlug dock functions to ACPI CA subsystem
*
* Copyright (C) 2006 Kristen Carlson Accardi (kristen.c.accardi@intel.com)
* Copyright (C) 2006 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 <kristen.c.accardi@intel.com>
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "../pci.h"
#include "pci_hotplug.h"
#include "acpiphp.h"
static struct acpiphp_dock_station *ds;
#define MY_NAME "acpiphp_dock"
int is_dependent_device(acpi_handle handle)
{
return (get_dependent_device(handle) ? 1 : 0);
}
static acpi_status
find_dependent_device(acpi_handle handle, u32 lvl, void *context, void **rv)
{
int *count = (int *)context;
if (is_dependent_device(handle)) {
(*count)++;
return AE_CTRL_TERMINATE;
} else {
return AE_OK;
}
}
void add_dependent_device(struct dependent_device *new_dd)
{
list_add_tail(&new_dd->device_list, &ds->dependent_devices);
}
void add_pci_dependent_device(struct dependent_device *new_dd)
{
list_add_tail(&new_dd->pci_list, &ds->pci_dependent_devices);
}
struct dependent_device * get_dependent_device(acpi_handle handle)
{
struct dependent_device *dd;
if (!ds)
return NULL;
list_for_each_entry(dd, &ds->dependent_devices, device_list) {
if (handle == dd->handle)
return dd;
}
return NULL;
}
struct dependent_device *alloc_dependent_device(acpi_handle handle)
{
struct dependent_device *dd;
dd = kzalloc(sizeof(*dd), GFP_KERNEL);
if (dd) {
INIT_LIST_HEAD(&dd->pci_list);
INIT_LIST_HEAD(&dd->device_list);
dd->handle = handle;
}
return dd;
}
static int is_dock(acpi_handle handle)
{
acpi_status status;
acpi_handle tmp;
status = acpi_get_handle(handle, "_DCK", &tmp);
if (ACPI_FAILURE(status)) {
return 0;
}
return 1;
}
static int dock_present(void)
{
unsigned long sta;
acpi_status status;
if (ds) {
status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
if (ACPI_SUCCESS(status) && sta)
return 1;
}
return 0;
}
static void eject_dock(void)
{
struct acpi_object_list arg_list;
union acpi_object arg;
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 1;
if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
&arg_list, NULL)) || dock_present())
warn("%s: failed to eject dock!\n", __FUNCTION__);
return;
}
static acpi_status handle_dock(int dock)
{
acpi_status status;
struct acpi_object_list arg_list;
union acpi_object arg;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
dbg("%s: %s\n", __FUNCTION__, dock ? "docking" : "undocking");
/* _DCK method has one argument */
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = dock;
status = acpi_evaluate_object(ds->handle, "_DCK",
&arg_list, &buffer);
if (ACPI_FAILURE(status))
err("%s: failed to execute _DCK\n", __FUNCTION__);
acpi_os_free(buffer.pointer);
return status;
}
static inline void dock(void)
{
handle_dock(1);
}
static inline void undock(void)
{
handle_dock(0);
}
/*
* the _DCK method can do funny things... and sometimes not
* hah-hah funny.
*
* TBD - figure out a way to only call fixups for
* systems that require them.
*/
static void post_dock_fixups(void)
{
struct pci_bus *bus;
u32 buses;
struct dependent_device *dd;
list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list) {
bus = dd->func->slot->bridge->pci_bus;
/* fixup bad _DCK function that rewrites
* secondary bridge on slot
*/
pci_read_config_dword(bus->self,
PCI_PRIMARY_BUS,
&buses);
if (((buses >> 8) & 0xff) != bus->secondary) {
buses = (buses & 0xff000000)
| ((unsigned int)(bus->primary) << 0)
| ((unsigned int)(bus->secondary) << 8)
| ((unsigned int)(bus->subordinate) << 16);
pci_write_config_dword(bus->self,
PCI_PRIMARY_BUS,
buses);
}
}
}
static void hotplug_pci(u32 type)
{
struct dependent_device *dd;
list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list)
handle_hotplug_event_func(dd->handle, type, dd->func);
}
static inline void begin_dock(void)
{
ds->flags |= DOCK_DOCKING;
}
static inline void complete_dock(void)
{
ds->flags &= ~(DOCK_DOCKING);
ds->last_dock_time = jiffies;
}
static int dock_in_progress(void)
{
if (ds->flags & DOCK_DOCKING ||
ds->last_dock_time == jiffies) {
dbg("dock in progress\n");
return 1;
}
return 0;
}
static void
handle_hotplug_event_dock(acpi_handle handle, u32 type, void *context)
{
dbg("%s: enter\n", __FUNCTION__);
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
dbg("BUS Check\n");
if (!dock_in_progress() && dock_present()) {
begin_dock();
dock();
if (!dock_present()) {
err("Unable to dock!\n");
break;
}
post_dock_fixups();
hotplug_pci(type);
complete_dock();
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
dbg("EJECT request\n");
if (!dock_in_progress() && dock_present()) {
hotplug_pci(type);
undock();
eject_dock();
if (dock_present())
err("Unable to undock!\n");
}
break;
}
}
static acpi_status
find_dock_ejd(acpi_handle handle, u32 lvl, void *context, void **rv)
{
acpi_status status;
acpi_handle tmp;
acpi_handle dck_handle = (acpi_handle) context;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
struct acpi_buffer ejd_buffer = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *ejd_obj;
status = acpi_get_handle(handle, "_EJD", &tmp);
if (ACPI_FAILURE(status))
return AE_OK;
/* make sure we are dependent on the dock device,
* by executing the _EJD method, then getting a handle
* to the device referenced by that name. If that
* device handle is the same handle as the dock station
* handle, then we are a device dependent on the dock station
*/
acpi_get_name(dck_handle, ACPI_FULL_PATHNAME, &buffer);
status = acpi_evaluate_object(handle, "_EJD", NULL, &ejd_buffer);
if (ACPI_FAILURE(status)) {
err("Unable to execute _EJD!\n");
goto find_ejd_out;
}
ejd_obj = ejd_buffer.pointer;
status = acpi_get_handle(NULL, ejd_obj->string.pointer, &tmp);
if (ACPI_FAILURE(status))
goto find_ejd_out;
if (tmp == dck_handle) {
struct dependent_device *dd;
dbg("%s: found device dependent on dock\n", __FUNCTION__);
dd = alloc_dependent_device(handle);
if (!dd) {
err("Can't allocate memory for dependent device!\n");
goto find_ejd_out;
}
add_dependent_device(dd);
}
find_ejd_out:
acpi_os_free(ejd_buffer.pointer);
return AE_OK;
}
int detect_dependent_devices(acpi_handle *bridge_handle)
{
acpi_status status;
int count;
count = 0;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
(u32)1, find_dependent_device,
(void *)&count, NULL);
return count;
}
static acpi_status
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
{
int *count = (int *)context;
if (is_dock(handle)) {
dbg("%s: found dock\n", __FUNCTION__);
ds = kzalloc(sizeof(*ds), GFP_KERNEL);
ds->handle = handle;
INIT_LIST_HEAD(&ds->dependent_devices);
INIT_LIST_HEAD(&ds->pci_dependent_devices);
/* look for devices dependent on dock station */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock_ejd, handle, NULL);
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_dock, ds);
(*count)++;
}
return AE_OK;
}
int find_dock_station(void)
{
int num = 0;
ds = NULL;
/* start from the root object, because some laptops define
* _DCK methods outside the scope of PCI (IBM x-series laptop)
*/
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock, &num, NULL);
return num;
}
void remove_dock_station(void)
{
struct dependent_device *dd, *tmp;
if (ds) {
if (ACPI_FAILURE(acpi_remove_notify_handler(ds->handle,
ACPI_SYSTEM_NOTIFY, handle_hotplug_event_dock)))
err("failed to remove dock notify handler\n");
/* free all dependent devices */
list_for_each_entry_safe(dd, tmp, &ds->dependent_devices,
device_list)
kfree(dd);
/* no need to touch the pci_dependent_device list,
* cause all memory was freed above
*/
kfree(ds);
}
}
This diff is collapsed.
......@@ -248,22 +248,19 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
* with the pci_hotplug subsystem.
*/
for (i = first; i <= last; ++i) {
slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof (struct slot));
hotplug_slot =
kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
if (!hotplug_slot)
goto error_slot;
memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
slot->hotplug_slot = hotplug_slot;
info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
if (!info)
goto error_hpslot;
memset(info, 0, sizeof (struct hotplug_slot_info));
hotplug_slot->info = info;
name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
......
......@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <asm/io.h> /* for read? and write? functions */
#include <linux/delay.h> /* for delays */
#include <linux/mutex.h>
#define MY_NAME "cpqphp"
......@@ -286,7 +287,7 @@ struct event_info {
struct controller {
struct controller *next;
u32 ctrl_int_comp;
struct semaphore crit_sect; /* critical section semaphore */
struct mutex crit_sect; /* critical section mutex */
void __iomem *hpc_reg; /* cookie for our pci controller location */
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
......
......@@ -347,26 +347,22 @@ static int ctrl_slot_setup(struct controller *ctrl,
slot_number = ctrl->first_slot;
while (number_of_slots) {
slot = kmalloc(sizeof(*slot), GFP_KERNEL);
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof(struct slot));
slot->hotplug_slot = kmalloc(sizeof(*(slot->hotplug_slot)),
slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
GFP_KERNEL);
if (!slot->hotplug_slot)
goto error_slot;
hotplug_slot = slot->hotplug_slot;
memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
hotplug_slot->info =
kmalloc(sizeof(*(hotplug_slot->info)),
kzalloc(sizeof(*(hotplug_slot->info)),
GFP_KERNEL);
if (!hotplug_slot->info)
goto error_hpslot;
hotplug_slot_info = hotplug_slot->info;
memset(hotplug_slot_info, 0,
sizeof(struct hotplug_slot_info));
hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
if (!hotplug_slot->name)
......@@ -599,7 +595,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
hp_slot = func->device - ctrl->slot_device_offset;
// Wait for exclusive access to hardware
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (status == 1) {
amber_LED_on (ctrl, hp_slot);
......@@ -607,7 +603,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
amber_LED_off (ctrl, hp_slot);
} else {
// Done with exclusive hardware access
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return(1);
}
......@@ -617,7 +613,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
wait_for_ctrl_irq (ctrl);
// Done with exclusive hardware access
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return(0);
}
......@@ -854,13 +850,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_disable_device;
}
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
rc = -ENOMEM;
goto err_disable_device;
}
memset(ctrl, 0, sizeof(struct controller));
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
if (rc) {
......@@ -1084,7 +1079,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
init_MUTEX(&ctrl->crit_sect);
mutex_init(&ctrl->crit_sect);
init_waitqueue_head(&ctrl->queue);
/* initialize our threads if they haven't already been started up */
......@@ -1223,7 +1218,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// turn off empty slots here unless command line option "ON" set
// Wait for exclusive access to hardware
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
......@@ -1270,12 +1265,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = init_SERR(ctrl);
if (rc) {
err("init_SERR failed\n");
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
goto err_free_irq;
}
// Done with exclusive hardware access
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
cpqhp_create_debugfs_files(ctrl);
......
......@@ -1282,9 +1282,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
u8 hp_slot;
u8 temp_byte;
u8 adapter_speed;
u32 index;
u32 rc = 0;
u32 src = 8;
hp_slot = func->device - ctrl->slot_device_offset;
......@@ -1299,7 +1297,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
**********************************/
rc = CARD_FUNCTIONING;
} else {
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
/* turn on board without attaching to the bus */
enable_slot_power (ctrl, hp_slot);
......@@ -1333,12 +1331,12 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
if (rc)
return rc;
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
slot_enable (ctrl, hp_slot);
green_LED_blink (ctrl, hp_slot);
......@@ -1350,7 +1348,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
/* Wait for ~1 second because of hot plug spec */
long_delay(1*HZ);
......@@ -1368,76 +1366,30 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
rc = cpqhp_configure_board(ctrl, func);
if (rc || src) {
/* If configuration fails, turn it off
* Get slot won't work for devices behind
* bridges, but in this case it will always be
* called for the "base" bus/dev/func of an
* adapter. */
/* If configuration fails, turn it off
* Get slot won't work for devices behind
* bridges, but in this case it will always be
* called for the "base" bus/dev/func of an
* adapter. */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
slot_disable (ctrl, hp_slot);
set_SOGO(ctrl);
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
if (rc)
return rc;
else
return 1;
}
func->status = 0;
func->switch_save = 0x10;
index = 1;
while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
rc |= cpqhp_configure_board(ctrl, func);
index++;
}
if (rc) {
/* If configuration fails, turn it off
* Get slot won't work for devices behind
* bridges, but in this case it will always be
* called for the "base" bus/dev/func of an
* adapter. */
down(&ctrl->crit_sect);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
slot_disable (ctrl, hp_slot);
set_SOGO(ctrl);
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
return rc;
}
/* Done configuring so turn LED on full time */
down(&ctrl->crit_sect);
green_LED_on (ctrl, hp_slot);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
slot_disable (ctrl, hp_slot);
set_SOGO(ctrl);
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
rc = 0;
mutex_unlock(&ctrl->crit_sect);
if (rc)
return rc;
else
return 1;
} else {
/* Something is wrong
......@@ -1445,7 +1397,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
* in this case it will always be called for the "base"
* bus/dev/func of an adapter. */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
......@@ -1456,7 +1408,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
}
}
......@@ -1488,7 +1440,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
__FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
/* turn on board without attaching to the bus */
enable_slot_power(ctrl, hp_slot);
......@@ -1522,7 +1474,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq(ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
if (rc)
return rc;
......@@ -1532,7 +1484,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* turn on board and blink green LED */
dbg("%s: before down\n", __FUNCTION__);
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
dbg("%s: after down\n", __FUNCTION__);
dbg("%s: before slot_enable\n", __FUNCTION__);
......@@ -1553,7 +1505,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
dbg("%s: before up\n", __FUNCTION__);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
dbg("%s: after up\n", __FUNCTION__);
/* Wait for ~1 second because of hot plug spec */
......@@ -1607,7 +1559,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
if (rc) {
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
......@@ -1618,7 +1570,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return rc;
} else {
cpqhp_save_slot_config(ctrl, func);
......@@ -1640,7 +1592,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
}
} while (new_slot);
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
green_LED_on (ctrl, hp_slot);
......@@ -1649,9 +1601,9 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
} else {
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
amber_LED_on (ctrl, hp_slot);
green_LED_off (ctrl, hp_slot);
......@@ -1662,7 +1614,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return rc;
}
......@@ -1721,7 +1673,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
func->status = 0x01;
func->configured = 0;
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
green_LED_off (ctrl, hp_slot);
slot_disable (ctrl, hp_slot);
......@@ -1736,7 +1688,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
if (!replace_flag && ctrl->add_support) {
while (func) {
......@@ -1899,7 +1851,7 @@ static void interrupt_event_handler(struct controller *ctrl)
dbg("button cancel\n");
del_timer(&p_slot->task_event);
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (p_slot->state == BLINKINGOFF_STATE) {
/* slot is on */
......@@ -1922,7 +1874,7 @@ static void interrupt_event_handler(struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
}
/*** button Released (No action on press...) */
else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
......@@ -1937,7 +1889,7 @@ static void interrupt_event_handler(struct controller *ctrl)
p_slot->state = BLINKINGON_STATE;
info(msg_button_on, p_slot->number);
}
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
dbg("blink green LED and turn off amber\n");
......@@ -1949,7 +1901,7 @@ static void interrupt_event_handler(struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
init_timer(&p_slot->task_event);
p_slot->hp_slot = hp_slot;
p_slot->ctrl = ctrl;
......
......@@ -95,15 +95,13 @@ static int add_slot(struct pci_dev *dev)
struct hotplug_slot *slot;
int retval = -ENOMEM;
slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof(*slot));
slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
if (!slot->info)
goto error_slot;
memset(slot->info, 0, sizeof(struct hotplug_slot_info));
slot->info->power_status = 1;
slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
......@@ -227,11 +225,10 @@ static void pci_rescan_bus(const struct pci_bus *bus)
{
unsigned int devfn;
struct pci_dev *dev;
dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!dev)
return;
memset(dev, 0, sizeof(dev));
dev->bus = (struct pci_bus*)bus;
dev->sysdata = bus->sysdata;
for (devfn = 0; devfn < 0x100; devfn += 8) {
......
......@@ -406,8 +406,6 @@ extern void ibmphp_hpc_stop_poll_thread (void);
//----------------------------------------------------------------------------
// HPC return codes
//----------------------------------------------------------------------------
#define FALSE 0x00
#define TRUE 0x01
#define HPC_ERROR 0xFF
//-----------------------------------------------------------------------------
......
......@@ -1141,7 +1141,7 @@ static int enable_slot(struct hotplug_slot *hs)
goto error_power;
}
slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
if (!slot_cur->func) {
/* We cannot do update_slot_info here, since no memory for
* kmalloc n.e.ways, and update_slot_info allocates some */
......@@ -1149,7 +1149,6 @@ static int enable_slot(struct hotplug_slot *hs)
rc = -ENOMEM;
goto error_power;
}
memset(slot_cur->func, 0, sizeof(struct pci_func));
slot_cur->func->busno = slot_cur->bus;
slot_cur->func->device = slot_cur->device;
for (i = 0; i < 4; i++)
......@@ -1240,9 +1239,9 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
}
flag = slot_cur->flag;
slot_cur->flag = TRUE;
slot_cur->flag = 1;
if (flag == TRUE) {
if (flag == 1) {
rc = validate(slot_cur, DISABLE);
/* checking if powered off already & valid slot # */
if (rc)
......@@ -1252,13 +1251,12 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
if (slot_cur->func == NULL) {
/* We need this for fncs's that were there on bootup */
slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
if (!slot_cur->func) {
err("out of system memory\n");
rc = -ENOMEM;
goto error;
}
memset(slot_cur->func, 0, sizeof(struct pci_func));
slot_cur->func->busno = slot_cur->bus;
slot_cur->func->device = slot_cur->device;
}
......
......@@ -72,13 +72,7 @@ static int ebda_rio_table (void);
static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
{
struct ebda_hpc_list *list;
list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
if (!list)
return NULL;
memset (list, 0, sizeof (*list));
return list;
return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL);
}
static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
......@@ -87,21 +81,18 @@ static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
struct ebda_hpc_slot *slots;
struct ebda_hpc_bus *buses;
controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
controller = kzalloc(sizeof(struct controller), GFP_KERNEL);
if (!controller)
goto error;
memset (controller, 0, sizeof (*controller));
slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
slots = kcalloc(slot_count, sizeof(struct ebda_hpc_slot), GFP_KERNEL);
if (!slots)
goto error_contr;
memset (slots, 0, sizeof (*slots) * slot_count);
controller->slots = slots;
buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
buses = kcalloc(bus_count, sizeof(struct ebda_hpc_bus), GFP_KERNEL);
if (!buses)
goto error_slots;
memset (buses, 0, sizeof (*buses) * bus_count);
controller->buses = buses;
return controller;
......@@ -122,24 +113,12 @@ static void free_ebda_hpc (struct controller *controller)
static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
{
struct ebda_rsrc_list *list;
list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
if (!list)
return NULL;
memset (list, 0, sizeof (*list));
return list;
return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL);
}
static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
{
struct ebda_pci_rsrc *resource;
resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
if (!resource)
return NULL;
memset (resource, 0, sizeof (*resource));
return resource;
return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL);
}
static void __init print_bus_info (void)
......@@ -390,10 +369,9 @@ int __init ibmphp_access_ebda (void)
debug ("now enter io table ---\n");
debug ("rio blk id: %x\n", blk_id);
rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
if (!rio_table_ptr)
return -ENOMEM;
memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
rio_table_ptr->ver_num = readb (io_mem + offset);
rio_table_ptr->scal_count = readb (io_mem + offset + 1);
rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
......@@ -445,10 +423,9 @@ static int __init ebda_rio_table (void)
// we do concern about rio details
for (i = 0; i < rio_table_ptr->riodev_count; i++) {
rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL);
if (!rio_detail_ptr)
return -ENOMEM;
memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
rio_detail_ptr->rio_node_id = readb (io_mem + offset);
rio_detail_ptr->bbar = readl (io_mem + offset + 1);
rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
......@@ -503,10 +480,9 @@ static int __init combine_wpg_for_chassis (void)
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
if (!opt_rio_ptr) {
opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
if (!opt_rio_ptr)
return -ENOMEM;
memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
......@@ -546,10 +522,9 @@ static int combine_wpg_for_expansion (void)
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
if (!opt_rio_lo_ptr) {
opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
if (!opt_rio_lo_ptr)
return -ENOMEM;
memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
......@@ -842,12 +817,11 @@ static int __init ebda_rsrc_controller (void)
bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
if (!bus_info_ptr2) {
bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
if (!bus_info_ptr1) {
rc = -ENOMEM;
goto error_no_hp_slot;
}
memset (bus_info_ptr1, 0, sizeof (struct bus_info));
bus_info_ptr1->slot_min = slot_ptr->slot_num;
bus_info_ptr1->slot_max = slot_ptr->slot_num;
bus_info_ptr1->slot_count += 1;
......@@ -946,19 +920,17 @@ static int __init ebda_rsrc_controller (void)
// register slots with hpc core as well as create linked list of ibm slot
for (index = 0; index < hpc_ptr->slot_count; index++) {
hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
hp_slot_ptr = kzalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
if (!hp_slot_ptr) {
rc = -ENOMEM;
goto error_no_hp_slot;
}
memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr));
hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL);
hp_slot_ptr->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
if (!hp_slot_ptr->info) {
rc = -ENOMEM;
goto error_no_hp_info;
}
memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info));
hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
if (!hp_slot_ptr->name) {
......@@ -966,14 +938,13 @@ static int __init ebda_rsrc_controller (void)
goto error_no_hp_name;
}
tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL);
tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
if (!tmp_slot) {
rc = -ENOMEM;
goto error_no_slot;
}
memset(tmp_slot, 0, sizeof(*tmp_slot));
tmp_slot->flag = TRUE;
tmp_slot->flag = 1;
tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
......
......@@ -34,9 +34,11 @@
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include "ibmphp.h"
static int to_debug = FALSE;
static int to_debug = 0;
#define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0)
//----------------------------------------------------------------------------
......@@ -93,15 +95,15 @@ static int to_debug = FALSE;
//----------------------------------------------------------------------------
// macro utilities
//----------------------------------------------------------------------------
// if bits 20,22,25,26,27,29,30 are OFF return TRUE
#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
// if bits 20,22,25,26,27,29,30 are OFF return 1
#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? 0 : 1))
//----------------------------------------------------------------------------
// global variables
//----------------------------------------------------------------------------
static int ibmphp_shutdown;
static int tid_poll;
static struct semaphore sem_hpcaccess; // lock access to HPC
static struct mutex sem_hpcaccess; // lock access to HPC
static struct semaphore semOperations; // lock all operations and
// access to data structures
static struct semaphore sem_exit; // make sure polling thread goes away
......@@ -131,11 +133,11 @@ void __init ibmphp_hpc_initvars (void)
{
debug ("%s - Entry\n", __FUNCTION__);
init_MUTEX (&sem_hpcaccess);
mutex_init(&sem_hpcaccess);
init_MUTEX (&semOperations);
init_MUTEX_LOCKED (&sem_exit);
to_debug = FALSE;
ibmphp_shutdown = FALSE;
to_debug = 0;
ibmphp_shutdown = 0;
tid_poll = 0;
debug ("%s - Exit\n", __FUNCTION__);
......@@ -737,21 +739,21 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
// check controller is still not working on the command
//--------------------------------------------------------------------
timeout = CMD_COMPLETE_TOUT_SEC;
done = FALSE;
done = 0;
while (!done) {
rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
&status);
if (!rc) {
if (NEEDTOCHECK_CMDSTATUS (cmd)) {
if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
done = TRUE;
done = 1;
} else
done = TRUE;
done = 1;
}
if (!done) {
msleep(1000);
if (timeout < 1) {
done = TRUE;
done = 1;
err ("%s - Error command complete timeout\n", __FUNCTION__);
rc = -EFAULT;
} else
......@@ -778,7 +780,7 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
*---------------------------------------------------------------------*/
static void get_hpc_access (void)
{
down (&sem_hpcaccess);
mutex_lock(&sem_hpcaccess);
}
/*----------------------------------------------------------------------
......@@ -786,7 +788,7 @@ static void get_hpc_access (void)
*---------------------------------------------------------------------*/
void free_hpc_access (void)
{
up (&sem_hpcaccess);
mutex_unlock(&sem_hpcaccess);
}
/*----------------------------------------------------------------------
......@@ -797,7 +799,7 @@ void free_hpc_access (void)
void ibmphp_lock_operations (void)
{
down (&semOperations);
to_debug = TRUE;
to_debug = 1;
}
/*----------------------------------------------------------------------
......@@ -807,7 +809,7 @@ void ibmphp_unlock_operations (void)
{
debug ("%s - Entry\n", __FUNCTION__);
up (&semOperations);
to_debug = FALSE;
to_debug = 0;
debug ("%s - Exit\n", __FUNCTION__);
}
......@@ -935,40 +937,40 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
{
u8 status;
int rc = 0;
u8 disable = FALSE;
u8 update = FALSE;
u8 disable = 0;
u8 update = 0;
debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
// bit 0 - HPC_SLOT_POWER
if ((pslot->status & 0x01) != (poldslot->status & 0x01))
update = TRUE;
update = 1;
// bit 1 - HPC_SLOT_CONNECT
// ignore
// bit 2 - HPC_SLOT_ATTN
if ((pslot->status & 0x04) != (poldslot->status & 0x04))
update = TRUE;
update = 1;
// bit 3 - HPC_SLOT_PRSNT2
// bit 4 - HPC_SLOT_PRSNT1
if (((pslot->status & 0x08) != (poldslot->status & 0x08))
|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))
update = TRUE;
update = 1;
// bit 5 - HPC_SLOT_PWRGD
if ((pslot->status & 0x20) != (poldslot->status & 0x20))
// OFF -> ON: ignore, ON -> OFF: disable slot
if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))
disable = TRUE;
disable = 1;
// bit 6 - HPC_SLOT_BUS_SPEED
// ignore
// bit 7 - HPC_SLOT_LATCH
if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
update = TRUE;
update = 1;
// OPEN -> CLOSE
if (pslot->status & 0x80) {
if (SLOT_PWRGD (pslot->status)) {
......@@ -977,7 +979,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
msleep(1000);
rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
if (SLOT_PWRGD (status))
update = TRUE;
update = 1;
else // overwrite power in pslot to OFF
pslot->status &= ~HPC_SLOT_POWER;
}
......@@ -985,17 +987,17 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
// CLOSE -> OPEN
else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
&& (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
disable = TRUE;
disable = 1;
}
// else - ignore
}
// bit 4 - HPC_SLOT_BLINK_ATTN
if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
update = TRUE;
update = 1;
if (disable) {
debug ("process_changeinstatus - disable slot\n");
pslot->flag = FALSE;
pslot->flag = 0;
rc = ibmphp_do_disable_slot (pslot);
}
......@@ -1100,7 +1102,7 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
{
debug ("%s - Entry\n", __FUNCTION__);
ibmphp_shutdown = TRUE;
ibmphp_shutdown = 1;
debug ("before locking operations \n");
ibmphp_lock_operations ();
debug ("after locking operations \n");
......@@ -1134,7 +1136,7 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v
u8 * pstatus)
{
int rc = 0;
u8 done = FALSE;
u8 done = 0;
debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
......@@ -1142,14 +1144,14 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v
*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
if (*pstatus == HPC_ERROR) {
rc = HPC_ERROR;
done = TRUE;
done = 1;
}
if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
done = TRUE;
done = 1;
if (!done) {
msleep(1000);
if (timeout < 1) {
done = TRUE;
done = 1;
err ("HPCreadslot - Error ctlr timeout\n");
rc = HPC_ERROR;
} else
......
This diff is collapsed.
This diff is collapsed.
......@@ -176,5 +176,21 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
struct hotplug_slot_info *info);
extern struct subsystem pci_hotplug_slots_subsys;
struct hotplug_params {
u8 cache_line_size;
u8 latency_timer;
u8 enable_serr;
u8 enable_perr;
};
#ifdef CONFIG_ACPI
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
extern acpi_status acpi_run_oshp(acpi_handle handle);
extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp);
int acpi_root_bridge(acpi_handle handle);
#endif
#endif
......@@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/sched.h> /* signal_pending() */
#include <linux/pcieport_if.h>
#include <linux/mutex.h>
#include "pci_hotplug.h"
#define MY_NAME "pciehp"
......@@ -49,12 +50,6 @@ extern int pciehp_force;
#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 hotplug_params {
u8 cache_line_size;
u8 latency_timer;
u8 enable_serr;
u8 enable_perr;
};
struct slot {
struct slot *next;
......@@ -96,7 +91,7 @@ struct php_ctlr_state_s {
#define MAX_EVENTS 10
struct controller {
struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */
struct mutex crit_sect; /* critical section mutex */
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 */
......@@ -191,9 +186,6 @@ extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
/* pci functions */
extern int pciehp_configure_device (struct slot *p_slot);
extern int pciehp_unconfigure_device (struct slot *p_slot);
extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp);
......@@ -285,4 +277,19 @@ struct hpc_ops {
int (*check_lnk_status) (struct controller *ctrl);
};
#ifdef CONFIG_ACPI
#define pciehp_get_hp_hw_control_from_firmware(dev) \
pciehp_acpi_get_hp_hw_control_from_firmware(dev)
static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
return -ENODEV;
return 0;
}
#else
#define pciehp_get_hp_hw_control_from_firmware(dev) 0
#define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV)
#endif /* CONFIG_ACPI */
#endif /* _PCIEHP_H */
......@@ -117,27 +117,23 @@ static int init_slots(struct controller *ctrl)
slot_number = ctrl->first_slot;
while (number_of_slots) {
slot = kmalloc(sizeof(*slot), GFP_KERNEL);
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof(struct slot));
slot->hotplug_slot =
kmalloc(sizeof(*(slot->hotplug_slot)),
kzalloc(sizeof(*(slot->hotplug_slot)),
GFP_KERNEL);
if (!slot->hotplug_slot)
goto error_slot;
hotplug_slot = slot->hotplug_slot;
memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
hotplug_slot->info =
kmalloc(sizeof(*(hotplug_slot->info)),
kzalloc(sizeof(*(hotplug_slot->info)),
GFP_KERNEL);
if (!hotplug_slot->info)
goto error_hpslot;
hotplug_slot_info = hotplug_slot->info;
memset(hotplug_slot_info, 0,
sizeof(struct hotplug_slot_info));
hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
if (!hotplug_slot->name)
goto error_info;
......@@ -373,12 +369,11 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
u8 value;
struct pci_dev *pdev;
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
goto err_out_none;
}
memset(ctrl, 0, sizeof(struct controller));
pdev = dev->port;
ctrl->pci_dev = pdev;
......@@ -439,7 +434,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
......@@ -447,7 +442,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
if (rc) {
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
goto err_out_free_ctrl_slot;
} else
/* Wait for the command to complete */
......@@ -455,7 +450,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return 0;
......
......@@ -229,13 +229,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
static void set_slot_off(struct controller *ctrl, struct slot * pslot)
{
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
if (POWER_CTRL(ctrl->ctrlcap)) {
if (pslot->hpc_ops->power_off_slot(pslot)) {
err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return;
}
wait_for_ctrl_irq (ctrl);
......@@ -249,14 +249,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
if (ATTN_LED(ctrl->ctrlcap)) {
if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return;
}
wait_for_ctrl_irq (ctrl);
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
}
/**
......@@ -279,13 +279,13 @@ static int board_added(struct slot *p_slot)
ctrl->slot_device_offset, hp_slot);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (POWER_CTRL(ctrl->ctrlcap)) {
/* Power on slot */
rc = p_slot->hpc_ops->power_on_slot(p_slot);
if (rc) {
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return -1;
}
......@@ -301,7 +301,7 @@ static int board_added(struct slot *p_slot)
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
/* Wait for ~1 second */
wait_for_ctrl_irq (ctrl);
......@@ -335,7 +335,7 @@ static int board_added(struct slot *p_slot)
pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
if (PWR_LED(ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
p_slot->hpc_ops->green_led_on(p_slot);
......@@ -343,7 +343,7 @@ static int board_added(struct slot *p_slot)
wait_for_ctrl_irq (ctrl);
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
}
return 0;
......@@ -375,14 +375,14 @@ static int remove_board(struct slot *p_slot)
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (POWER_CTRL(ctrl->ctrlcap)) {
/* power off slot */
rc = p_slot->hpc_ops->power_off_slot(p_slot);
if (rc) {
err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return rc;
}
/* Wait for the command to complete */
......@@ -398,7 +398,7 @@ static int remove_board(struct slot *p_slot)
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
return 0;
}
......@@ -445,7 +445,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
down(&p_slot->ctrl->crit_sect);
mutex_lock(&p_slot->ctrl->crit_sect);
p_slot->hpc_ops->green_led_off(p_slot);
......@@ -453,7 +453,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
wait_for_ctrl_irq (p_slot->ctrl);
/* Done with exclusive hardware access */
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
}
p_slot->state = STATIC_STATE;
}
......@@ -495,7 +495,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
down(&p_slot->ctrl->crit_sect);
mutex_lock(&p_slot->ctrl->crit_sect);
p_slot->hpc_ops->green_led_off(p_slot);
......@@ -503,7 +503,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
wait_for_ctrl_irq (p_slot->ctrl);
/* Done with exclusive hardware access */
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
}
p_slot->state = STATIC_STATE;
}
......@@ -616,7 +616,7 @@ static void interrupt_event_handler(struct controller *ctrl)
switch (p_slot->state) {
case BLINKINGOFF_STATE:
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (PWR_LED(ctrl->ctrlcap)) {
p_slot->hpc_ops->green_led_on(p_slot);
......@@ -630,11 +630,11 @@ static void interrupt_event_handler(struct controller *ctrl)
wait_for_ctrl_irq (ctrl);
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
break;
case BLINKINGON_STATE:
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (PWR_LED(ctrl->ctrlcap)) {
p_slot->hpc_ops->green_led_off(p_slot);
......@@ -647,7 +647,7 @@ static void interrupt_event_handler(struct controller *ctrl)
wait_for_ctrl_irq (ctrl);
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
break;
default:
......@@ -676,7 +676,7 @@ static void interrupt_event_handler(struct controller *ctrl)
}
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
/* blink green LED and turn off amber */
if (PWR_LED(ctrl->ctrlcap)) {
......@@ -693,7 +693,7 @@ static void interrupt_event_handler(struct controller *ctrl)
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
init_timer(&p_slot->task_event);
p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
......@@ -708,7 +708,7 @@ static void interrupt_event_handler(struct controller *ctrl)
if (POWER_CTRL(ctrl->ctrlcap)) {
dbg("power fault\n");
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
mutex_lock(&ctrl->crit_sect);
if (ATTN_LED(ctrl->ctrlcap)) {
p_slot->hpc_ops->set_attention_status(p_slot, 1);
......@@ -721,7 +721,7 @@ static void interrupt_event_handler(struct controller *ctrl)
}
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
mutex_unlock(&ctrl->crit_sect);
}
}
/***********SURPRISE REMOVAL********************/
......@@ -756,19 +756,19 @@ int pciehp_enable_slot(struct slot *p_slot)
int rc;
/* Check to see if (latch closed, card present, power off) */
down(&p_slot->ctrl->crit_sect);
mutex_lock(&p_slot->ctrl->crit_sect);
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
}
......@@ -777,11 +777,11 @@ int pciehp_enable_slot(struct slot *p_slot)
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
}
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
......@@ -806,13 +806,13 @@ int pciehp_disable_slot(struct slot *p_slot)
return 1;
/* Check to see if (latch closed, card present, power on) */
down(&p_slot->ctrl->crit_sect);
mutex_lock(&p_slot->ctrl->crit_sect);
if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (ret || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
}
......@@ -821,7 +821,7 @@ int pciehp_disable_slot(struct slot *p_slot)
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
}
......@@ -830,12 +830,12 @@ int pciehp_disable_slot(struct slot *p_slot)
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) {
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
return 1;
}
}
up(&p_slot->ctrl->crit_sect);
mutex_unlock(&p_slot->ctrl->crit_sect);
ret = remove_board(p_slot);
update_slot_info(p_slot);
......
......@@ -38,7 +38,10 @@
#include "../pci.h"
#include "pciehp.h"
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include <linux/pci-acpi.h>
#ifdef DEBUG
#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
......@@ -1236,6 +1239,76 @@ static struct hpc_ops pciehp_hpc_ops = {
.check_lnk_status = hpc_check_lnk_status,
};
#ifdef CONFIG_ACPI
int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
acpi_status status;
acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
struct pci_dev *pdev = dev;
struct pci_bus *parent;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
/*
* Per PCI firmware specification, we should run the ACPI _OSC
* method to get control of hotplug hardware before using it.
* If an _OSC is missing, we look for an OSHP to do the same thing.
* To handle different BIOS behavior, we look for _OSC and OSHP
* within the scope of the hotplug controller and its parents, upto
* the host bridge under which this controller exists.
*/
while (!handle) {
/*
* This hotplug controller was not listed in the ACPI name
* space at all. Try to get acpi handle of parent pci bus.
*/
if (!pdev || !pdev->bus->parent)
break;
parent = pdev->bus->parent;
dbg("Could not find %s in acpi namespace, trying parent\n",
pci_name(pdev));
if (!parent->self)
/* Parent must be a host bridge */
handle = acpi_get_pci_rootbridge_handle(
pci_domain_nr(parent),
parent->number);
else
handle = DEVICE_ACPI_HANDLE(
&(parent->self->dev));
pdev = parent->self;
}
while (handle) {
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s \n",
(char *)string.pointer);
status = pci_osc_control_set(handle,
OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
if (status == AE_NOT_FOUND)
status = acpi_run_oshp(handle);
if (ACPI_SUCCESS(status)) {
dbg("Gained control for hotplug HW for pci %s (%s)\n",
pci_name(dev), (char *)string.pointer);
acpi_os_free(string.pointer);
return 0;
}
if (acpi_root_bridge(handle))
break;
chandle = handle;
status = acpi_get_parent(chandle, &handle);
if (ACPI_FAILURE(status))
break;
}
err("Cannot get control of hotplug hardware for pci %s\n",
pci_name(dev));
acpi_os_free(string.pointer);
return -1;
}
#endif
int pcie_init(struct controller * ctrl, struct pcie_device *dev)
{
struct php_ctlr_state_s *php_ctlr, *p;
......@@ -1334,7 +1407,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
if (pci_enable_device(pdev))
goto abort_free_ctlr;
init_MUTEX(&ctrl->crit_sect);
mutex_init(&ctrl->crit_sect);
/* setup wait queue */
init_waitqueue_head(&ctrl->queue);
......
/*
* PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
*
* 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 <kristen.c.accardi@intel.com>
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/pci-acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "pciehp.h"
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
static u8 * acpi_path_name( acpi_handle handle)
{
acpi_status status;
static u8 path_name[ACPI_PATHNAME_MAX];
struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
memset(path_name, 0, sizeof (path_name));
status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
if (ACPI_FAILURE(status))
return NULL;
else
return path_name;
}
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(handle);
int i, len = 0;
/* get _hpp */
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 ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
path_name);
return AE_NO_MEMORY;
}
status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
NULL, &ret_buf);
if (ACPI_SUCCESS(status))
break;
default:
if (ACPI_FAILURE(status)) {
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 ("%s:%s _HPP obj not a package\n", __FUNCTION__,
path_name);
status = AE_ERROR;
goto free_and_return;
}
len = ext_obj->package.count;
package = (union acpi_object *) ret_buf.pointer;
for ( i = 0; (i < len) || (i < 4); i++) {
ext_obj = (union acpi_object *) &package->package.elements[i];
switch (ext_obj->type) {
case ACPI_TYPE_INTEGER:
nui[i] = (u8)ext_obj->integer.value;
break;
default:
err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
path_name);
status = AE_ERROR;
goto free_and_return;
}
}
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", 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 acpi_status acpi_run_oshp(acpi_handle handle)
{
acpi_status status;
u8 *path_name = acpi_path_name(handle);
/* run OSHP */
status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
if (ACPI_FAILURE(status)) {
dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
status);
} else {
dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
}
return status;
}
static int is_root_bridge(acpi_handle handle)
{
acpi_status status;
struct acpi_device_info *info;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
int i;
status = acpi_get_object_info(handle, &buffer);
if (ACPI_SUCCESS(status)) {
info = buffer.pointer;
if ((info->valid & ACPI_VALID_HID) &&
!strcmp(PCI_ROOT_HID_STRING,
info->hardware_id.value)) {
acpi_os_free(buffer.pointer);
return 1;
}
if (info->valid & ACPI_VALID_CID) {
for (i=0; i < info->compatibility_id.count; i++) {
if (!strcmp(PCI_ROOT_HID_STRING,
info->compatibility_id.id[i].value)) {
acpi_os_free(buffer.pointer);
return 1;
}
}
}
}
return 0;
}
int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
acpi_status status;
acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
struct pci_dev *pdev = dev;
struct pci_bus *parent;
u8 *path_name;
/*
* Per PCI firmware specification, we should run the ACPI _OSC
* method to get control of hotplug hardware before using it.
* If an _OSC is missing, we look for an OSHP to do the same thing.
* To handle different BIOS behavior, we look for _OSC and OSHP
* within the scope of the hotplug controller and its parents, upto
* the host bridge under which this controller exists.
*/
while (!handle) {
/*
* This hotplug controller was not listed in the ACPI name
* space at all. Try to get acpi handle of parent pci bus.
*/
if (!pdev || !pdev->bus->parent)
break;
parent = pdev->bus->parent;
dbg("Could not find %s in acpi namespace, trying parent\n",
pci_name(pdev));
if (!parent->self)
/* Parent must be a host bridge */
handle = acpi_get_pci_rootbridge_handle(
pci_domain_nr(parent),
parent->number);
else
handle = DEVICE_ACPI_HANDLE(
&(parent->self->dev));
pdev = parent->self;
}
while (handle) {
path_name = acpi_path_name(handle);
dbg("Trying to get hotplug control for %s \n", path_name);
status = pci_osc_control_set(handle,
OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
if (status == AE_NOT_FOUND)
status = acpi_run_oshp(handle);
if (ACPI_SUCCESS(status)) {
dbg("Gained control for hotplug HW for pci %s (%s)\n",
pci_name(dev), path_name);
return 0;
}
if (is_root_bridge(handle))
break;
chandle = handle;
status = acpi_get_parent(chandle, &handle);
if (ACPI_FAILURE(status))
break;
}
err("Cannot get control of hotplug hardware for pci %s\n",
pci_name(dev));
return -1;
}
void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
acpi_status status = AE_NOT_FOUND;
struct pci_dev *pdev = dev;
/*
* _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;
status = acpi_run_hpp(handle, hpp);
if (!(pdev->bus->parent))
break;
/* Check if a parent object supports _HPP */
pdev = pdev->bus->parent->self;
}
}
/*
* PCIEHPRM 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>
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include "pciehp.h"
void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
return;
}
int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
return 0;
}
......@@ -37,10 +37,12 @@
#include <linux/init.h>
#include "pci_hotplug.h"
#define SLOT_NAME_SIZE 10
struct slot {
u8 number;
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
char name[SLOT_NAME_SIZE];
};
static LIST_HEAD(slot_list);
......@@ -233,12 +235,10 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
kfree(slot->hotplug_slot->info);
kfree(slot->hotplug_slot->name);
kfree(slot->hotplug_slot);
kfree(slot);
}
#define SLOT_NAME_SIZE 10
static void make_slot_name(struct slot *slot)
{
/*
......@@ -257,7 +257,6 @@ static int __init init_slots(void)
struct slot *slot;
struct hotplug_slot *hotplug_slot;
struct hotplug_slot_info *info;
char *name;
int retval = -ENOMEM;
int i;
......@@ -266,31 +265,23 @@ static int __init init_slots(void)
* with the pci_hotplug subsystem.
*/
for (i = 0; i < num_slots; ++i) {
slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
goto error;
memset(slot, 0, sizeof(struct slot));
hotplug_slot = kmalloc(sizeof(struct hotplug_slot),
GFP_KERNEL);
hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
if (!hotplug_slot)
goto error_slot;
memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
slot->hotplug_slot = hotplug_slot;
info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
goto error_hpslot;
memset(info, 0, sizeof (struct hotplug_slot_info));
hotplug_slot->info = info;
name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
if (!name)
goto error_info;
hotplug_slot->name = name;
slot->number = i;
hotplug_slot->name = slot->name;
hotplug_slot->private = slot;
hotplug_slot->release = &release_slot;
make_slot_name(slot);
......@@ -300,16 +291,16 @@ static int __init init_slots(void)
* Initialize the slot info structure with some known
* good values.
*/
info->power_status = get_power_status(slot);
info->attention_status = get_attention_status(slot);
info->latch_status = get_latch_status(slot);
info->adapter_status = get_adapter_status(slot);
get_power_status(hotplug_slot, &info->power_status);
get_attention_status(hotplug_slot, &info->attention_status);
get_latch_status(hotplug_slot, &info->latch_status);
get_adapter_status(hotplug_slot, &info->adapter_status);
dbg("registering slot %d\n", i);
retval = pci_hp_register(slot->hotplug_slot);
if (retval) {
err("pci_hp_register failed with error %d\n", retval);
goto error_name;
goto error_info;
}
/* add slot to our internal list */
......@@ -317,8 +308,6 @@ static int __init init_slots(void)
}
return 0;
error_name:
kfree(name);
error_info:
kfree(info);
error_hpslot:
......
......@@ -84,19 +84,16 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_
{
struct slot *slot;
slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
slot = kzalloc(sizeof(struct slot), GFP_KERNEL);
if (!slot)
goto error_nomem;
memset(slot, 0, sizeof (struct slot));
slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
if (!slot->hotplug_slot)
goto error_slot;
memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info),
slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
GFP_KERNEL);
if (!slot->hotplug_slot->info)
goto error_hpslot;
memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL);
if (!slot->hotplug_slot->name)
goto error_info;
......
......@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
*
* This work was based on the 2.4/2.6 kernel development by Dick Reigner.
* Work to add BIOS PROM support was completed by Mike Habeck.
......@@ -230,6 +230,13 @@ static void sn_bus_free_data(struct pci_dev *dev)
list_for_each_entry(child, &subordinate_bus->devices, bus_list)
sn_bus_free_data(child);
}
/*
* Some drivers may use dma accesses during the
* driver remove function. We release the sysdata
* areas after the driver remove functions have
* been called.
*/
sn_bus_store_sysdata(dev);
sn_pci_unfixup_slot(dev);
}
......@@ -429,13 +436,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
PCI_DEVFN(slot->device_num + 1,
PCI_FUNC(func)));
if (dev) {
/*
* Some drivers may use dma accesses during the
* driver remove function. We release the sysdata
* areas after the driver remove functions have
* been called.
*/
sn_bus_store_sysdata(dev);
sn_bus_free_data(dev);
pci_remove_bus_device(dev);
pci_dev_put(dev);
......
......@@ -33,6 +33,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/sched.h> /* signal_pending(), struct timer_list */
#include <linux/mutex.h>
#include "pci_hotplug.h"
......@@ -45,6 +46,7 @@
extern int shpchp_poll_mode;
extern int shpchp_poll_time;
extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
......@@ -52,10 +54,8 @@ 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)
#define SLOT_MAGIC 0x67267321
#define SLOT_NAME_SIZE 10
struct slot {
u32 magic;
struct slot *next;
u8 bus;
u8 device;
u16 status;
......@@ -70,26 +70,27 @@ struct slot {
struct hpc_ops *hpc_ops;
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
char name[SLOT_NAME_SIZE];
struct work_struct work; /* work for button event */
struct mutex lock;
};
struct event_info {
u32 event_type;
u8 hp_slot;
struct slot *p_slot;
struct work_struct work;
};
struct controller {
struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */
struct mutex crit_sect; /* critical section mutex */
struct mutex cmd_lock; /* command lock */
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_dev *pci_dev;
struct pci_bus *pci_bus;
struct event_info event_queue[10];
struct slot *slot;
struct list_head slot_list;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 next_event;
u8 bus;
u8 device;
u8 function;
......@@ -105,12 +106,6 @@ struct controller {
volatile int cmd_busy;
};
struct hotplug_params {
u8 cache_line_size;
u8 latency_timer;
u8 enable_serr;
u8 enable_perr;
};
/* Define AMD SHPC ID */
#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
......@@ -180,11 +175,8 @@ struct hotplug_params {
/* sysfs functions for the hotplug controller info */
extern void shpchp_create_ctrl_files (struct controller *ctrl);
/* controller functions */
extern int shpchp_event_start_thread(void);
extern void shpchp_event_stop_thread(void);
extern int shpchp_enable_slot(struct slot *slot);
extern int shpchp_disable_slot(struct slot *slot);
extern int shpchp_sysfs_enable_slot(struct slot *slot);
extern int shpchp_sysfs_disable_slot(struct slot *slot);
extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
......@@ -195,16 +187,28 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
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);
extern void cleanup_slots(struct controller *ctrl);
extern void queue_pushbutton_work(void *data);
/* Global variables */
extern struct controller *shpchp_ctrl_list;
#ifdef CONFIG_ACPI
static inline int get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
return -ENODEV;
return 0;
}
#define get_hp_hw_control_from_firmware(pdev) \
do { \
if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
} while (0)
#else
#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
#define get_hp_hw_control_from_firmware(dev) do { } while (0)
#endif
struct ctrl_reg {
volatile u32 base_offset;
......@@ -286,10 +290,6 @@ static inline int slot_paranoia_check (struct slot *slot, const char *function)
dbg("%s - slot == NULL", function);
return -1;
}
if (slot->magic != SLOT_MAGIC) {
dbg("%s - bad magic number for slot", function);
return -1;
}
if (!slot->hotplug_slot) {
dbg("%s - slot->hotplug_slot == NULL!", function);
return -1;
......@@ -314,44 +314,19 @@ static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const ch
static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
{
struct slot *p_slot, *tmp_slot = NULL;
struct slot *slot;
if (!ctrl)
return NULL;
p_slot = ctrl->slot;
while (p_slot && (p_slot->device != device)) {
tmp_slot = p_slot;
p_slot = p_slot->next;
list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
if (slot->device == device)
return slot;
}
if (p_slot == NULL) {
err("ERROR: shpchp_find_slot device=0x%x\n", device);
p_slot = tmp_slot;
}
return (p_slot);
}
static inline int wait_for_ctrl_irq (struct controller *ctrl)
{
DECLARE_WAITQUEUE(wait, current);
int retval = 0;
add_wait_queue(&ctrl->queue, &wait);
if (!shpchp_poll_mode) {
/* Sleep for up to 1 second */
msleep_interruptible(1000);
} else {
/* Sleep for up to 2 seconds */
msleep_interruptible(2000);
}
remove_wait_queue(&ctrl->queue, &wait);
if (signal_pending(current))
retval = -EINTR;
err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
return retval;
return NULL;
}
static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot)
......@@ -427,13 +402,6 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
}
#define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
{
snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
}
enum php_ctlr_type {
PCI,
ISA,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -38,7 +38,7 @@ static void program_fw_provided_values(struct pci_dev *dev)
{
u16 pci_cmd, pci_bctl;
struct pci_dev *cdev;
struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
struct hotplug_params hpp;
/* Program hpp values for this device */
if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
......@@ -46,7 +46,13 @@ static void program_fw_provided_values(struct pci_dev *dev)
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
return;
get_hp_params_from_firmware(dev, &hpp);
/* use default values if we can't get them from firmware */
if (get_hp_params_from_firmware(dev, &hpp)) {
hpp.cache_line_size = 8;
hpp.latency_timer = 0x40;
hpp.enable_serr = 0;
hpp.enable_perr = 0;
}
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
......
/*
* SHPCHPRM Legacy: 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>
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include "shpchp.h"
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
{
int offset = devnum - ctrl->slot_device_offset;
*sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
return 0;
}
void get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
return;
}
void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
return;
}
/*
* 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>
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include "shpchp.h"
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;
}
void get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
return;
}
void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
return;
}
This diff is collapsed.
......@@ -53,11 +53,10 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
if (fields < 0)
return -EINVAL;
dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
if (!dynid)
return -ENOMEM;
memset(dynid, 0, sizeof(*dynid));
INIT_LIST_HEAD(&dynid->node);
dynid->id.vendor = vendor;
dynid->id.device = device;
......@@ -380,14 +379,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
/* FIXME, once all of the existing PCI drivers have been fixed to set
* 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 = owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
......@@ -514,6 +505,7 @@ struct bus_type pci_bus_type = {
.probe = pci_device_probe,
.remove = pci_device_remove,
.suspend = pci_device_suspend,
.shutdown = pci_device_shutdown,
.resume = pci_device_resume,
.dev_attrs = pci_dev_attrs,
};
......
......@@ -501,9 +501,8 @@ int pci_create_sysfs_dev_files (struct pci_dev *pdev)
if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
struct bin_attribute *rom_attr;
rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC);
if (rom_attr) {
memset(rom_attr, 0x00, sizeof(*rom_attr));
pdev->rom_attr = rom_attr;
rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
rom_attr->attr.name = "rom";
......
......@@ -19,7 +19,6 @@
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
#if 0
/**
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
......@@ -34,7 +33,7 @@ pci_bus_max_busnr(struct pci_bus* bus)
struct list_head *tmp;
unsigned char max, n;
max = bus->number;
max = bus->subordinate;
list_for_each(tmp, &bus->children) {
n = pci_bus_max_busnr(pci_bus_b(tmp));
if(n > max)
......@@ -42,7 +41,9 @@ pci_bus_max_busnr(struct pci_bus* bus)
}
return max;
}
EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
#if 0
/**
* pci_max_busnr - returns maximum PCI bus number
*
......@@ -495,9 +496,8 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
int
pci_enable_device(struct pci_dev *dev)
{
int err;
if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
if (err)
return err;
pci_fixup_device(pci_fixup_enable, dev);
dev->is_enabled = 1;
......@@ -639,7 +639,7 @@ void pci_release_region(struct pci_dev *pdev, int bar)
* Returns 0 on success, or %EBUSY on error. A warning
* message is also printed on failure.
*/
int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
{
if (pci_resource_len(pdev, bar) == 0)
return 0;
......@@ -697,7 +697,7 @@ void pci_release_regions(struct pci_dev *pdev)
* Returns 0 on success, or %EBUSY on error. A warning
* message is also printed on failure.
*/
int pci_request_regions(struct pci_dev *pdev, char *res_name)
int pci_request_regions(struct pci_dev *pdev, const char *res_name)
{
int i;
......@@ -900,8 +900,12 @@ static int __devinit pci_setup(char *str)
if (k)
*k++ = 0;
if (*str && (str = pcibios_setup(str)) && *str) {
/* PCI layer options should be handled here */
printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
if (!strcmp(str, "nomsi")) {
pci_no_msi();
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
}
}
str = k;
}
......
......@@ -50,8 +50,10 @@ extern int pci_msi_quirk;
#ifdef CONFIG_PCI_MSI
void disable_msi_mode(struct pci_dev *dev, int pos, int type);
void pci_no_msi(void);
#else
static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
static inline void pci_no_msi(void) { }
#endif
extern int pcie_mch_quirk;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment