PCI hotplug changes for 2.5.69
Subsystems (2)
PATCH 1/1 PCI hotplug changes for 2.5.69
Hi,
Here's some patches that fix the pci hotplug drivers so that they now work again. Sorry it's taken so long to get these done...
I've also included a patch from Torben Mathiasen that adds PCI-X support to the Compaq PCI Hotplug driver. This patch is in the 2.4 tree already. There are also a few other minor fixes and cleanups in this fixing build configurations, and removing unused variables.
Please pull from: bk://kernel.bkbits.net/gregkh/linux/pci-2.5
thanks,
greg k-h
Documentation/DocBook/kernel-api.tmpl | 1 drivers/acpi/acpi_ksyms.c | 1 drivers/hotplug/Kconfig | 2 drivers/hotplug/acpiphp_glue.c | 6 drivers/hotplug/cpqphp.h | 414 ++++++++++++++++++++++++++++++++-- drivers/hotplug/cpqphp_core.c | 114 ++++++++- drivers/hotplug/cpqphp_ctrl.c | 296 +++++++++++++----------- drivers/hotplug/cpqphp_pci.c | 21 - drivers/hotplug/ibmphp_core.c | 14 - 9 files changed, 688 insertions(+), 181 deletions(-)
-----
<rusty:linux.co.intel.com>:
o PCI Hotplug: kernel-api docbook fix for now non-existant PCI hotplug
<torben.mathiasen:hp.com>:
o PCI Hotplug: cpqphp 66/100/133MHz PCI-X support
Greg Kroah-Hartman:
o PCI Hotplug: export the acpi_resource_to_address64 function, as the acpi pci hotplug driver needs it
o PCI Hotplug: fix dependancies for CONFIG_HOTPLUG_PCI_ACPI
o PCI Hotplug: fix up the acpi driver to work properly again
o PCI Hotplug: fix compiler warning in ibm driver
o PCI Hotplug: fix up the ibm driver to work properly again
o PCI Hotplug: fix up the compaq driver to work properly again
Hanna V. Linder:
o patch: remove unnecessary proc stuff from controller struct
PATCH 1/1 PCI hotplug changes for 2.5.69
ChangeSet 1.889.392.1, 2003/03/19 13:30:05-08:00, [email protected]
[PATCH] PCI Hotplug: cpqphp 66/100/133MHz PCI-X support
After being put on hold for a while (needed fixes to CCISS driver, etc) I attached a patch that adds pci-x support to the cpqphp driver in 2.5.65.
Changes:
Adds 66/100/133MHz PCI-X support.
Adds support for dynamically chaning frequency and mode. Changes code to also blink the power LED when powering down. Uses the IRQ from PCI config space if the ROM resource table doesn't provide one (would previously use the same interrupt as the hotplug controller which would lead to bad things when trying to update routing tables). Dan Zink should have the credit for this fix. Changes find_slot() to cpqhp_find_slot().
Uses sysfs to display speed/freq.
Some documentation updates.
drivers/hotplug/cpqphp.h | 203 ++++++++++++++++++++++++++++++++++++++++-- drivers/hotplug/cpqphp_core.c | 57 ++++++++++- drivers/hotplug/cpqphp_ctrl.c | 148 ++++++++++++++++-------------- drivers/hotplug/cpqphp_pci.c | 5 - 4 files changed, 334 insertions(+), 79 deletions(-)
drivers/hotplug/cpqphp.h +197 -6
@@ -30,7 +30,7 @@#include "pci_hotplug.h" #include <asm/io.h> /* for read? and write? functions */ - +#include <linux/delay.h> /* for delays */ #if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE )#define MY_NAME "cpqphp.o"
@@ -145,6 +145,10 @@u8 reserved11;/* 0x2b */ u8 slot_SERR;/* 0x2c */ u8 slot_power;/* 0x2d */ +u8 reserved12;/* 0x2e */ +u8 reserved13;/* 0x2f */ +u8 next_curr_freq;/* 0x30 */ +u8 reset_freq_mode;/* 0x31 */ } __attribute__ ((packed));/* offsets to the controller registers based on the above structure layout */
@@ -172,6 +176,8 @@CTRL_RESERVED11 = offsetof(struct ctrl_reg , reserved11),SLOT_SERR = offsetof(struct ctrl_reg , slot_SERR),SLOT_POWER = offsetof(struct ctrl_reg , slot_power), +NEXT_CURR_FREQ = offsetof(struct ctrl_reg , next_curr_freq), + RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode), }; struct hrt {
@@ -299,6 +305,7 @@struct slot *slot;u8 next_event;u8 interrupt; +u8 cfgspc_irq;u8 bus;/* bus number for the pci hotplug controller */ u8 rev;u8 slot_device_offset;
@@ -343,6 +350,7 @@#define PCI_SUB_HPC_ID2 0xA2F8#define PCI_SUB_HPC_ID3 0xA2F9#define PCI_SUB_HPC_ID_INTC 0xA2FA +#define PCI_SUB_HPC_ID4 0xA2FD#define INT_BUTTON_IGNORE 0#define INT_PRESENCE_ON 1
@@ -435,7 +443,7 @@extern void cpqhp_destroy_resource_list (struct resource_lists * resources);extern int cpqhp_configure_device (struct controller * ctrl,struct pci_func * func);extern int cpqhp_unconfigure_device (struct pci_func * func); - +extern struct slot *cpqhp_find_slot (struct controller *ctrl,u8 device);/* Global variables */ extern int cpqhp_debug;
@@ -563,6 +571,7 @@u32 led_control; led_control =readl (ctrl->hpc_reg +LED_CONTROL ); + led_control &= ~(0x0101L << slot); led_control |= (0x0001L << slot);writel (led_control, ctrl->hpc_reg +LED_CONTROL ); }
@@ -604,14 +613,63 @@ } +/* +* get_controller_speed - find the current frequency/mode of controller. +* +* @ctrl: controller to get frequency/mode for. +* +* Returns controller speed. +* +*/ static inline u8 get_controller_speed (struct controller *ctrl) { -u16 misc; - - misc =readw (ctrl->hpc_reg +MISC ); -return (misc &0x0800 ) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; +u8 curr_freq; +u16 misc; + +if (ctrl->pcix_support) { + curr_freq =readb (ctrl->hpc_reg +NEXT_CURR_FREQ ); +if ((curr_freq &0xB0 ) ==0xB0 ) +return PCI_SPEED_133MHz_PCIX; +if ((curr_freq &0xA0 ) ==0xA0 ) +return PCI_SPEED_100MHz_PCIX; +if ((curr_freq &0x90 ) ==0x90 ) +return PCI_SPEED_66MHz_PCIX; +if (curr_freq &0x10 ) +return PCI_SPEED_66MHz; + +return PCI_SPEED_33MHz; + } + + misc =readw (ctrl->hpc_reg +MISC ); +return (misc &0x0800 ) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; } + + +/* +* get_adapter_speed - find the max supported frequency/mode of adapter. +* +* @ctrl: hotplug controller. +* @hp_slot: hotplug slot where adapter is installed. +* +* Returns adapter speed. +* +*/ +static inline u8 get_adapter_speed (struct controller *ctrl,u8 hp_slot) +{ +u32 temp_dword =readl (ctrl->hpc_reg +NON_INT_INPUT ); +dbg ("slot: %d, PCIXCAP: %8x\n" , hp_slot, temp_dword); +if (ctrl->pcix_support) { +if (temp_dword & (0x10000 << hp_slot)) +return PCI_SPEED_133MHz_PCIX; +if (temp_dword & (0x100 << hp_slot)) +return PCI_SPEED_66MHz_PCIX; + } +if (temp_dword & (0x01 << hp_slot)) +return PCI_SPEED_66MHz; + +return PCI_SPEED_33MHz; +}static inline void enable_slot_power (struct controller *ctrl,u8 slot) {
@@ -718,6 +776,139 @@dbg ("%s - end\n" , __FUNCTION__); return retval; +} + + +/** +* set_controller_speed - set the frequency and/or mode of a specific +* controller segment. +* +* @ctrl: controller to change frequency/mode for. +* @adapter_speed: the speed of the adapter we want to match. +* @hp_slot: the slot number where the adapter is installed. +* +* Returns 0 if we successfully change frequency and/or mode to match the +* adapter speed. +* +*/ +static inline u8 set_controller_speed (struct controller *ctrl,u8 adapter_speed,u8 hp_slot) +{ +struct slot *slot; +u8 reg; +u8 slot_power =readb (ctrl->hpc_reg +SLOT_POWER ); +u16 reg16; +u32 leds =readl (ctrl->hpc_reg +LED_CONTROL ); + +if (ctrl->speed == adapter_speed) +return 0 ; + +/* We don't allow freq/mode changes if we find another adapter running +* in another slot on this controller */ +for (slot = ctrl->slot; slot; slot = slot->next) { +if (slot->device == (hp_slot + ctrl->slot_device_offset)) +continue ; +if (!slot->hotplug_slot && !slot->hotplug_slot->info) +continue ; +if (slot->hotplug_slot->info->adapter_status ==0 ) +continue ; +/* If another adapter is running on the same segment but at a +* lower speed/mode, we allow the new adapter to function at +* this rate if supported */ +if (ctrl->speed < adapter_speed) +return 0 ; + +return 1 ; + } + +/* If the controller doesn't support freq/mode changes and the +* controller is running at a higher mode, we bail */ +if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) +return 1 ; + +/* But we allow the adapter to run at a lower rate if possible */ +if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) +return 0 ; + +/* We try to set the max speed supported by both the adapter and +* controller */ +if (ctrl->speed_capability < adapter_speed) { +if (ctrl->speed == ctrl->speed_capability) +return 0 ; + adapter_speed = ctrl->speed_capability; + } + +writel (0x0L , ctrl->hpc_reg +LED_CONTROL ); +writeb (0x00 , ctrl->hpc_reg +SLOT_ENABLE ); + +set_SOGO (ctrl); +wait_for_ctrl_irq (ctrl); + +if (adapter_speed != PCI_SPEED_133MHz_PCIX) + reg =0xF5 ; +else + reg =0xF4 ; +pci_write_config_byte (ctrl->pci_dev,0x41 , reg); + + reg16 =readw (ctrl->hpc_reg +NEXT_CURR_FREQ ); + reg16 &= ~0x000F ; +switch (adapter_speed) { +case (PCI_SPEED_133MHz_PCIX): + reg =0x75 ; + reg16 |=0xB ; +break ; +case (PCI_SPEED_100MHz_PCIX): + reg =0x74 ; + reg16 |=0xA ; +break ; +case (PCI_SPEED_66MHz_PCIX): + reg =0x73 ; + reg16 |=0x9 ; +break ; +case (PCI_SPEED_66MHz): + reg =0x73 ; + reg16 |=0x1 ; +break ; +default :/* 33MHz PCI 2.2 */ + reg =0x71 ; +break ; + + } + reg16 |=0xB <<12 ; +writew (reg16, ctrl->hpc_reg +NEXT_CURR_FREQ ); + +mdelay (5 ); + +/* Reenable interrupts */ +writel (0 , ctrl->hpc_reg +INT_MASK ); + +pci_write_config_byte (ctrl->pci_dev,0x41 , reg); + +/* Restart state machine */ + reg = ~0xF ; +pci_read_config_byte (ctrl->pci_dev,0x43 , ®); +pci_write_config_byte (ctrl->pci_dev,0x43 , reg); + +/* Only if mode change...*/ +if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || + ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) +set_SOGO (ctrl); + +wait_for_ctrl_irq (ctrl); +mdelay (1100 ); + +/* Restore LED/Slot state */ +writel (leds, ctrl->hpc_reg +LED_CONTROL ); +writeb (slot_power, ctrl->hpc_reg +SLOT_ENABLE ); + +set_SOGO (ctrl); +wait_for_ctrl_irq (ctrl); + + ctrl->speed = adapter_speed; + slot =cpqhp_find_slot (ctrl, hp_slot + ctrl->slot_device_offset); + +info ("Successfully changed frequency/mode for adapter in slot %d\n" , + slot->number); +return 0 ; }#endif
drivers/hotplug/cpqphp_core.c +53 -4
106 lines not on this page · raw message
drivers/hotplug/cpqphp_ctrl.c +81 -67
246 lines not on this page · raw message
drivers/hotplug/cpqphp_pci.c +3 -2
@@ -97,6 +97,7 @@//this will generate pci_dev structures for all functions, but we will only call this case when lookup fails func->pci_dev =pci_scan_slot (ctrl->pci_dev->bus, (func->device <<3 ) + (func->function &0x7 )); +if (func->pci_dev ==NULL ) {dbg ("ERROR: pci_dev still null\n" );return 0 ;
@@ -1209,11 +1210,11 @@ temp =0 ;if (!cpqhp_nic_irq) { - cpqhp_nic_irq = ctrl->interrupt; + cpqhp_nic_irq = ctrl->cfgspc_irq; }if (!cpqhp_disk_irq) { - cpqhp_disk_irq = ctrl->interrupt; + cpqhp_disk_irq = ctrl->cfgspc_irq; }dbg ("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n" , cpqhp_disk_irq, cpqhp_nic_irq);
ChangeSet 1.889.392.2, 2003/03/19 14:39:42-08:00, [email protected]
[PATCH] patch: remove unnecessary proc stuff from controller struct
drivers/hotplug/cpqphp.h | 4 ---- 1 files changed, 4 deletions(-)
drivers/hotplug/cpqphp.h +0 -4
@@ -299,8 +299,6 @@struct pci_resource *bus_head;struct pci_dev *pci_dev;struct pci_bus *pci_bus; -struct proc_dir_entry * proc_entry; -struct proc_dir_entry * proc_entry2;struct event_info event_queue[10 ];struct slot *slot;u8 next_event;
@@ -322,8 +320,6 @@u8 pcix_speed_capability;/* PCI-X */ u8 pcix_support;/* PCI-X */ u16 vendor_id; -char proc_name[20 ]; -char proc_name2[20 ];struct work_struct int_task_event;wait_queue_head_t queue;/* sleep & wake process */ };
ChangeSet 1.889.392.3, 2003/03/19 15:45:39-08:00, [email protected]
[PATCH] PCI Hotplug: kernel-api docbook fix for now non-existant PCI hotplug
Here is a trivial documentation fix for some of recent PCI hotplug changes that enables 'make htmldocs' to complete.
Documentation/DocBook/kernel-api.tmpl | 1 - 1 files changed, 1 deletion(-)
Documentation/DocBook/kernel-api.tmpl +0 -1
@@ -173,7 +173,6 @@ </sect1> <sect1><title>PCI Hotplug Support Library</title> !Edrivers/hotplug/pci_hotplug_core.c -!Edrivers/hotplug/pci_hotplug_util.c </sect1> <sect1><title>MCA Architecture</title> <sect2><title>MCA Device Functions</title>
ChangeSet 1.1081, 2003/05/06 15:34:00-07:00, [email protected]
[PATCH] PCI Hotplug: fix up the compaq driver to work properly again.
drivers/hotplug/cpqphp_pci.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)
drivers/hotplug/cpqphp_pci.c +8 -8
@@ -85,19 +85,20 @@ {unsigned char bus;struct pci_bus *child; -int rc =0 ; +int num;if (func->pci_dev ==NULL ) - func->pci_dev =pci_find_slot (func->bus, (func->device <<3 ) | (func->function &0x7 )); + func->pci_dev =pci_find_slot (func->bus,PCI_DEVFN (func->device, func->function)); -//Still NULL ? Well then scan for it ! +/* No pci device, we need to create it then */ if (func->pci_dev ==NULL ) {dbg ("INFO: pci_dev still null\n" ); -//this will generate pci_dev structures for all functions, but we will only call this case when lookup fails - func->pci_dev =pci_scan_slot (ctrl->pci_dev->bus, - (func->device <<3 ) + (func->function &0x7 )); + num =pci_scan_slot (ctrl->pci_dev->bus,PCI_DEVFN (func->device, func->function)); +if (num) +pci_bus_add_devices (ctrl->pci_dev->bus); + func->pci_dev =pci_find_slot (func->bus,PCI_DEVFN (func->device, func->function));if (func->pci_dev ==NULL ) {dbg ("ERROR: pci_dev still null\n" );return 0 ;
@@ -108,10 +109,9 @@pci_read_config_byte (func->pci_dev,PCI_SECONDARY_BUS , &bus); child = (struct pci_bus *)pci_add_new_bus (func->pci_dev->bus, (func->pci_dev), bus);pci_do_scan_bus (child); - } -return rc; +return 0 ; }
ChangeSet 1.1082, 2003/05/06 15:35:23-07:00, [email protected]
[PATCH] PCI Hotplug: fix up the ibm driver to work properly again.
drivers/hotplug/ibmphp_core.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)
drivers/hotplug/ibmphp_core.c +7 -5
@@ -846,22 +846,24 @@ {unsigned char bus;struct pci_bus *child; -int rc =0 ; +int num;int flag =0 ;/* this is to make sure we don't double scan the bus, for bridged devices primarily */ if (!(bus_structure_fixup (func->busno))) flag =1 ;if (func->dev ==NULL ) - func->dev =pci_find_slot (func->busno, (func->device <<3 ) | (func->function &0x7 )); + func->dev =pci_find_slot (func->busno,PCI_DEVFN (func->device, func->function));if (func->dev ==NULL ) {struct pci_bus *bus =ibmphp_find_bus (func->busno);if (!bus)return 0 ; - func->dev =pci_scan_slot (bus, - (func->device <<3 ) + (func->function &0x7 )); + num =pci_scan_slot (bus,PCI_DEVFN (func->device, func->function)); +if (num) +pci_bus_add_devices (bus); + func->dev =pci_find_slot (func->busno,PCI_DEVFN (func->device, func->function));if (func->dev ==NULL ) {err ("ERROR... : pci_dev still NULL \n" );return 0 ;
@@ -873,7 +875,7 @@pci_do_scan_bus (child); } -return rc; +return 0 ; }/*******************************************************
ChangeSet 1.1083, 2003/05/06 15:35:34-07:00, [email protected]
[PATCH] PCI Hotplug: fix compiler warning in ibm driver.
drivers/hotplug/ibmphp_core.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/hotplug/ibmphp_core.c +1 -1
@@ -1417,7 +1417,7 @@/* lock ourselves into memory with a module * count of -1 so that no one can unload us. */ -MOD_DEC_USE_COUNT ; +module_put (THIS_MODULE ); exit:return rc;
ChangeSet 1.1084, 2003/05/06 15:35:45-07:00, [email protected]
[PATCH] PCI Hotplug: fix up the acpi driver to work properly again.
drivers/hotplug/acpiphp_glue.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-)
drivers/hotplug/acpiphp_glue.c +5 -1
@@ -806,6 +806,7 @@struct list_head *l;struct acpiphp_func *func;int retval =0 ; +int num;if (slot->flags &SLOT_ENABLED ) goto err_exit;
@@ -825,7 +826,10 @@ goto err_exit;/* returned `dev' is the *first function* only! */ - dev =pci_scan_slot (slot->bridge->pci_bus,PCI_DEVFN (slot->device,0 )); + num =pci_scan_slot (slot->bridge->pci_bus,PCI_DEVFN (slot->device,0 )); +if (num) +pci_bus_add_devices (slot->bridge->pci_bus); + dev =pci_find_slot (slot->bridge->bus,PCI_DEVFN (slot->device,0 ));if (!dev) {err ("No new device found\n" );
ChangeSet 1.1085, 2003/05/06 15:43:13-07:00, [email protected]
[PATCH] PCI Hotplug: fix dependancies for CONFIG_HOTPLUG_PCI_ACPI
Thanks to Adrian Bunk <[email protected]> for pointing this out.
drivers/hotplug/Kconfig | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/hotplug/Kconfig +1 -1
@@ -61,7 +61,7 @@ config HOTPLUG_PCI_ACPI tristate "ACPI PCI Hotplug driver" - depends on ACPI && HOTPLUG_PCI + depends on ACPI_BUS && HOTPLUG_PCI help Say Y here if you have a system that supports PCI Hotplug using ACPI.
ChangeSet 1.1086, 2003/05/06 15:51:03-07:00, [email protected]
PCI Hotplug: export the acpi_resource_to_address64 function, as the acpi pci hotplug driver needs it.
drivers/acpi/acpi_ksyms.c | 1 + 1 files changed, 1 insertion(+)
drivers/acpi/acpi_ksyms.c +1 -0
@@ -80,6 +80,7 @@EXPORT_SYMBOL (acpi_get_possible_resources);EXPORT_SYMBOL (acpi_walk_resources);EXPORT_SYMBOL (acpi_set_current_resources); +EXPORT_SYMBOL (acpi_resource_to_address64);EXPORT_SYMBOL (acpi_enable_event);EXPORT_SYMBOL (acpi_disable_event);EXPORT_SYMBOL (acpi_clear_event);