diff options
Diffstat (limited to 'drivers/pci/hotplug')
47 files changed, 1435 insertions, 1538 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 0a648af8953..df8caec5978 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -133,8 +133,8 @@ config HOTPLUG_PCI_RPA_DLPAR  	  To compile this driver as a module, choose M here: the  	  module will be called rpadlpar_io. -  - 	  When in doubt, say N. + +	  When in doubt, say N.  config HOTPLUG_PCI_SGI  	tristate "SGI PCI Hotplug Support" diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 47ec8c80e16..3e6532b945c 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -31,7 +31,7 @@ pci_hotplug-objs	+=	cpci_hotplug_core.o	\  				cpci_hotplug_pci.o  endif  ifdef CONFIG_ACPI -pci_hotplug-objs 	+= 	acpi_pcihp.o +pci_hotplug-objs	+=	acpi_pcihp.o  endif  cpqphp-objs		:=	cpqphp_core.o	\ diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2a47e82821d..a94d850ae22 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -338,7 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)  	acpi_handle chandle, handle;  	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; -	flags &= OSC_SHPC_NATIVE_HP_CONTROL; +	flags &= OSC_PCI_SHPC_NATIVE_HP_CONTROL;  	if (!flags) {  		err("Invalid flags %u specified!\n", flags);  		return -EINVAL; @@ -367,7 +367,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)  		string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };  	} -	handle = DEVICE_ACPI_HANDLE(&pdev->dev); +	handle = ACPI_HANDLE(&pdev->dev);  	if (!handle) {  		/*  		 * This hotplug controller was not listed in the ACPI name @@ -411,13 +411,10 @@ EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware);  static int pcihp_is_ejectable(acpi_handle handle)  {  	acpi_status status; -	acpi_handle tmp;  	unsigned long long removable; -	status = acpi_get_handle(handle, "_ADR", &tmp); -	if (ACPI_FAILURE(status)) +	if (!acpi_has_method(handle, "_ADR"))  		return 0; -	status = acpi_get_handle(handle, "_EJ0", &tmp); -	if (ACPI_SUCCESS(status)) +	if (acpi_has_method(handle, "_EJ0"))  		return 1;  	status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable);  	if (ACPI_SUCCESS(status) && removable) diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index f4e02892466..b0e61bf261a 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -39,16 +39,6 @@  #include <linux/mutex.h>  #include <linux/pci_hotplug.h> -#define dbg(format, arg...)					\ -	do {							\ -		if (acpiphp_debug)				\ -			printk(KERN_DEBUG "%s: " format,	\ -				MY_NAME , ## arg);		\ -	} while (0) -#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) -#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 acpiphp_context;  struct acpiphp_bridge;  struct acpiphp_slot; @@ -87,6 +77,8 @@ struct acpiphp_bridge {  	/* PCI-to-PCI bridge device */  	struct pci_dev *pci_dev; + +	bool is_going_away;  }; @@ -101,7 +93,6 @@ struct acpiphp_slot {  	struct list_head funcs;		/* one slot may have different  					   objects (i.e. for each function) */  	struct slot *slot; -	struct mutex crit_sect;  	u8		device;		/* pci device# */  	u32		flags;		/* see below */ @@ -125,20 +116,40 @@ struct acpiphp_func {  };  struct acpiphp_context { -	acpi_handle handle; +	struct acpi_hotplug_context hp;  	struct acpiphp_func func;  	struct acpiphp_bridge *bridge;  	unsigned int refcount;  }; +static inline struct acpiphp_context *to_acpiphp_context(struct acpi_hotplug_context *hp) +{ +	return container_of(hp, struct acpiphp_context, hp); +} +  static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func)  {  	return container_of(func, struct acpiphp_context, func);  } +static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func) +{ +	return func_to_context(func)->hp.self; +} +  static inline acpi_handle func_to_handle(struct acpiphp_func *func)  { -	return func_to_context(func)->handle; +	return func_to_acpi_device(func)->handle; +} + +struct acpiphp_root_context { +	struct acpi_hotplug_context hp; +	struct acpiphp_bridge *root_bridge; +}; + +static inline struct acpiphp_root_context *to_acpiphp_root_context(struct acpi_hotplug_context *hp) +{ +	return container_of(hp, struct acpiphp_root_context, hp);  }  /* @@ -160,12 +171,12 @@ struct acpiphp_attention_info  /* slot flags */  #define SLOT_ENABLED		(0x00000001) +#define SLOT_IS_GOING_AWAY	(0x00000002)  /* function flags */  #define FUNC_HAS_STA		(0x00000001)  #define FUNC_HAS_EJ0		(0x00000002) -#define FUNC_HAS_DCK            (0x00000004)  /* function prototypes */ @@ -179,14 +190,13 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);  typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);  int acpiphp_enable_slot(struct acpiphp_slot *slot); -int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); +int acpiphp_disable_slot(struct acpiphp_slot *slot);  u8 acpiphp_get_power_status(struct acpiphp_slot *slot);  u8 acpiphp_get_attention_status(struct acpiphp_slot *slot);  u8 acpiphp_get_latch_status(struct acpiphp_slot *slot);  u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot);  /* variables */ -extern bool acpiphp_debug;  extern bool acpiphp_disabled;  #endif /* _ACPIPHP_H */ diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index bf2203ef130..e291efcd02a 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -31,6 +31,8 @@   *   */ +#define pr_fmt(fmt) "acpiphp: " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -43,12 +45,9 @@  #include <linux/smp.h>  #include "acpiphp.h" -#define MY_NAME	"acpiphp" -  /* name size which is used for entries in pcihpfs */  #define SLOT_NAME_SIZE  21              /* {_SUN} */ -bool acpiphp_debug;  bool acpiphp_disabled;  /* local variables */ @@ -61,15 +60,9 @@ static struct acpiphp_attention_info *attention_info;  MODULE_AUTHOR(DRIVER_AUTHOR);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(debug, "Debugging mode enabled or not");  MODULE_PARM_DESC(disable, "disable acpiphp driver"); -module_param_named(debug, acpiphp_debug, bool, 0644);  module_param_named(disable, acpiphp_disabled, bool, 0444); -/* export the attention callback registration methods */ -EXPORT_SYMBOL_GPL(acpiphp_register_attention); -EXPORT_SYMBOL_GPL(acpiphp_unregister_attention); -  static int enable_slot		(struct hotplug_slot *slot);  static int disable_slot		(struct hotplug_slot *slot);  static int set_attention_status (struct hotplug_slot *slot, u8 value); @@ -107,6 +100,7 @@ int acpiphp_register_attention(struct acpiphp_attention_info *info)  	}  	return retval;  } +EXPORT_SYMBOL_GPL(acpiphp_register_attention);  /** @@ -114,7 +108,7 @@ int acpiphp_register_attention(struct acpiphp_attention_info *info)   * @info: must match the pointer used to register   *   * Description: This is used to un-register a hardware specific acpi - * driver that manipulates the attention LED.  The pointer to the  + * driver that manipulates the attention LED.  The pointer to the   * info struct must be the same as the one used to set it.   */  int acpiphp_unregister_attention(struct acpiphp_attention_info *info) @@ -127,6 +121,7 @@ int acpiphp_unregister_attention(struct acpiphp_attention_info *info)  	}  	return retval;  } +EXPORT_SYMBOL_GPL(acpiphp_unregister_attention);  /** @@ -139,7 +134,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	/* enable the specified slot */  	return acpiphp_enable_slot(slot->acpi_slot); @@ -156,10 +151,10 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	/* disable the specified slot */ -	return acpiphp_disable_and_eject_slot(slot->acpi_slot); +	return acpiphp_disable_slot(slot->acpi_slot);  } @@ -172,20 +167,21 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)   * was registered with us.  This allows hardware specific   * ACPI implementations to blink the light for us.   */ - static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) - { +static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) +{  	int retval = -ENODEV; -	dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot)); -  +	pr_debug("%s - physical_slot = %s\n", __func__, +		hotplug_slot_name(hotplug_slot)); +  	if (attention_info && try_module_get(attention_info->owner)) {  		retval = attention_info->set_attn(hotplug_slot, status);  		module_put(attention_info->owner);  	} else  		attention_info = NULL;  	return retval; - } -  +} +  /**   * get_power_status - get power status of a slot @@ -199,7 +195,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	*value = acpiphp_get_power_status(slot->acpi_slot); @@ -221,7 +217,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int retval = -EINVAL; -	dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, +		hotplug_slot_name(hotplug_slot));  	if (attention_info && try_module_get(attention_info->owner)) {  		retval = attention_info->get_attn(hotplug_slot, value); @@ -244,7 +241,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	*value = acpiphp_get_latch_status(slot->acpi_slot); @@ -264,7 +261,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	*value = acpiphp_get_adapter_status(slot->acpi_slot); @@ -279,7 +276,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)  {  	struct slot *slot = hotplug_slot->private; -	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); +	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));  	kfree(slot->hotplug_slot);  	kfree(slot); @@ -322,11 +319,11 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,  	if (retval == -EBUSY)  		goto error_hpslot;  	if (retval) { -		err("pci_hp_register failed with error %d\n", retval); +		pr_err("pci_hp_register failed with error %d\n", retval);  		goto error_hpslot; - 	} +	} -	info("Slot [%s] registered\n", slot_name(slot)); +	pr_info("Slot [%s] registered\n", slot_name(slot));  	return 0;  error_hpslot: @@ -343,17 +340,17 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)  	struct slot *slot = acpiphp_slot->slot;  	int retval = 0; -	info("Slot [%s] unregistered\n", slot_name(slot)); +	pr_info("Slot [%s] unregistered\n", slot_name(slot));  	retval = pci_hp_deregister(slot->hotplug_slot);  	if (retval) -		err("pci_hp_deregister failed with error %d\n", retval); +		pr_err("pci_hp_deregister failed with error %d\n", retval);  }  void __init acpiphp_init(void)  { -	info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", +	pr_info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n",  		acpiphp_disabled ? ", disabled by user; please report a bug"  				 : "");  } diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b7d23b4ad9..602d153c705 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -39,7 +39,8 @@   *    bus. It loses the refcount when the the driver unloads.   */ -#include <linux/init.h> +#define pr_fmt(fmt) "acpiphp_glue: " fmt +  #include <linux/module.h>  #include <linux/kernel.h> @@ -56,73 +57,59 @@  static LIST_HEAD(bridge_list);  static DEFINE_MUTEX(bridge_mutex); -static DEFINE_MUTEX(acpiphp_context_lock); - -#define MY_NAME "acpiphp_glue" -static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); +static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); +static void acpiphp_post_dock_fixup(struct acpi_device *adev);  static void acpiphp_sanitize_bus(struct pci_bus *bus);  static void acpiphp_set_hpp_values(struct pci_bus *bus); -static void hotplug_event(acpi_handle handle, u32 type, void *data); +static void hotplug_event(u32 type, struct acpiphp_context *context);  static void free_bridge(struct kref *kref); -static void acpiphp_context_handler(acpi_handle handle, void *context) -{ -	/* Intentionally empty. */ -} -  /**   * acpiphp_init_context - Create hotplug context and grab a reference to it. - * @handle: ACPI object handle to create the context for. + * @adev: ACPI device object to create the context for.   * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock.   */ -static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) +static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)  {  	struct acpiphp_context *context; -	acpi_status status;  	context = kzalloc(sizeof(*context), GFP_KERNEL);  	if (!context)  		return NULL; -	context->handle = handle;  	context->refcount = 1; -	status = acpi_attach_data(handle, acpiphp_context_handler, context); -	if (ACPI_FAILURE(status)) { -		kfree(context); -		return NULL; -	} +	acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL, +			    acpiphp_post_dock_fixup);  	return context;  }  /**   * acpiphp_get_context - Get hotplug context and grab a reference to it. - * @handle: ACPI object handle to get the context for. + * @adev: ACPI device object to get the context for.   * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock.   */ -static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) +static struct acpiphp_context *acpiphp_get_context(struct acpi_device *adev)  { -	struct acpiphp_context *context = NULL; -	acpi_status status; -	void *data; +	struct acpiphp_context *context; -	status = acpi_get_data(handle, acpiphp_context_handler, &data); -	if (ACPI_SUCCESS(status)) { -		context = data; -		context->refcount++; -	} +	if (!adev->hp) +		return NULL; + +	context = to_acpiphp_context(adev->hp); +	context->refcount++;  	return context;  }  /**   * acpiphp_put_context - Drop a reference to ACPI hotplug context. - * @handle: ACPI object handle to put the context for. + * @context: ACPI hotplug context to drop a reference to.   *   * The context object is removed if there are no more references to it.   * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock.   */  static void acpiphp_put_context(struct acpiphp_context *context)  { @@ -130,7 +117,7 @@ static void acpiphp_put_context(struct acpiphp_context *context)  		return;  	WARN_ON(context->bridge); -	acpi_detach_data(context->handle, acpiphp_context_handler); +	context->hp.self->hp = NULL;  	kfree(context);  } @@ -144,6 +131,27 @@ static inline void put_bridge(struct acpiphp_bridge *bridge)  	kref_put(&bridge->ref, free_bridge);  } +static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev) +{ +	struct acpiphp_context *context; + +	acpi_lock_hp_context(); +	context = acpiphp_get_context(adev); +	if (!context || context->func.parent->is_going_away) { +		acpi_unlock_hp_context(); +		return NULL; +	} +	get_bridge(context->func.parent); +	acpiphp_put_context(context); +	acpi_unlock_hp_context(); +	return context; +} + +static void acpiphp_let_context_go(struct acpiphp_context *context) +{ +	put_bridge(context->func.parent); +} +  static void free_bridge(struct kref *kref)  {  	struct acpiphp_context *context; @@ -151,7 +159,7 @@ static void free_bridge(struct kref *kref)  	struct acpiphp_slot *slot, *next;  	struct acpiphp_func *func, *tmp; -	mutex_lock(&acpiphp_context_lock); +	acpi_lock_hp_context();  	bridge = container_of(kref, struct acpiphp_bridge, ref); @@ -175,31 +183,32 @@ static void free_bridge(struct kref *kref)  	pci_dev_put(bridge->pci_dev);  	kfree(bridge); -	mutex_unlock(&acpiphp_context_lock); +	acpi_unlock_hp_context();  } -/* - * the _DCK method can do funny things... and sometimes not - * hah-hah funny. +/** + * acpiphp_post_dock_fixup - Post-dock fixups for PCI devices. + * @adev: ACPI device object corresponding to a PCI device.   * - * TBD - figure out a way to only call fixups for - * systems that require them. + * TBD - figure out a way to only call fixups for systems that require them.   */ -static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) +static void acpiphp_post_dock_fixup(struct acpi_device *adev)  { -	struct acpiphp_context *context = data; -	struct pci_bus *bus = context->func.slot->bus; +	struct acpiphp_context *context = acpiphp_grab_context(adev); +	struct pci_bus *bus;  	u32 buses; -	if (!bus->self) +	if (!context)  		return; +	bus = context->func.slot->bus; +	if (!bus->self) +		goto out; +  	/* fixup bad _DCK function that rewrites  	 * secondary bridge on slot  	 */ -	pci_read_config_dword(bus->self, -			PCI_PRIMARY_BUS, -			&buses); +	pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses);  	if (((buses >> 8) & 0xff) != bus->busn_res.start) {  		buses = (buses & 0xff000000) @@ -208,13 +217,10 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data)  			| ((unsigned int)(bus->busn_res.end) << 16);  		pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);  	} -} - -static const struct acpi_dock_ops acpiphp_dock_ops = { -	.fixup = post_dock_fixups, -	.handler = hotplug_event, -}; + out: +	acpiphp_let_context_go(context); +}  /* Check whether the PCI device is managed by native PCIe hotplug driver */  static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) @@ -245,26 +251,19 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)  	return true;  } -static void acpiphp_dock_init(void *data) -{ -	struct acpiphp_context *context = data; - -	get_bridge(context->func.parent); -} - -static void acpiphp_dock_release(void *data) -{ -	struct acpiphp_context *context = data; - -	put_bridge(context->func.parent); -} - -/* callback routine to register each ACPI PCI slot object */ -static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, -				 void **rv) +/** + * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. + * @handle: ACPI handle of the object to add a context to. + * @lvl: Not used. + * @data: The object's parent ACPIPHP bridge. + * @rv: Not used. + */ +static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, +				       void **rv)  {  	struct acpiphp_bridge *bridge = data;  	struct acpiphp_context *context; +	struct acpi_device *adev;  	struct acpiphp_slot *slot;  	struct acpiphp_func *newfunc;  	acpi_status status = AE_OK; @@ -274,39 +273,41 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,  	struct pci_dev *pdev = bridge->pci_dev;  	u32 val; -	if (pdev && device_is_managed_by_native_pciehp(pdev)) -		return AE_OK; -  	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);  	if (ACPI_FAILURE(status)) { -		acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status); +		if (status != AE_NOT_FOUND) +			acpi_handle_warn(handle, +				"can't evaluate _ADR (%#x)\n", status);  		return AE_OK;  	} +	if (acpi_bus_get_device(handle, &adev)) +		return AE_OK;  	device = (adr >> 16) & 0xffff;  	function = adr & 0xffff; -	mutex_lock(&acpiphp_context_lock); -	context = acpiphp_init_context(handle); +	acpi_lock_hp_context(); +	context = acpiphp_init_context(adev);  	if (!context) { -		mutex_unlock(&acpiphp_context_lock); +		acpi_unlock_hp_context();  		acpi_handle_err(handle, "No hotplug context\n");  		return AE_NOT_EXIST;  	}  	newfunc = &context->func;  	newfunc->function = function;  	newfunc->parent = bridge; -	mutex_unlock(&acpiphp_context_lock); +	acpi_unlock_hp_context(); -	if (acpi_has_method(handle, "_EJ0")) +	/* +	 * If this is a dock device, its _EJ0 should be executed by the dock +	 * notify handler after calling _DCK. +	 */ +	if (!is_dock_device(adev) && acpi_has_method(handle, "_EJ0"))  		newfunc->flags = FUNC_HAS_EJ0;  	if (acpi_has_method(handle, "_STA"))  		newfunc->flags |= FUNC_HAS_STA; -	if (acpi_has_method(handle, "_DCK")) -		newfunc->flags |= FUNC_HAS_DCK; -  	/* search for objects that share the same slot */  	list_for_each_entry(slot, &bridge->slots, node)  		if (slot->device == device) @@ -314,19 +315,26 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,  	slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);  	if (!slot) { -		status = AE_NO_MEMORY; -		goto err; +		acpi_lock_hp_context(); +		acpiphp_put_context(context); +		acpi_unlock_hp_context(); +		return AE_NO_MEMORY;  	}  	slot->bus = bridge->pci_bus;  	slot->device = device;  	INIT_LIST_HEAD(&slot->funcs); -	mutex_init(&slot->crit_sect);  	list_add_tail(&slot->node, &bridge->slots); -	/* Register slots for ejectable funtions only. */ -	if (acpi_pci_check_ejectable(pbus, handle)  || is_dock_device(handle)) { +	/* +	 * Expose slots to user space for functions that have _EJ0 or _RMV or +	 * are located in dock stations.  Do not expose them for devices handled +	 * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to +	 * expose slots to user space in those cases. +	 */ +	if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) +	    && !(pdev && device_is_managed_by_native_pciehp(pdev))) {  		unsigned long long sun;  		int retval; @@ -335,7 +343,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,  		if (ACPI_FAILURE(status))  			sun = bridge->nr_slots; -		dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", +		pr_debug("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",  		    sun, pci_domain_nr(pbus), pbus->number, device);  		retval = acpiphp_register_hotplug_slot(slot, sun); @@ -343,11 +351,9 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,  			slot->slot = NULL;  			bridge->nr_slots--;  			if (retval == -EBUSY) -				warn("Slot %llu already registered by another " -					"hotplug driver\n", sun); +				pr_warn("Slot %llu already registered by another hotplug driver\n", sun);  			else -				warn("acpiphp_register_hotplug_slot failed " -					"(err code = 0x%x)\n", retval); +				pr_warn("acpiphp_register_hotplug_slot failed (err code = 0x%x)\n", retval);  		}  		/* Even if the slot registration fails, we can still use it. */  	} @@ -360,52 +366,20 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,  				       &val, 60*1000))  		slot->flags |= SLOT_ENABLED; -	if (is_dock_device(handle)) { -		/* we don't want to call this device's _EJ0 -		 * because we want the dock notify handler -		 * to call it after it calls _DCK -		 */ -		newfunc->flags &= ~FUNC_HAS_EJ0; -		if (register_hotplug_dock_device(handle, -			&acpiphp_dock_ops, context, -			acpiphp_dock_init, acpiphp_dock_release)) -			dbg("failed to register dock device\n"); -	} - -	/* install notify handler */ -	if (!(newfunc->flags & FUNC_HAS_DCK)) { -		status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, -						     handle_hotplug_event, -						     context); -		if (ACPI_FAILURE(status)) -			acpi_handle_err(handle, -					"failed to install notify handler\n"); -	} -  	return AE_OK; - - err: -	mutex_lock(&acpiphp_context_lock); -	acpiphp_put_context(context); -	mutex_unlock(&acpiphp_context_lock); -	return status;  } -static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) +static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev)  { -	struct acpiphp_context *context;  	struct acpiphp_bridge *bridge = NULL; -	mutex_lock(&acpiphp_context_lock); -	context = acpiphp_get_context(handle); -	if (context) { -		bridge = context->bridge; +	acpi_lock_hp_context(); +	if (adev->hp) { +		bridge = to_acpiphp_root_context(adev->hp)->root_bridge;  		if (bridge)  			get_bridge(bridge); - -		acpiphp_put_context(context);  	} -	mutex_unlock(&acpiphp_context_lock); +	acpi_unlock_hp_context();  	return bridge;  } @@ -413,23 +387,17 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)  {  	struct acpiphp_slot *slot;  	struct acpiphp_func *func; -	acpi_status status;  	list_for_each_entry(slot, &bridge->slots, node) {  		list_for_each_entry(func, &slot->funcs, sibling) { -			acpi_handle handle = func_to_handle(func); - -			if (is_dock_device(handle)) -				unregister_hotplug_dock_device(handle); +			struct acpi_device *adev = func_to_acpi_device(func); -			if (!(func->flags & FUNC_HAS_DCK)) { -				status = acpi_remove_notify_handler(handle, -							ACPI_SYSTEM_NOTIFY, -							handle_hotplug_event); -				if (ACPI_FAILURE(status)) -					err("failed to remove notify handler\n"); -			} +			acpi_lock_hp_context(); +			adev->hp->notify = NULL; +			adev->hp->fixup = NULL; +			acpi_unlock_hp_context();  		} +		slot->flags |= SLOT_IS_GOING_AWAY;  		if (slot->slot)  			acpiphp_unregister_hotplug_slot(slot);  	} @@ -437,6 +405,10 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)  	mutex_lock(&bridge_mutex);  	list_del(&bridge->list);  	mutex_unlock(&bridge_mutex); + +	acpi_lock_hp_context(); +	bridge->is_going_away = true; +	acpi_unlock_hp_context();  }  /** @@ -445,7 +417,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)   */  static unsigned char acpiphp_max_busnr(struct pci_bus *bus)  { -	struct list_head *tmp; +	struct pci_bus *tmp;  	unsigned char max, n;  	/* @@ -458,41 +430,14 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)  	 */  	max = bus->busn_res.start; -	list_for_each(tmp, &bus->children) { -		n = pci_bus_max_busnr(pci_bus_b(tmp)); +	list_for_each_entry(tmp, &bus->children, node) { +		n = pci_bus_max_busnr(tmp);  		if (n > max)  			max = n;  	}  	return max;  } -/** - * acpiphp_bus_trim - Trim device objects in an ACPI namespace subtree. - * @handle: ACPI device object handle to start from. - */ -static void acpiphp_bus_trim(acpi_handle handle) -{ -	struct acpi_device *adev = NULL; - -	acpi_bus_get_device(handle, &adev); -	if (adev) -		acpi_bus_trim(adev); -} - -/** - * acpiphp_bus_add - Scan ACPI namespace subtree. - * @handle: ACPI object handle to start the scan from. - */ -static void acpiphp_bus_add(acpi_handle handle) -{ -	struct acpi_device *adev = NULL; - -	acpi_bus_scan(handle); -	acpi_bus_get_device(handle, &adev); -	if (adev) -		acpi_device_set_power(adev, ACPI_STATE_D0); -} -  static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)  {  	struct acpiphp_func *func; @@ -532,9 +477,13 @@ static int acpiphp_rescan_slot(struct acpiphp_slot *slot)  {  	struct acpiphp_func *func; -	list_for_each_entry(func, &slot->funcs, sibling) -		acpiphp_bus_add(func_to_handle(func)); +	list_for_each_entry(func, &slot->funcs, sibling) { +		struct acpi_device *adev = func_to_acpi_device(func); +		acpi_bus_scan(adev->handle); +		if (acpi_device_enumerated(adev)) +			acpi_device_set_power(adev, ACPI_STATE_D0); +	}  	return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0));  } @@ -545,24 +494,22 @@ static int acpiphp_rescan_slot(struct acpiphp_slot *slot)   * This function should be called per *physical slot*,   * not per each slot object in ACPI namespace.   */ -static void __ref enable_slot(struct acpiphp_slot *slot) +static void enable_slot(struct acpiphp_slot *slot)  {  	struct pci_dev *dev;  	struct pci_bus *bus = slot->bus;  	struct acpiphp_func *func;  	int max, pass;  	LIST_HEAD(add_list); -	int nr_found; -	nr_found = acpiphp_rescan_slot(slot); +	acpiphp_rescan_slot(slot);  	max = acpiphp_max_busnr(bus);  	for (pass = 0; pass < 2; pass++) {  		list_for_each_entry(dev, &bus->devices, bus_list) {  			if (PCI_SLOT(dev->devfn) != slot->device)  				continue; -			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || -			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { +			if (pci_is_bridge(dev)) {  				max = pci_scan_bridge(bus, dev, max, pass);  				if (pass && dev->subordinate) {  					check_hotplug_bridge(slot, dev); @@ -574,9 +521,6 @@ static void __ref enable_slot(struct acpiphp_slot *slot)  		}  	}  	__pci_bus_assign_resources(bus, &add_list, NULL); -	/* Nothing more to do here if there are no new devices on this bus. */ -	if (!nr_found && (slot->flags & SLOT_ENABLED)) -		return;  	acpiphp_sanitize_bus(bus);  	acpiphp_set_hpp_values(bus); @@ -603,32 +547,15 @@ static void __ref enable_slot(struct acpiphp_slot *slot)  	}  } -/* return first device in slot, acquiring a reference on it */ -static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) -{ -	struct pci_bus *bus = slot->bus; -	struct pci_dev *dev; -	struct pci_dev *ret = NULL; - -	down_read(&pci_bus_sem); -	list_for_each_entry(dev, &bus->devices, bus_list) -		if (PCI_SLOT(dev->devfn) == slot->device) { -			ret = pci_dev_get(dev); -			break; -		} -	up_read(&pci_bus_sem); - -	return ret; -} -  /**   * disable_slot - disable a slot   * @slot: ACPI PHP slot   */  static void disable_slot(struct acpiphp_slot *slot)  { +	struct pci_bus *bus = slot->bus; +	struct pci_dev *dev, *prev;  	struct acpiphp_func *func; -	struct pci_dev *pdev;  	/*  	 * enable_slot() enumerates all functions in this device via @@ -636,17 +563,31 @@ static void disable_slot(struct acpiphp_slot *slot)  	 * methods (_EJ0, etc.) or not.  Therefore, we remove all functions  	 * here.  	 */ -	while ((pdev = dev_in_slot(slot))) { -		pci_stop_and_remove_bus_device(pdev); -		pci_dev_put(pdev); -	} +	list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list) +		if (PCI_SLOT(dev->devfn) == slot->device) +			pci_stop_and_remove_bus_device(dev);  	list_for_each_entry(func, &slot->funcs, sibling) -		acpiphp_bus_trim(func_to_handle(func)); +		acpi_bus_trim(func_to_acpi_device(func));  	slot->flags &= (~SLOT_ENABLED);  } +static bool acpiphp_no_hotplug(struct acpi_device *adev) +{ +	return adev && adev->flags.no_hotplug; +} + +static bool slot_no_hotplug(struct acpiphp_slot *slot) +{ +	struct acpiphp_func *func; + +	list_for_each_entry(func, &slot->funcs, sibling) +		if (acpiphp_no_hotplug(func_to_acpi_device(func))) +			return true; + +	return false; +}  /**   * get_slot_status - get ACPI slot status @@ -690,39 +631,48 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)  	return (unsigned int)sta;  } +static inline bool device_status_valid(unsigned int sta) +{ +	/* +	 * ACPI spec says that _STA may return bit 0 clear with bit 3 set +	 * if the device is valid but does not require a device driver to be +	 * loaded (Section 6.3.7 of ACPI 5.0A). +	 */ +	unsigned int mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING; +	return (sta & mask) == mask; +} +  /**   * trim_stale_devices - remove PCI devices that are not responding.   * @dev: PCI device to start walking the hierarchy from.   */  static void trim_stale_devices(struct pci_dev *dev)  { -	acpi_handle handle = ACPI_HANDLE(&dev->dev); +	struct acpi_device *adev = ACPI_COMPANION(&dev->dev);  	struct pci_bus *bus = dev->subordinate;  	bool alive = false; -	if (handle) { +	if (adev) {  		acpi_status status;  		unsigned long long sta; -		status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); -		alive = ACPI_SUCCESS(status) && sta == ACPI_STA_ALL; +		status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); +		alive = (ACPI_SUCCESS(status) && device_status_valid(sta)) +			|| acpiphp_no_hotplug(adev);  	} -	if (!alive) { -		u32 v; +	if (!alive) +		alive = pci_device_is_present(dev); -		/* Check if the device responds. */ -		alive = pci_bus_read_dev_vendor_id(dev->bus, dev->devfn, &v, 0); -	}  	if (!alive) {  		pci_stop_and_remove_bus_device(dev); -		if (handle) -			acpiphp_bus_trim(handle); +		if (adev) +			acpi_bus_trim(adev);  	} else if (bus) {  		struct pci_dev *child, *tmp;  		/* The device is a bridge. so check the bus below it. */  		pm_runtime_get_sync(&dev->dev); -		list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) +		list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list)  			trim_stale_devices(child);  		pm_runtime_put(&dev->dev); @@ -740,16 +690,20 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)  {  	struct acpiphp_slot *slot; +	/* Bail out if the bridge is going away. */ +	if (bridge->is_going_away) +		return; +  	list_for_each_entry(slot, &bridge->slots, node) {  		struct pci_bus *bus = slot->bus;  		struct pci_dev *dev, *tmp; -		mutex_lock(&slot->crit_sect); -		/* wake up all functions */ -		if (get_slot_status(slot) == ACPI_STA_ALL) { +		if (slot_no_hotplug(slot)) { +			; /* do nothing */ +		} else if (device_status_valid(get_slot_status(slot))) {  			/* remove stale devices if any */ -			list_for_each_entry_safe(dev, tmp, &bus->devices, -						 bus_list) +			list_for_each_entry_safe_reverse(dev, tmp, +							 &bus->devices, bus_list)  				if (PCI_SLOT(dev->devfn) == slot->device)  					trim_stale_devices(dev); @@ -758,7 +712,6 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)  		} else {  			disable_slot(slot);  		} -		mutex_unlock(&slot->crit_sect);  	}  } @@ -780,7 +733,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)  	int i;  	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; -	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { +	list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {  		for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {  			struct resource *res = &dev->resource[i];  			if ((res->flags & type_mask) && !res->start && @@ -798,179 +751,112 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)   * ACPI event handlers   */ -void acpiphp_check_host_bridge(acpi_handle handle) +void acpiphp_check_host_bridge(struct acpi_device *adev)  {  	struct acpiphp_bridge *bridge; -	bridge = acpiphp_handle_to_bridge(handle); +	bridge = acpiphp_dev_to_bridge(adev);  	if (bridge) { +		pci_lock_rescan_remove(); +  		acpiphp_check_bridge(bridge); + +		pci_unlock_rescan_remove();  		put_bridge(bridge);  	}  } -static void hotplug_event(acpi_handle handle, u32 type, void *data) +static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); + +static void hotplug_event(u32 type, struct acpiphp_context *context)  { -	struct acpiphp_context *context = data; +	acpi_handle handle = context->hp.self->handle;  	struct acpiphp_func *func = &context->func; +	struct acpiphp_slot *slot = func->slot;  	struct acpiphp_bridge *bridge; -	char objname[64]; -	struct acpi_buffer buffer = { .length = sizeof(objname), -				      .pointer = objname }; -	mutex_lock(&acpiphp_context_lock); +	acpi_lock_hp_context();  	bridge = context->bridge;  	if (bridge)  		get_bridge(bridge); -	mutex_unlock(&acpiphp_context_lock); +	acpi_unlock_hp_context(); -	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); +	pci_lock_rescan_remove();  	switch (type) {  	case ACPI_NOTIFY_BUS_CHECK:  		/* bus re-enumerate */ -		dbg("%s: Bus check notify on %s\n", __func__, objname); -		dbg("%s: re-enumerating slots under %s\n", __func__, objname); -		if (bridge) { +		acpi_handle_debug(handle, "Bus check in %s()\n", __func__); +		if (bridge)  			acpiphp_check_bridge(bridge); -		} else { -			struct acpiphp_slot *slot = func->slot; - -			mutex_lock(&slot->crit_sect); +		else if (!(slot->flags & SLOT_IS_GOING_AWAY))  			enable_slot(slot); -			mutex_unlock(&slot->crit_sect); -		} +  		break;  	case ACPI_NOTIFY_DEVICE_CHECK:  		/* device check */ -		dbg("%s: Device check notify on %s\n", __func__, objname); +		acpi_handle_debug(handle, "Device check in %s()\n", __func__);  		if (bridge) {  			acpiphp_check_bridge(bridge); -		} else { -			struct acpiphp_slot *slot = func->slot; -			int ret; - +		} else if (!(slot->flags & SLOT_IS_GOING_AWAY)) {  			/*  			 * Check if anything has changed in the slot and rescan  			 * from the parent if that's the case.  			 */ -			mutex_lock(&slot->crit_sect); -			ret = acpiphp_rescan_slot(slot); -			mutex_unlock(&slot->crit_sect); -			if (ret) +			if (acpiphp_rescan_slot(slot))  				acpiphp_check_bridge(func->parent);  		}  		break;  	case ACPI_NOTIFY_EJECT_REQUEST:  		/* request device eject */ -		dbg("%s: Device eject notify on %s\n", __func__, objname); -		acpiphp_disable_and_eject_slot(func->slot); +		acpi_handle_debug(handle, "Eject request in %s()\n", __func__); +		acpiphp_disable_and_eject_slot(slot);  		break;  	} +	pci_unlock_rescan_remove();  	if (bridge)  		put_bridge(bridge);  } -static void hotplug_event_work(struct work_struct *work) +static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type)  {  	struct acpiphp_context *context; -	struct acpi_hp_work *hp_work; - -	hp_work = container_of(work, struct acpi_hp_work, work); -	context = hp_work->context; -	acpi_scan_lock_acquire(); -	hotplug_event(hp_work->handle, hp_work->type, context); +	context = acpiphp_grab_context(adev); +	if (!context) +		return -ENODATA; -	acpi_scan_lock_release(); -	acpi_evaluate_hotplug_ost(hp_work->handle, hp_work->type, -				  ACPI_OST_SC_SUCCESS, NULL); -	kfree(hp_work); /* allocated in handle_hotplug_event() */ -	put_bridge(context->func.parent); +	hotplug_event(type, context); +	acpiphp_let_context_go(context); +	return 0;  }  /** - * handle_hotplug_event - handle ACPI hotplug event - * @handle: Notify()'ed acpi_handle - * @type: Notify code - * @data: pointer to acpiphp_context structure + * acpiphp_enumerate_slots - Enumerate PCI slots for a given bus. + * @bus: PCI bus to enumerate the slots for.   * - * Handles ACPI event notification on slots. - */ -static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) -{ -	struct acpiphp_context *context; -	u32 ost_code = ACPI_OST_SC_SUCCESS; - -	switch (type) { -	case ACPI_NOTIFY_BUS_CHECK: -	case ACPI_NOTIFY_DEVICE_CHECK: -		break; -	case ACPI_NOTIFY_EJECT_REQUEST: -		ost_code = ACPI_OST_SC_EJECT_IN_PROGRESS; -		acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); -		break; - -	case ACPI_NOTIFY_DEVICE_WAKE: -		return; - -	case ACPI_NOTIFY_FREQUENCY_MISMATCH: -		acpi_handle_err(handle, "Device cannot be configured due " -				"to a frequency mismatch\n"); -		goto out; - -	case ACPI_NOTIFY_BUS_MODE_MISMATCH: -		acpi_handle_err(handle, "Device cannot be configured due " -				"to a bus mode mismatch\n"); -		goto out; - -	case ACPI_NOTIFY_POWER_FAULT: -		acpi_handle_err(handle, "Device has suffered a power fault\n"); -		goto out; - -	default: -		acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); -		ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; -		goto out; -	} - -	mutex_lock(&acpiphp_context_lock); -	context = acpiphp_get_context(handle); -	if (context) { -		get_bridge(context->func.parent); -		acpiphp_put_context(context); -		alloc_acpi_hp_work(handle, type, context, hotplug_event_work); -		mutex_unlock(&acpiphp_context_lock); -		return; -	} -	mutex_unlock(&acpiphp_context_lock); -	ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; - - out: -	acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); -} - -/* - * Create hotplug slots for the PCI bus. - * It should always return 0 to avoid skipping following notifiers. + * A "slot" is an object associated with a PCI device number.  All functions + * (PCI devices) with the same bus and device number belong to the same slot.   */  void acpiphp_enumerate_slots(struct pci_bus *bus)  {  	struct acpiphp_bridge *bridge; +	struct acpi_device *adev;  	acpi_handle handle;  	acpi_status status;  	if (acpiphp_disabled)  		return; -	handle = ACPI_HANDLE(bus->bridge); -	if (!handle) +	adev = ACPI_COMPANION(bus->bridge); +	if (!adev)  		return; +	handle = adev->handle;  	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);  	if (!bridge) {  		acpi_handle_err(handle, "No memory for bridge object\n"); @@ -989,45 +875,79 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)  	 */  	get_device(&bus->dev); -	if (!pci_is_root_bus(bridge->pci_bus)) { +	acpi_lock_hp_context(); +	if (pci_is_root_bus(bridge->pci_bus)) { +		struct acpiphp_root_context *root_context; + +		root_context = kzalloc(sizeof(*root_context), GFP_KERNEL); +		if (!root_context) +			goto err; + +		root_context->root_bridge = bridge; +		acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL); +	} else {  		struct acpiphp_context *context;  		/*  		 * This bridge should have been registered as a hotplug function -		 * under its parent, so the context has to be there.  If not, we -		 * are in deep goo. +		 * under its parent, so the context should be there, unless the +		 * parent is going to be handled by pciehp, in which case this +		 * bridge is not interesting to us either.  		 */ -		mutex_lock(&acpiphp_context_lock); -		context = acpiphp_get_context(handle); -		if (WARN_ON(!context)) { -			mutex_unlock(&acpiphp_context_lock); -			put_device(&bus->dev); -			kfree(bridge); -			return; -		} +		context = acpiphp_get_context(adev); +		if (!context) +			goto err; +  		bridge->context = context;  		context->bridge = bridge;  		/* Get a reference to the parent bridge. */  		get_bridge(context->func.parent); -		mutex_unlock(&acpiphp_context_lock);  	} +	acpi_unlock_hp_context(); -	/* must be added to the list prior to calling register_slot */ +	/* Must be added to the list prior to calling acpiphp_add_context(). */  	mutex_lock(&bridge_mutex);  	list_add(&bridge->list, &bridge_list);  	mutex_unlock(&bridge_mutex);  	/* register all slot objects under this bridge */  	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, -				     register_slot, NULL, bridge, NULL); +				     acpiphp_add_context, NULL, bridge, NULL);  	if (ACPI_FAILURE(status)) {  		acpi_handle_err(handle, "failed to register slots\n");  		cleanup_bridge(bridge);  		put_bridge(bridge);  	} +	return; + + err: +	acpi_unlock_hp_context(); +	put_device(&bus->dev); +	pci_dev_put(bridge->pci_dev); +	kfree(bridge);  } -/* Destroy hotplug slots associated with the PCI bus */ +void acpiphp_drop_bridge(struct acpiphp_bridge *bridge) +{ +	if (pci_is_root_bus(bridge->pci_bus)) { +		struct acpiphp_root_context *root_context; +		struct acpi_device *adev; + +		acpi_lock_hp_context(); +		adev = ACPI_COMPANION(bridge->pci_bus->bridge); +		root_context = to_acpiphp_root_context(adev->hp); +		adev->hp = NULL; +		acpi_unlock_hp_context(); +		kfree(root_context); +	} +	cleanup_bridge(bridge); +	put_bridge(bridge); +} + +/** + * acpiphp_remove_slots - Remove slot objects associated with a given bus. + * @bus: PCI bus to remove the slot objects for. + */  void acpiphp_remove_slots(struct pci_bus *bus)  {  	struct acpiphp_bridge *bridge; @@ -1039,8 +959,7 @@ void acpiphp_remove_slots(struct pci_bus *bus)  	list_for_each_entry(bridge, &bridge_list, list)  		if (bridge->pci_bus == bus) {  			mutex_unlock(&bridge_mutex); -			cleanup_bridge(bridge); -			put_bridge(bridge); +			acpiphp_drop_bridge(bridge);  			return;  		} @@ -1053,12 +972,16 @@ void acpiphp_remove_slots(struct pci_bus *bus)   */  int acpiphp_enable_slot(struct acpiphp_slot *slot)  { -	mutex_lock(&slot->crit_sect); +	pci_lock_rescan_remove(); + +	if (slot->flags & SLOT_IS_GOING_AWAY) +		return -ENODEV; +  	/* configure all functions */  	if (!(slot->flags & SLOT_ENABLED))  		enable_slot(slot); -	mutex_unlock(&slot->crit_sect); +	pci_unlock_rescan_remove();  	return 0;  } @@ -1066,12 +989,12 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)   * acpiphp_disable_and_eject_slot - power off and eject slot   * @slot: ACPI PHP slot   */ -int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) +static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)  {  	struct acpiphp_func *func; -	int retval = 0; -	mutex_lock(&slot->crit_sect); +	if (slot->flags & SLOT_IS_GOING_AWAY) +		return -ENODEV;  	/* unconfigure all functions */  	disable_slot(slot); @@ -1086,10 +1009,24 @@ int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)  			break;  		} -	mutex_unlock(&slot->crit_sect); -	return retval; +	return 0;  } +int acpiphp_disable_slot(struct acpiphp_slot *slot) +{ +	int ret; + +	/* +	 * Acquire acpi_scan_lock to ensure that the execution of _EJ0 in +	 * acpiphp_disable_and_eject_slot() will be synchronized properly. +	 */ +	acpi_scan_lock_acquire(); +	pci_lock_rescan_remove(); +	ret = acpiphp_disable_and_eject_slot(slot); +	pci_unlock_rescan_remove(); +	acpi_scan_lock_release(); +	return ret; +}  /*   * slot enabled:  1 @@ -1100,7 +1037,6 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot)  	return (slot->flags & SLOT_ENABLED);  } -  /*   * latch   open:  1   * latch closed:  0 @@ -1110,7 +1046,6 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)  	return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI);  } -  /*   * adapter presence : 1   *          absence : 0 diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 2f5786c8522..8dcccffd6e2 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -25,16 +25,17 @@   *   */ +#define pr_fmt(fmt) "acpiphp_ibm: " fmt +  #include <linux/init.h>  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/kernel.h> -#include <acpi/acpi_bus.h>  #include <linux/sysfs.h>  #include <linux/kobject.h> -#include <asm/uaccess.h>  #include <linux/moduleparam.h>  #include <linux/pci.h> +#include <asm/uaccess.h>  #include "acpiphp.h"  #include "../pci.h" @@ -43,23 +44,11 @@  #define DRIVER_AUTHOR	"Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"  #define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver IBM extension" -static bool debug;  MODULE_AUTHOR(DRIVER_AUTHOR);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL");  MODULE_VERSION(DRIVER_VERSION); -module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, " Debugging mode enabled or not"); -#define MY_NAME "acpiphp_ibm" - -#undef dbg -#define dbg(format, arg...)				\ -do {							\ -	if (debug)					\ -		printk(KERN_DEBUG "%s: " format,	\ -				MY_NAME , ## arg);	\ -} while (0)  #define FOUND_APCI 0x61504349  /* these are the names for the IBM ACPI pseudo-device */ @@ -126,7 +115,7 @@ static struct bin_attribute ibm_apci_table_attr = {  	    .read = ibm_read_apci_table,  	    .write = NULL,  }; -static struct acpiphp_attention_info ibm_attention_info =  +static struct acpiphp_attention_info ibm_attention_info =  {  	.set_attn = ibm_set_attention_status,  	.get_attn = ibm_get_attention_status, @@ -181,15 +170,15 @@ ibm_slot_done:   */  static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)  { -	union acpi_object args[2];  +	union acpi_object args[2];  	struct acpi_object_list params = { .pointer = args, .count = 2 }; -	acpi_status stat;  +	acpi_status stat;  	unsigned long long rc;  	union apci_descriptor *ibm_slot;  	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); -	dbg("%s: set slot %d (%d) attention status to %d\n", __func__, +	pr_debug("%s: set slot %d (%d) attention status to %d\n", __func__,  			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,  			(status ? 1 : 0)); @@ -202,10 +191,10 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)  	stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", ¶ms, &rc);  	if (ACPI_FAILURE(stat)) { -		err("APLS evaluation failed:  0x%08x\n", stat); +		pr_err("APLS evaluation failed:  0x%08x\n", stat);  		return -ENODEV;  	} else if (!rc) { -		err("APLS method failed:  0x%08llx\n", rc); +		pr_err("APLS method failed:  0x%08llx\n", rc);  		return -ERANGE;  	}  	return 0; @@ -218,7 +207,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)   *   * Description: This method is registered with the acpiphp module as a   * callback to do the device specific task of getting the LED status. - *  + *   * Because there is no direct method of getting the LED status directly   * from an ACPI call, we read the aPCI table and parse out our   * slot descriptor to read the status from that. @@ -234,7 +223,7 @@ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)  	else  		*status = 0; -	dbg("%s: get slot %d (%d) attention status is %d\n", __func__, +	pr_debug("%s: get slot %d (%d) attention status is %d\n", __func__,  			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,  			*status); @@ -266,10 +255,10 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context)  	u8 subevent = event & 0xf0;  	struct notification *note = context; -	dbg("%s: Received notification %02x\n", __func__, event); +	pr_debug("%s: Received notification %02x\n", __func__, event);  	if (subevent == 0x80) { -		dbg("%s: generationg bus event\n", __func__); +		pr_debug("%s: generating bus event\n", __func__);  		acpi_bus_generate_netlink_event(note->device->pnp.device_class,  						  dev_name(¬e->device->dev),  						  note->event, detail); @@ -301,7 +290,7 @@ static int ibm_get_table_from_acpi(char **bufp)  	status = acpi_evaluate_object(ibm_acpi_handle, "APCI", NULL, &buffer);  	if (ACPI_FAILURE(status)) { -		err("%s:  APCI evaluation failed\n", __func__); +		pr_err("%s:  APCI evaluation failed\n", __func__);  		return -ENODEV;  	} @@ -309,13 +298,13 @@ static int ibm_get_table_from_acpi(char **bufp)  	if (!(package) ||  			(package->type != ACPI_TYPE_PACKAGE) ||  			!(package->package.elements)) { -		err("%s:  Invalid APCI object\n", __func__); +		pr_err("%s:  Invalid APCI object\n", __func__);  		goto read_table_done;  	}  	for(size = 0, i = 0; i < package->package.count; i++) {  		if (package->package.elements[i].type != ACPI_TYPE_BUFFER) { -			err("%s:  Invalid APCI element %d\n", __func__, i); +			pr_err("%s:  Invalid APCI element %d\n", __func__, i);  			goto read_table_done;  		}  		size += package->package.elements[i].buffer.length; @@ -325,7 +314,7 @@ static int ibm_get_table_from_acpi(char **bufp)  		goto read_table_done;  	lbuf = kzalloc(size, GFP_KERNEL); -	dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n", +	pr_debug("%s: element count: %i, ASL table size: %i, &table = 0x%p\n",  			__func__, package->package.count, size, lbuf);  	if (lbuf) { @@ -370,8 +359,8 @@ static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj,  {  	int bytes_read = -EINVAL;  	char *table = NULL; -	 -	dbg("%s: pos = %d, size = %zd\n", __func__, (int)pos, size); + +	pr_debug("%s: pos = %d, size = %zd\n", __func__, (int)pos, size);  	if (pos == 0) {  		bytes_read = ibm_get_table_from_acpi(&table); @@ -397,13 +386,13 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle,  		u32 lvl, void *context, void **rv)  {  	acpi_handle *phandle = (acpi_handle *)context; -	acpi_status status;  +	acpi_status status;  	struct acpi_device_info *info;  	int retval = 0;  	status = acpi_get_object_info(handle, &info);  	if (ACPI_FAILURE(status)) { -		err("%s:  Failed to get device information status=0x%x\n", +		pr_err("%s:  Failed to get device information status=0x%x\n",  			__func__, status);  		return retval;  	} @@ -411,11 +400,11 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle,  	if (info->current_status && (info->valid & ACPI_VALID_HID) &&  			(!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) ||  			 !strcmp(info->hardware_id.string, IBM_HARDWARE_ID2))) { -		dbg("found hardware: %s, handle: %p\n", +		pr_debug("found hardware: %s, handle: %p\n",  			info->hardware_id.string, handle);  		*phandle = handle;  		/* returning non-zero causes the search to stop -		 * and returns this value to the caller of  +		 * and returns this value to the caller of  		 * acpi_walk_namespace, but it also causes some warnings  		 * in the acpi debug code to print...  		 */ @@ -432,18 +421,18 @@ static int __init ibm_acpiphp_init(void)  	struct acpi_device *device;  	struct kobject *sysdir = &pci_slots_kset->kobj; -	dbg("%s\n", __func__); +	pr_debug("%s\n", __func__);  	if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,  			ACPI_UINT32_MAX, ibm_find_acpi_device, NULL,  			&ibm_acpi_handle, NULL) != FOUND_APCI) { -		err("%s: acpi_walk_namespace failed\n", __func__); +		pr_err("%s: acpi_walk_namespace failed\n", __func__);  		retval = -ENODEV;  		goto init_return;  	} -	dbg("%s: found IBM aPCI device\n", __func__); +	pr_debug("%s: found IBM aPCI device\n", __func__);  	if (acpi_bus_get_device(ibm_acpi_handle, &device)) { -		err("%s: acpi_bus_get_device failed\n", __func__); +		pr_err("%s: acpi_bus_get_device failed\n", __func__);  		retval = -ENODEV;  		goto init_return;  	} @@ -457,7 +446,7 @@ static int __init ibm_acpiphp_init(void)  			ACPI_DEVICE_NOTIFY, ibm_handle_events,  			&ibm_note);  	if (ACPI_FAILURE(status)) { -		err("%s: Failed to register notification handler\n", +		pr_err("%s: Failed to register notification handler\n",  				__func__);  		retval = -EBUSY;  		goto init_cleanup; @@ -479,17 +468,17 @@ static void __exit ibm_acpiphp_exit(void)  	acpi_status status;  	struct kobject *sysdir = &pci_slots_kset->kobj; -	dbg("%s\n", __func__); +	pr_debug("%s\n", __func__);  	if (acpiphp_unregister_attention(&ibm_attention_info)) -		err("%s: attention info deregistration failed", __func__); +		pr_err("%s: attention info deregistration failed", __func__);  	status = acpi_remove_notify_handler(  			   ibm_acpi_handle,  			   ACPI_DEVICE_NOTIFY,  			   ibm_handle_events);  	if (ACPI_FAILURE(status)) -		err("%s: Notification handler removal failed\n", __func__); +		pr_err("%s: Notification handler removal failed\n", __func__);  	/* remove the /sys entries */  	sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr);  } diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 1356211431d..6a0ddf75734 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h @@ -56,9 +56,9 @@ struct cpci_hp_controller_ops {  	int (*enable_irq) (void);  	int (*disable_irq) (void);  	int (*check_irq) (void *dev_id); -	int (*hardware_test) (struct slot* slot, u32 value); -	u8  (*get_power) (struct slot* slot); -	int (*set_power) (struct slot* slot, int value); +	int (*hardware_test) (struct slot *slot, u32 value); +	u8  (*get_power) (struct slot *slot); +	int (*set_power) (struct slot *slot, int value);  };  struct cpci_hp_controller { @@ -89,13 +89,13 @@ int cpci_hp_stop(void);  u8 cpci_get_attention_status(struct slot *slot);  u8 cpci_get_latch_status(struct slot *slot);  u8 cpci_get_adapter_status(struct slot *slot); -u16 cpci_get_hs_csr(struct slot * slot); +u16 cpci_get_hs_csr(struct slot *slot);  int cpci_set_attention_status(struct slot *slot, int status); -int cpci_check_and_clear_ins(struct slot * slot); -int cpci_check_ext(struct slot * slot); -int cpci_clear_ext(struct slot * slot); -int cpci_led_on(struct slot * slot); -int cpci_led_off(struct slot * slot); +int cpci_check_and_clear_ins(struct slot *slot); +int cpci_check_ext(struct slot *slot); +int cpci_clear_ext(struct slot *slot); +int cpci_led_on(struct slot *slot); +int cpci_led_off(struct slot *slot);  int cpci_configure_slot(struct slot *slot);  int cpci_unconfigure_slot(struct slot *slot); diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 2b4c412f94c..e09cf7827d6 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -46,7 +46,7 @@  	do {							\  		if (cpci_debug)					\  			printk (KERN_DEBUG "%s: " format "\n",	\ -				MY_NAME , ## arg); 		\ +				MY_NAME , ## arg);		\  	} while (0)  #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) @@ -65,10 +65,10 @@ static int thread_finished;  static int enable_slot(struct hotplug_slot *slot);  static int disable_slot(struct hotplug_slot *slot);  static int set_attention_status(struct hotplug_slot *slot, u8 value); -static int get_power_status(struct hotplug_slot *slot, u8 * value); -static int get_attention_status(struct hotplug_slot *slot, u8 * value); -static int get_adapter_status(struct hotplug_slot *slot, u8 * value); -static int get_latch_status(struct hotplug_slot *slot, u8 * value); +static int get_power_status(struct hotplug_slot *slot, u8 *value); +static int get_attention_status(struct hotplug_slot *slot, u8 *value); +static int get_adapter_status(struct hotplug_slot *slot, u8 *value); +static int get_latch_status(struct hotplug_slot *slot, u8 *value);  static struct hotplug_slot_ops cpci_hotplug_slot_ops = {  	.enable_slot = enable_slot, @@ -168,7 +168,7 @@ cpci_get_power_status(struct slot *slot)  }  static int -get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) +get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = hotplug_slot->private; @@ -177,7 +177,7 @@ get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)  }  static int -get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) +get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = hotplug_slot->private; @@ -192,14 +192,14 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)  }  static int -get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) +get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	*value = hotplug_slot->info->adapter_status;  	return 0;  }  static int -get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) +get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	*value = hotplug_slot->info->latch_status;  	return 0; @@ -299,6 +299,7 @@ error_slot:  error:  	return status;  } +EXPORT_SYMBOL_GPL(cpci_hp_register_bus);  int  cpci_hp_unregister_bus(struct pci_bus *bus) @@ -329,6 +330,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)  	up_write(&list_rwsem);  	return status;  } +EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);  /* This is the interrupt mode interrupt handler */  static irqreturn_t @@ -360,7 +362,7 @@ static int  init_slots(int clear_ins)  {  	struct slot *slot; -	struct pci_dev* dev; +	struct pci_dev *dev;  	dbg("%s - enter", __func__);  	down_read(&list_rwsem); @@ -614,6 +616,7 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller)  		controller = new_controller;  	return status;  } +EXPORT_SYMBOL_GPL(cpci_hp_register_controller);  static void  cleanup_slots(void) @@ -653,6 +656,7 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)  		status = -ENODEV;  	return status;  } +EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);  int  cpci_hp_start(void) @@ -690,6 +694,7 @@ cpci_hp_start(void)  	dbg("%s - exit", __func__);  	return 0;  } +EXPORT_SYMBOL_GPL(cpci_hp_start);  int  cpci_hp_stop(void) @@ -704,6 +709,7 @@ cpci_hp_stop(void)  	cpci_stop_thread();  	return 0;  } +EXPORT_SYMBOL_GPL(cpci_hp_stop);  int __init  cpci_hotplug_init(int debug) @@ -721,10 +727,3 @@ cpci_hotplug_exit(void)  	cpci_hp_stop();  	cpci_hp_unregister_controller(controller);  } - -EXPORT_SYMBOL_GPL(cpci_hp_register_controller); -EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller); -EXPORT_SYMBOL_GPL(cpci_hp_register_bus); -EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus); -EXPORT_SYMBOL_GPL(cpci_hp_start); -EXPORT_SYMBOL_GPL(cpci_hp_stop); diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index d8add34177f..7d48ecae669 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -39,14 +39,14 @@ extern int cpci_debug;  	do {							\  		if (cpci_debug)					\  			printk (KERN_DEBUG "%s: " format "\n",	\ -				MY_NAME , ## arg); 		\ +				MY_NAME , ## arg);		\  	} while (0)  #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)  #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) -u8 cpci_get_attention_status(struct slot* slot) +u8 cpci_get_attention_status(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -66,7 +66,7 @@ u8 cpci_get_attention_status(struct slot* slot)  	return hs_csr & 0x0008 ? 1 : 0;  } -int cpci_set_attention_status(struct slot* slot, int status) +int cpci_set_attention_status(struct slot *slot, int status)  {  	int hs_cap;  	u16 hs_csr; @@ -93,7 +93,7 @@ int cpci_set_attention_status(struct slot* slot, int status)  	return 1;  } -u16 cpci_get_hs_csr(struct slot* slot) +u16 cpci_get_hs_csr(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -111,7 +111,7 @@ u16 cpci_get_hs_csr(struct slot* slot)  	return hs_csr;  } -int cpci_check_and_clear_ins(struct slot* slot) +int cpci_check_and_clear_ins(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -140,7 +140,7 @@ int cpci_check_and_clear_ins(struct slot* slot)  	return ins;  } -int cpci_check_ext(struct slot* slot) +int cpci_check_ext(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -161,7 +161,7 @@ int cpci_check_ext(struct slot* slot)  	return ext;  } -int cpci_clear_ext(struct slot* slot) +int cpci_clear_ext(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -187,7 +187,7 @@ int cpci_clear_ext(struct slot* slot)  	return 0;  } -int cpci_led_on(struct slot* slot) +int cpci_led_on(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -216,7 +216,7 @@ int cpci_led_on(struct slot* slot)  	return 0;  } -int cpci_led_off(struct slot* slot) +int cpci_led_off(struct slot *slot)  {  	int hs_cap;  	u16 hs_csr; @@ -250,13 +250,16 @@ int cpci_led_off(struct slot* slot)   * Device configuration functions   */ -int __ref cpci_configure_slot(struct slot *slot) +int cpci_configure_slot(struct slot *slot)  {  	struct pci_dev *dev;  	struct pci_bus *parent; +	int ret = 0;  	dbg("%s - enter", __func__); +	pci_lock_rescan_remove(); +  	if (slot->dev == NULL) {  		dbg("pci_dev null, finding %02x:%02x:%x",  		    slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); @@ -277,7 +280,8 @@ int __ref cpci_configure_slot(struct slot *slot)  		slot->dev = pci_get_slot(slot->bus, slot->devfn);  		if (slot->dev == NULL) {  			err("Could not find PCI device for slot %02x", slot->number); -			return -ENODEV; +			ret = -ENODEV; +			goto out;  		}  	}  	parent = slot->dev->bus; @@ -285,8 +289,7 @@ int __ref cpci_configure_slot(struct slot *slot)  	list_for_each_entry(dev, &parent->devices, bus_list)  		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))  			continue; -		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || -		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) +		if (pci_is_bridge(dev))  			pci_hp_add_bridge(dev); @@ -294,11 +297,13 @@ int __ref cpci_configure_slot(struct slot *slot)  	pci_bus_add_devices(parent); + out: +	pci_unlock_rescan_remove();  	dbg("%s - exit", __func__); -	return 0; +	return ret;  } -int cpci_unconfigure_slot(struct slot* slot) +int cpci_unconfigure_slot(struct slot *slot)  {  	struct pci_dev *dev, *temp; @@ -308,6 +313,8 @@ int cpci_unconfigure_slot(struct slot* slot)  		return -ENODEV;  	} +	pci_lock_rescan_remove(); +  	list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {  		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))  			continue; @@ -318,6 +325,8 @@ int cpci_unconfigure_slot(struct slot* slot)  	pci_dev_put(slot->dev);  	slot->dev = NULL; +	pci_unlock_rescan_remove(); +  	dbg("%s - exit", __func__);  	return 0;  } diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index a6a71c41cdf..04fcd781140 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c @@ -13,14 +13,14 @@   * option) any later version.   *   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY  - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR  - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   *   * You should have received a copy of the GNU General Public License along @@ -53,9 +53,9 @@  #define dbg(format, arg...)					\  	do {							\ -		if(debug)					\ +		if (debug)					\  			printk (KERN_DEBUG "%s: " format "\n",	\ -				MY_NAME , ## arg); 		\ +				MY_NAME , ## arg);		\  	} while(0)  #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) @@ -78,8 +78,8 @@ static struct cpci_hp_controller generic_hpc;  static int __init validate_parameters(void)  { -	char* str; -	char* p; +	char *str; +	char *p;  	unsigned long tmp;  	if(!bridge) { @@ -142,8 +142,8 @@ static int query_enum(void)  static int __init cpcihp_generic_init(void)  {  	int status; -	struct resource* r; -	struct pci_dev* dev; +	struct resource *r; +	struct pci_dev *dev;  	info(DRIVER_DESC " version: " DRIVER_VERSION);  	status = validate_parameters(); diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index 449b4bbc830..6757b3ef7e1 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c @@ -13,14 +13,14 @@   * option) any later version.   *   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY  - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR  - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   *   * You should have received a copy of the GNU General Public License along @@ -48,9 +48,9 @@  #define dbg(format, arg...)					\  	do {							\ -		if(debug)					\ +		if (debug)					\  			printk (KERN_DEBUG "%s: " format "\n",	\ -				MY_NAME , ## arg); 		\ +				MY_NAME , ## arg);		\  	} while(0)  #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) @@ -285,7 +285,7 @@ static struct pci_device_id zt5550_hc_pci_tbl[] = {  	{ 0, }  };  MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl); -	 +  static struct pci_driver zt5550_hc_driver = {  	.name		= "zt5550_hc",  	.id_table	= zt5550_hc_pci_tbl, @@ -295,7 +295,7 @@ static struct pci_driver zt5550_hc_driver = {  static int __init zt5550_init(void)  { -	struct resource* r; +	struct resource *r;  	int rc;  	info(DRIVER_DESC " version: " DRIVER_VERSION); diff --git a/drivers/pci/hotplug/cpcihp_zt5550.h b/drivers/pci/hotplug/cpcihp_zt5550.h index bebc6060a55..9a57fda5348 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.h +++ b/drivers/pci/hotplug/cpcihp_zt5550.h @@ -13,14 +13,14 @@   * option) any later version.   *   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY  - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR  - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   *   * You should have received a copy of the GNU General Public License along @@ -55,7 +55,7 @@  #define HC_CMD_REG		0x0C  #define ARB_CONFIG_GNT_REG	0x10  #define ARB_CONFIG_CFG_REG	0x12 -#define ARB_CONFIG_REG	 	0x10 +#define ARB_CONFIG_REG		0x10  #define ISOL_CONFIG_REG		0x18  #define FAULT_STATUS_REG	0x20  #define FAULT_CONFIG_REG	0x24 diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 516b87738b6..0450f405807 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -255,7 +255,7 @@ struct pci_func {  	struct pci_resource *io_head;  	struct pci_resource *bus_head;  	struct timer_list *p_task_event; -	struct pci_dev* pci_dev; +	struct pci_dev *pci_dev;  };  struct slot { @@ -278,7 +278,7 @@ struct slot {  };  struct pci_resource { -	struct pci_resource * next; +	struct pci_resource *next;  	u32 base;  	u32 length;  }; diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index c8eaeb43fa5..4aaee746df8 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -94,7 +94,7 @@ static inline int is_slot66mhz(struct slot *slot)   *   * Returns pointer to the head of the SMBIOS tables (or %NULL).   */ -static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end) +static void __iomem *detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)  {  	void __iomem *fp;  	void __iomem *endp; @@ -131,7 +131,7 @@ static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *e   *   * For unexpected switch opens   */ -static int init_SERR(struct controller * ctrl) +static int init_SERR(struct controller *ctrl)  {  	u32 tempdword;  	u32 number_of_slots; @@ -291,7 +291,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)  	kfree(slot);  } -static int ctrl_slot_cleanup (struct controller * ctrl) +static int ctrl_slot_cleanup (struct controller *ctrl)  {  	struct slot *old_slot, *next_slot; @@ -706,8 +706,7 @@ static int ctrl_slot_setup(struct controller *ctrl,  		hotplug_slot_info->adapter_status =  			get_presence_status(ctrl, slot); -		dbg("registering bus %d, dev %d, number %d, " -				"ctrl->slot_device_offset %d, slot %d\n", +		dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n",  				slot->bus, slot->device,  				slot->number, ctrl->slot_device_offset,  				slot_number); @@ -837,8 +836,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	bus = pdev->subordinate;  	if (!bus) { -		dev_notice(&pdev->dev, "the device is not a bridge, " -				"skipping\n"); +		dev_notice(&pdev->dev, "the device is not a bridge, skipping\n");  		rc = -ENODEV;  		goto err_disable_device;  	} @@ -862,10 +860,10 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		goto err_disable_device;  	} -	/* Check for the proper subsystem ID's +	/* Check for the proper subsystem IDs  	 * Intel uses a different SSID programming model than Compaq.  	 * For Intel, each SSID bit identifies a PHP capability. -	 * Also Intel HPC's may have RID=0. +	 * Also Intel HPCs may have RID=0.  	 */  	if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {  		err(msg_HPC_not_supported); @@ -920,12 +918,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  				bus->max_bus_speed = PCI_SPEED_100MHz_PCIX;  				break;  			} -			if (bus_cap & 20) { +			if (bus_cap & 0x20) {  				dbg("bus max supports 66MHz PCI-X\n");  				bus->max_bus_speed = PCI_SPEED_66MHz_PCIX;  				break;  			} -			if (bus_cap & 10) { +			if (bus_cap & 0x10) {  				dbg("bus max supports 66MHz PCI\n");  				bus->max_bus_speed = PCI_SPEED_66MHz;  				break; diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index d282019cda5..bde47fce324 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -39,9 +39,9 @@  #include <linux/kthread.h>  #include "cpqphp.h" -static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, +static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,  			u8 behind_bridge, struct resource_lists *resources); -static int configure_new_function(struct controller* ctrl, struct pci_func *func, +static int configure_new_function(struct controller *ctrl, struct pci_func *func,  			u8 behind_bridge, struct resource_lists *resources);  static void interrupt_event_handler(struct controller *ctrl); @@ -64,7 +64,7 @@ static void long_delay(int delay)  /* FIXME: The following line needs to be somewhere else... */  #define WRONG_BUS_FREQUENCY 0x07 -static u8 handle_switch_change(u8 change, struct controller * ctrl) +static u8 handle_switch_change(u8 change, struct controller *ctrl)  {  	int hp_slot;  	u8 rc = 0; @@ -138,7 +138,7 @@ static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)  } -static u8 handle_presence_change(u16 change, struct controller * ctrl) +static u8 handle_presence_change(u16 change, struct controller *ctrl)  {  	int hp_slot;  	u8 rc = 0; @@ -232,7 +232,7 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)  } -static u8 handle_power_fault(u8 change, struct controller * ctrl) +static u8 handle_power_fault(u8 change, struct controller *ctrl)  {  	int hp_slot;  	u8 rc = 0; @@ -709,7 +709,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz  				temp = temp->next;  			} -			temp->next = max->next; +			if (temp) +				temp->next = max->next;  		}  		max->next = NULL; @@ -996,7 +997,7 @@ struct pci_func *cpqhp_slot_create(u8 busnumber)   *   * Returns %0 if successful, !0 otherwise.   */ -static int slot_remove(struct pci_func * old_slot) +static int slot_remove(struct pci_func *old_slot)  {  	struct pci_func *next; @@ -1108,7 +1109,7 @@ struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)  /* DJZ: I don't think is_bridge will work as is.   * FIXME */ -static int is_bridge(struct pci_func * func) +static int is_bridge(struct pci_func *func)  {  	/* Check the header type */  	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01) @@ -1231,7 +1232,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_  	/* Only if mode change...*/  	if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || -		((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))  +		((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))  			set_SOGO(ctrl);  	wait_for_ctrl_irq(ctrl); @@ -1624,7 +1625,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)   * @replace_flag: whether replacing or adding a new device   * @ctrl: target controller   */ -static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl) +static u32 remove_board(struct pci_func *func, u32 replace_flag, struct controller *ctrl)  {  	int index;  	u8 skip = 0; @@ -1741,7 +1742,7 @@ static void pushbutton_helper_thread(unsigned long data)  /* this is the main worker thread */ -static int event_thread(void* data) +static int event_thread(void *data)  {  	struct controller *ctrl; @@ -1828,7 +1829,7 @@ static void interrupt_event_handler(struct controller *ctrl)  				if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {  					dbg("button pressed\n"); -				} else if (ctrl->event_queue[loop].event_type ==  +				} else if (ctrl->event_queue[loop].event_type ==  					   INT_BUTTON_CANCEL) {  					dbg("button cancel\n");  					del_timer(&p_slot->task_event); @@ -1991,7 +1992,7 @@ int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func)  	u16 temp_word;  	u32 tempdword;  	int rc; -	struct slot* p_slot; +	struct slot *p_slot;  	int physical_slot = 0;  	tempdword = 0; @@ -2087,7 +2088,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)  	u8 replace_flag;  	u32 rc = 0;  	unsigned int devfn; -	struct slot* p_slot; +	struct slot *p_slot;  	struct pci_bus *pci_bus = ctrl->pci_bus;  	int physical_slot=0; @@ -2269,8 +2270,8 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)   *   * Returns 0 if success.   */ -static u32 configure_new_device(struct controller * ctrl, struct pci_func * func, -				 u8 behind_bridge, struct resource_lists * resources) +static u32 configure_new_device(struct controller  *ctrl, struct pci_func  *func, +				 u8 behind_bridge, struct resource_lists  *resources)  {  	u8 temp_byte, function, max_functions, stop_it;  	int rc; @@ -2411,11 +2412,11 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func  		if (rc)  			return rc; -		/* find range of busses to use */ +		/* find range of buses to use */  		dbg("find ranges of buses to use\n");  		bus_node = get_max_resource(&(resources->bus_head), 1); -		/* If we don't have any busses to allocate, we can't continue */ +		/* If we don't have any buses to allocate, we can't continue */  		if (!bus_node)  			return -ENOMEM; @@ -2900,7 +2901,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func  			/* If this function needs an interrupt and we are behind  			 * a bridge and the pin is tied to something that's -			 * alread mapped, set this one the same */ +			 * already mapped, set this one the same */  			if (temp_byte && resources->irqs &&  			    (resources->irqs->valid_INT &  			     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index 76ba8a1c774..0968a9bcb34 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c @@ -34,7 +34,6 @@  #include <linux/workqueue.h>  #include <linux/pci.h>  #include <linux/pci_hotplug.h> -#include <linux/init.h>  #include <asm/uaccess.h>  #include "cpqphp.h"  #include "cpqphp_nvram.h" @@ -108,7 +107,7 @@ static spinlock_t int15_lock;   */ -static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail) +static u32 add_byte(u32 **p_buffer, u8 value, u32 *used, u32 *avail)  {  	u8 **tByte; @@ -123,7 +122,7 @@ static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)  } -static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail) +static u32 add_dword(u32 **p_buffer, u32 value, u32 *used, u32 *avail)  {  	if ((*used + 4) > *avail)  		return(1); @@ -268,12 +267,12 @@ static u32 store_HRT (void __iomem *rom_start)  	ctrl = cpqhp_ctrl_list;  	/* The revision of this structure */ -	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available); +	rc = add_byte(&pFill, 1 + ctrl->push_flag, &usedbytes, &available);  	if (rc)  		return(rc);  	/* The number of controllers */ -	rc = add_byte( &pFill, 1, &usedbytes, &available); +	rc = add_byte(&pFill, 1, &usedbytes, &available);  	if (rc)  		return(rc); @@ -283,22 +282,22 @@ static u32 store_HRT (void __iomem *rom_start)  		numCtrl++;  		/* The bus number */ -		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available); +		rc = add_byte(&pFill, ctrl->bus, &usedbytes, &available);  		if (rc)  			return(rc);  		/* The device Number */ -		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available); +		rc = add_byte(&pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);  		if (rc)  			return(rc);  		/* The function Number */ -		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available); +		rc = add_byte(&pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);  		if (rc)  			return(rc);  		/* Skip the number of available entries */ -		rc = add_dword( &pFill, 0, &usedbytes, &available); +		rc = add_dword(&pFill, 0, &usedbytes, &available);  		if (rc)  			return(rc); @@ -312,12 +311,12 @@ static u32 store_HRT (void __iomem *rom_start)  			loop ++;  			/* base */ -			rc = add_dword( &pFill, resNode->base, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);  			if (rc)  				return(rc);  			/* length */ -			rc = add_dword( &pFill, resNode->length, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);  			if (rc)  				return(rc); @@ -337,12 +336,12 @@ static u32 store_HRT (void __iomem *rom_start)  			loop ++;  			/* base */ -			rc = add_dword( &pFill, resNode->base, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);  			if (rc)  				return(rc);  			/* length */ -			rc = add_dword( &pFill, resNode->length, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);  			if (rc)  				return(rc); @@ -362,12 +361,12 @@ static u32 store_HRT (void __iomem *rom_start)  			loop ++;  			/* base */ -			rc = add_dword( &pFill, resNode->base, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);  			if (rc)  				return(rc);  			/* length */ -			rc = add_dword( &pFill, resNode->length, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);  			if (rc)  				return(rc); @@ -387,12 +386,12 @@ static u32 store_HRT (void __iomem *rom_start)  			loop ++;  			/* base */ -			rc = add_dword( &pFill, resNode->base, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);  			if (rc)  				return(rc);  			/* length */ -			rc = add_dword( &pFill, resNode->length, &usedbytes, &available); +			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);  			if (rc)  				return(rc); diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 09801c6945c..1c8c2f130d3 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -81,11 +81,13 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom  } -int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) +int cpqhp_configure_device (struct controller *ctrl, struct pci_func *func)  {  	struct pci_bus *child;  	int num; +	pci_lock_rescan_remove(); +  	if (func->pci_dev == NULL)  		func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function)); @@ -100,7 +102,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  		func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));  		if (func->pci_dev == NULL) {  			dbg("ERROR: pci_dev still null\n"); -			return 0; +			goto out;  		}  	} @@ -113,23 +115,27 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  	pci_dev_put(func->pci_dev); + out: +	pci_unlock_rescan_remove();  	return 0;  } -int cpqhp_unconfigure_device(struct pci_func* func) +int cpqhp_unconfigure_device(struct pci_func *func)  {  	int j;  	dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); +	pci_lock_rescan_remove();  	for (j=0; j<8 ; j++) { -		struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); +		struct pci_dev *temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));  		if (temp) {  			pci_dev_put(temp);  			pci_stop_and_remove_bus_device(temp);  		}  	} +	pci_unlock_rescan_remove();  	return 0;  } @@ -197,7 +203,7 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)  } -static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num) +static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_num)  {  	u16 tdevice;  	u32 work; @@ -274,7 +280,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num  } -int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot) +int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot)  {  	/* plain (bridges allowed) */  	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); @@ -291,7 +297,7 @@ int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 s   *   * Reads configuration for all slots in a PCI bus and saves info.   * - * Note:  For non-hot plug busses, the slot # saved is the device # + * Note:  For non-hot plug buses, the slot # saved is the device #   *   * returns 0 if success   */ @@ -455,11 +461,11 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)   * cpqhp_save_slot_config   *   * Saves configuration info for all PCI devices in a given slot - * including subordinate busses. + * including subordinate buses.   *   * returns 0 if success   */ -int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) +int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func *new_slot)  {  	long rc;  	u8 class_code; @@ -543,7 +549,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)   *   * returns 0 if success   */ -int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) +int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)  {  	u8 cloop;  	u8 header_type; @@ -680,7 +686,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)   *   * returns 0 if success   */ -int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) +int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func *func)  {  	u8 cloop;  	u8 header_type; @@ -943,7 +949,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)   *   * returns 0 if success   */ -int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) +int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)  {  	int cloop;  	u8 header_type; @@ -1021,7 +1027,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)   *   * returns 0 if the board is the same nonzero otherwise   */ -int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) +int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)  {  	u8 cloop;  	u8 header_type; @@ -1413,7 +1419,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st   *   * returns 0 if success   */ -int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources) +int cpqhp_return_board_resources(struct pci_func *func, struct resource_lists *resources)  {  	int rc = 0;  	struct pci_resource *node; @@ -1469,7 +1475,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists *   *   * Puts node back in the resource list pointed to by head   */ -void cpqhp_destroy_resource_list (struct resource_lists * resources) +void cpqhp_destroy_resource_list (struct resource_lists *resources)  {  	struct pci_resource *res, *tres; @@ -1516,7 +1522,7 @@ void cpqhp_destroy_resource_list (struct resource_lists * resources)   *   * Puts node back in the resource list pointed to by head   */ -void cpqhp_destroy_board_resources (struct pci_func * func) +void cpqhp_destroy_board_resources (struct pci_func *func)  {  	struct pci_resource *res, *tres; @@ -1556,4 +1562,3 @@ void cpqhp_destroy_board_resources (struct pci_func * func)  		kfree(tres);  	}  } - diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 17c1f36315d..4a392c44e3d 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -79,7 +79,7 @@ static int show_ctrl (struct controller *ctrl, char *buf)  static int show_dev (struct controller *ctrl, char *buf)  { -	char * out = buf; +	char *out = buf;  	int index;  	struct pci_resource *res;  	struct pci_func *new_slot; diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index 8c5b25871d0..e3e46a7b3ee 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h @@ -59,7 +59,7 @@ extern int ibmphp_debug;  /************************************************************ -*  RESOURE TYPE                                             * +*  RESOURCE TYPE                                             *  ************************************************************/  #define EBDA_RSRC_TYPE_MASK		0x03 @@ -103,7 +103,7 @@ extern int ibmphp_debug;  //--------------------------------------------------------------  struct rio_table_hdr { -	u8 ver_num;  +	u8 ver_num;  	u8 scal_count;  	u8 riodev_count;  	u16 offset; @@ -127,7 +127,7 @@ struct scal_detail {  };  //-------------------------------------------------------------- -// RIO DETAIL  +// RIO DETAIL  //--------------------------------------------------------------  struct rio_detail { @@ -152,7 +152,7 @@ struct opt_rio {  	u8 first_slot_num;  	u8 middle_num;  	struct list_head opt_rio_list; -};	 +};  struct opt_rio_lo {  	u8 rio_type; @@ -161,7 +161,7 @@ struct opt_rio_lo {  	u8 middle_num;  	u8 pack_count;  	struct list_head opt_rio_lo_list; -};	 +};  /****************************************************************  *  HPC DESCRIPTOR NODE                                          * @@ -574,7 +574,7 @@ void ibmphp_hpc_stop_poll_thread(void);  #define HPC_CTLR_IRQ_PENDG	0x80  //---------------------------------------------------------------------------- -// HPC_CTLR_WROKING status return codes +// HPC_CTLR_WORKING status return codes  //----------------------------------------------------------------------------  #define HPC_CTLR_WORKING_NO	0x00  #define HPC_CTLR_WORKING_YES	0x01 diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index cbd72d81d25..f7b8684a773 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -58,7 +58,7 @@ MODULE_DESCRIPTION (DRIVER_DESC);  struct pci_bus *ibmphp_pci_bus;  static int max_slots; -static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS +static int irqs[16];    /* PIC mode IRQs we're using so far (in case MPS  			 * tables don't provide default info for empty slots */  static int init_flag; @@ -71,20 +71,20 @@ static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)  	return get_max_adapter_speed_1 (hs, value, 1);  }  */ -static inline int get_cur_bus_info(struct slot **sl)  +static inline int get_cur_bus_info(struct slot **sl)  {  	int rc = 1; -	struct slot * slot_cur = *sl; +	struct slot *slot_cur = *sl;  	debug("options = %x\n", slot_cur->ctrl->options); -	debug("revision = %x\n", slot_cur->ctrl->revision);	 +	debug("revision = %x\n", slot_cur->ctrl->revision); -	if (READ_BUS_STATUS(slot_cur->ctrl))  +	if (READ_BUS_STATUS(slot_cur->ctrl))  		rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL); -	 -	if (rc)  + +	if (rc)  		return rc; -	   +  	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);  	if (READ_BUS_MODE(slot_cur->ctrl))  		slot_cur->bus_on->current_bus_mode = @@ -96,7 +96,7 @@ static inline int get_cur_bus_info(struct slot **sl)  			slot_cur->busstatus,  			slot_cur->bus_on->current_speed,  			slot_cur->bus_on->current_bus_mode); -	 +  	*sl = slot_cur;  	return 0;  } @@ -104,8 +104,8 @@ static inline int get_cur_bus_info(struct slot **sl)  static inline int slot_update(struct slot **sl)  {  	int rc; - 	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL); -	if (rc)  +	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL); +	if (rc)  		return rc;  	if (!init_flag)  		rc = get_cur_bus_info(sl); @@ -114,8 +114,8 @@ static inline int slot_update(struct slot **sl)  static int __init get_max_slots (void)  { -	struct slot * slot_cur; -	struct list_head * tmp; +	struct slot *slot_cur; +	struct list_head *tmp;  	u8 slot_count = 0;  	list_for_each(tmp, &ibmphp_slot_head) { @@ -172,7 +172,7 @@ int ibmphp_init_devno(struct slot **cur_slot)  			debug("(*cur_slot)->irq[3] = %x\n",  					(*cur_slot)->irq[3]); -			debug("rtable->exlusive_irqs = %x\n", +			debug("rtable->exclusive_irqs = %x\n",  					rtable->exclusive_irqs);  			debug("rtable->slots[loop].irq[0].bitmap = %x\n",  					rtable->slots[loop].irq[0].bitmap); @@ -271,7 +271,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)  			else  				rc = -ENODEV;  		} -	} else	 +	} else  		rc = -ENODEV;  	ibmphp_unlock_operations(); @@ -280,7 +280,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)  	return rc;  } -static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -288,7 +288,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)  	debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",  					(ulong) hotplug_slot, (ulong) value); -         +  	ibmphp_lock_operations();  	if (hotplug_slot) {  		pslot = hotplug_slot->private; @@ -311,7 +311,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)  	return rc;  } -static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -338,7 +338,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)  } -static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -364,7 +364,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)  	return rc;  } -static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -406,14 +406,14 @@ static int get_max_bus_speed(struct slot *slot)  	ibmphp_lock_operations();  	mode = slot->supported_bus_mode; -	speed = slot->supported_speed;  +	speed = slot->supported_speed;  	ibmphp_unlock_operations();  	switch (speed) {  	case BUS_SPEED_33:  		break;  	case BUS_SPEED_66: -		if (mode == BUS_MODE_PCIX)  +		if (mode == BUS_MODE_PCIX)  			speed += 0x01;  		break;  	case BUS_SPEED_100: @@ -433,7 +433,7 @@ static int get_max_bus_speed(struct slot *slot)  }  /* -static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag) +static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 *value, u8 flag)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -471,7 +471,7 @@ static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value  	return rc;  } -static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value) +static int get_bus_name(struct hotplug_slot *hotplug_slot, char *value)  {  	int rc = -ENODEV;  	struct slot *pslot = NULL; @@ -515,13 +515,13 @@ static int __init init_ops(void)  		debug("BEFORE GETTING SLOT STATUS, slot # %x\n",  							slot_cur->number); -		if (slot_cur->ctrl->revision == 0xFF)  +		if (slot_cur->ctrl->revision == 0xFF)  			if (get_ctrl_revision(slot_cur,  						&slot_cur->ctrl->revision))  				return -1; -		if (slot_cur->bus_on->current_speed == 0xFF)  -			if (get_cur_bus_info(&slot_cur))  +		if (slot_cur->bus_on->current_speed == 0xFF) +			if (get_cur_bus_info(&slot_cur))  				return -1;  		get_max_bus_speed(slot_cur); @@ -539,8 +539,8 @@ static int __init init_ops(void)  		debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));  		debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status)); -		if ((SLOT_PWRGD(slot_cur->status)) &&  -		    !(SLOT_PRESENT(slot_cur->status)) &&  +		if ((SLOT_PWRGD(slot_cur->status)) && +		    !(SLOT_PRESENT(slot_cur->status)) &&  		    !(SLOT_LATCH(slot_cur->status))) {  			debug("BEFORE POWER OFF COMMAND\n");  				rc = power_off(slot_cur); @@ -581,13 +581,13 @@ static int validate(struct slot *slot_cur, int opn)  	switch (opn) {  		case ENABLE: -			if (!(SLOT_PWRGD(slot_cur->status)) &&  -			     (SLOT_PRESENT(slot_cur->status)) &&  +			if (!(SLOT_PWRGD(slot_cur->status)) && +			     (SLOT_PRESENT(slot_cur->status)) &&  			     !(SLOT_LATCH(slot_cur->status)))  				return 0;  			break;  		case DISABLE: -			if ((SLOT_PWRGD(slot_cur->status)) &&  +			if ((SLOT_PWRGD(slot_cur->status)) &&  			    (SLOT_PRESENT(slot_cur->status)) &&  			    !(SLOT_LATCH(slot_cur->status)))  				return 0; @@ -617,7 +617,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  		err("out of system memory\n");  		return -ENOMEM;  	} -         +  	info->power_status = SLOT_PWRGD(slot_cur->status);  	info->attention_status = SLOT_ATTN(slot_cur->status,  						slot_cur->ext_status); @@ -638,7 +638,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  		case BUS_SPEED_33:  			break;  		case BUS_SPEED_66: -			if (mode == BUS_MODE_PCIX)  +			if (mode == BUS_MODE_PCIX)  				bus_speed += 0x01;  			else if (mode == BUS_MODE_PCI)  				; @@ -654,8 +654,8 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  	}  	bus->cur_bus_speed = bus_speed; -	// To do: bus_names  -	 +	// To do: bus_names +  	rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);  	kfree(info);  	return rc; @@ -671,7 +671,7 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)  {  	struct pci_func *func_cur;  	struct slot *slot_cur; -	struct list_head * tmp; +	struct list_head *tmp;  	list_for_each(tmp, &ibmphp_slot_head) {  		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);  		if (slot_cur->func) { @@ -696,8 +696,8 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)  static void free_slots(void)  {  	struct slot *slot_cur; -	struct list_head * tmp; -	struct list_head * next; +	struct list_head *tmp; +	struct list_head *next;  	debug("%s -- enter\n", __func__); @@ -718,6 +718,8 @@ static void ibm_unconfigure_device(struct pci_func *func)  					func->device, func->function);  	debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0); +	pci_lock_rescan_remove(); +  	for (j = 0; j < 0x08; j++) {  		temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);  		if (temp) { @@ -725,12 +727,15 @@ static void ibm_unconfigure_device(struct pci_func *func)  			pci_dev_put(temp);  		}  	} +  	pci_dev_put(func->dev); + +	pci_unlock_rescan_remove();  }  /* - * The following function is to fix kernel bug regarding  - * getting bus entries, here we manually add those primary  + * The following function is to fix kernel bug regarding + * getting bus entries, here we manually add those primary   * bus entries to kernel bus structure whenever apply   */  static u8 bus_structure_fixup(u8 busno) @@ -780,6 +785,8 @@ static int ibm_configure_device(struct pci_func *func)  	int flag = 0;	/* this is to make sure we don't double scan the bus,  					for bridged devices primarily */ +	pci_lock_rescan_remove(); +  	if (!(bus_structure_fixup(func->busno)))  		flag = 1;  	if (func->dev == NULL) @@ -789,7 +796,7 @@ static int ibm_configure_device(struct pci_func *func)  	if (func->dev == NULL) {  		struct pci_bus *bus = pci_find_bus(0, func->busno);  		if (!bus) -			return 0; +			goto out;  		num = pci_scan_slot(bus,  				PCI_DEVFN(func->device, func->function)); @@ -800,7 +807,7 @@ static int ibm_configure_device(struct pci_func *func)  				PCI_DEVFN(func->device, func->function));  		if (func->dev == NULL) {  			err("ERROR... : pci_dev still NULL\n"); -			return 0; +			goto out;  		}  	}  	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { @@ -810,16 +817,18 @@ static int ibm_configure_device(struct pci_func *func)  			pci_bus_add_devices(child);  	} + out: +	pci_unlock_rescan_remove();  	return 0;  }  /******************************************************* - * Returns whether the bus is empty or not  + * Returns whether the bus is empty or not   *******************************************************/ -static int is_bus_empty(struct slot * slot_cur) +static int is_bus_empty(struct slot *slot_cur)  {  	int rc; -	struct slot * tmp_slot; +	struct slot *tmp_slot;  	u8 i = slot_cur->bus_on->slot_min;  	while (i <= slot_cur->bus_on->slot_max) { @@ -842,12 +851,12 @@ static int is_bus_empty(struct slot * slot_cur)  }  /*********************************************************** - * If the HPC permits and the bus currently empty, tries to set the  + * If the HPC permits and the bus currently empty, tries to set the   * bus speed and mode at the maximum card and bus capability   * Parameters: slot   * Returns: bus is set (0) or error code   ***********************************************************/ -static int set_bus(struct slot * slot_cur) +static int set_bus(struct slot *slot_cur)  {  	int rc;  	u8 speed; @@ -856,7 +865,7 @@ static int set_bus(struct slot * slot_cur)  	static struct pci_device_id ciobx[] = {  		{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },  	        { }, -	};	 +	};  	debug("%s - entry slot # %d\n", __func__, slot_cur->number);  	if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) { @@ -877,7 +886,7 @@ static int set_bus(struct slot * slot_cur)  				else if (!SLOT_BUS_MODE(slot_cur->ext_status))  					/* if max slot/bus capability is 66 pci  					and there's no bus mode mismatch, then -					the adapter supports 66 pci */  +					the adapter supports 66 pci */  					cmd = HPC_BUS_66CONVMODE;  				else  					cmd = HPC_BUS_33CONVMODE; @@ -930,7 +939,7 @@ static int set_bus(struct slot * slot_cur)  			return -EIO;  		}  	} -	/* This is for x440, once Brandon fixes the firmware,  +	/* This is for x440, once Brandon fixes the firmware,  	will not need this delay */  	msleep(1000);  	debug("%s -Exit\n", __func__); @@ -938,16 +947,16 @@ static int set_bus(struct slot * slot_cur)  }  /* This routine checks the bus limitations that the slot is on from the BIOS. - * This is used in deciding whether or not to power up the slot.   + * This is used in deciding whether or not to power up the slot.   * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on - * same bus)  + * same bus)   * Parameters: slot   * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus   */  static int check_limitations(struct slot *slot_cur)  {  	u8 i; -	struct slot * tmp_slot; +	struct slot *tmp_slot;  	u8 count = 0;  	u8 limitation = 0; @@ -986,7 +995,7 @@ static int check_limitations(struct slot *slot_cur)  static inline void print_card_capability(struct slot *slot_cur)  {  	info("capability of the card is "); -	if ((slot_cur->ext_status & CARD_INFO) == PCIX133)  +	if ((slot_cur->ext_status & CARD_INFO) == PCIX133)  		info("   133 MHz PCI-X\n");  	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)  		info("    66 MHz PCI-X\n"); @@ -1020,7 +1029,7 @@ static int enable_slot(struct hotplug_slot *hs)  	}  	attn_LED_blink(slot_cur); -	 +  	rc = set_bus(slot_cur);  	if (rc) {  		err("was not able to set the bus\n"); @@ -1036,8 +1045,7 @@ static int enable_slot(struct hotplug_slot *hs)  	rc = check_limitations(slot_cur);  	if (rc) {  		err("Adding this card exceeds the limitations of this bus.\n"); -		err("(i.e., >1 133MHz cards running on same bus, or " -		     ">2 66 PCI cards running on same bus.\n"); +		err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");  		err("Try hot-adding into another bus\n");  		rc = -EINVAL;  		goto error_nopower; @@ -1061,12 +1069,10 @@ static int enable_slot(struct hotplug_slot *hs)  					!(SLOT_PWRGD(slot_cur->status)))  			err("power fault occurred trying to power up\n");  		else if (SLOT_BUS_SPEED(slot_cur->status)) { -			err("bus speed mismatch occurred.  please check " -				"current bus speed and card capability\n"); +			err("bus speed mismatch occurred.  please check current bus speed and card capability\n");  			print_card_capability(slot_cur);  		} else if (SLOT_BUS_MODE(slot_cur->ext_status)) { -			err("bus mode mismatch occurred.  please check " -				"current bus mode and card capability\n"); +			err("bus mode mismatch occurred.  please check current bus mode and card capability\n");  			print_card_capability(slot_cur);  		}  		ibmphp_update_slot_info(slot_cur); @@ -1082,18 +1088,17 @@ static int enable_slot(struct hotplug_slot *hs)  	rc = slot_update(&slot_cur);  	if (rc)  		goto error_power; -	 +  	rc = -EINVAL;  	if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {  		err("power fault occurred trying to power up...\n");  		goto error_power;  	}  	if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) { -		err("bus speed mismatch occurred.  please check current bus " -					"speed and card capability\n"); +		err("bus speed mismatch occurred.  please check current bus speed and card capability\n");  		print_card_capability(slot_cur);  		goto error_power; -	}  +	}  	/* Don't think this case will happen after above checks...  	 * but just in case, for paranoia sake */  	if (!(SLOT_POWER(slot_cur->status))) { @@ -1144,7 +1149,7 @@ static int enable_slot(struct hotplug_slot *hs)  	ibmphp_print_test();  	rc = ibmphp_update_slot_info(slot_cur);  exit: -	ibmphp_unlock_operations();  +	ibmphp_unlock_operations();  	return rc;  error_nopower: @@ -1180,7 +1185,7 @@ static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)  {  	struct slot *slot = hotplug_slot->private;  	int rc; -	 +  	ibmphp_lock_operations();  	rc = ibmphp_do_disable_slot(slot);  	ibmphp_unlock_operations(); @@ -1192,12 +1197,12 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	int rc;  	u8 flag; -	debug("DISABLING SLOT...\n");  -		 +	debug("DISABLING SLOT...\n"); +  	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {  		return -ENODEV;  	} -	 +  	flag = slot_cur->flag;  	slot_cur->flag = 1; @@ -1210,7 +1215,7 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	attn_LED_blink(slot_cur);  	if (slot_cur->func == NULL) { -		/* We need this for fncs's that were there on bootup */ +		/* We need this for functions that were there on bootup */  		slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);  		if (!slot_cur->func) {  			err("out of system memory\n"); @@ -1222,12 +1227,13 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	}  	ibm_unconfigure_device(slot_cur->func); -         -	/* If we got here from latch suddenly opening on operating card or  -	a power fault, there's no power to the card, so cannot -	read from it to determine what resources it occupied.  This operation -	is forbidden anyhow.  The best we can do is remove it from kernel -	lists at least */ + +	/* +	 * If we got here from latch suddenly opening on operating card or +	 * a power fault, there's no power to the card, so cannot +	 * read from it to determine what resources it occupied.  This operation +	 * is forbidden anyhow.  The best we can do is remove it from kernel +	 * lists at least */  	if (!flag) {  		attn_off(slot_cur); @@ -1264,7 +1270,7 @@ error:  		rc = -EFAULT;  		goto exit;  	} -	if (flag)		 +	if (flag)  		ibmphp_update_slot_info(slot_cur);  	goto exit;  } @@ -1339,7 +1345,7 @@ static int __init ibmphp_init(void)  	debug("AFTER Resource & EBDA INITIALIZATIONS\n");  	max_slots = get_max_slots(); -	 +  	if ((rc = ibmphp_register_pci()))  		goto error; diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 9df78bc1454..0f65ac55543 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -123,7 +123,7 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)  static void __init print_bus_info (void)  {  	struct bus_info *ptr; -	 +  	list_for_each_entry(ptr, &bus_info_head, bus_info_list) {  		debug ("%s - slot_min = %x\n", __func__, ptr->slot_min);  		debug ("%s - slot_max = %x\n", __func__, ptr->slot_max); @@ -131,7 +131,7 @@ static void __init print_bus_info (void)  		debug ("%s - bus# = %x\n", __func__, ptr->busno);  		debug ("%s - current_speed = %x\n", __func__, ptr->current_speed);  		debug ("%s - controller_id = %x\n", __func__, ptr->controller_id); -		 +  		debug ("%s - slots_at_33_conv = %x\n", __func__, ptr->slots_at_33_conv);  		debug ("%s - slots_at_66_conv = %x\n", __func__, ptr->slots_at_66_conv);  		debug ("%s - slots_at_66_pcix = %x\n", __func__, ptr->slots_at_66_pcix); @@ -144,7 +144,7 @@ static void __init print_bus_info (void)  static void print_lo_info (void)  {  	struct rio_detail *ptr; -	debug ("print_lo_info ----\n");	 +	debug ("print_lo_info ----\n");  	list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {  		debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);  		debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); @@ -176,7 +176,7 @@ static void __init print_ebda_pci_rsrc (void)  	struct ebda_pci_rsrc *ptr;  	list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) { -		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",  +		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",  			__func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);  	}  } @@ -259,7 +259,7 @@ int __init ibmphp_access_ebda (void)  	ebda_seg = readw (io_mem);  	iounmap (io_mem);  	debug ("returned ebda segment: %x\n", ebda_seg); -	 +  	io_mem = ioremap(ebda_seg<<4, 1);  	if (!io_mem)  		return -ENOMEM; @@ -310,7 +310,7 @@ int __init ibmphp_access_ebda (void)  			re = readw (io_mem + sub_addr);	/* next sub blk */  			sub_addr += 2; -			rc_id = readw (io_mem + sub_addr); 	/* sub blk id */ +			rc_id = readw (io_mem + sub_addr);	/* sub blk id */  			sub_addr += 2;  			if (rc_id != 0x5243) @@ -330,7 +330,7 @@ int __init ibmphp_access_ebda (void)  			debug ("info about hpc descriptor---\n");  			debug ("hot blk format: %x\n", format);  			debug ("num of controller: %x\n", num_ctlrs); -			debug ("offset of hpc data structure enteries: %x\n ", sub_addr); +			debug ("offset of hpc data structure entries: %x\n ", sub_addr);  			sub_addr = base + re;	/* re sub blk */  			/* FIXME: rc is never used/checked */ @@ -359,7 +359,7 @@ int __init ibmphp_access_ebda (void)  			debug ("info about rsrc descriptor---\n");  			debug ("format: %x\n", format);  			debug ("num of rsrc: %x\n", num_entries); -			debug ("offset of rsrc data structure enteries: %x\n ", sub_addr); +			debug ("offset of rsrc data structure entries: %x\n ", sub_addr);  			hs_complete = 1;  		} else { @@ -376,7 +376,7 @@ int __init ibmphp_access_ebda (void)  			rio_table_ptr->scal_count = readb (io_mem + offset + 1);  			rio_table_ptr->riodev_count = readb (io_mem + offset + 2);  			rio_table_ptr->offset = offset +3 ; -			 +  			debug("info about rio table hdr ---\n");  			debug("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ",  				rio_table_ptr->ver_num, rio_table_ptr->scal_count, @@ -440,12 +440,12 @@ static int __init ebda_rio_table (void)  		rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);  //		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);  		//create linked list of chassis -		if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)  +		if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)  			list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head); -		//create linked list of expansion box				 -		else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)  +		//create linked list of expansion box +		else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)  			list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head); -		else  +		else  			// not in my concern  			kfree (rio_detail_ptr);  		offset += 15; @@ -456,7 +456,7 @@ static int __init ebda_rio_table (void)  }  /* - * reorganizing linked list of chassis	  + * reorganizing linked list of chassis   */  static struct opt_rio *search_opt_vg (u8 chassis_num)  { @@ -464,7 +464,7 @@ static struct opt_rio *search_opt_vg (u8 chassis_num)  	list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {  		if (ptr->chassis_num == chassis_num)  			return ptr; -	}		 +	}  	return NULL;  } @@ -472,7 +472,7 @@ static int __init combine_wpg_for_chassis (void)  {  	struct opt_rio *opt_rio_ptr = NULL;  	struct rio_detail *rio_detail_ptr = NULL; -	 +  	list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {  		opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);  		if (!opt_rio_ptr) { @@ -484,14 +484,14 @@ static int __init combine_wpg_for_chassis (void)  			opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;  			opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;  			list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head); -		} else {	 +		} else {  			opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);  			opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num); -		}	 +		}  	}  	print_opt_vg (); -	return 0;	 -}	 +	return 0; +}  /*   * reorganizing linked list of expansion box @@ -502,7 +502,7 @@ static struct opt_rio_lo *search_opt_lo (u8 chassis_num)  	list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {  		if (ptr->chassis_num == chassis_num)  			return ptr; -	}		 +	}  	return NULL;  } @@ -510,7 +510,7 @@ static int combine_wpg_for_expansion (void)  {  	struct opt_rio_lo *opt_rio_lo_ptr = NULL;  	struct rio_detail *rio_detail_ptr = NULL; -	 +  	list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {  		opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);  		if (!opt_rio_lo_ptr) { @@ -522,22 +522,22 @@ static int combine_wpg_for_expansion (void)  			opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;  			opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;  			opt_rio_lo_ptr->pack_count = 1; -			 +  			list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head); -		} else {	 +		} else {  			opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);  			opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);  			opt_rio_lo_ptr->pack_count = 2; -		}	 +		}  	} -	return 0;	 +	return 0;  } -	 +  /* Since we don't know the max slot number per each chassis, hence go   * through the list of all chassis to find out the range - * Arguments: slot_num, 1st slot number of the chassis we think we are on,  - * var (0 = chassis, 1 = expansion box)  + * Arguments: slot_num, 1st slot number of the chassis we think we are on, + * var (0 = chassis, 1 = expansion box)   */  static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)  { @@ -547,7 +547,7 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)  	if (!var) {  		list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { -			if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {  +			if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {  				rc = -ENODEV;  				break;  			} @@ -563,25 +563,25 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)  	return rc;  } -static struct opt_rio_lo * find_rxe_num (u8 slot_num) +static struct opt_rio_lo *find_rxe_num (u8 slot_num)  {  	struct opt_rio_lo *opt_lo_ptr;  	list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {  		//check to see if this slot_num belongs to expansion box -		if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))  +		if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))  			return opt_lo_ptr;  	}  	return NULL;  } -static struct opt_rio * find_chassis_num (u8 slot_num) +static struct opt_rio *find_chassis_num (u8 slot_num)  {  	struct opt_rio *opt_vg_ptr;  	list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { -		//check to see if this slot_num belongs to chassis  -		if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))  +		//check to see if this slot_num belongs to chassis +		if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))  			return opt_vg_ptr;  	}  	return NULL; @@ -593,21 +593,21 @@ static struct opt_rio * find_chassis_num (u8 slot_num)  static u8 calculate_first_slot (u8 slot_num)  {  	u8 first_slot = 1; -	struct slot * slot_cur; -	 +	struct slot *slot_cur; +  	list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {  		if (slot_cur->ctrl) { -			if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))  +			if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))  				first_slot = slot_cur->ctrl->ending_slot_num;  		} -	}			 +	}  	return first_slot + 1;  }  #define SLOT_NAME_SIZE 30 -static char *create_file_name (struct slot * slot_cur) +static char *create_file_name (struct slot *slot_cur)  {  	struct opt_rio *opt_vg_ptr = NULL;  	struct opt_rio_lo *opt_lo_ptr = NULL; @@ -622,11 +622,11 @@ static char *create_file_name (struct slot * slot_cur)  		err ("Structure passed is empty\n");  		return NULL;  	} -	 +  	slot_num = slot_cur->number;  	memset (str, 0, sizeof(str)); -	 +  	if (rio_table_ptr) {  		if (rio_table_ptr->ver_num == 3) {  			opt_vg_ptr = find_chassis_num (slot_num); @@ -660,7 +660,7 @@ static char *create_file_name (struct slot * slot_cur)  			/* if both NULL and we DO have correct RIO table in BIOS */  			return NULL;  		} -	}  +	}  	if (!flag) {  		if (slot_cur->ctrl->ctlr_type == 4) {  			first_slot = calculate_first_slot (slot_num); @@ -798,7 +798,7 @@ static int __init ebda_rsrc_controller (void)  			slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);  			slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num); -			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max  +			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max  			bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);  			if (!bus_info_ptr2) { @@ -814,9 +814,9 @@ static int __init ebda_rsrc_controller (void)  				bus_info_ptr1->index = bus_index++;  				bus_info_ptr1->current_speed = 0xff;  				bus_info_ptr1->current_bus_mode = 0xff; -				 +  				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id; -				 +  				list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);  			} else { @@ -851,7 +851,7 @@ static int __init ebda_rsrc_controller (void)  				bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;  				bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;  				bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix; -				bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;  +				bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;  			}  			bus_ptr++;  		} @@ -864,7 +864,7 @@ static int __init ebda_rsrc_controller (void)  				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);  				hpc_ptr->irq = readb (io_mem + addr + 2);  				addr += 3; -				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",  +				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",  					hpc_ptr->u.pci_ctlr.bus,  					hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);  				break; @@ -932,7 +932,7 @@ static int __init ebda_rsrc_controller (void)  				tmp_slot->supported_speed =  2;  			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)  				tmp_slot->supported_speed =  1; -				 +  			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)  				tmp_slot->supported_bus_mode = 1;  			else @@ -1000,7 +1000,7 @@ error_no_hpc:  	return rc;  } -/*  +/*   * map info (bus, devfun, start addr, end addr..) of i/o, memory,   * pfm from the physical addr to a list of resource.   */ @@ -1057,7 +1057,7 @@ static int __init ebda_rsrc_rsrc (void)  			addr += 10;  			debug ("rsrc from mem or pfm ---\n"); -			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",  +			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",  				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);  			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); @@ -1096,7 +1096,7 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num)  	struct bus_info *ptr;  	list_for_each_entry(ptr, &bus_info_head, bus_info_list) { -		if (ptr->busno == num)  +		if (ptr->busno == num)  			 return ptr;  	}  	return NULL; @@ -1110,7 +1110,7 @@ int ibmphp_get_bus_index (u8 num)  	struct bus_info *ptr;  	list_for_each_entry(ptr, &bus_info_head, bus_info_list) { -		if (ptr->busno == num)   +		if (ptr->busno == num)  			return ptr->index;  	}  	return -ENODEV; @@ -1168,7 +1168,7 @@ static struct pci_device_id id_table[] = {  		.subdevice	= HPC_SUBSYSTEM_ID,  		.class		= ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),  	}, {} -};		 +};  MODULE_DEVICE_TABLE(pci, id_table); @@ -1192,12 +1192,12 @@ int ibmphp_register_pci (void)  	}  	return rc;  } -static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids) +static int ibmphp_probe (struct pci_dev *dev, const struct pci_device_id *ids)  {  	struct controller *ctrl;  	debug ("inside ibmphp_probe\n"); -	 +  	list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {  		if (ctrl->ctlr_type == 1) {  			if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { @@ -1210,4 +1210,3 @@ static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)  	}  	return -ENODEV;  } - diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index f59ed30512b..a936022956e 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c @@ -258,7 +258,7 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8  {  	u8 rc;  	void __iomem *wpg_addr;	// base addr + offset -	unsigned long wpg_data;	// data to/from WPG LOHI format  +	unsigned long wpg_data;	// data to/from WPG LOHI format  	unsigned long ultemp;  	unsigned long data;	// actual data HILO format  	int i; @@ -351,7 +351,7 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8  }  //------------------------------------------------------------ -//  Read from ISA type HPC  +//  Read from ISA type HPC  //------------------------------------------------------------  static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)  { @@ -372,7 +372,7 @@ static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)  {  	u16 start_address;  	u16 port_address; -	 +  	start_address = ctlr_ptr->u.isa_ctlr.io_start;  	port_address = start_address + (u16) offset;  	outb (data, port_address); @@ -533,7 +533,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index)  *  * Return   0 or error codes  *---------------------------------------------------------------------*/ -int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) +int ibmphp_hpc_readslot (struct slot *pslot, u8 cmd, u8 *pstatus)  {  	void __iomem *wpg_bbar = NULL;  	struct controller *ctlr_ptr; @@ -656,11 +656,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)  	//--------------------------------------------------------------------  	// cleanup  	//-------------------------------------------------------------------- -	 +  	// remove physical to logical address mapping  	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))  		iounmap (wpg_bbar); -	 +  	free_hpc_access ();  	debug_polling ("%s - Exit rc[%d]\n", __func__, rc); @@ -672,7 +672,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)  *  * Action: issue a WRITE command to HPC  *---------------------------------------------------------------------*/ -int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) +int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)  {  	void __iomem *wpg_bbar = NULL;  	struct controller *ctlr_ptr; @@ -835,7 +835,7 @@ static int poll_hpc(void *data)  		down (&semOperations);  		switch (poll_state) { -		case POLL_LATCH_REGISTER:  +		case POLL_LATCH_REGISTER:  			oldlatchlow = curlatchlow;  			ctrl_count = 0x00;  			list_for_each (pslotlist, &ibmphp_slot_head) { @@ -892,16 +892,16 @@ static int poll_hpc(void *data)  			if (kthread_should_stop())  				goto out_sleep; -			 +  			down (&semOperations); -			 +  			if (poll_count >= POLL_LATCH_CNT) {  				poll_count = 0;  				poll_state = POLL_SLOTS;  			} else  				poll_state = POLL_LATCH_REGISTER;  			break; -		}	 +		}  		/* give up the hardware semaphore */  		up (&semOperations);  		/* sleep for a short time just for good measure */ @@ -958,7 +958,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)  	// 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)))  +		if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))  			disable = 1;  	// bit 6 - HPC_SLOT_BUS_SPEED @@ -980,7 +980,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)  					pslot->status &= ~HPC_SLOT_POWER;  			}  		} -		// CLOSE -> OPEN  +		// CLOSE -> OPEN  		else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)  			&& (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {  			disable = 1; @@ -1075,7 +1075,7 @@ void __exit ibmphp_hpc_stop_poll_thread (void)  	debug ("before locking operations \n");  	ibmphp_lock_operations ();  	debug ("after locking operations \n"); -	 +  	// wait for poll thread to exit  	debug ("before sem_exit down \n");  	down (&sem_exit); @@ -1102,7 +1102,7 @@ void __exit ibmphp_hpc_stop_poll_thread (void)  * Value:  *---------------------------------------------------------------------*/  static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar, -				    u8 * pstatus) +				    u8 *pstatus)  {  	int rc = 0;  	u8 done = 0; diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c index c60f5f3e838..2fd296706ce 100644 --- a/drivers/pci/hotplug/ibmphp_pci.c +++ b/drivers/pci/hotplug/ibmphp_pci.c @@ -1,8 +1,8 @@  /*   * IBM Hot Plug Controller Driver - *  + *   * Written By: Irene Zubarev, IBM Corporation - *  + *   * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)   * Copyright (C) 2001,2002 IBM Corp.   * @@ -42,12 +42,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno);  /*   * NOTE..... If BIOS doesn't provide default routing, we assign: - * 9 for SCSI, 10 for LAN adapters, and 11 for everything else.  + * 9 for SCSI, 10 for LAN adapters, and 11 for everything else.   * If adapter is bridged, then we assign 11 to it and devices behind it.   * We also assign the same irq numbers for multi function devices.   * These are PIC mode, so shouldn't matter n.e.ways (hopefully)   */ -static void assign_alt_irq (struct pci_func * cur_func, u8 class_code) +static void assign_alt_irq (struct pci_func *cur_func, u8 class_code)  {  	int j;  	for (j = 0; j < 4; j++) { @@ -71,11 +71,11 @@ static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)   * Configures the device to be added (will allocate needed resources if it   * can), the device can be a bridge or a regular pci device, can also be   * multi-functional - *  + *   * Input: function to be added - *  + *   * TO DO:  The error case with Multifunction device or multi function bridge, - * if there is an error, will need to go through all previous functions and  + * if there is an error, will need to go through all previous functions and   * unconfigure....or can add some code into unconfigure_card....   */  int ibmphp_configure_card (struct pci_func *func, u8 slotno) @@ -98,7 +98,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)  	cur_func = func;  	/* We only get bus and device from IRQ routing table.  So at this point, -	 * func->busno is correct, and func->device contains only device (at the 5  +	 * func->busno is correct, and func->device contains only device (at the 5  	 * highest bits)  	 */ @@ -137,8 +137,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)  				     "Please choose another device.\n", cur_func->device);  				return -ENODEV;  			} else if (class == PCI_CLASS_DISPLAY_VGA) { -				err ("The device %x is not supported for hot plugging. " -				     "Please choose another device.\n", cur_func->device); +				err ("The device %x is not supported for hot plugging. Please choose another device.\n", +				     cur_func->device);  				return -ENODEV;  			}  			switch (hdr_type) { @@ -151,7 +151,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)  						     cur_func->device, cur_func->busno);  						cleanup_count = 6;  						goto error; -					}	 +					}  					cur_func->next = NULL;  					function = 0x8;  					break; @@ -179,8 +179,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)  				case PCI_HEADER_TYPE_MULTIBRIDGE:  					class >>= 8;  					if (class != PCI_CLASS_BRIDGE_PCI) { -						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. " -						     "Please insert another card.\n", cur_func->device); +						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n", +						     cur_func->device);  						return -ENODEV;  					}  					assign_alt_irq (cur_func, class_code); @@ -247,8 +247,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)  					class >>= 8;  					debug ("class now is %x\n", class);  					if (class != PCI_CLASS_BRIDGE_PCI) { -						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. " -						     "Please insert another card.\n", cur_func->device); +						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n", +						     cur_func->device);  						return -ENODEV;  					} @@ -339,7 +339,7 @@ error:  }  /* - * This function configures the pci BARs of a single device.   + * This function configures the pci BARs of a single device.   * Input: pointer to the pci_func   * Output: configured PCI, 0, or error   */ @@ -371,17 +371,17 @@ static int configure_device (struct pci_func *func)  	for (count = 0; address[count]; count++) {	/* for 6 BARs */ -		/* not sure if i need this.  per scott, said maybe need smth like this +		/* not sure if i need this.  per scott, said maybe need * something like this  		   if devices don't adhere 100% to the spec, so don't want to write  		   to the reserved bits -		pcibios_read_config_byte(cur_func->busno, cur_func->device,  +		pcibios_read_config_byte(cur_func->busno, cur_func->device,  		PCI_BASE_ADDRESS_0 + 4 * count, &tmp);  		if (tmp & 0x01) // IO -			pcibios_write_config_dword(cur_func->busno, cur_func->device,  +			pcibios_write_config_dword(cur_func->busno, cur_func->device,  			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);  		else  // Memory -			pcibios_write_config_dword(cur_func->busno, cur_func->device,  +			pcibios_write_config_dword(cur_func->busno, cur_func->device,  			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);  		 */  		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF); @@ -421,8 +421,8 @@ static int configure_device (struct pci_func *func)  				return -EIO;  			}  			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start); -	 -			/* _______________This is for debugging purposes only_____________________ */  + +			/* _______________This is for debugging purposes only_____________________ */  			debug ("b4 writing, the IO address is %x\n", func->io[count]->start);  			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);  			debug ("after writing.... the start address is %x\n", bar[count]); @@ -484,7 +484,7 @@ static int configure_device (struct pci_func *func)  				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start); -				/*_______________This is for debugging purposes only______________________________*/				 +				/*_______________This is for debugging purposes only______________________________*/  				debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);  				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);  				debug ("after writing, start address is %x\n", bar[count]); @@ -559,7 +559,7 @@ static int configure_device (struct pci_func *func)  /******************************************************************************   * This routine configures a PCI-2-PCI bridge and the functions behind it   * Parameters: pci_func - * Returns:  + * Returns:   ******************************************************************************/  static int configure_bridge (struct pci_func **func_passed, u8 slotno)  { @@ -622,7 +622,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  	debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);  	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number); -	 +  	/* __________________For debugging purposes only __________________________________  	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);  	debug ("sec_number after write/read is %x\n", sec_number); @@ -644,7 +644,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!!  +	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!!  	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ @@ -670,7 +670,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  			debug ("len[count] in IO = %x\n", len[count]);  			bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); -		 +  			if (!bus_io[count]) {  				err ("out of system memory\n");  				retval = -ENOMEM; @@ -735,7 +735,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  						ibmphp_add_pfmem_from_mem (bus_pfmem[count]);  						func->pfmem[count] = bus_pfmem[count];  					} else { -						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",  +						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",  						     func->busno, func->device, len[count]);  						kfree (mem_tmp);  						kfree (bus_pfmem[count]); @@ -805,7 +805,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  	debug ("amount_needed->mem = %x\n", amount_needed->mem);  	debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem); -	if (amount_needed->not_correct) {		 +	if (amount_needed->not_correct) {  		debug ("amount_needed is not correct\n");  		for (count = 0; address[count]; count++) {  			/* for 2 BARs */ @@ -830,7 +830,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  	} else {  		debug ("it wants %x IO behind the bridge\n", amount_needed->io);  		io = kzalloc(sizeof(*io), GFP_KERNEL); -		 +  		if (!io) {  			err ("out of system memory\n");  			retval = -ENOMEM; @@ -959,7 +959,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  		if (bus->noIORanges) {  			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8); -			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);	 +			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);  			/* _______________This is for debugging purposes only ____________________  			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp); @@ -980,7 +980,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  		if (bus->noMemRanges) {  			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);  			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16); -			 +  			/* ____________________This is for debugging purposes only ________________________  			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);  			debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); @@ -1017,7 +1017,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)  		pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);  		if ((irq > 0x00) && (irq < 0x05))  			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]); -		/*     +		/*  		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);  		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);  		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR); @@ -1071,9 +1071,9 @@ error:   * This function adds up the amount of resources needed behind the PPB bridge   * and passes it to the configure_bridge function   * Input: bridge function - * Ouput: amount of resources needed + * Output: amount of resources needed   *****************************************************************************/ -static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) +static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)  {  	int count, len[6];  	u16 vendor_id; @@ -1125,13 +1125,11 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)  				class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */  				if (class == PCI_CLASS_NOT_DEFINED_VGA) { -					err ("The device %x is VGA compatible and as is not supported for hot plugging. " -					     "Please choose another device.\n", device); +					err ("The device %x is VGA compatible and as is not supported for hot plugging.  Please choose another device.\n", device);  					amount->not_correct = 1;  					return amount;  				} else if (class == PCI_CLASS_DISPLAY_VGA) { -					err ("The device %x is not supported for hot plugging. " -					     "Please choose another device.\n", device); +					err ("The device %x is not supported for hot plugging.  Please choose another device.\n", device);  					amount->not_correct = 1;  					return amount;  				} @@ -1204,9 +1202,9 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)  	return amount;  } -/* The following 3 unconfigure_boot_ routines deal with the case when we had the card  - * upon bootup in the system, since we don't allocate func to such case, we need to read  - * the start addresses from pci config space and then find the corresponding entries in  +/* The following 3 unconfigure_boot_ routines deal with the case when we had the card + * upon bootup in the system, since we don't allocate func to such case, we need to read + * the start addresses from pci config space and then find the corresponding entries in   * our resource lists.  The functions return either 0, -ENODEV, or -1 (general failure)   * Change: we also call these functions even if we configured the card ourselves (i.e., not   * the bootup case), since it should work same way @@ -1483,12 +1481,10 @@ static int unconfigure_boot_card (struct slot *slot_cur)  			debug ("hdr_type %x, class %x\n", hdr_type, class);  			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */  			if (class == PCI_CLASS_NOT_DEFINED_VGA) { -				err ("The device %x function %x is VGA compatible and is not supported for hot removing. " -				     "Please choose another device.\n", device, function); +				err ("The device %x function %x is VGA compatible and is not supported for hot removing.  Please choose another device.\n", device, function);  				return -ENODEV;  			} else if (class == PCI_CLASS_DISPLAY_VGA) { -				err ("The device %x function %x is not supported for hot removing. " -				     "Please choose another device.\n", device, function); +				err ("The device %x function %x is not supported for hot removing.  Please choose another device.\n", device, function);  				return -ENODEV;  			} @@ -1513,9 +1509,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)  				case PCI_HEADER_TYPE_BRIDGE:  					class >>= 8;  					if (class != PCI_CLASS_BRIDGE_PCI) { -						err ("This device %x function %x is not PCI-to-PCI bridge, " -						     "and is not supported for hot-removing. " -						     "Please try another card.\n", device, function); +						err ("This device %x function %x is not PCI-to-PCI bridge, and is not supported for hot-removing.  Please try another card.\n", device, function);  						return -ENODEV;  					}  					rc = unconfigure_boot_bridge (busno, device, function); @@ -1529,9 +1523,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)  				case PCI_HEADER_TYPE_MULTIBRIDGE:  					class >>= 8;  					if (class != PCI_CLASS_BRIDGE_PCI) { -						err ("This device %x function %x is not PCI-to-PCI bridge, " -						     "and is not supported for hot-removing. " -						     "Please try another card.\n", device, function); +						err ("This device %x function %x is not PCI-to-PCI bridge,  and is not supported for hot-removing.  Please try another card.\n", device, function);  						return -ENODEV;  					}  					rc = unconfigure_boot_bridge (busno, device, function); @@ -1561,8 +1553,8 @@ static int unconfigure_boot_card (struct slot *slot_cur)   * unconfiguring the device   * TO DO:  will probably need to add some code in case there was some resource,   * to remove it... this is from when we have errors in the configure_card... - * 			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!! - * Returns: 0, -1, -ENODEV  + *			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!! + * Returns: 0, -1, -ENODEV   */  int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)  { @@ -1634,7 +1626,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)   * Input: bus and the amount of resources needed (we know we can assign those,   *        since they've been checked already   * Output: bus added to the correct spot - *         0, -1, error  + *         0, -1, error   */  static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)  { @@ -1650,7 +1642,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r  			err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");  			return -ENODEV;  		} -	 +  		list_add (&bus->bus_list, &cur_bus->bus_list);  	}  	if (io) { @@ -1679,7 +1671,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r  	}  	if (pfmem) {  		pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL); -		if (!pfmem_range) {	 +		if (!pfmem_range) {  			err ("out of system memory\n");  			return -ENOMEM;  		} @@ -1726,4 +1718,3 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)  		return busno;  	return 0xff;  } - diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index e2dc289f767..f34745abd5b 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c @@ -46,9 +46,9 @@ static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);  static LIST_HEAD(gbuses); -static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag) +static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc *curr, u8 busno, int flag)  { -	struct bus_node * newbus; +	struct bus_node *newbus;  	if (!(curr) && !(flag)) {  		err ("NULL pointer passed\n"); @@ -69,10 +69,10 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8  	return newbus;  } -static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr) +static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc *curr)  {  	struct resource_node *rs; -	 +  	if (!curr) {  		err ("NULL passed to allocate\n");  		return NULL; @@ -93,7 +93,7 @@ static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * cur  static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)  { -	struct bus_node * newbus; +	struct bus_node *newbus;  	struct range_node *newrange;  	u8 num_ranges = 0; @@ -128,7 +128,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node  	}  	newrange->start = curr->start_addr;  	newrange->end = curr->end_addr; -		 +  	if (first_bus || (!num_ranges))  		newrange->rangeno = 1;  	else { @@ -162,7 +162,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node  			newbus->rangePFMem = newrange;  			if (first_bus)  				newbus->noPFMemRanges = 1; -			else {	 +			else {  				debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);  				++newbus->noPFMemRanges;  				fix_resources (newbus); @@ -190,7 +190,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node   * This is the Resource Management initialization function.  It will go through   * the Resource list taken from EBDA and fill in this module's data structures   * - * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES,  + * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES,   * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW   *   * Input: ptr to the head of the resource list from EBDA @@ -382,7 +382,7 @@ int __init ibmphp_rsrc_init (void)   * pci devices' resources for the appropriate resource   *   * Input: type of the resource, range to add, current bus - * Output: 0 or -1, bus and range ptrs  + * Output: 0 or -1, bus and range ptrs   ********************************************************************************/  static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur)  { @@ -466,7 +466,7 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno)  	switch (type) {  		case MEM: -			if (bus_cur->firstMem)  +			if (bus_cur->firstMem)  				res = bus_cur->firstMem;  			break;  		case PFMEM: @@ -583,7 +583,7 @@ static void fix_resources (struct bus_node *bus_cur)  }  /******************************************************************************* - * This routine adds a resource to the list of resources to the appropriate bus  + * This routine adds a resource to the list of resources to the appropriate bus   * based on their resource type and sorted by their starting addresses.  It assigns   * the ptrs to next and nextRange if needed.   * @@ -605,11 +605,11 @@ int ibmphp_add_resource (struct resource_node *res)  		err ("NULL passed to add\n");  		return -ENODEV;  	} -	 +  	bus_cur = find_bus_wprev (res->busno, NULL, 0); -	 +  	if (!bus_cur) { -		/* didn't find a bus, smth's wrong!!! */ +		/* didn't find a bus, something's wrong!!! */  		debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");  		return -ENODEV;  	} @@ -648,7 +648,7 @@ int ibmphp_add_resource (struct resource_node *res)  	if (!range_cur) {  		switch (res->type) {  			case IO: -				++bus_cur->needIOUpdate;					 +				++bus_cur->needIOUpdate;  				break;  			case MEM:  				++bus_cur->needMemUpdate; @@ -659,13 +659,13 @@ int ibmphp_add_resource (struct resource_node *res)  		}  		res->rangeno = -1;  	} -	 +  	debug ("The range is %d\n", res->rangeno);  	if (!res_start) {  		/* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */  		switch (res->type) {  			case IO: -				bus_cur->firstIO = res;					 +				bus_cur->firstIO = res;  				break;  			case MEM:  				bus_cur->firstMem = res; @@ -673,7 +673,7 @@ int ibmphp_add_resource (struct resource_node *res)  			case PFMEM:  				bus_cur->firstPFMem = res;  				break; -		}	 +		}  		res->next = NULL;  		res->nextRange = NULL;  	} else { @@ -770,7 +770,7 @@ int ibmphp_add_resource (struct resource_node *res)   * This routine will remove the resource from the list of resources   *   * Input: io, mem, and/or pfmem resource to be deleted - * Ouput: modified resource list + * Output: modified resource list   *        0 or error code   ****************************************************************************/  int ibmphp_remove_resource (struct resource_node *res) @@ -789,8 +789,7 @@ int ibmphp_remove_resource (struct resource_node *res)  	bus_cur = find_bus_wprev (res->busno, NULL, 0);  	if (!bus_cur) { -		err ("cannot find corresponding bus of the io resource to remove  " -			"bailing out...\n"); +		err ("cannot find corresponding bus of the io resource to remove  bailing out...\n");  		return -ENODEV;  	} @@ -825,7 +824,7 @@ int ibmphp_remove_resource (struct resource_node *res)  	if (!res_cur) {  		if (res->type == PFMEM) { -			/*  +			/*  			 * case where pfmem might be in the PFMemFromMem list  			 * so will also need to remove the corresponding mem  			 * entry @@ -934,9 +933,9 @@ int ibmphp_remove_resource (struct resource_node *res)  	return 0;  } -static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res) +static struct range_node *find_range (struct bus_node *bus_cur, struct resource_node *res)  { -	struct range_node * range = NULL; +	struct range_node *range = NULL;  	switch (res->type) {  		case IO: @@ -961,12 +960,12 @@ static struct range_node * find_range (struct bus_node *bus_cur, struct resource  }  /***************************************************************************** - * This routine will check to make sure the io/mem/pfmem->len that the device asked for  + * This routine will check to make sure the io/mem/pfmem->len that the device asked for   * can fit w/i our list of available IO/MEM/PFMEM resources.  If cannot, returns -EINVAL,   * otherwise, returns 0   *   * Input: resource - * Ouput: the correct start and end address are inputted into the resource node, + * Output: the correct start and end address are inputted into the resource node,   *        0 or -EINVAL   *****************************************************************************/  int ibmphp_check_resource (struct resource_node *res, u8 bridge) @@ -996,7 +995,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)  	bus_cur = find_bus_wprev (res->busno, NULL, 0);  	if (!bus_cur) { -		/* didn't find a bus, smth's wrong!!! */ +		/* didn't find a bus, something's wrong!!! */  		debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");  		return -EINVAL;  	} @@ -1066,7 +1065,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)  								break;  						}  					} -			 +  					if (flag && len_cur == res->len) {  						debug ("but we are not here, right?\n");  						res->start = start_cur; @@ -1118,10 +1117,10 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)  		if (res_prev) {  			if (res_prev->rangeno != res_cur->rangeno) {  				/* 1st device on this range */ -				if ((res_cur->start != range->start) &&  +				if ((res_cur->start != range->start) &&  					((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {  					if ((len_tmp < len_cur) || (len_cur == 0)) { -						if ((range->start % tmp_divide) == 0) {	 +						if ((range->start % tmp_divide) == 0) {  							/* just perfect, starting address is divisible by length */  							flag = 1;  							len_cur = len_tmp; @@ -1344,7 +1343,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)   * This routine is called from remove_card if the card contained PPB.   * It will remove all the resources on the bus as well as the bus itself   * Input: Bus - * Ouput: 0, -ENODEV + * Output: 0, -ENODEV   ********************************************************************************/  int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)  { @@ -1353,7 +1352,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)  	struct bus_node *prev_bus;  	int rc; -	prev_bus = find_bus_wprev (parent_busno, NULL, 0);	 +	prev_bus = find_bus_wprev (parent_busno, NULL, 0);  	if (!prev_bus) {  		debug ("something terribly wrong. Cannot find parent bus to the one to remove\n"); @@ -1424,7 +1423,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)  }  /****************************************************************************** - * This routine deletes the ranges from a given bus, and the entries from the  + * This routine deletes the ranges from a given bus, and the entries from the   * parent's bus in the resources   * Input: current bus, previous bus   * Output: 0, -EINVAL @@ -1453,7 +1452,7 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)  	if (bus_cur->noMemRanges) {  		range_cur = bus_cur->rangeMem;  		for (i = 0; i < bus_cur->noMemRanges; i++) { -			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0)  +			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0)  				return -EINVAL;  			ibmphp_remove_resource (res); @@ -1467,7 +1466,7 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)  	if (bus_cur->noPFMemRanges) {  		range_cur = bus_cur->rangePFMem;  		for (i = 0; i < bus_cur->noPFMemRanges; i++) { -			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0)  +			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0)  				return -EINVAL;  			ibmphp_remove_resource (res); @@ -1482,7 +1481,7 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)  }  /* - * find the resource node in the bus  + * find the resource node in the bus   * Input: Resource needed, start address of the resource, type of resource   */  int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag) @@ -1512,7 +1511,7 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour  			err ("wrong type of flag\n");  			return -EINVAL;  	} -	 +  	while (res_cur) {  		if (res_cur->start == start_address) {  			*res = res_cur; @@ -1718,7 +1717,7 @@ static int __init once_over (void)  			}	/* end for pfmem */  		}	/* end if */  	}	/* end list_for_each bus */ -	return 0;  +	return 0;  }  int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem) @@ -1760,9 +1759,9 @@ static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u  	list_for_each (tmp, &gbuses) {  		tmp_prev = tmp->prev;  		bus_cur = list_entry (tmp, struct bus_node, bus_list); -		if (flag)  +		if (flag)  			*prev = list_entry (tmp_prev, struct bus_node, bus_list); -		if (bus_cur->busno == bus_number)  +		if (bus_cur->busno == bus_number)  			return bus_cur;  	} @@ -1776,7 +1775,7 @@ void ibmphp_print_test (void)  	struct range_node *range;  	struct resource_node *res;  	struct list_head *tmp; -	 +  	debug_pci ("*****************START**********************\n");  	if ((!list_empty(&gbuses)) && flags) { @@ -1906,7 +1905,7 @@ static int range_exists_already (struct range_node * range, struct bus_node * bu  			return 1;  		range_cur = range_cur->next;  	} -	 +  	return 0;  } @@ -1920,7 +1919,7 @@ static int range_exists_already (struct range_node * range, struct bus_node * bu   * Returns: none   * Note: this function doesn't take into account IO restrictions etc,   *	 so will only work for bridges with no video/ISA devices behind them It - *	 also will not work for onboard PPB's that can have more than 1 *bus + *	 also will not work for onboard PPBs that can have more than 1 *bus   *	 behind them All these are TO DO.   *	 Also need to add more error checkings... (from fnc returns etc)   */ @@ -1963,7 +1962,7 @@ static int __init update_bridge_ranges (struct bus_node **bus)  					case PCI_HEADER_TYPE_BRIDGE:  						function = 0x8;  					case PCI_HEADER_TYPE_MULTIBRIDGE: -						/* We assume here that only 1 bus behind the bridge  +						/* We assume here that only 1 bus behind the bridge  						   TO DO: add functionality for several:  						   temp = secondary;  						   while (temp < subordinate) { @@ -1972,7 +1971,7 @@ static int __init update_bridge_ranges (struct bus_node **bus)  						   }  						 */  						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno); -						bus_sec = find_bus_wprev (sec_busno, NULL, 0);  +						bus_sec = find_bus_wprev (sec_busno, NULL, 0);  						/* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */  						if (!bus_sec) {  							bus_sec = alloc_error_bus (NULL, sec_busno, 1); @@ -2028,7 +2027,7 @@ static int __init update_bridge_ranges (struct bus_node **bus)  								io->len = io->end - io->start + 1;  								ibmphp_add_resource (io);  							} -						}	 +						}  						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);  						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address); diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index ec20f74c898..56d8486dc16 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -59,14 +59,12 @@ static bool debug;  #define DRIVER_DESC	"PCI Hot Plug PCI Core" -////////////////////////////////////////////////////////////////// -  static LIST_HEAD(pci_hotplug_slot_list);  static DEFINE_MUTEX(pci_hp_mutex);  /* Weee, fun with macros... */ -#define GET_STATUS(name,type)	\ -static int get_##name (struct hotplug_slot *slot, type *value)		\ +#define GET_STATUS(name, type)	\ +static int get_##name(struct hotplug_slot *slot, type *value)		\  {									\  	struct hotplug_slot_ops *ops = slot->ops;			\  	int retval = 0;							\ @@ -92,46 +90,45 @@ static ssize_t power_read_file(struct pci_slot *slot, char *buf)  	retval = get_power_status(slot->hotplug, &value);  	if (retval) -		goto exit; -	retval = sprintf (buf, "%d\n", value); -exit: -	return retval; +		return retval; + +	return sprintf(buf, "%d\n", value);  }  static ssize_t power_write_file(struct pci_slot *pci_slot, const char *buf, -		size_t count) +				size_t count)  {  	struct hotplug_slot *slot = pci_slot->hotplug;  	unsigned long lpower;  	u8 power;  	int retval = 0; -	lpower = simple_strtoul (buf, NULL, 10); +	lpower = simple_strtoul(buf, NULL, 10);  	power = (u8)(lpower & 0xff); -	dbg ("power = %d\n", power); +	dbg("power = %d\n", power);  	if (!try_module_get(slot->ops->owner)) {  		retval = -ENODEV;  		goto exit;  	}  	switch (power) { -		case 0: -			if (slot->ops->disable_slot) -				retval = slot->ops->disable_slot(slot); -			break; - -		case 1: -			if (slot->ops->enable_slot) -				retval = slot->ops->enable_slot(slot); -			break; - -		default: -			err ("Illegal value specified for power\n"); -			retval = -EINVAL; +	case 0: +		if (slot->ops->disable_slot) +			retval = slot->ops->disable_slot(slot); +		break; + +	case 1: +		if (slot->ops->enable_slot) +			retval = slot->ops->enable_slot(slot); +		break; + +	default: +		err("Illegal value specified for power\n"); +		retval = -EINVAL;  	}  	module_put(slot->ops->owner); -exit:	 +exit:  	if (retval)  		return retval;  	return count; @@ -150,24 +147,22 @@ static ssize_t attention_read_file(struct pci_slot *slot, char *buf)  	retval = get_attention_status(slot->hotplug, &value);  	if (retval) -		goto exit; -	retval = sprintf(buf, "%d\n", value); +		return retval; -exit: -	return retval; +	return sprintf(buf, "%d\n", value);  }  static ssize_t attention_write_file(struct pci_slot *slot, const char *buf, -		size_t count) +				    size_t count)  {  	struct hotplug_slot_ops *ops = slot->hotplug->ops;  	unsigned long lattention;  	u8 attention;  	int retval = 0; -	lattention = simple_strtoul (buf, NULL, 10); +	lattention = simple_strtoul(buf, NULL, 10);  	attention = (u8)(lattention & 0xff); -	dbg (" - attention = %d\n", attention); +	dbg(" - attention = %d\n", attention);  	if (!try_module_get(ops->owner)) {  		retval = -ENODEV; @@ -177,7 +172,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,  		retval = ops->set_attention_status(slot->hotplug, attention);  	module_put(ops->owner); -exit:	 +exit:  	if (retval)  		return retval;  	return count; @@ -196,11 +191,9 @@ static ssize_t latch_read_file(struct pci_slot *slot, char *buf)  	retval = get_latch_status(slot->hotplug, &value);  	if (retval) -		goto exit; -	retval = sprintf (buf, "%d\n", value); +		return retval; -exit: -	return retval; +	return sprintf(buf, "%d\n", value);  }  static struct pci_slot_attribute hotplug_slot_attr_latch = { @@ -215,11 +208,9 @@ static ssize_t presence_read_file(struct pci_slot *slot, char *buf)  	retval = get_adapter_status(slot->hotplug, &value);  	if (retval) -		goto exit; -	retval = sprintf (buf, "%d\n", value); +		return retval; -exit: -	return retval; +	return sprintf(buf, "%d\n", value);  }  static struct pci_slot_attribute hotplug_slot_attr_presence = { @@ -228,7 +219,7 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = {  };  static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, -		size_t count) +			       size_t count)  {  	struct hotplug_slot *slot = pci_slot->hotplug;  	unsigned long ltest; @@ -237,7 +228,7 @@ static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf,  	ltest = simple_strtoul (buf, NULL, 10);  	test = (u32)(ltest & 0xffffffff); -	dbg ("test = %d\n", test); +	dbg("test = %d\n", test);  	if (!try_module_get(slot->ops->owner)) {  		retval = -ENODEV; @@ -247,7 +238,7 @@ static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf,  		retval = slot->ops->hardware_test(slot, test);  	module_put(slot->ops->owner); -exit:	 +exit:  	if (retval)  		return retval;  	return count; @@ -261,6 +252,7 @@ static struct pci_slot_attribute hotplug_slot_attr_test = {  static bool has_power_file(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug; +  	if ((!slot) || (!slot->ops))  		return false;  	if ((slot->ops->enable_slot) || @@ -273,6 +265,7 @@ static bool has_power_file(struct pci_slot *pci_slot)  static bool has_attention_file(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug; +  	if ((!slot) || (!slot->ops))  		return false;  	if ((slot->ops->set_attention_status) || @@ -284,6 +277,7 @@ static bool has_attention_file(struct pci_slot *pci_slot)  static bool has_latch_file(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug; +  	if ((!slot) || (!slot->ops))  		return false;  	if (slot->ops->get_latch_status) @@ -294,6 +288,7 @@ static bool has_latch_file(struct pci_slot *pci_slot)  static bool has_adapter_file(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug; +  	if ((!slot) || (!slot->ops))  		return false;  	if (slot->ops->get_adapter_status) @@ -304,6 +299,7 @@ static bool has_adapter_file(struct pci_slot *pci_slot)  static bool has_test_file(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug; +  	if ((!slot) || (!slot->ops))  		return false;  	if (slot->ops->hardware_test) @@ -397,13 +393,13 @@ static void fs_remove_slot(struct pci_slot *slot)  	pci_hp_remove_module_link(slot);  } -static struct hotplug_slot *get_slot_from_name (const char *name) +static struct hotplug_slot *get_slot_from_name(const char *name)  {  	struct hotplug_slot *slot;  	struct list_head *tmp; -	list_for_each (tmp, &pci_hotplug_slot_list) { -		slot = list_entry (tmp, struct hotplug_slot, slot_list); +	list_for_each(tmp, &pci_hotplug_slot_list) { +		slot = list_entry(tmp, struct hotplug_slot, slot_list);  		if (strcmp(hotplug_slot_name(slot), name) == 0)  			return slot;  	} @@ -436,8 +432,7 @@ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus,  	if ((slot->info == NULL) || (slot->ops == NULL))  		return -EINVAL;  	if (slot->release == NULL) { -		dbg("Why are you trying to register a hotplug slot " -		    "without a proper release function?\n"); +		dbg("Why are you trying to register a hotplug slot without a proper release function?\n");  		return -EINVAL;  	} @@ -468,6 +463,7 @@ out:  	mutex_unlock(&pci_hp_mutex);  	return result;  } +EXPORT_SYMBOL_GPL(__pci_hp_register);  /**   * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem @@ -506,13 +502,14 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)  	return 0;  } +EXPORT_SYMBOL_GPL(pci_hp_deregister);  /**   * pci_hp_change_slot_info - changes the slot's information structure in the core   * @hotplug: pointer to the slot whose info has changed   * @info: pointer to the info copy into the slot's info structure   * - * @slot must have been registered with the pci  + * @slot must have been registered with the pci   * hotplug subsystem previously with a call to pci_hp_register().   *   * Returns 0 if successful, anything else for an error. @@ -527,24 +524,23 @@ int pci_hp_change_slot_info(struct hotplug_slot *hotplug,  	return 0;  } +EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); -static int __init pci_hotplug_init (void) +static int __init pci_hotplug_init(void)  {  	int result;  	result = cpci_hotplug_init(debug);  	if (result) { -		err ("cpci_hotplug_init with error %d\n", result); -		goto err_cpci; +		err("cpci_hotplug_init with error %d\n", result); +		return result;  	} -	info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); - -err_cpci: +	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");  	return result;  } -static void __exit pci_hotplug_exit (void) +static void __exit pci_hotplug_exit(void)  {  	cpci_hotplug_exit();  } @@ -557,7 +553,3 @@ MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL");  module_param(debug, bool, 0644);  MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); - -EXPORT_SYMBOL_GPL(__pci_hp_register); -EXPORT_SYMBOL_GPL(pci_hp_deregister); -EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 541bbe6d534..8e9012dca45 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -43,7 +43,6 @@  extern bool pciehp_poll_mode;  extern int pciehp_poll_time;  extern bool pciehp_debug; -extern bool pciehp_force;  #define dbg(format, arg...)						\  do {									\ @@ -77,6 +76,7 @@ struct slot {  	struct hotplug_slot *hotplug_slot;  	struct delayed_work work;	/* work for button event */  	struct mutex lock; +	struct mutex hotplug_lock;  	struct workqueue_struct *wq;  }; @@ -110,6 +110,8 @@ struct controller {  #define INT_BUTTON_PRESS		7  #define INT_BUTTON_RELEASE		8  #define INT_BUTTON_CANCEL		9 +#define INT_LINK_UP			10 +#define INT_LINK_DOWN			11  #define STATIC_STATE			0  #define BLINKINGON_STATE		1 @@ -125,7 +127,7 @@ struct controller {  #define HP_SUPR_RM(ctrl)	((ctrl)->slot_cap & PCI_EXP_SLTCAP_HPS)  #define EMI(ctrl)		((ctrl)->slot_cap & PCI_EXP_SLTCAP_EIP)  #define NO_CMD_CMPL(ctrl)	((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) -#define PSN(ctrl)		((ctrl)->slot_cap >> 19) +#define PSN(ctrl)		(((ctrl)->slot_cap & PCI_EXP_SLTCAP_PSN) >> 19)  int pciehp_sysfs_enable_slot(struct slot *slot);  int pciehp_sysfs_disable_slot(struct slot *slot); @@ -133,6 +135,7 @@ u8 pciehp_handle_attention_button(struct slot *p_slot);  u8 pciehp_handle_switch_change(struct slot *p_slot);  u8 pciehp_handle_presence_change(struct slot *p_slot);  u8 pciehp_handle_power_fault(struct slot *p_slot); +void pciehp_handle_linkstate_change(struct slot *p_slot);  int pciehp_configure_device(struct slot *p_slot);  int pciehp_unconfigure_device(struct slot *p_slot);  void pciehp_queue_pushbutton_work(struct work_struct *work); @@ -140,20 +143,21 @@ struct controller *pcie_init(struct pcie_device *dev);  int pcie_init_notification(struct controller *ctrl);  int pciehp_enable_slot(struct slot *p_slot);  int pciehp_disable_slot(struct slot *p_slot); -int pcie_enable_notification(struct controller *ctrl); +void pcie_enable_notification(struct controller *ctrl);  int pciehp_power_on_slot(struct slot *slot); -int pciehp_power_off_slot(struct slot *slot); -int pciehp_get_power_status(struct slot *slot, u8 *status); -int pciehp_get_attention_status(struct slot *slot, u8 *status); +void pciehp_power_off_slot(struct slot *slot); +void pciehp_get_power_status(struct slot *slot, u8 *status); +void pciehp_get_attention_status(struct slot *slot, u8 *status); -int pciehp_set_attention_status(struct slot *slot, u8 status); -int pciehp_get_latch_status(struct slot *slot, u8 *status); -int pciehp_get_adapter_status(struct slot *slot, u8 *status); +void pciehp_set_attention_status(struct slot *slot, u8 status); +void pciehp_get_latch_status(struct slot *slot, u8 *status); +void pciehp_get_adapter_status(struct slot *slot, u8 *status);  int pciehp_query_power_fault(struct slot *slot);  void pciehp_green_led_on(struct slot *slot);  void pciehp_green_led_off(struct slot *slot);  void pciehp_green_led_blink(struct slot *slot);  int pciehp_check_link_status(struct controller *ctrl); +bool pciehp_check_link_active(struct controller *ctrl);  void pciehp_release_ctrl(struct controller *ctrl);  int pciehp_reset_slot(struct slot *slot, int probe); @@ -163,8 +167,6 @@ static inline const char *slot_name(struct slot *slot)  }  #ifdef CONFIG_ACPI -#include <acpi/acpi.h> -#include <acpi/acpi_bus.h>  #include <linux/pci-acpi.h>  void __init pciehp_acpi_slot_detection_init(void); @@ -180,5 +182,5 @@ static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev)  {  	return 0;  } -#endif 				/* CONFIG_ACPI */ +#endif				/* CONFIG_ACPI */  #endif				/* _PCIEHP_H */ diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index ead7c534095..93cc9266e8c 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -54,7 +54,7 @@ int pciehp_acpi_slot_detection_check(struct pci_dev *dev)  {  	if (slot_detection_mode != PCIEHP_DETECT_ACPI)  		return 0; -	if (acpi_pci_detect_ejectable(DEVICE_ACPI_HANDLE(&dev->dev))) +	if (acpi_pci_detect_ejectable(ACPI_HANDLE(&dev->dev)))  		return 0;  	return -ENODEV;  } @@ -78,7 +78,7 @@ static int __initdata dup_slot_id;  static int __initdata acpi_slot_detected;  static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); -/* Dummy driver for dumplicate name detection */ +/* Dummy driver for duplicate name detection */  static int __init dummy_probe(struct pcie_device *dev)  {  	u32 slot_cap; @@ -96,22 +96,23 @@ static int __init dummy_probe(struct pcie_device *dev)  			dup_slot_id++;  	}  	list_add_tail(&slot->list, &dummy_slots); -	handle = DEVICE_ACPI_HANDLE(&pdev->dev); +	handle = ACPI_HANDLE(&pdev->dev);  	if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle))  		acpi_slot_detected = 1;  	return -ENODEV;         /* dummy driver always returns error */  }  static struct pcie_port_service_driver __initdata dummy_driver = { -        .name           = "pciehp_dummy", +	.name		= "pciehp_dummy",  	.port_type	= PCIE_ANY_PORT,  	.service	= PCIE_PORT_SERVICE_HP, -        .probe          = dummy_probe, +	.probe		= dummy_probe,  };  static int __init select_detection_mode(void)  {  	struct dummy_slot *slot, *tmp; +  	if (pcie_port_service_register(&dummy_driver))  		return PCIEHP_DETECT_ACPI;  	pcie_port_service_unregister(&dummy_driver); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index f4a18f51a29..a2297db8081 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -41,7 +41,7 @@  bool pciehp_debug;  bool pciehp_poll_mode;  int pciehp_poll_time; -bool pciehp_force; +static bool pciehp_force;  #define DRIVER_VERSION	"0.4"  #define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" @@ -108,6 +108,7 @@ static int init_slot(struct controller *ctrl)  	ops = kzalloc(sizeof(*ops), GFP_KERNEL);  	if (!ops)  		goto out; +  	ops->enable_slot = enable_slot;  	ops->disable_slot = disable_slot;  	ops->get_power_status = get_power_status; @@ -160,7 +161,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)  	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",  		  __func__, slot_name(slot)); -	return pciehp_set_attention_status(slot, status); +	pciehp_set_attention_status(slot, status); +	return 0;  } @@ -192,7 +194,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",  		  __func__, slot_name(slot)); -	return pciehp_get_power_status(slot, value); +	pciehp_get_power_status(slot, value); +	return 0;  }  static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) @@ -202,7 +205,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",  		  __func__, slot_name(slot)); -	return pciehp_get_attention_status(slot, value); +	pciehp_get_attention_status(slot, value); +	return 0;  }  static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) @@ -212,7 +216,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)  	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",  		 __func__, slot_name(slot)); -	return pciehp_get_latch_status(slot, value); +	pciehp_get_latch_status(slot, value); +	return 0;  }  static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) @@ -222,7 +227,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)  	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",  		 __func__, slot_name(slot)); -	return pciehp_get_adapter_status(slot, value); +	pciehp_get_adapter_status(slot, value); +	return 0;  }  static int reset_slot(struct hotplug_slot *hotplug_slot, int probe) @@ -260,8 +266,7 @@ static int pciehp_probe(struct pcie_device *dev)  	rc = init_slot(ctrl);  	if (rc) {  		if (rc == -EBUSY) -			ctrl_warn(ctrl, "Slot already registered by another " -				  "hotplug driver\n"); +			ctrl_warn(ctrl, "Slot already registered by another hotplug driver\n");  		else  			ctrl_err(ctrl, "Slot initialization failed\n");  		goto err_out_release_ctlr; @@ -278,8 +283,11 @@ static int pciehp_probe(struct pcie_device *dev)  	slot = ctrl->slot;  	pciehp_get_adapter_status(slot, &occupied);  	pciehp_get_power_status(slot, &poweron); -	if (occupied && pciehp_force) +	if (occupied && pciehp_force) { +		mutex_lock(&slot->hotplug_lock);  		pciehp_enable_slot(slot); +		mutex_unlock(&slot->hotplug_lock); +	}  	/* If empty slot's power status is on, turn power off */  	if (!occupied && poweron && POWER_CTRL(ctrl))  		pciehp_power_off_slot(slot); @@ -303,12 +311,12 @@ static void pciehp_remove(struct pcie_device *dev)  }  #ifdef CONFIG_PM -static int pciehp_suspend (struct pcie_device *dev) +static int pciehp_suspend(struct pcie_device *dev)  {  	return 0;  } -static int pciehp_resume (struct pcie_device *dev) +static int pciehp_resume(struct pcie_device *dev)  {  	struct controller *ctrl;  	struct slot *slot; @@ -323,10 +331,12 @@ static int pciehp_resume (struct pcie_device *dev)  	/* Check if slot is occupied */  	pciehp_get_adapter_status(slot, &status); +	mutex_lock(&slot->hotplug_lock);  	if (status)  		pciehp_enable_slot(slot);  	else  		pciehp_disable_slot(slot); +	mutex_unlock(&slot->hotplug_lock);  	return 0;  }  #endif /* PM */ @@ -351,8 +361,8 @@ static int __init pcied_init(void)  	pciehp_firmware_init();  	retval = pcie_port_service_register(&hpdriver_portdrv); - 	dbg("pcie_port_service_register = %d\n", retval); -  	info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); +	dbg("pcie_port_service_register = %d\n", retval); +	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");  	if (retval)  		dbg("Failure to register service\n"); diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 38f01867917..ff32e85e1de 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -150,19 +150,37 @@ u8 pciehp_handle_power_fault(struct slot *p_slot)  	return 1;  } +void pciehp_handle_linkstate_change(struct slot *p_slot) +{ +	u32 event_type; +	struct controller *ctrl = p_slot->ctrl; + +	/* Link Status Change */ +	ctrl_dbg(ctrl, "Data Link Layer State change\n"); + +	if (pciehp_check_link_active(ctrl)) { +		ctrl_info(ctrl, "slot(%s): Link Up event\n", +			  slot_name(p_slot)); +		event_type = INT_LINK_UP; +	} else { +		ctrl_info(ctrl, "slot(%s): Link Down event\n", +			  slot_name(p_slot)); +		event_type = INT_LINK_DOWN; +	} + +	queue_interrupt_event(p_slot, event_type); +} +  /* The following routines constitute the bulk of the     hotplug controller logic   */ -static void set_slot_off(struct controller *ctrl, struct slot * pslot) +static void set_slot_off(struct controller *ctrl, struct slot *pslot)  {  	/* turn off slot, turn on Amber LED, turn off Green LED if supported*/  	if (POWER_CTRL(ctrl)) { -		if (pciehp_power_off_slot(pslot)) { -			ctrl_err(ctrl, -				 "Issue of Slot Power Off command failed\n"); -			return; -		} +		pciehp_power_off_slot(pslot); +  		/*  		 * After turning power off, we must wait for at least 1 second  		 * before taking any action that relies on power having been @@ -171,16 +189,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)  		msleep(1000);  	} -	if (PWR_LED(ctrl)) -		pciehp_green_led_off(pslot); - -	if (ATTN_LED(ctrl)) { -		if (pciehp_set_attention_status(pslot, 1)) { -			ctrl_err(ctrl, -				 "Issue of Set Attention Led command failed\n"); -			return; -		} -	} +	pciehp_green_led_off(pslot); +	pciehp_set_attention_status(pslot, 1);  }  /** @@ -203,8 +213,7 @@ static int board_added(struct slot *p_slot)  			return retval;  	} -	if (PWR_LED(ctrl)) -		pciehp_green_led_blink(p_slot); +	pciehp_green_led_blink(p_slot);  	/* Check link training status */  	retval = pciehp_check_link_status(ctrl); @@ -224,12 +233,11 @@ static int board_added(struct slot *p_slot)  	if (retval) {  		ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",  			 pci_domain_nr(parent), parent->number); -		goto err_exit; +		if (retval != -EEXIST) +			goto err_exit;  	} -	if (PWR_LED(ctrl)) -		pciehp_green_led_on(p_slot); - +	pciehp_green_led_on(p_slot);  	return 0;  err_exit: @@ -243,7 +251,7 @@ err_exit:   */  static int remove_board(struct slot *p_slot)  { -	int retval = 0; +	int retval;  	struct controller *ctrl = p_slot->ctrl;  	retval = pciehp_unconfigure_device(p_slot); @@ -251,13 +259,8 @@ static int remove_board(struct slot *p_slot)  		return retval;  	if (POWER_CTRL(ctrl)) { -		/* power off slot */ -		retval = pciehp_power_off_slot(p_slot); -		if (retval) { -			ctrl_err(ctrl, -				 "Issue of Slot Disable command failed\n"); -			return retval; -		} +		pciehp_power_off_slot(p_slot); +  		/*  		 * After turning power off, we must wait for at least 1 second  		 * before taking any action that relies on power having been @@ -267,15 +270,16 @@ static int remove_board(struct slot *p_slot)  	}  	/* turn off Green LED */ -	if (PWR_LED(ctrl)) -		pciehp_green_led_off(p_slot); - +	pciehp_green_led_off(p_slot);  	return 0;  }  struct power_work_info {  	struct slot *p_slot;  	struct work_struct work; +	unsigned int req; +#define DISABLE_REQ 0 +#define ENABLE_REQ  1  };  /** @@ -290,30 +294,38 @@ static void pciehp_power_thread(struct work_struct *work)  	struct power_work_info *info =  		container_of(work, struct power_work_info, work);  	struct slot *p_slot = info->p_slot; +	int ret; -	mutex_lock(&p_slot->lock); -	switch (p_slot->state) { -	case POWEROFF_STATE: -		mutex_unlock(&p_slot->lock); +	switch (info->req) { +	case DISABLE_REQ:  		ctrl_dbg(p_slot->ctrl,  			 "Disabling domain:bus:device=%04x:%02x:00\n",  			 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),  			 p_slot->ctrl->pcie->port->subordinate->number); +		mutex_lock(&p_slot->hotplug_lock);  		pciehp_disable_slot(p_slot); +		mutex_unlock(&p_slot->hotplug_lock);  		mutex_lock(&p_slot->lock);  		p_slot->state = STATIC_STATE; -		break; -	case POWERON_STATE:  		mutex_unlock(&p_slot->lock); -		if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl)) +		break; +	case ENABLE_REQ: +		ctrl_dbg(p_slot->ctrl, +			 "Enabling domain:bus:device=%04x:%02x:00\n", +			 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), +			 p_slot->ctrl->pcie->port->subordinate->number); +		mutex_lock(&p_slot->hotplug_lock); +		ret = pciehp_enable_slot(p_slot); +		mutex_unlock(&p_slot->hotplug_lock); +		if (ret)  			pciehp_green_led_off(p_slot);  		mutex_lock(&p_slot->lock);  		p_slot->state = STATIC_STATE; +		mutex_unlock(&p_slot->lock);  		break;  	default:  		break;  	} -	mutex_unlock(&p_slot->lock);  	kfree(info);  } @@ -336,9 +348,11 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)  	switch (p_slot->state) {  	case BLINKINGOFF_STATE:  		p_slot->state = POWEROFF_STATE; +		info->req = DISABLE_REQ;  		break;  	case BLINKINGON_STATE:  		p_slot->state = POWERON_STATE; +		info->req = ENABLE_REQ;  		break;  	default:  		kfree(info); @@ -362,21 +376,16 @@ static void handle_button_press_event(struct slot *p_slot)  		pciehp_get_power_status(p_slot, &getstatus);  		if (getstatus) {  			p_slot->state = BLINKINGOFF_STATE; -			ctrl_info(ctrl, -				  "PCI slot #%s - powering off due to button " -				  "press.\n", slot_name(p_slot)); +			ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", +				  slot_name(p_slot));  		} else {  			p_slot->state = BLINKINGON_STATE; -			ctrl_info(ctrl, -				  "PCI slot #%s - powering on due to button " -				  "press.\n", slot_name(p_slot)); +			ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", +				  slot_name(p_slot));  		}  		/* blink green LED and turn off amber */ -		if (PWR_LED(ctrl)) -			pciehp_green_led_blink(p_slot); -		if (ATTN_LED(ctrl)) -			pciehp_set_attention_status(p_slot, 0); - +		pciehp_green_led_blink(p_slot); +		pciehp_set_attention_status(p_slot, 0);  		queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);  		break;  	case BLINKINGOFF_STATE: @@ -388,17 +397,13 @@ static void handle_button_press_event(struct slot *p_slot)  		 */  		ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));  		cancel_delayed_work(&p_slot->work); -		if (p_slot->state == BLINKINGOFF_STATE) { -			if (PWR_LED(ctrl)) -				pciehp_green_led_on(p_slot); -		} else { -			if (PWR_LED(ctrl)) -				pciehp_green_led_off(p_slot); -		} -		if (ATTN_LED(ctrl)) -			pciehp_set_attention_status(p_slot, 0); -		ctrl_info(ctrl, "PCI slot #%s - action canceled " -			  "due to button press\n", slot_name(p_slot)); +		if (p_slot->state == BLINKINGOFF_STATE) +			pciehp_green_led_on(p_slot); +		else +			pciehp_green_led_off(p_slot); +		pciehp_set_attention_status(p_slot, 0); +		ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", +			  slot_name(p_slot));  		p_slot->state = STATIC_STATE;  		break;  	case POWEROFF_STATE: @@ -434,14 +439,81 @@ static void handle_surprise_event(struct slot *p_slot)  	INIT_WORK(&info->work, pciehp_power_thread);  	pciehp_get_adapter_status(p_slot, &getstatus); -	if (!getstatus) +	if (!getstatus) {  		p_slot->state = POWEROFF_STATE; -	else +		info->req = DISABLE_REQ; +	} else {  		p_slot->state = POWERON_STATE; +		info->req = ENABLE_REQ; +	}  	queue_work(p_slot->wq, &info->work);  } +/* + * Note: This function must be called with slot->lock held + */ +static void handle_link_event(struct slot *p_slot, u32 event) +{ +	struct controller *ctrl = p_slot->ctrl; +	struct power_work_info *info; + +	info = kmalloc(sizeof(*info), GFP_KERNEL); +	if (!info) { +		ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", +			 __func__); +		return; +	} +	info->p_slot = p_slot; +	info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ; +	INIT_WORK(&info->work, pciehp_power_thread); + +	switch (p_slot->state) { +	case BLINKINGON_STATE: +	case BLINKINGOFF_STATE: +		cancel_delayed_work(&p_slot->work); +		/* Fall through */ +	case STATIC_STATE: +		p_slot->state = event == INT_LINK_UP ? +		    POWERON_STATE : POWEROFF_STATE; +		queue_work(p_slot->wq, &info->work); +		break; +	case POWERON_STATE: +		if (event == INT_LINK_UP) { +			ctrl_info(ctrl, +				  "Link Up event ignored on slot(%s): already powering on\n", +				  slot_name(p_slot)); +			kfree(info); +		} else { +			ctrl_info(ctrl, +				  "Link Down event queued on slot(%s): currently getting powered on\n", +				  slot_name(p_slot)); +			p_slot->state = POWEROFF_STATE; +			queue_work(p_slot->wq, &info->work); +		} +		break; +	case POWEROFF_STATE: +		if (event == INT_LINK_UP) { +			ctrl_info(ctrl, +				  "Link Up event queued on slot(%s): currently getting powered off\n", +				  slot_name(p_slot)); +			p_slot->state = POWERON_STATE; +			queue_work(p_slot->wq, &info->work); +		} else { +			ctrl_info(ctrl, +				  "Link Down event ignored on slot(%s): already powering off\n", +				  slot_name(p_slot)); +			kfree(info); +		} +		break; +	default: +		ctrl_err(ctrl, "Not a valid state on slot(%s)\n", +			 slot_name(p_slot)); +		kfree(info); +		break; +	} +} +  static void interrupt_event_handler(struct work_struct *work)  {  	struct event_info *info = container_of(work, struct event_info, work); @@ -456,18 +528,27 @@ static void interrupt_event_handler(struct work_struct *work)  	case INT_POWER_FAULT:  		if (!POWER_CTRL(ctrl))  			break; -		if (ATTN_LED(ctrl)) -			pciehp_set_attention_status(p_slot, 1); -		if (PWR_LED(ctrl)) -			pciehp_green_led_off(p_slot); +		pciehp_set_attention_status(p_slot, 1); +		pciehp_green_led_off(p_slot);  		break;  	case INT_PRESENCE_ON: -	case INT_PRESENCE_OFF:  		if (!HP_SUPR_RM(ctrl))  			break; +		ctrl_dbg(ctrl, "Surprise Insertion\n"); +		handle_surprise_event(p_slot); +		break; +	case INT_PRESENCE_OFF: +		/* +		 * Regardless of surprise capability, we need to +		 * definitely remove a card that has been pulled out! +		 */  		ctrl_dbg(ctrl, "Surprise Removal\n");  		handle_surprise_event(p_slot);  		break; +	case INT_LINK_UP: +	case INT_LINK_DOWN: +		handle_link_event(p_slot, info->event_type); +		break;  	default:  		break;  	} @@ -476,20 +557,23 @@ static void interrupt_event_handler(struct work_struct *work)  	kfree(info);  } +/* + * Note: This function must be called with slot->hotplug_lock held + */  int pciehp_enable_slot(struct slot *p_slot)  {  	u8 getstatus = 0;  	int rc;  	struct controller *ctrl = p_slot->ctrl; -	rc = pciehp_get_adapter_status(p_slot, &getstatus); -	if (rc || !getstatus) { +	pciehp_get_adapter_status(p_slot, &getstatus); +	if (!getstatus) {  		ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot));  		return -ENODEV;  	}  	if (MRL_SENS(p_slot->ctrl)) { -		rc = pciehp_get_latch_status(p_slot, &getstatus); -		if (rc || getstatus) { +		pciehp_get_latch_status(p_slot, &getstatus); +		if (getstatus) {  			ctrl_info(ctrl, "Latch open on slot(%s)\n",  				  slot_name(p_slot));  			return -ENODEV; @@ -497,8 +581,8 @@ int pciehp_enable_slot(struct slot *p_slot)  	}  	if (POWER_CTRL(p_slot->ctrl)) { -		rc = pciehp_get_power_status(p_slot, &getstatus); -		if (rc || getstatus) { +		pciehp_get_power_status(p_slot, &getstatus); +		if (getstatus) {  			ctrl_info(ctrl, "Already enabled on slot(%s)\n",  				  slot_name(p_slot));  			return -EINVAL; @@ -508,43 +592,26 @@ int pciehp_enable_slot(struct slot *p_slot)  	pciehp_get_latch_status(p_slot, &getstatus);  	rc = board_added(p_slot); -	if (rc) { +	if (rc)  		pciehp_get_latch_status(p_slot, &getstatus); -	} +  	return rc;  } - +/* + * Note: This function must be called with slot->hotplug_lock held + */  int pciehp_disable_slot(struct slot *p_slot)  {  	u8 getstatus = 0; -	int ret = 0;  	struct controller *ctrl = p_slot->ctrl;  	if (!p_slot->ctrl)  		return 1; -	if (!HP_SUPR_RM(p_slot->ctrl)) { -		ret = pciehp_get_adapter_status(p_slot, &getstatus); -		if (ret || !getstatus) { -			ctrl_info(ctrl, "No adapter on slot(%s)\n", -				  slot_name(p_slot)); -			return -ENODEV; -		} -	} - -	if (MRL_SENS(p_slot->ctrl)) { -		ret = pciehp_get_latch_status(p_slot, &getstatus); -		if (ret || getstatus) { -			ctrl_info(ctrl, "Latch open on slot(%s)\n", -				  slot_name(p_slot)); -			return -ENODEV; -		} -	} -  	if (POWER_CTRL(p_slot->ctrl)) { -		ret = pciehp_get_power_status(p_slot, &getstatus); -		if (ret || !getstatus) { +		pciehp_get_power_status(p_slot, &getstatus); +		if (!getstatus) {  			ctrl_info(ctrl, "Already disabled on slot(%s)\n",  				  slot_name(p_slot));  			return -EINVAL; @@ -566,7 +633,9 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)  	case STATIC_STATE:  		p_slot->state = POWERON_STATE;  		mutex_unlock(&p_slot->lock); +		mutex_lock(&p_slot->hotplug_lock);  		retval = pciehp_enable_slot(p_slot); +		mutex_unlock(&p_slot->hotplug_lock);  		mutex_lock(&p_slot->lock);  		p_slot->state = STATIC_STATE;  		break; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 51f56ef4ab6..42914e04d11 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -41,34 +41,11 @@  #include "../pci.h"  #include "pciehp.h" -static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) +static inline struct pci_dev *ctrl_dev(struct controller *ctrl)  { -	struct pci_dev *dev = ctrl->pcie->port; -	return pcie_capability_read_word(dev, reg, value); +	return ctrl->pcie->port;  } -static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) -{ -	struct pci_dev *dev = ctrl->pcie->port; -	return pcie_capability_read_dword(dev, reg, value); -} - -static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) -{ -	struct pci_dev *dev = ctrl->pcie->port; -	return pcie_capability_write_word(dev, reg, value); -} - -static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) -{ -	struct pci_dev *dev = ctrl->pcie->port; -	return pcie_capability_write_dword(dev, reg, value); -} - -/* Power Control Command */ -#define POWER_ON	0 -#define POWER_OFF	PCI_EXP_SLTCTL_PCC -  static irqreturn_t pcie_isr(int irq, void *dev_id);  static void start_int_poll_timer(struct controller *ctrl, int sec); @@ -92,7 +69,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)  {  	/* Clamp to sane value */  	if ((sec <= 0) || (sec > 60)) -        	sec = 2; +		sec = 2;  	ctrl->poll_timer.function = &int_poll_timeout;  	ctrl->poll_timer.data = (unsigned long)ctrl; @@ -129,20 +106,23 @@ static inline void pciehp_free_irq(struct controller *ctrl)  static int pcie_poll_cmd(struct controller *ctrl)  { +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_status; -	int err, timeout = 1000; +	int timeout = 1000; -	err = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (!err && (slot_status & PCI_EXP_SLTSTA_CC)) { -		pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC); +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); +	if (slot_status & PCI_EXP_SLTSTA_CC) { +		pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +					   PCI_EXP_SLTSTA_CC);  		return 1;  	}  	while (timeout > 0) {  		msleep(10);  		timeout -= 10; -		err = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -		if (!err && (slot_status & PCI_EXP_SLTSTA_CC)) { -			pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC); +		pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); +		if (slot_status & PCI_EXP_SLTSTA_CC) { +			pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +						   PCI_EXP_SLTSTA_CC);  			return 1;  		}  	} @@ -169,22 +149,18 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll)   * @cmd:  command value written to slot control register   * @mask: bitmask of slot control register to be modified   */ -static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) +static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)  { -	int retval = 0; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_status;  	u16 slot_ctrl;  	mutex_lock(&ctrl->ctrl_lock); -	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", -			 __func__); -		goto out; -	} - +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);  	if (slot_status & PCI_EXP_SLTSTA_CC) { +		pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +					   PCI_EXP_SLTSTA_CC);  		if (!ctrl->no_cmd_complete) {  			/*  			 * After 1 sec and CMD_COMPLETED still not set, just @@ -194,37 +170,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)  			ctrl_dbg(ctrl, "CMD_COMPLETED not clear after 1 sec\n");  		} else if (!NO_CMD_CMPL(ctrl)) {  			/* -			 * This controller semms to notify of command completed +			 * This controller seems to notify of command completed  			 * event even though it supports none of power  			 * controller, attention led, power led and EMI.  			 */ -			ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Need to " -				 "wait for command completed event.\n"); +			ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Need to wait for command completed event\n");  			ctrl->no_cmd_complete = 0;  		} else { -			ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Maybe " -				 "the controller is broken.\n"); +			ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Maybe the controller is broken\n");  		}  	} -	retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); -		goto out; -	} - +	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);  	slot_ctrl &= ~mask;  	slot_ctrl |= (cmd & mask);  	ctrl->cmd_busy = 1;  	smp_mb(); -	retval = pciehp_writew(ctrl, PCI_EXP_SLTCTL, slot_ctrl); -	if (retval) -		ctrl_err(ctrl, "Cannot write to SLOTCTRL register\n"); +	pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);  	/*  	 * Wait for command completion.  	 */ -	if (!retval && !ctrl->no_cmd_complete) { +	if (!ctrl->no_cmd_complete) {  		int poll = 0;  		/*  		 * if hotplug interrupt is not enabled or command @@ -234,21 +201,18 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)  		if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) ||  		    !(slot_ctrl & PCI_EXP_SLTCTL_CCIE))  			poll = 1; -                pcie_wait_cmd(ctrl, poll); +		pcie_wait_cmd(ctrl, poll);  	} - out:  	mutex_unlock(&ctrl->ctrl_lock); -	return retval;  } -static bool check_link_active(struct controller *ctrl) +bool pciehp_check_link_active(struct controller *ctrl)  { -	bool ret = false; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 lnk_status; +	bool ret; -	if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status)) -		return ret; - +	pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);  	ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);  	if (ret) @@ -261,12 +225,12 @@ static void __pcie_wait_link_active(struct controller *ctrl, bool active)  {  	int timeout = 1000; -	if (check_link_active(ctrl) == active) +	if (pciehp_check_link_active(ctrl) == active)  		return;  	while (timeout > 0) {  		msleep(10);  		timeout -= 10; -		if (check_link_active(ctrl) == active) +		if (pciehp_check_link_active(ctrl) == active)  			return;  	}  	ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", @@ -278,11 +242,6 @@ static void pcie_wait_link_active(struct controller *ctrl)  	__pcie_wait_link_active(ctrl, true);  } -static void pcie_wait_link_not_active(struct controller *ctrl) -{ -	__pcie_wait_link_active(ctrl, false); -} -  static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)  {  	u32 l; @@ -311,71 +270,56 @@ static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)  int pciehp_check_link_status(struct controller *ctrl)  { +	struct pci_dev *pdev = ctrl_dev(ctrl); +	bool found;  	u16 lnk_status; -	int retval = 0; -	bool found = false; -        /* -         * Data Link Layer Link Active Reporting must be capable for -         * hot-plug capable downstream port. But old controller might -         * not implement it. In this case, we wait for 1000 ms. -         */ -        if (ctrl->link_active_reporting) -                pcie_wait_link_active(ctrl); -        else -                msleep(1000); +	/* +	 * Data Link Layer Link Active Reporting must be capable for +	 * hot-plug capable downstream port. But old controller might +	 * not implement it. In this case, we wait for 1000 ms. +	*/ +	if (ctrl->link_active_reporting) +		pcie_wait_link_active(ctrl); +	else +		msleep(1000);  	/* wait 100ms before read pci conf, and try in 1s */  	msleep(100);  	found = pci_bus_check_dev(ctrl->pcie->port->subordinate,  					PCI_DEVFN(0, 0)); -	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); -	if (retval) { -		ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); -		return retval; -	} - +	pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);  	ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);  	if ((lnk_status & PCI_EXP_LNKSTA_LT) ||  	    !(lnk_status & PCI_EXP_LNKSTA_NLW)) { -		ctrl_err(ctrl, "Link Training Error occurs \n"); -		retval = -1; -		return retval; +		ctrl_err(ctrl, "Link Training Error occurs\n"); +		return -1;  	}  	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); -	if (!found && !retval) -		retval = -1; +	if (!found) +		return -1; -	return retval; +	return 0;  }  static int __pciehp_link_set(struct controller *ctrl, bool enable)  { +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 lnk_ctrl; -	int retval = 0; -	retval = pciehp_readw(ctrl, PCI_EXP_LNKCTL, &lnk_ctrl); -	if (retval) { -		ctrl_err(ctrl, "Cannot read LNKCTRL register\n"); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl);  	if (enable)  		lnk_ctrl &= ~PCI_EXP_LNKCTL_LD;  	else  		lnk_ctrl |= PCI_EXP_LNKCTL_LD; -	retval = pciehp_writew(ctrl, PCI_EXP_LNKCTL, lnk_ctrl); -	if (retval) { -		ctrl_err(ctrl, "Cannot write LNKCTRL register\n"); -		return retval; -	} +	pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl);  	ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); - -	return retval; +	return 0;  }  static int pciehp_link_enable(struct controller *ctrl) @@ -383,228 +327,165 @@ static int pciehp_link_enable(struct controller *ctrl)  	return __pciehp_link_set(ctrl, true);  } -static int pciehp_link_disable(struct controller *ctrl) -{ -	return __pciehp_link_set(ctrl, false); -} - -int pciehp_get_attention_status(struct slot *slot, u8 *status) +void pciehp_get_attention_status(struct slot *slot, u8 *status)  {  	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_ctrl; -	u8 atten_led_state; -	int retval = 0; - -	retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,  		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); -	atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; - -	switch (atten_led_state) { -	case 0: -		*status = 0xFF;	/* Reserved */ -		break; -	case 1: +	switch (slot_ctrl & PCI_EXP_SLTCTL_AIC) { +	case PCI_EXP_SLTCTL_ATTN_IND_ON:  		*status = 1;	/* On */  		break; -	case 2: +	case PCI_EXP_SLTCTL_ATTN_IND_BLINK:  		*status = 2;	/* Blink */  		break; -	case 3: +	case PCI_EXP_SLTCTL_ATTN_IND_OFF:  		*status = 0;	/* Off */  		break;  	default:  		*status = 0xFF;  		break;  	} - -	return 0;  } -int pciehp_get_power_status(struct slot *slot, u8 *status) +void pciehp_get_power_status(struct slot *slot, u8 *status)  {  	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_ctrl; -	u8 pwr_state; -	int	retval = 0; -	retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__,  		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); -	pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; - -	switch (pwr_state) { -	case 0: -		*status = 1; +	switch (slot_ctrl & PCI_EXP_SLTCTL_PCC) { +	case PCI_EXP_SLTCTL_PWR_ON: +		*status = 1;	/* On */  		break; -	case 1: -		*status = 0; +	case PCI_EXP_SLTCTL_PWR_OFF: +		*status = 0;	/* Off */  		break;  	default:  		*status = 0xFF;  		break;  	} - -	return retval;  } -int pciehp_get_latch_status(struct slot *slot, u8 *status) +void pciehp_get_latch_status(struct slot *slot, u8 *status)  { -	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(slot->ctrl);  	u16 slot_status; -	int retval; -	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", -			 __func__); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);  	*status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS); -	return 0;  } -int pciehp_get_adapter_status(struct slot *slot, u8 *status) +void pciehp_get_adapter_status(struct slot *slot, u8 *status)  { -	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(slot->ctrl);  	u16 slot_status; -	int retval; -	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", -			 __func__); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);  	*status = !!(slot_status & PCI_EXP_SLTSTA_PDS); -	return 0;  }  int pciehp_query_power_fault(struct slot *slot)  { -	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(slot->ctrl);  	u16 slot_status; -	int retval; -	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (retval) { -		ctrl_err(ctrl, "Cannot check for power fault\n"); -		return retval; -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);  	return !!(slot_status & PCI_EXP_SLTSTA_PFD);  } -int pciehp_set_attention_status(struct slot *slot, u8 value) +void pciehp_set_attention_status(struct slot *slot, u8 value)  {  	struct controller *ctrl = slot->ctrl;  	u16 slot_cmd; -	u16 cmd_mask; -	cmd_mask = PCI_EXP_SLTCTL_AIC; +	if (!ATTN_LED(ctrl)) +		return; +  	switch (value) { -	case 0 :	/* turn off */ -		slot_cmd = 0x00C0; +	case 0:		/* turn off */ +		slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_OFF;  		break;  	case 1:		/* turn on */ -		slot_cmd = 0x0040; +		slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_ON;  		break;  	case 2:		/* turn blink */ -		slot_cmd = 0x0080; +		slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_BLINK;  		break;  	default: -		return -EINVAL; +		return;  	}  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,  		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); -	return pcie_write_cmd(ctrl, slot_cmd, cmd_mask); +	pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC);  }  void pciehp_green_led_on(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl; -	u16 slot_cmd; -	u16 cmd_mask; -	slot_cmd = 0x0100; -	cmd_mask = PCI_EXP_SLTCTL_PIC; -	pcie_write_cmd(ctrl, slot_cmd, cmd_mask); +	if (!PWR_LED(ctrl)) +		return; + +	pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON, PCI_EXP_SLTCTL_PIC);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, -		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); +		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, +		 PCI_EXP_SLTCTL_PWR_IND_ON);  }  void pciehp_green_led_off(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl; -	u16 slot_cmd; -	u16 cmd_mask; -	slot_cmd = 0x0300; -	cmd_mask = PCI_EXP_SLTCTL_PIC; -	pcie_write_cmd(ctrl, slot_cmd, cmd_mask); +	if (!PWR_LED(ctrl)) +		return; + +	pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, PCI_EXP_SLTCTL_PIC);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, -		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); +		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, +		 PCI_EXP_SLTCTL_PWR_IND_OFF);  }  void pciehp_green_led_blink(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl; -	u16 slot_cmd; -	u16 cmd_mask; -	slot_cmd = 0x0200; -	cmd_mask = PCI_EXP_SLTCTL_PIC; -	pcie_write_cmd(ctrl, slot_cmd, cmd_mask); +	if (!PWR_LED(ctrl)) +		return; + +	pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, PCI_EXP_SLTCTL_PIC);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, -		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); +		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, +		 PCI_EXP_SLTCTL_PWR_IND_BLINK);  } -int pciehp_power_on_slot(struct slot * slot) +int pciehp_power_on_slot(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl; -	u16 slot_cmd; -	u16 cmd_mask; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_status; -	int retval = 0; +	int retval;  	/* Clear sticky power-fault bit from previous power failures */ -	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", -			 __func__); -		return retval; -	} -	slot_status &= PCI_EXP_SLTSTA_PFD; -	if (slot_status) { -		retval = pciehp_writew(ctrl, PCI_EXP_SLTSTA, slot_status); -		if (retval) { -			ctrl_err(ctrl, -				 "%s: Cannot write to SLOTSTATUS register\n", -				 __func__); -			return retval; -		} -	} +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); +	if (slot_status & PCI_EXP_SLTSTA_PFD) +		pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +					   PCI_EXP_SLTSTA_PFD);  	ctrl->power_fault_detected = 0; -	slot_cmd = POWER_ON; -	cmd_mask = PCI_EXP_SLTCTL_PCC; -	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); -	if (retval) { -		ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); -		return retval; -	} +	pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, -		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); +		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, +		 PCI_EXP_SLTCTL_PWR_ON);  	retval = pciehp_link_enable(ctrl);  	if (retval) @@ -613,36 +494,20 @@ int pciehp_power_on_slot(struct slot * slot)  	return retval;  } -int pciehp_power_off_slot(struct slot * slot) +void pciehp_power_off_slot(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl; -	u16 slot_cmd; -	u16 cmd_mask; -	int retval; -	/* Disable the link at first */ -	pciehp_link_disable(ctrl); -	/* wait the link is down */ -	if (ctrl->link_active_reporting) -		pcie_wait_link_not_active(ctrl); -	else -		msleep(1000); - -	slot_cmd = POWER_OFF; -	cmd_mask = PCI_EXP_SLTCTL_PCC; -	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); -	if (retval) { -		ctrl_err(ctrl, "Write command failed!\n"); -		return retval; -	} +	pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC);  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, -		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); -	return 0; +		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, +		 PCI_EXP_SLTCTL_PWR_OFF);  }  static irqreturn_t pcie_isr(int irq, void *dev_id)  {  	struct controller *ctrl = (struct controller *)dev_id; +	struct pci_dev *pdev = ctrl_dev(ctrl);  	struct slot *slot = ctrl->slot;  	u16 detected, intr_loc; @@ -653,24 +518,18 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)  	 */  	intr_loc = 0;  	do { -		if (pciehp_readw(ctrl, PCI_EXP_SLTSTA, &detected)) { -			ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n", -				 __func__); -			return IRQ_NONE; -		} +		pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected);  		detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |  			     PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | -			     PCI_EXP_SLTSTA_CC); +			     PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);  		detected &= ~intr_loc;  		intr_loc |= detected;  		if (!intr_loc)  			return IRQ_NONE; -		if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) { -			ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", -				 __func__); -			return IRQ_NONE; -		} +		if (detected) +			pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +						   intr_loc);  	} while (detected);  	ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc); @@ -702,10 +561,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)  		ctrl->power_fault_detected = 1;  		pciehp_handle_power_fault(slot);  	} + +	if (intr_loc & PCI_EXP_SLTSTA_DLLSC) +		pciehp_handle_linkstate_change(slot); +  	return IRQ_HANDLED;  } -int pcie_enable_notification(struct controller *ctrl) +void pcie_enable_notification(struct controller *ctrl)  {  	u16 cmd, mask; @@ -719,9 +582,17 @@ int pcie_enable_notification(struct controller *ctrl)  	 * when it is cleared in the interrupt service routine, and  	 * next power fault detected interrupt was notified again.  	 */ -	cmd = PCI_EXP_SLTCTL_PDCE; + +	/* +	 * Always enable link events: thus link-up and link-down shall +	 * always be treated as hotplug and unplug respectively. Enable +	 * presence detect only if Attention Button is not present. +	 */ +	cmd = PCI_EXP_SLTCTL_DLLSCE;  	if (ATTN_BUTTN(ctrl))  		cmd |= PCI_EXP_SLTCTL_ABPE; +	else +		cmd |= PCI_EXP_SLTCTL_PDCE;  	if (MRL_SENS(ctrl))  		cmd |= PCI_EXP_SLTCTL_MRLSCE;  	if (!pciehp_poll_mode) @@ -729,53 +600,57 @@ int pcie_enable_notification(struct controller *ctrl)  	mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |  		PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | -		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); +		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | +		PCI_EXP_SLTCTL_DLLSCE); -	if (pcie_write_cmd(ctrl, cmd, mask)) { -		ctrl_err(ctrl, "Cannot enable software notification\n"); -		return -1; -	} -	return 0; +	pcie_write_cmd(ctrl, cmd, mask);  }  static void pcie_disable_notification(struct controller *ctrl)  {  	u16 mask; +  	mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |  		PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |  		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |  		PCI_EXP_SLTCTL_DLLSCE); -	if (pcie_write_cmd(ctrl, 0, mask)) -		ctrl_warn(ctrl, "Cannot disable software notification\n"); +	pcie_write_cmd(ctrl, 0, mask);  }  /*   * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary - * bus reset of the bridge, but if the slot supports surprise removal we need - * to disable presence detection around the bus reset and clear any spurious + * bus reset of the bridge, but at the same time we want to ensure that it is + * not seen as a hot-unplug, followed by the hot-plug of the device. Thus, + * disable link state notification and presence detection change notification + * momentarily, if we see that they could interfere. Also, clear any spurious   * events after.   */  int pciehp_reset_slot(struct slot *slot, int probe)  {  	struct controller *ctrl = slot->ctrl; +	struct pci_dev *pdev = ctrl_dev(ctrl); +	u16 stat_mask = 0, ctrl_mask = 0;  	if (probe)  		return 0; -	if (HP_SUPR_RM(ctrl)) { -		pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE); -		if (pciehp_poll_mode) -			del_timer_sync(&ctrl->poll_timer); +	if (!ATTN_BUTTN(ctrl)) { +		ctrl_mask |= PCI_EXP_SLTCTL_PDCE; +		stat_mask |= PCI_EXP_SLTSTA_PDC;  	} +	ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE; +	stat_mask |= PCI_EXP_SLTSTA_DLLSC; + +	pcie_write_cmd(ctrl, 0, ctrl_mask); +	if (pciehp_poll_mode) +		del_timer_sync(&ctrl->poll_timer);  	pci_reset_bridge_secondary_bus(ctrl->pcie->port); -	if (HP_SUPR_RM(ctrl)) { -		pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDC); -		pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE); -		if (pciehp_poll_mode) -			int_poll_timeout(ctrl->poll_timer.data); -	} +	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); +	pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); +	if (pciehp_poll_mode) +		int_poll_timeout(ctrl->poll_timer.data);  	return 0;  } @@ -784,10 +659,7 @@ int pcie_init_notification(struct controller *ctrl)  {  	if (pciehp_request_irq(ctrl))  		return -1; -	if (pcie_enable_notification(ctrl)) { -		pciehp_free_irq(ctrl); -		return -1; -	} +	pcie_enable_notification(ctrl);  	ctrl->notification_enabled = 1;  	return 0;  } @@ -815,6 +687,7 @@ static int pcie_init_slot(struct controller *ctrl)  	slot->ctrl = ctrl;  	mutex_init(&slot->lock); +	mutex_init(&slot->hotplug_lock);  	INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);  	ctrl->slot = slot;  	return 0; @@ -875,12 +748,14 @@ static inline void dbg_ctrl(struct controller *ctrl)  		  EMI(ctrl)        ? "yes" : "no");  	ctrl_info(ctrl, "  Command Completed    : %3s\n",  		  NO_CMD_CMPL(ctrl) ? "no" : "yes"); -	pciehp_readw(ctrl, PCI_EXP_SLTSTA, ®16); +	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, ®16);  	ctrl_info(ctrl, "Slot Status            : 0x%04x\n", reg16); -	pciehp_readw(ctrl, PCI_EXP_SLTCTL, ®16); +	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, ®16);  	ctrl_info(ctrl, "Slot Control           : 0x%04x\n", reg16);  } +#define FLAG(x, y)	(((x) & (y)) ? '+' : '-') +  struct controller *pcie_init(struct pcie_device *dev)  {  	struct controller *ctrl; @@ -893,11 +768,7 @@ struct controller *pcie_init(struct pcie_device *dev)  		goto abort;  	}  	ctrl->pcie = dev; -	if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { -		ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); -		goto abort_ctrl; -	} - +	pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);  	ctrl->slot_cap = slot_cap;  	mutex_init(&ctrl->ctrl_lock);  	init_waitqueue_head(&ctrl->queue); @@ -910,28 +781,34 @@ struct controller *pcie_init(struct pcie_device *dev)  	 */  	if (NO_CMD_CMPL(ctrl) ||  	    !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl))) -	    ctrl->no_cmd_complete = 1; - -        /* Check if Data Link Layer Link Active Reporting is implemented */ -        if (pciehp_readl(ctrl, PCI_EXP_LNKCAP, &link_cap)) { -                ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); -                goto abort_ctrl; -        } -        if (link_cap & PCI_EXP_LNKCAP_DLLLARC) { -                ctrl_dbg(ctrl, "Link Active Reporting supported\n"); -                ctrl->link_active_reporting = 1; -        } +		ctrl->no_cmd_complete = 1; + +	/* Check if Data Link Layer Link Active Reporting is implemented */ +	pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); +	if (link_cap & PCI_EXP_LNKCAP_DLLLARC) { +		ctrl_dbg(ctrl, "Link Active Reporting supported\n"); +		ctrl->link_active_reporting = 1; +	}  	/* Clear all remaining event bits in Slot Status register */ -	if (pciehp_writew(ctrl, PCI_EXP_SLTSTA, 0x1f)) -		goto abort_ctrl; +	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, +		PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | +		PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | +		PCI_EXP_SLTSTA_CC); -	/* Disable sotfware notification */ +	/* Disable software notification */  	pcie_disable_notification(ctrl); -	ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", -		  pdev->vendor, pdev->device, pdev->subsystem_vendor, -		  pdev->subsystem_device); +	ctrl_info(ctrl, "Slot #%d AttnBtn%c AttnInd%c PwrInd%c PwrCtrl%c MRL%c Interlock%c NoCompl%c LLActRep%c\n", +		(slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, +		FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_AIP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_PIP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_PCP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_MRLSP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_EIP), +		FLAG(slot_cap, PCI_EXP_SLTCAP_NCCS), +		FLAG(link_cap, PCI_EXP_LNKCAP_DLLLARC));  	if (pcie_init_slot(ctrl))  		goto abort_ctrl; diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 0e0d0f7f63f..5f871f4c4af 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -39,27 +39,29 @@ int pciehp_configure_device(struct slot *p_slot)  	struct pci_dev *dev;  	struct pci_dev *bridge = p_slot->ctrl->pcie->port;  	struct pci_bus *parent = bridge->subordinate; -	int num; +	int num, ret = 0;  	struct controller *ctrl = p_slot->ctrl; +	pci_lock_rescan_remove(); +  	dev = pci_get_slot(parent, PCI_DEVFN(0, 0));  	if (dev) { -		ctrl_err(ctrl, "Device %s already exists " -			 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), -			 pci_domain_nr(parent), parent->number); +		ctrl_err(ctrl, "Device %s already exists at %04x:%02x:00, cannot hot-add\n", +			 pci_name(dev), pci_domain_nr(parent), parent->number);  		pci_dev_put(dev); -		return -EINVAL; +		ret = -EEXIST; +		goto out;  	}  	num = pci_scan_slot(parent, PCI_DEVFN(0, 0));  	if (num == 0) {  		ctrl_err(ctrl, "No new device found\n"); -		return -ENODEV; +		ret = -ENODEV; +		goto out;  	}  	list_for_each_entry(dev, &parent->devices, bus_list) -		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || -				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) +		if (pci_is_bridge(dev))  			pci_hp_add_bridge(dev);  	pci_assign_unassigned_bridge_resources(bridge); @@ -73,12 +75,14 @@ int pciehp_configure_device(struct slot *p_slot)  	pci_bus_add_devices(parent); -	return 0; + out: +	pci_unlock_rescan_remove(); +	return ret;  }  int pciehp_unconfigure_device(struct slot *p_slot)  { -	int ret, rc = 0; +	int rc = 0;  	u8 bctl = 0;  	u8 presence = 0;  	struct pci_dev *dev, *temp; @@ -88,9 +92,9 @@ int pciehp_unconfigure_device(struct slot *p_slot)  	ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n",  		 __func__, pci_domain_nr(parent), parent->number); -	ret = pciehp_get_adapter_status(p_slot, &presence); -	if (ret) -		presence = 0; +	pciehp_get_adapter_status(p_slot, &presence); + +	pci_lock_rescan_remove();  	/*  	 * Stopping an SR-IOV PF device removes all the associated VFs, @@ -126,5 +130,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)  		pci_dev_put(dev);  	} +	pci_unlock_rescan_remove();  	return rc;  } diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index 1f00b937f72..d062c008fc9 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c @@ -51,8 +51,8 @@ static LIST_HEAD(slot_list);  #define dbg(format, arg...)					\  	do {							\  		if (debug)					\ -			printk (KERN_DEBUG "%s: " format "\n",	\ -				MY_NAME , ## arg); 		\ +			printk(KERN_DEBUG "%s: " format "\n",	\ +				MY_NAME , ## arg);		\  	} while (0)  #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) @@ -128,18 +128,18 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)  	dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);  	switch (status) { -		case 0: -			/* -			 * Fill in code here to turn light off -			 */ -			break; - -		case 1: -		default: -			/* -			 * Fill in code here to turn light on -			 */ -			break; +	case 0: +		/* +		 * Fill in code here to turn light off +		 */ +		break; + +	case 1: +	default: +		/* +		 * Fill in code here to turn light on +		 */ +		break;  	}  	return retval; @@ -153,12 +153,12 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)  	dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);  	switch (value) { -		case 0: -			/* Specify a test here */ -			break; -		case 1: -			/* Specify another test here */ -			break; +	case 0: +		/* Specify a test here */ +		break; +	case 1: +		/* Specify another test here */ +		break;  	}  	return retval; @@ -287,7 +287,7 @@ static int __init init_slots(void)  		hotplug_slot->release = &release_slot;  		make_slot_name(slot);  		hotplug_slot->ops = &skel_hotplug_slot_ops; -		 +  		/*  		 * Initialize the slot info structure with some known  		 * good values. @@ -296,7 +296,7 @@ static int __init init_slots(void)  		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) { @@ -336,7 +336,7 @@ static void __exit cleanup_slots(void)  		pci_hp_deregister(slot->hotplug_slot);  	}  } -		 +  static int __init pcihp_skel_init(void)  {  	int retval; diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index 16f92035231..e246a10a0d2 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c @@ -160,8 +160,7 @@ void pci_configure_slot(struct pci_dev *dev)  			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))  		return; -	if (dev->bus) -		pcie_bus_configure_settings(dev->bus); +	pcie_bus_configure_settings(dev->bus);  	memset(&hpp, 0, sizeof(hpp));  	ret = pci_get_hp_params(dev, &hpp); diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index bb7af78e4ee..7660232ef46 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -157,8 +157,7 @@ static void dlpar_pci_add_bus(struct device_node *dn)  	}  	/* Scan below the new bridge */ -	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || -	    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) +	if (pci_is_bridge(dev))  		of_scan_pci_bridge(dev);  	/* Map IO space for child bus, which may or may not succeed */ @@ -217,7 +216,7 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn)  	if (!pcibios_find_pci_bus(dn))  		return -EINVAL; -	/* If pci slot is hotplugable, use hotplug to remove it */ +	/* If pci slot is hotpluggable, use hotplug to remove it */  	slot = find_php_slot(dn);  	if (slot && rpaphp_deregister_slot(slot)) {  		printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", @@ -354,10 +353,15 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)  {  	struct pci_bus *bus;  	struct slot *slot; +	int ret = 0; + +	pci_lock_rescan_remove();  	bus = pcibios_find_pci_bus(dn); -	if (!bus) -		return -EINVAL; +	if (!bus) { +		ret = -EINVAL; +		goto out; +	}  	pr_debug("PCI: Removing PCI slot below EADS bridge %s\n",  		 bus->self ? pci_name(bus->self) : "<!PHB!>"); @@ -371,7 +375,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)  			printk(KERN_ERR  				"%s: unable to remove hotplug slot %s\n",  				__func__, drc_name); -			return -EIO; +			ret = -EIO; +			goto out;  		}  	} @@ -382,7 +387,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)  	if (pcibios_unmap_io_space(bus)) {  		printk(KERN_ERR "%s: failed to unmap bus range\n",  			__func__); -		return -ERANGE; +		ret = -ERANGE; +		goto out;  	}  	/* Remove the EADS bridge device itself */ @@ -390,7 +396,9 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)  	pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));  	pci_stop_and_remove_bus_device(bus->self); -	return 0; + out: +	pci_unlock_rescan_remove(); +	return ret;  }  /** diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 3135856e5e1..b2593e876a0 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -49,9 +49,9 @@  extern bool rpaphp_debug;  #define dbg(format, arg...)					\  	do {							\ -		if (rpaphp_debug)					\ +		if (rpaphp_debug)				\  			printk(KERN_DEBUG "%s: " format,	\ -				MY_NAME , ## arg); 		\ +				MY_NAME , ## arg);		\  	} while (0)  #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)  #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) @@ -99,5 +99,5 @@ void dealloc_slot_struct(struct slot *slot);  struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);  int rpaphp_register_slot(struct slot *slot);  int rpaphp_deregister_slot(struct slot *slot); -	 +  #endif				/* _PPC64PHP_H */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 127d6e60018..93aa29f6d39 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -39,6 +39,7 @@  bool rpaphp_debug;  LIST_HEAD(rpaphp_slot_head); +EXPORT_SYMBOL_GPL(rpaphp_slot_head);  #define DRIVER_VERSION	"0.1"  #define DRIVER_AUTHOR	"Linda Xie <lxie@us.ibm.com>" @@ -88,7 +89,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)   * @hotplug_slot: slot to get status   * @value: pointer to store status   */ -static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int retval, level;  	struct slot *slot = (struct slot *)hotplug_slot->private; @@ -104,14 +105,14 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)   * @hotplug_slot: slot to get status   * @value: pointer to store status   */ -static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = (struct slot *)hotplug_slot->private;  	*value = slot->hotplug_slot->info->attention_status;  	return 0;  } -static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	struct slot *slot = (struct slot *)hotplug_slot->private;  	int rc, state; @@ -223,16 +224,16 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,  	type_tmp = (char *) &types[1];  	/* Iterate through parent properties, looking for my-drc-index */ -	for (i = 0; i < indexes[0]; i++) { +	for (i = 0; i < be32_to_cpu(indexes[0]); i++) {  		if ((unsigned int) indexes[i + 1] == *my_index) {  			if (drc_name) -                		*drc_name = name_tmp; +				*drc_name = name_tmp;  			if (drc_type)  				*drc_type = type_tmp;  			if (drc_index) -				*drc_index = *my_index; +				*drc_index = be32_to_cpu(*my_index);  			if (drc_power_domain) -				*drc_power_domain = domains[i+1]; +				*drc_power_domain = be32_to_cpu(domains[i+1]);  			return 0;  		}  		name_tmp += (strlen(name_tmp) + 1); @@ -241,6 +242,7 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,  	return -EINVAL;  } +EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);  static int is_php_type(char *drc_type)  { @@ -289,7 +291,7 @@ static int is_php_dn(struct device_node *dn, const int **indexes,   * rpaphp_add_slot -- declare a hotplug slot to the hotplug subsystem.   * @dn: device node of slot   * - * This subroutine will register a hotplugable slot with the + * This subroutine will register a hotpluggable slot with the   * PCI hotplug infrastructure. This routine is typically called   * during boot time, if the hotplug slots are present at boot time,   * or is called later, by the dlpar add code, if the slot is @@ -321,16 +323,19 @@ int rpaphp_add_slot(struct device_node *dn)  	/* register PCI devices */  	name = (char *) &names[1];  	type = (char *) &types[1]; -	for (i = 0; i < indexes[0]; i++) { +	for (i = 0; i < be32_to_cpu(indexes[0]); i++) { +		int index; -		slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]); +		index = be32_to_cpu(indexes[i + 1]); +		slot = alloc_slot_struct(dn, index, name, +					 be32_to_cpu(power_domains[i + 1]));  		if (!slot)  			return -ENOMEM;  		slot->type = simple_strtoul(type, NULL, 10); -				 +  		dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", -				indexes[i + 1], name, type); +				index, name, type);  		retval = rpaphp_enable_slot(slot);  		if (!retval) @@ -347,6 +352,7 @@ int rpaphp_add_slot(struct device_node *dn)  	/* XXX FIXME: reports a failure only if last entry in loop failed */  	return retval;  } +EXPORT_SYMBOL_GPL(rpaphp_add_slot);  static void __exit cleanup_slots(void)  { @@ -356,7 +362,7 @@ static void __exit cleanup_slots(void)  	/*  	 * Unregister all of our slots with the pci_hotplug subsystem,  	 * and free up all memory that we had allocated. -	 * memory will be freed in release_slot callback.  +	 * memory will be freed in release_slot callback.  	 */  	list_for_each_safe(tmp, n, &rpaphp_slot_head) { @@ -398,7 +404,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)  		return retval;  	if (state == PRESENT) { +		pci_lock_rescan_remove();  		pcibios_add_pci_devices(slot->bus); +		pci_unlock_rescan_remove();  		slot->state = CONFIGURED;  	} else if (state == EMPTY) {  		slot->state = EMPTY; @@ -418,7 +426,9 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)  	if (slot->state == NOT_CONFIGURED)  		return -EINVAL; +	pci_lock_rescan_remove();  	pcibios_remove_pci_devices(slot->bus); +	pci_unlock_rescan_remove();  	vm_unmap_aliases();  	slot->state = NOT_CONFIGURED; @@ -436,7 +446,3 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {  module_init(rpaphp_init);  module_exit(rpaphp_exit); - -EXPORT_SYMBOL_GPL(rpaphp_add_slot); -EXPORT_SYMBOL_GPL(rpaphp_slot_head); -EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 513e1e28239..9243f3e7a1c 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -44,7 +44,7 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state)  			dbg("%s: slot must be power up to get sensor-state\n",  			    __func__); -			/* some slots have to be powered up  +			/* some slots have to be powered up  			 * before get-sensor will succeed.  			 */  			rc = rtas_set_power_level(slot->power_domain, POWER_ON, @@ -133,4 +133,3 @@ int rpaphp_enable_slot(struct slot *slot)  	return 0;  } - diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b283bbea6d2..a6082cc263f 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -1,5 +1,5 @@  /* - * RPA Virtual I/O device functions  + * RPA Virtual I/O device functions   * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>   *   * All rights reserved. @@ -51,27 +51,27 @@ struct slot *alloc_slot_struct(struct device_node *dn,                         int drc_index, char *drc_name, int power_domain)  {  	struct slot *slot; -	 +  	slot = kzalloc(sizeof(struct slot), GFP_KERNEL);  	if (!slot)  		goto error_nomem;  	slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);  	if (!slot->hotplug_slot) -		goto error_slot;	 +		goto error_slot;  	slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),  					   GFP_KERNEL);  	if (!slot->hotplug_slot->info)  		goto error_hpslot;  	slot->name = kstrdup(drc_name, GFP_KERNEL);  	if (!slot->name) -		goto error_info;	 +		goto error_info;  	slot->dn = dn;  	slot->index = drc_index;  	slot->power_domain = power_domain;  	slot->hotplug_slot->private = slot;  	slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;  	slot->hotplug_slot->release = &rpaphp_release_slot; -	 +  	return (slot);  error_info: @@ -91,7 +91,7 @@ static int is_registered(struct slot *slot)  	list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) {  		if (!strcmp(tmp_slot->name, slot->name))  			return 1; -	}	 +	}  	return 0;  } @@ -104,7 +104,7 @@ int rpaphp_deregister_slot(struct slot *slot)  		__func__, slot->name);  	list_del(&slot->rpaphp_slot_list); -	 +  	retval = pci_hp_deregister(php_slot);  	if (retval)  		err("Problem unregistering a slot %s\n", slot->name); @@ -120,7 +120,7 @@ int rpaphp_register_slot(struct slot *slot)  	int retval;  	int slotno; -	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",  +	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",  		__func__, slot->dn->full_name, slot->index, slot->name,  		slot->power_domain, slot->type); @@ -128,7 +128,7 @@ int rpaphp_register_slot(struct slot *slot)  	if (is_registered(slot)) {  		err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);  		return -EAGAIN; -	}	 +	}  	if (slot->dn->child)  		slotno = PCI_SLOT(PCI_DN(slot->dn->child)->devfn); @@ -145,4 +145,3 @@ int rpaphp_register_slot(struct slot *slot)  	info("Slot [%s] registered\n", slot->name);  	return 0;  } - diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 66e505ca24e..d1332d2f873 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -15,7 +15,6 @@  #include <linux/slab.h>  #include <linux/pci.h>  #include <linux/pci_hotplug.h> -#include <linux/init.h>  #include <asm/pci_debug.h>  #include <asm/sclp.h> @@ -80,7 +79,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)  		goto out_deconfigure;  	pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); +	pci_lock_rescan_remove();  	pci_bus_add_devices(slot->zdev->bus); +	pci_unlock_rescan_remove();  	return rc; @@ -98,7 +99,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)  		return -EIO;  	if (slot->zdev->pdev) -		pci_stop_and_remove_bus_device(slot->zdev->pdev); +		pci_stop_and_remove_bus_device_locked(slot->zdev->pdev);  	rc = zpci_disable_device(slot->zdev);  	if (rc) @@ -133,7 +134,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)  {  	struct slot *slot = hotplug_slot->private; -	pr_debug("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));  	kfree(slot->hotplug_slot->info);  	kfree(slot->hotplug_slot);  	kfree(slot); @@ -183,10 +183,9 @@ int zpci_init_slot(struct zpci_dev *zdev)  	snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);  	rc = pci_hp_register(slot->hotplug_slot, zdev->bus,  			     ZPCI_DEVFN, name); -	if (rc) { -		pr_err("pci_hp_register failed with error %d\n", rc); +	if (rc)  		goto error_reg; -	} +  	list_add(&slot->slot_list, &s390_hotplug_slot_list);  	return 0; diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index b2781dfe60e..bada2099987 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -9,6 +9,7 @@   * Work to add BIOS PROM support was completed by Mike Habeck.   */ +#include <linux/acpi.h>  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/module.h> @@ -29,7 +30,6 @@  #include <asm/sn/sn_feature_sets.h>  #include <asm/sn/sn_sal.h>  #include <asm/sn/types.h> -#include <linux/acpi.h>  #include <asm/sn/acpi.h>  #include "../pci.h" @@ -188,7 +188,7 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,  	return 0;  } -static struct hotplug_slot * sn_hp_destroy(void) +static struct hotplug_slot *sn_hp_destroy(void)  {  	struct slot *slot;  	struct pci_slot *pci_slot; @@ -250,15 +250,13 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,  	}  	if (rc == PCI_L1_ERR) { -		dev_dbg(&slot->pci_bus->self->dev, -			"L1 failure %d with message: %s", +		dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message: %s",  			resp.resp_sub_errno, resp.resp_l1_msg);  		return -EPERM;  	}  	if (rc) { -		dev_dbg(&slot->pci_bus->self->dev, -			"insert failed with error %d sub-error %d\n", +		dev_dbg(&slot->pci_bus->self->dev, "insert failed with error %d sub-error %d\n",  			rc, resp.resp_sub_errno);  		return -EIO;  	} @@ -288,21 +286,18 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,  	}  	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) { -		dev_dbg(&slot->pci_bus->self->dev, -			"Cannot remove last 33MHz card\n"); +		dev_dbg(&slot->pci_bus->self->dev, "Cannot remove last 33MHz card\n");  		return -EPERM;  	}  	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) { -		dev_dbg(&slot->pci_bus->self->dev, -			"L1 failure %d with message \n%s\n", +		dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message \n%s\n",  			resp.resp_sub_errno, resp.resp_l1_msg);  		return -EPERM;  	}  	if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) { -		dev_dbg(&slot->pci_bus->self->dev, -			"remove failed with error %d sub-error %d\n", +		dev_dbg(&slot->pci_bus->self->dev, "remove failed with error %d sub-error %d\n",  			rc, resp.resp_sub_errno);  		return -EIO;  	} @@ -414,11 +409,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)  		acpi_handle rethandle;  		acpi_status ret; -		phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; +		phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);  		if (acpi_bus_get_device(phandle, &pdevice)) { -			dev_dbg(&slot->pci_bus->self->dev, -				"no parent device, assuming NULL\n"); +			dev_dbg(&slot->pci_bus->self->dev, "no parent device, assuming NULL\n");  			pdevice = NULL;  		} @@ -447,10 +441,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)  				ret = acpi_bus_scan(chandle);  				if (ACPI_FAILURE(ret)) { -					printk(KERN_ERR "%s: acpi_bus_scan " -					       "failed (0x%x) for slot %d " -					       "func %d\n", __func__, -					       ret, (int)(adr>>16), +					printk(KERN_ERR "%s: acpi_bus_scan failed (0x%x) for slot %d func %d\n", +					       __func__, ret, (int)(adr>>16),  					       (int)(adr&0xffff));  					/* try to continue on */  				} @@ -459,20 +451,21 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)  		acpi_scan_lock_release();  	} +	pci_lock_rescan_remove(); +  	/* Call the driver for the new device */  	pci_bus_add_devices(slot->pci_bus);  	/* Call the drivers for the new devices subordinate to PPB */  	if (new_ppb)  		pci_bus_add_devices(new_bus); +	pci_unlock_rescan_remove();  	mutex_unlock(&sn_hotplug_mutex);  	if (rc == 0) -		dev_dbg(&slot->pci_bus->self->dev, -			"insert operation successful\n"); +		dev_dbg(&slot->pci_bus->self->dev, "insert operation successful\n");  	else -		dev_dbg(&slot->pci_bus->self->dev, -			"insert operation failed rc = %d\n", rc); +		dev_dbg(&slot->pci_bus->self->dev, "insert operation failed rc = %d\n", rc);  	return rc;  } @@ -495,7 +488,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)  	/* free the ACPI resources for the slot */  	if (SN_ACPI_BASE_SUPPORT() && -            PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { +            PCI_CONTROLLER(slot->pci_bus)->companion) {  		unsigned long long adr;  		struct acpi_device *device;  		acpi_handle phandle; @@ -504,7 +497,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)  		acpi_status ret;  		/* Get the rootbus node pointer */ -		phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; +		phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);  		acpi_scan_lock_acquire();  		/* @@ -540,6 +533,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)  		acpi_scan_lock_release();  	} +	pci_lock_rescan_remove();  	/* Free the SN resources assigned to the Linux device.*/  	list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {  		if (PCI_SLOT(dev->devfn) != slot->device_num + 1) @@ -550,14 +544,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)  		pci_stop_and_remove_bus_device(dev);  		pci_dev_put(dev);  	} +	pci_unlock_rescan_remove();  	/* Remove the SSDT for the slot from the ACPI namespace */  	if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {  		acpi_status ret;  		ret = acpi_unload_table_id(ssdt_id);  		if (ACPI_FAILURE(ret)) { -			printk(KERN_ERR "%s: acpi_unload_table_id " -			       "failed (0x%x) for id %d\n", +			printk(KERN_ERR "%s: acpi_unload_table_id failed (0x%x) for id %d\n",  			       __func__, ret, ssdt_id);  			/* try to continue on */  		} diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index e260f207a90..5897d516427 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -180,7 +180,7 @@ int shpchp_configure_device(struct slot *p_slot);  int shpchp_unconfigure_device(struct slot *p_slot);  void cleanup_slots(struct controller *ctrl);  void shpchp_queue_pushbutton_work(struct work_struct *work); -int shpc_init( struct controller *ctrl, struct pci_dev *pdev); +int shpc_init(struct controller *ctrl, struct pci_dev *pdev);  static inline const char *slot_name(struct slot *slot)  { @@ -191,7 +191,7 @@ static inline const char *slot_name(struct slot *slot)  #include <linux/pci-acpi.h>  static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev)  { -	u32 flags = OSC_SHPC_NATIVE_HP_CONTROL; +	u32 flags = OSC_PCI_SHPC_NATIVE_HP_CONTROL;  	return acpi_get_hp_hw_control_from_firmware(dev, flags);  }  #else @@ -216,13 +216,13 @@ struct ctrl_reg {  /* offsets to the controller registers based on the above structure layout */  enum ctrl_offsets { -	BASE_OFFSET 	 = offsetof(struct ctrl_reg, base_offset), -	SLOT_AVAIL1 	 = offsetof(struct ctrl_reg, slot_avail1), +	BASE_OFFSET	 = offsetof(struct ctrl_reg, base_offset), +	SLOT_AVAIL1	 = offsetof(struct ctrl_reg, slot_avail1),  	SLOT_AVAIL2	 = offsetof(struct ctrl_reg, slot_avail2), -	SLOT_CONFIG 	 = offsetof(struct ctrl_reg, slot_config), +	SLOT_CONFIG	 = offsetof(struct ctrl_reg, slot_config),  	SEC_BUS_CONFIG	 = offsetof(struct ctrl_reg, sec_bus_config),  	MSI_CTRL	 = offsetof(struct ctrl_reg, msi_ctrl), -	PROG_INTERFACE 	 = offsetof(struct ctrl_reg, prog_interface), +	PROG_INTERFACE	 = offsetof(struct ctrl_reg, prog_interface),  	CMD		 = offsetof(struct ctrl_reg, cmd),  	CMD_STATUS	 = offsetof(struct ctrl_reg, cmd_status),  	INTR_LOC	 = offsetof(struct ctrl_reg, intr_loc), @@ -295,7 +295,7 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)  		pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, rse_set);  	}  	/* restore MiscII register */ -	pci_read_config_dword( p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp ); +	pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp );  	if (p_slot->ctrl->pcix_misc2_reg & SERRFATALENABLE_MASK)  		pcix_misc2_temp |= SERRFATALENABLE_MASK; diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index d3f757df691..294ef4b10cf 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -143,11 +143,10 @@ static int init_slots(struct controller *ctrl)  		snprintf(name, SLOT_NAME_SIZE, "%d", slot->number);  		hotplug_slot->ops = &shpchp_hotplug_slot_ops; - 		ctrl_dbg(ctrl, "Registering domain:bus:dev=%04x:%02x:%02x " - 			 "hp_slot=%x sun=%x slot_device_offset=%x\n", - 			 pci_domain_nr(ctrl->pci_dev->subordinate), - 			 slot->bus, slot->device, slot->hp_slot, slot->number, - 			 ctrl->slot_device_offset); +		ctrl_dbg(ctrl, "Registering domain:bus:dev=%04x:%02x:%02x hp_slot=%x sun=%x slot_device_offset=%x\n", +			 pci_domain_nr(ctrl->pci_dev->subordinate), +			 slot->bus, slot->device, slot->hp_slot, slot->number, +			 ctrl->slot_device_offset);  		retval = pci_hp_register(slot->hotplug_slot,  				ctrl->pci_dev->subordinate, slot->device, name);  		if (retval) { diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 58499277903..a81fb67ea9a 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -162,7 +162,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)  	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); -	if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { +	if (!(p_slot->hpc_ops->query_power_fault(p_slot))) {  		/*  		 * Power fault Cleared  		 */ @@ -196,8 +196,8 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,  	ctrl_dbg(ctrl, "Change speed to %d\n", speed);  	if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { -		ctrl_err(ctrl, "%s: Issue of set bus speed mode command " -			 "failed\n", __func__); +		ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", +			 __func__);  		return WRONG_BUS_FREQUENCY;  	}  	return rc; @@ -215,8 +215,8 @@ static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,  	 */  	if (flag) {  		if (asp < bsp) { -			ctrl_err(ctrl, "Speed of bus %x and adapter %x " -				 "mismatch\n", bsp, asp); +			ctrl_err(ctrl, "Speed of bus %x and adapter %x mismatch\n", +				 bsp, asp);  			rc = WRONG_BUS_FREQUENCY;  		}  		return rc; @@ -250,8 +250,7 @@ static int board_added(struct slot *p_slot)  	hp_slot = p_slot->device - ctrl->slot_device_offset; -	ctrl_dbg(ctrl, -		 "%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n", +	ctrl_dbg(ctrl, "%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n",  		 __func__, p_slot->device, ctrl->slot_device_offset, hp_slot);  	/* Power on slot without connecting to bus */ @@ -263,8 +262,8 @@ static int board_added(struct slot *p_slot)  	if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {  		if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { -			ctrl_err(ctrl, "%s: Issue of set bus speed mode command" -				 " failed\n", __func__); +			ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", +				 __func__);  			return WRONG_BUS_FREQUENCY;  		} @@ -277,20 +276,19 @@ static int board_added(struct slot *p_slot)  	rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp);  	if (rc) { -		ctrl_err(ctrl, "Can't get adapter speed or " -			 "bus mode mismatch\n"); +		ctrl_err(ctrl, "Can't get adapter speed or bus mode mismatch\n");  		return WRONG_BUS_FREQUENCY;  	} -	bsp = ctrl->pci_dev->bus->cur_bus_speed; -	msp = ctrl->pci_dev->bus->max_bus_speed; +	bsp = ctrl->pci_dev->subordinate->cur_bus_speed; +	msp = ctrl->pci_dev->subordinate->max_bus_speed;  	/* Check if there are other slots or devices on the same bus */  	if (!list_empty(&ctrl->pci_dev->subordinate->devices))  		slots_not_empty = 1; -	ctrl_dbg(ctrl, "%s: slots_not_empty %d, adapter_speed %d, bus_speed %d," -		 " max_bus_speed %d\n", __func__, slots_not_empty, asp, +	ctrl_dbg(ctrl, "%s: slots_not_empty %d, adapter_speed %d, bus_speed %d, max_bus_speed %d\n", +		 __func__, slots_not_empty, asp,  		 bsp, msp);  	rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp); @@ -490,12 +488,12 @@ static void handle_button_press_event(struct slot *p_slot)  		p_slot->hpc_ops->get_power_status(p_slot, &getstatus);  		if (getstatus) {  			p_slot->state = BLINKINGOFF_STATE; -			ctrl_info(ctrl, "PCI slot #%s - powering off due to " -				  "button press.\n", slot_name(p_slot)); +			ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", +				  slot_name(p_slot));  		} else {  			p_slot->state = BLINKINGON_STATE; -			ctrl_info(ctrl, "PCI slot #%s - powering on due to " -				  "button press.\n", slot_name(p_slot)); +			ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", +				  slot_name(p_slot));  		}  		/* blink green LED and turn off amber */  		p_slot->hpc_ops->green_led_blink(p_slot); @@ -518,8 +516,8 @@ static void handle_button_press_event(struct slot *p_slot)  		else  			p_slot->hpc_ops->green_led_off(p_slot);  		p_slot->hpc_ops->set_attention_status(p_slot, 0); -		ctrl_info(ctrl, "PCI slot #%s - action canceled due to " -			  "button press\n", slot_name(p_slot)); +		ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", +			  slot_name(p_slot));  		p_slot->state = STATIC_STATE;  		break;  	case POWEROFF_STATE: diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 75ba2311b54..29e22352822 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -116,7 +116,7 @@  #define SLOT_REG_RSVDZ_MASK	((1 << 15) | (7 << 21))  /* - * SHPC Command Code definitnions + * SHPC Command Code definitions   *   *     Slot Operation				00h - 3Fh   *     Set Bus Segment Speed/Mode A		40h - 47h @@ -341,8 +341,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)  	cmd_status = hpc_check_cmd_status(slot->ctrl);  	if (cmd_status) { -		ctrl_err(ctrl, -			 "Failed to issued command 0x%x (error code = %d)\n", +		ctrl_err(ctrl, "Failed to issued command 0x%x (error code = %d)\n",  			 cmd, cmd_status);  		retval = -EIO;  	} @@ -404,7 +403,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)  	return 0;  } -static int hpc_get_power_status(struct slot * slot, u8 *status) +static int hpc_get_power_status(struct slot *slot, u8 *status)  {  	struct controller *ctrl = slot->ctrl;  	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); @@ -528,7 +527,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)  	return retval;  } -static int hpc_query_power_fault(struct slot * slot) +static int hpc_query_power_fault(struct slot *slot)  {  	struct controller *ctrl = slot->ctrl;  	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); @@ -614,7 +613,7 @@ static void hpc_release_ctlr(struct controller *ctrl)  	release_mem_region(ctrl->mmio_base, ctrl->mmio_size);  } -static int hpc_power_on_slot(struct slot * slot) +static int hpc_power_on_slot(struct slot *slot)  {  	int retval; @@ -625,7 +624,7 @@ static int hpc_power_on_slot(struct slot * slot)  	return retval;  } -static int hpc_slot_enable(struct slot * slot) +static int hpc_slot_enable(struct slot *slot)  {  	int retval; @@ -638,7 +637,7 @@ static int hpc_slot_enable(struct slot * slot)  	return retval;  } -static int hpc_slot_disable(struct slot * slot) +static int hpc_slot_disable(struct slot *slot)  {  	int retval; @@ -720,7 +719,7 @@ static int shpc_get_cur_bus_speed(struct controller *ctrl)  } -static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) +static int hpc_set_bus_speed_mode(struct slot *slot, enum pci_bus_speed value)  {  	int retval;  	struct controller *ctrl = slot->ctrl; @@ -974,8 +973,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)  		for (i = 0; i < 9 + num_slots; i++) {  			rc = shpc_indirect_read(ctrl, i, &tempdword);  			if (rc) { -				ctrl_err(ctrl, -					 "Cannot read creg (index = %d)\n", i); +				ctrl_err(ctrl, "Cannot read creg (index = %d)\n", +					 i);  				goto abort;  			}  			ctrl_dbg(ctrl, " offset %d: value %x\n", i, tempdword); @@ -1060,10 +1059,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)  		/* Installs the interrupt handler */  		rc = pci_enable_msi(pdev);  		if (rc) { -			ctrl_info(ctrl, -				  "Can't get msi for the hotplug controller\n"); -			ctrl_info(ctrl, -				  "Use INTx for the hotplug controller\n"); +			ctrl_info(ctrl, "Can't get msi for the hotplug controller\n"); +			ctrl_info(ctrl, "Use INTx for the hotplug controller\n");  		}  		rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, @@ -1071,8 +1068,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)  		ctrl_dbg(ctrl, "request_irq %d (returns %d)\n",  			 ctrl->pci_dev->irq, rc);  		if (rc) { -			ctrl_err(ctrl, "Can't get irq %d for the hotplug " -				 "controller\n", ctrl->pci_dev->irq); +			ctrl_err(ctrl, "Can't get irq %d for the hotplug controller\n", +				 ctrl->pci_dev->irq);  			goto abort_iounmap;  		}  	} diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index b0e83132542..469454e0cc4 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -34,34 +34,37 @@  #include "../pci.h"  #include "shpchp.h" -int __ref shpchp_configure_device(struct slot *p_slot) +int shpchp_configure_device(struct slot *p_slot)  {  	struct pci_dev *dev;  	struct controller *ctrl = p_slot->ctrl;  	struct pci_dev *bridge = ctrl->pci_dev;  	struct pci_bus *parent = bridge->subordinate; -	int num; +	int num, ret = 0; + +	pci_lock_rescan_remove();  	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));  	if (dev) { -		ctrl_err(ctrl, "Device %s already exists " -			 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev), -			 pci_domain_nr(parent), p_slot->bus, p_slot->device); +		ctrl_err(ctrl, "Device %s already exists at %04x:%02x:%02x, cannot hot-add\n", +			 pci_name(dev), pci_domain_nr(parent), +			 p_slot->bus, p_slot->device);  		pci_dev_put(dev); -		return -EINVAL; +		ret = -EINVAL; +		goto out;  	}  	num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));  	if (num == 0) {  		ctrl_err(ctrl, "No new device found\n"); -		return -ENODEV; +		ret = -ENODEV; +		goto out;  	}  	list_for_each_entry(dev, &parent->devices, bus_list) {  		if (PCI_SLOT(dev->devfn) != p_slot->device)  			continue; -		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || -		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) +		if (pci_is_bridge(dev))  			pci_hp_add_bridge(dev);  	} @@ -75,7 +78,9 @@ int __ref shpchp_configure_device(struct slot *p_slot)  	pci_bus_add_devices(parent); -	return 0; + out: +	pci_unlock_rescan_remove(); +	return ret;  }  int shpchp_unconfigure_device(struct slot *p_slot) @@ -89,6 +94,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)  	ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",  		 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); +	pci_lock_rescan_remove(); +  	list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {  		if (PCI_SLOT(dev->devfn) != p_slot->device)  			continue; @@ -108,6 +115,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)  		pci_stop_and_remove_bus_device(dev);  		pci_dev_put(dev);  	} + +	pci_unlock_rescan_remove();  	return rc;  } diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index e8c31fe2056..52875b36046 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -38,7 +38,7 @@  static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)  {  	struct pci_dev *pdev; -	char * out = buf; +	char *out = buf;  	int index, busnr;  	struct resource *res;  	struct pci_bus *bus;  | 
