linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH-2.4.20] PCI-X hotplug support for Compaq driver
@ 2003-01-15  9:55 Torben Mathiasen
  2003-01-15 23:05 ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Torben Mathiasen @ 2003-01-15  9:55 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, pcihpd-discuss, stormy_peters, john.cagle, dan.zink

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]

Hi Greg,

Attached is a patch against 2.4.20 (should apply to .21-pre3 and BK-current as
well) that adds 66/100/133MHz PCI-X support to the Compaq Hotplug driver.

Please apply.

Thanks,
Torben Mathiasen

[-- Attachment #2: linux-2.4.20-pcix-3.diff --]
[-- Type: text/plain, Size: 19619 bytes --]

diff -ur -X exclude linux-2.4.20/drivers/hotplug/cpqphp.h linux-2.4.20-pcix/drivers/hotplug/cpqphp.h
--- linux-2.4.20/drivers/hotplug/cpqphp.h	Thu Nov 28 17:53:12 2002
+++ linux-2.4.20-pcix/drivers/hotplug/cpqphp.h	Thu Jan  9 03:12:20 2003
@@ -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 {
@@ -345,6 +351,8 @@
 #define PCI_SUB_HPC_ID2			0xA2F8
 #define PCI_SUB_HPC_ID3			0xA2F9
 #define PCI_SUB_HPC_ID_INTC		0xA2FA
+#define PCI_SUB_HPC_ID4			0xA2FC
+#define PCI_SUB_HPC_ID5			0xA2FD
 
 #define INT_BUTTON_IGNORE		0
 #define INT_PRESENCE_ON			1
@@ -474,7 +482,7 @@
 
 
 /* inline functions */
-
+extern inline struct slot *find_slot (struct controller *ctrl, u8 device);
 
 /* Inline functions to check the sanity of a pointer that is passed to us */
 static inline int slot_paranoia_check (struct slot *slot, const char *function)
@@ -629,14 +637,82 @@
 }
 
 
+/*
+ * 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)
 {
+	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 char *get_speed_string (int speed)
+{
+	switch(speed) {
+		case(PCI_SPEED_33MHz):
+			return "33MHz PCI";
+		case(PCI_SPEED_66MHz):
+			return "66MHz PCI";
+		case(PCI_SPEED_50MHz_PCIX):
+			return "50MHz PCI-X";
+		case(PCI_SPEED_66MHz_PCIX):
+			return "66MHz PCI-X";
+		case(PCI_SPEED_100MHz_PCIX):
+			return "100MHz PCI-X";
+		case(PCI_SPEED_133MHz_PCIX):
+			return "133MHz PCI-X";
+		default:
+			return "UNKNOWN";
+	}
+}
 
 static inline void enable_slot_power (struct controller *ctrl, u8 slot)
 {
@@ -744,5 +820,139 @@
 	return retval;
 }
 
-#endif
+/**
+ * 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); 
+	
+	/* Renable 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, &reg);
+	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 = find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+
+	info("Successfully changed frequency/mode for adapter in slot %d\n", 
+			slot->number);
+	info("Bus %d now running in %s mode\n", ctrl->pci_dev->bus->number,
+			get_speed_string(ctrl->speed));
+
+	return 0;
+}
+
+#endif
diff -ur -X exclude linux-2.4.20/drivers/hotplug/cpqphp_core.c linux-2.4.20-pcix/drivers/hotplug/cpqphp_core.c
--- linux-2.4.20/drivers/hotplug/cpqphp_core.c	Thu Nov 28 17:53:12 2002
+++ linux-2.4.20-pcix/drivers/hotplug/cpqphp_core.c	Tue Jan 14 22:02:30 2003
@@ -24,6 +24,9 @@
  *
  * Send feedback to <greg@kroah.com>
  *
+ * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support, 
+ * 			Torben Mathiasen <torben.mathiasen@hp.com>
+ *
  */
 
 #include <linux/config.h>
@@ -53,7 +56,7 @@
 static u8 power_mode;
 static int debug;
 
-#define DRIVER_VERSION	"0.9.6"
+#define DRIVER_VERSION	"0.9.7"
 #define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC	"Compaq Hot Plug PCI Controller Driver"
 
@@ -829,6 +832,7 @@
 	u8 hp_slot = 0;
 	u8 device;
 	u8 rev;
+	u8 bus_cap;
 	u16 temp_word;
 	u16 vendor_id;
 	u16 subsystem_vid;
@@ -890,6 +894,39 @@
 
 		switch (subsystem_vid) {
 			case PCI_VENDOR_ID_COMPAQ:
+				if (rev >= 0x13) { /* CIOBX */
+					ctrl->push_flag = 1;
+					ctrl->slot_switch_type = 1;		// Switch is present
+					ctrl->push_button = 1;			// Pushbutton is present
+					ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+					ctrl->defeature_PHP = 1;		// PHP is supported
+					ctrl->pcix_support = 1;			// PCI-X supported
+					ctrl->pcix_speed_capability = 1;
+					pci_read_config_byte(pdev, 0x41, &bus_cap);
+					if (bus_cap & 0x80) {
+						dbg("bus max supports 133MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 0x40) {
+						dbg("bus max supports 100MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 20) {
+						dbg("bus max supports 66MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 10) {
+						dbg("bus max supports 66MHz PCI\n");
+						ctrl->speed_capability = PCI_SPEED_66MHz;
+						break;
+					}
+
+					break;
+				}
+
 				switch (subsystem_deviceid) {
 					case PCI_SUB_HPC_ID:
 						/* Original 6500/7000 implementation */
@@ -933,8 +970,29 @@
 						ctrl->pcix_support = 0;			// PCI-X not supported
 						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
 						break;
+					case PCI_SUB_HPC_ID4:	
+						/* First PCI-X implementation, 50MHz */
+						ctrl->push_flag = 1;
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_50MHz_PCIX;
+						ctrl->push_button = 1;			// Pushbutton is present
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 1;			// PCI-X supported
+						ctrl->pcix_speed_capability = 0;	
+						break;
+					case PCI_SUB_HPC_ID5:
+						/* First PCI-X implementation, 100MHz */
+						ctrl->push_flag = 1;
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+						ctrl->push_button = 1;			// Pushbutton is present
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 1;			// PCI-X supported
+						ctrl->pcix_speed_capability = 0;	
+						break;
 					default:
-						// TODO: Add SSIDs for CPQ systems that support PCI-X
 						err(msg_HPC_not_supported);
 						rc = -ENODEV;
 						goto err_free_ctrl;
@@ -1023,7 +1081,7 @@
 	info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
 
 	dbg ("Hotplug controller capabilities:\n");
-	dbg ("    speed_capability       %s\n", ctrl->speed_capability == PCI_SPEED_33MHz ? "33MHz" : "66Mhz");
+	dbg ("    speed_capability       %s\n", get_speed_string(ctrl->speed_capability));
 	dbg ("    slot_switch_type       %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
 	dbg ("    defeature_PHP          %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
 	dbg ("    alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
@@ -1066,11 +1124,9 @@
 		goto err_free_mem_region;
 	}
 
-	// Check for 66Mhz operation
-	// TODO: Add PCI-X support
+	// Check for 66Mhz and/or PCI-X operation
 	ctrl->speed = get_controller_speed(ctrl);
-
-
+	
 	//**************************************************
 	//
 	//              Save configuration headers for this and
@@ -1222,7 +1278,8 @@
 		err("cpqhp_proc_create_ctrl failed\n");
 		goto err_free_irq;
 	}
-
+	
+	info("Bus %d configured for %s\n", pdev->bus->number, get_speed_string(ctrl->speed));
 	return 0;
 
 err_free_irq:
diff -ur -X exclude linux-2.4.20/drivers/hotplug/cpqphp_ctrl.c linux-2.4.20-pcix/drivers/hotplug/cpqphp_ctrl.c
--- linux-2.4.20/drivers/hotplug/cpqphp_ctrl.c	Thu Nov 28 17:53:12 2002
+++ linux-2.4.20-pcix/drivers/hotplug/cpqphp_ctrl.c	Thu Jan  9 01:03:12 2003
@@ -137,7 +137,7 @@
 /*
  * find_slot
  */
-static inline struct slot *find_slot (struct controller * ctrl, u8 device)
+inline struct slot *find_slot (struct controller * ctrl, u8 device)
 {
 	struct slot *slot;
 
@@ -916,6 +916,7 @@
 void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs)
 {
 	u8 schedule_flag = 0;
+	u8 reset;
 	u16 misc;
 	u32 Diff;
 	u32 temp_dword;
@@ -966,6 +967,15 @@
 		schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
 		schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
 	}
+	
+	reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
+	if (reset & 0x40) {
+		/* Bus Reset has completed */
+		reset &= 0xCF;
+		writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
+		reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
+		wake_up_interruptible(&ctrl->queue);
+	}
 
 	if (schedule_flag) {
 		up(&event_semaphore);
@@ -1169,6 +1179,7 @@
 {
 	u8 hp_slot;
 	u8 temp_byte;
+	u8 adapter_speed;
 	u32 index;
 	u32 rc = 0;
 	u32 src = 8;
@@ -1186,46 +1197,47 @@
 		//*********************************
 		rc = CARD_FUNCTIONING;
 	} else {
-		if (ctrl->speed == PCI_SPEED_66MHz) {
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			// turn on board without attaching to the bus
-			enable_slot_power (ctrl, hp_slot);
+		// Wait for exclusive access to hardware
+		down(&ctrl->crit_sect);
 
-			set_SOGO(ctrl);
+		// turn on board without attaching to the bus
+		enable_slot_power (ctrl, hp_slot);
 
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
+		set_SOGO(ctrl);
 
-			// Change bits in slot power register to force another shift out
-			// NOTE: this is to work around the timer bug
-			temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-			writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-			writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
 
-			set_SOGO(ctrl);
+		// Change bits in slot power register to force another shift out
+		// NOTE: this is to work around the timer bug
+		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
+		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
+		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
 
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
+		set_SOGO(ctrl);
 
-			if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) {
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+		
+		// 66MHz and/or PCI-X support check
+		adapter_speed = get_adapter_speed(ctrl, hp_slot);
+		if (ctrl->speed != adapter_speed)
+			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 				rc = WRONG_BUS_FREQUENCY;
-			}
-			// turn off board without attaching to the bus
-			disable_slot_power (ctrl, hp_slot);
 
-			set_SOGO(ctrl);
+		// turn off board without attaching to the bus
+		disable_slot_power (ctrl, hp_slot);
 
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
+		set_SOGO(ctrl);
 
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
 
-			if (rc)
-				return(rc);
-		}
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+
+		if (rc)
+			return(rc);
 
 		// Wait for exclusive access to hardware
 		down(&ctrl->crit_sect);
@@ -1373,6 +1385,7 @@
 {
 	u8 hp_slot;
 	u8 temp_byte;
+	u8 adapter_speed;
 	int index;
 	u32 temp_register = 0xFFFFFFFF;
 	u32 rc = 0;
@@ -1383,47 +1396,49 @@
 	hp_slot = func->device - ctrl->slot_device_offset;
 	dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n",
 	    func->device, ctrl->slot_device_offset, hp_slot);
+	
+	// Wait for exclusive access to hardware
+	down(&ctrl->crit_sect);
 
-	if (ctrl->speed == PCI_SPEED_66MHz) {
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
+	// turn on board without attaching to the bus
+	enable_slot_power (ctrl, hp_slot);
 
-		// turn on board without attaching to the bus
-		enable_slot_power (ctrl, hp_slot);
+	set_SOGO(ctrl);
 
-		set_SOGO(ctrl);
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
 
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
+	// Change bits in slot power register to force another shift out
+	// NOTE: this is to work around the timer bug
+	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
+	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
+	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
 
-		// Change bits in slot power register to force another shift out
-		// NOTE: this is to work around the timer bug
-		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
+	set_SOGO(ctrl);
 
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) {
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+	
+	// 66MHz and/or PCI-X support check
+	adapter_speed = get_adapter_speed(ctrl, hp_slot);
+	if (ctrl->speed != adapter_speed)
+		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 			rc = WRONG_BUS_FREQUENCY;
-		}
-		// turn off board without attaching to the bus
-		disable_slot_power (ctrl, hp_slot);
+	
+	// turn off board without attaching to the bus
+	disable_slot_power (ctrl, hp_slot);
 
-		set_SOGO(ctrl);
+	set_SOGO(ctrl);
 
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
 
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
+	// Done with exclusive hardware access
+	up(&ctrl->crit_sect);
 
-		if (rc)
-			return(rc);
-	}
+	if (rc)
+		return(rc);
+	
 	p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
 	// turn on board and blink green LED
diff -ur -X exclude linux-2.4.20/drivers/hotplug/cpqphp_proc.c linux-2.4.20-pcix/drivers/hotplug/cpqphp_proc.c
--- linux-2.4.20/drivers/hotplug/cpqphp_proc.c	Fri Aug  2 19:39:43 2002
+++ linux-2.4.20-pcix/drivers/hotplug/cpqphp_proc.c	Thu Jan  9 00:10:15 2003
@@ -54,6 +54,7 @@
 	out += sprintf(out, "hot plug ctrl Info Page\n");
 	out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus,
 		       ctrl->device, ctrl->function);
+	out += sprintf(out, "bus frequency/mode = %s\n", get_speed_string(ctrl->speed));
 	out += sprintf(out, "Free resources: memory\n");
 	index = 11;
 	res = ctrl->mem_head;
diff -ur -X exclude linux-2.4.20/drivers/hotplug/pci_hotplug.h linux-2.4.20-pcix/drivers/hotplug/pci_hotplug.h
--- linux-2.4.20/drivers/hotplug/pci_hotplug.h	Thu Nov 28 17:53:13 2002
+++ linux-2.4.20-pcix/drivers/hotplug/pci_hotplug.h	Mon Jan  6 22:54:47 2003
@@ -33,9 +33,10 @@
 enum pci_bus_speed {
 	PCI_SPEED_33MHz			= 0x00,
 	PCI_SPEED_66MHz			= 0x01,
-	PCI_SPEED_66MHz_PCIX		= 0x02,
-	PCI_SPEED_100MHz_PCIX		= 0x03,
-	PCI_SPEED_133MHz_PCIX		= 0x04,
+	PCI_SPEED_50MHz_PCIX		= 0x02,
+	PCI_SPEED_66MHz_PCIX		= 0x03,
+	PCI_SPEED_100MHz_PCIX		= 0x04,
+	PCI_SPEED_133MHz_PCIX		= 0x05,
 	PCI_SPEED_66MHz_PCIX_266	= 0x09,
 	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
 	PCI_SPEED_133MHz_PCIX_266	= 0x0b,

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH-2.4.20] PCI-X hotplug support for Compaq driver
  2003-01-15  9:55 [PATCH-2.4.20] PCI-X hotplug support for Compaq driver Torben Mathiasen
@ 2003-01-15 23:05 ` Greg KH
  2003-01-16 11:47   ` Torben Mathiasen
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2003-01-15 23:05 UTC (permalink / raw)
  To: Torben Mathiasen
  Cc: linux-kernel, pcihpd-discuss, stormy_peters, john.cagle, dan.zink

On Wed, Jan 15, 2003 at 10:55:13AM +0100, Torben Mathiasen wrote:
> Hi Greg,
> 
> Attached is a patch against 2.4.20 (should apply to .21-pre3 and BK-current as
> well) that adds 66/100/133MHz PCI-X support to the Compaq Hotplug driver.
> 
> Please apply.

Looks almost ready.  Could you make up a 2.5 version first?  I don't
like to have new features in 2.4 before they go into 2.5.

>  /* inline functions */
> -
> +extern inline struct slot *find_slot (struct controller *ctrl, u8 device);

Can you just make this a normal function then, with a more private name?

> +/*
> + * 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)

Thanks for documenting this and get_adapter_speed().

> +static char *get_speed_string (int speed)
> +{
> +	switch(speed) {
> +		case(PCI_SPEED_33MHz):
> +			return "33MHz PCI";
> +		case(PCI_SPEED_66MHz):
> +			return "66MHz PCI";
> +		case(PCI_SPEED_50MHz_PCIX):
> +			return "50MHz PCI-X";
> +		case(PCI_SPEED_66MHz_PCIX):
> +			return "66MHz PCI-X";
> +		case(PCI_SPEED_100MHz_PCIX):
> +			return "100MHz PCI-X";
> +		case(PCI_SPEED_133MHz_PCIX):
> +			return "133MHz PCI-X";
> +		default:
> +			return "UNKNOWN";
> +	}
> +}

Ick, why?  Just for a debugging message?  That /proc file is on the
short list of things to delete :)

> --- linux-2.4.20/drivers/hotplug/pci_hotplug.h	Thu Nov 28 17:53:13 2002
> +++ linux-2.4.20-pcix/drivers/hotplug/pci_hotplug.h	Mon Jan  6 22:54:47 2003
> @@ -33,9 +33,10 @@
>  enum pci_bus_speed {
>  	PCI_SPEED_33MHz			= 0x00,
>  	PCI_SPEED_66MHz			= 0x01,
> -	PCI_SPEED_66MHz_PCIX		= 0x02,
> -	PCI_SPEED_100MHz_PCIX		= 0x03,
> -	PCI_SPEED_133MHz_PCIX		= 0x04,
> +	PCI_SPEED_50MHz_PCIX		= 0x02,
> +	PCI_SPEED_66MHz_PCIX		= 0x03,
> +	PCI_SPEED_100MHz_PCIX		= 0x04,
> +	PCI_SPEED_133MHz_PCIX		= 0x05,
>  	PCI_SPEED_66MHz_PCIX_266	= 0x09,
>  	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
>  	PCI_SPEED_133MHz_PCIX_266	= 0x0b,

Where are you getting the PCI_SPEED_50MHz_PCIX value from?  I took these
values from the Hotplug PCI draft spec.  Has 02 been reserved for 50MHz
PCIX and the other values changed?

If it's not in the spec, I'd recommend adding it to the end of the list,
with a big comment about why it's different from the spec values.

thanks,

greg k-h


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH-2.4.20] PCI-X hotplug support for Compaq driver
  2003-01-15 23:05 ` Greg KH
@ 2003-01-16 11:47   ` Torben Mathiasen
  2003-01-16 18:35     ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Torben Mathiasen @ 2003-01-16 11:47 UTC (permalink / raw)
  To: Greg KH
  Cc: Torben Mathiasen, linux-kernel, pcihpd-discuss, john.cagle, dan.zink

Sure. I started out doing the patch for 2.5, but hit some hotplug bugs so I
decided to get it working for 2.4 first and then port it to 2.5. I'll get on
that.

A few comments below.
 
> > +static char *get_speed_string (int speed)
> > +{
> > +	switch(speed) {
> > +		case(PCI_SPEED_33MHz):
> > +			return "33MHz PCI";
> > +		case(PCI_SPEED_66MHz):
> > +			return "66MHz PCI";
> > +		case(PCI_SPEED_50MHz_PCIX):
> > +			return "50MHz PCI-X";
> > +		case(PCI_SPEED_66MHz_PCIX):
> > +			return "66MHz PCI-X";
> > +		case(PCI_SPEED_100MHz_PCIX):
> > +			return "100MHz PCI-X";
> > +		case(PCI_SPEED_133MHz_PCIX):
> > +			return "133MHz PCI-X";
> > +		default:
> > +			return "UNKNOWN";
> > +	}
> > +}
> 
> Ick, why?  Just for a debugging message?  That /proc file is on the
> short list of things to delete :)
>

I wanted the user to be able to know exactly which bus speed/mode the driver
switched to in case of a freq/mode change. Besides that it also put the info in
proc as you mention.

> > --- linux-2.4.20/drivers/hotplug/pci_hotplug.h	Thu Nov 28 17:53:13 2002
> > +++ linux-2.4.20-pcix/drivers/hotplug/pci_hotplug.h	Mon Jan  6 22:54:47 2003
> > @@ -33,9 +33,10 @@
> >  enum pci_bus_speed {
> >  	PCI_SPEED_33MHz			= 0x00,
> >  	PCI_SPEED_66MHz			= 0x01,
> > -	PCI_SPEED_66MHz_PCIX		= 0x02,
> > -	PCI_SPEED_100MHz_PCIX		= 0x03,
> > -	PCI_SPEED_133MHz_PCIX		= 0x04,
> > +	PCI_SPEED_50MHz_PCIX		= 0x02,
> > +	PCI_SPEED_66MHz_PCIX		= 0x03,
> > +	PCI_SPEED_100MHz_PCIX		= 0x04,
> > +	PCI_SPEED_133MHz_PCIX		= 0x05,
> >  	PCI_SPEED_66MHz_PCIX_266	= 0x09,
> >  	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
> >  	PCI_SPEED_133MHz_PCIX_266	= 0x0b,
> 
> Where are you getting the PCI_SPEED_50MHz_PCIX value from?  I took these
> values from the Hotplug PCI draft spec.  Has 02 been reserved for 50MHz
> PCIX and the other values changed?
> 
> If it's not in the spec, I'd recommend adding it to the end of the list,
> with a big comment about why it's different from the spec values.
>

Sure, we used to ship a system that only supported 50MHz PCI-X, but I'll have
to get more details on that.

Torben


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH-2.4.20] PCI-X hotplug support for Compaq driver
  2003-01-16 11:47   ` Torben Mathiasen
@ 2003-01-16 18:35     ` Greg KH
  0 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2003-01-16 18:35 UTC (permalink / raw)
  To: Torben Mathiasen; +Cc: linux-kernel, pcihpd-discuss, john.cagle, dan.zink

On Thu, Jan 16, 2003 at 12:47:17PM +0100, Torben Mathiasen wrote:
> Sure. I started out doing the patch for 2.5, but hit some hotplug bugs so I
> decided to get it working for 2.4 first and then port it to 2.5. I'll get on
> that.

Thanks.

> I wanted the user to be able to know exactly which bus speed/mode the driver
> switched to in case of a freq/mode change. Besides that it also put the info in
> proc as you mention.

But that is what the cur_bus_speed and max_bus_speed files in pcihpfs
for the slot are for, right?  Isn't this just duplicating that
information?

> Sure, we used to ship a system that only supported 50MHz PCI-X, but I'll have
> to get more details on that.

So 50MHz PCI-X is not in the spec, right?  If you all supported it, why
didn't you get it included in the spec?  :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-01-16 18:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-15  9:55 [PATCH-2.4.20] PCI-X hotplug support for Compaq driver Torben Mathiasen
2003-01-15 23:05 ` Greg KH
2003-01-16 11:47   ` Torben Mathiasen
2003-01-16 18:35     ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).