Skip to contentSkip to conversation

Sysfs interface for ZT5550 Redundant Host Controller

PATCH In review Rusty Lynch 2 participants 3 messages Feb 4, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Sysfs interface for ZT5550 Redundant Host Controller

Last week I finally got access to a decent (but old) technical specification for the ZT5550 redundant host controller. The document was published for the ZT5550C, but I am hoping that newer versions of the RHC just add more functionality to all the documented reserved bits in the document I am looking at.

The following patch adds a sysfs interface to most of the bits accessible via the indirect register (through the HCINDEX and HCDATA addresses in the Command and Status Register (CSR). The only bits I did not add access to were the ones that are cleared by reading. There are a lot of bits to get access to, which makes this patch a little bigger then I first expected, so I created a new config option so only people who actually want to mess with the RHC would pay for it.

Enabling this code will cause a new directory called zt5550_rhc to be created in the root of sysfs, with the following tree:

[rusty@penguin sysfs]$ tree zt5550_rhc
zt5550_rhc/

|-- diag                 <== fault injection capabilities
|   |-- diag_b0_serr
|   |-- diag_cputemp
|   |-- diag_iochk
|   |-- diag_nmi
|   |-- diag_perr
|   |-- diag_power_fail
|   `-- diag_wd_timeout
|-- fltc                 <== configurable actions for given faults
|   |-- b0_serr
|   |-- cputemp
|   |-- eject_ah
|   |-- eject_bh
|   |-- hard_reset
|   |-- iochk
|   |-- nmi
|   |-- perr
|   |-- power_fail
|   |-- soft_reset
|   `-- wd_timeout
|-- hcc                 <== various commands
|   |-- ah_s1_response
|   |-- bh_s1_response
|   |-- configuration_mode
|   |-- diagnostics_mode
|   |-- initiate_takeover
|   |-- power_down_bh
|   |-- reset
|   |-- reset_bh
|   |-- s1_bp_reset
|   |-- s2_bp_reset
|   |-- warm_boot
|   `-- wd_enable
|-- hci                 <== interrupt mask settings
|   |-- fault_interrupt_mask
|   |-- hcf_interrupt_mask
|   `-- serial_interrupt_mask
|-- isoc                <== isolation configuration
|   |-- bp_interrupt_mask
|   |-- friendly
|   |-- hostile
|   |-- s1_bp_reset_mask
|   |-- s2_bp_reset_mask
|   `-- unlock
|-- pmcc               <== control of PCI Mezzanine Cards
|   |-- pmc1_command2
|   |-- pmc1_command4
|   |-- pmc1_status
|   |-- pmc2_command2
|   |-- pmc2_command4
|   `-- pmc2_status

`-- wdc <== watchdog timer configuration
|-- prescaler
`-- terminal_count

This provides all kind of rope to hang yourself with, but it was fun messing with it. This also points out other areas where an interested party could further enable this particular board, for example adding the code to respond to a fault condition (after enabling fault handling through sysfs).

This patch was generated off of today's bk tree with the previously posted patch by Scott to fix the deadlock issue and the patch posted by Stanley to add sysfs support. Both of these patches are attached as a single patch to this email message.

--rustyl

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.982 -> 1.983
# drivers/hotplug/cpcihp_zt5550.h 1.2 -> 1.3
# drivers/hotplug/Kconfig 1.5 -> 1.6
# drivers/hotplug/cpcihp_zt5550.c 1.2 -> 1.3
# drivers/hotplug/Makefile 1.12 -> 1.13
# (new) -> 1.1 drivers/hotplug/cpcihp_zt5550_rhc.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/04 [email protected] 1.983
# Adding a sysfs inteface for the zt5550 redundant host controller # --------------------------------------------
#

drivers/hotplug/Kconfig +17 -0
diff -Nru a/drivers/hotplug/Kconfig b/drivers/hotplug/Kconfig
@@ -101,6 +101,23 @@
 
 	  When in doubt, say N.
 
+config HOTPLUG_PCI_CPCI_ZT5550_RHC
+	bool "Ziatech ZT5550 CompactPCI RHC Sysfs Interface"
+	depends on HOTPLUG_PCI_CPCI_ZT5550
+	help
+	  Say Y here if you have an Performance Technologies (formerly Intel,
+          formerly just Ziatech) Ziatech ZT5550 CompactPCI system card, and
+          would like to have configuration access to the onboard 
+          Redundant Host Controller.
+
+          Saying Y here will cause a new "zt5550_rhc" directory to be created
+          in the root of your sysfs, with a directory for each of the rhc
+          indirect registers created inside the zt5550_rhc directory, and then
+          control files in each of those directorys giving user space access
+          to all of the bits in those indirect registers.
+
+	  When in doubt, say N.
+
 config HOTPLUG_PCI_CPCI_GENERIC
 	tristate "Generic port I/O CompactPCI Hotplug driver"
 	depends on HOTPLUG_PCI_CPCI && X86
drivers/hotplug/Makefile +1 -0
diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
+obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550_RHC)	+= cpcihp_zt5550_rhc.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o	\
drivers/hotplug/cpcihp_zt5550.c +14 -21
diff -Nru a/drivers/hotplug/cpcihp_zt5550.c b/drivers/hotplug/cpcihp_zt5550.c
@@ -35,6 +35,8 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/kobject.h>
+#include <linux/bitops.h>
 #include "cpci_hotplug.h"
 #include "cpcihp_zt5550.h"
 
@@ -42,22 +44,6 @@
 #define DRIVER_AUTHOR	"Scott Murray <[email protected]>"
 #define DRIVER_DESC	"ZT5550 CompactPCI Hot Plug Driver"
 
-#if !defined(CONFIG_HOTPLUG_PCI_CPCI_ZT5550_MODULE)
-#define MY_NAME	"cpcihp_zt5550"
-#else
-#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if(debug)					\
-			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)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
 /* local variables */
 static int debug;
 static int poll;
@@ -75,8 +61,8 @@
 
 /* Host controller register addresses */
 static void *hc_registers;
-static void *csr_hc_index;
-static void *csr_hc_data;
+void *csr_hc_index;
+void *csr_hc_data;
 static void *csr_intstat;
 static void *csr_intmask;
 
@@ -259,12 +245,12 @@
 	}
 	dbg("registered controller");
 
-	if(hcf_hcs & HCS_BUS1_ACTIVE) {
+	if(hcf_hcs & HCS_BUS1_ACTIVE_MASK) {
 		status = zt5550_register_bus(BUS1_SLOT, &bus1_dev, &bus1);
 		if(status)
 			goto init_register_error;
 	}
-	if(hcf_hcs & HCS_BUS2_ACTIVE) {
+	if(hcf_hcs & HCS_BUS2_ACTIVE_MASK) {
 		status = zt5550_register_bus(BUS2_SLOT, &bus2_dev, &bus2);
 		if(status)
 			goto init_register_error;
@@ -318,13 +304,20 @@
 
 static int __init zt5550_init(void)
 {
+	int rv;
+
 	info(DRIVER_DESC " version: " DRIVER_VERSION);
-	return pci_module_init(&zt5550_hc_driver);
+	rv = pci_module_init(&zt5550_hc_driver);
+	if (!rv)
+		create_hc_files(csr_hc_index,csr_hc_data);
+
+	return rv;
 }
 
 static void __exit
 zt5550_exit(void)
 {
+	remove_hc_files();
 	pci_unregister_driver(&zt5550_hc_driver);
 	release_region(ENUM_PORT, 1);
 }
drivers/hotplug/cpcihp_zt5550.h +258 -13

308 lines not on this page · raw message

drivers/hotplug/cpcihp_zt5550_rhc.c new file +538 -0

538 lines not on this page · raw message

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.981 -> 1.982
# drivers/hotplug/cpcihp_zt5550.h 1.1 -> 1.2
# drivers/hotplug/cpci_hotplug.h 1.1 -> 1.2
# drivers/hotplug/pci_hotplug.h 1.4 -> 1.5
# drivers/hotplug/cpci_hotplug_core.c 1.2 -> 1.3
# drivers/hotplug/cpcihp_zt5550.c 1.1 -> 1.2
# drivers/hotplug/cpci_hotplug_pci.c 1.3 -> 1.4
# drivers/hotplug/pci_hotplug_core.c 1.31 -> 1.32
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/04 [email protected] 1.982
# Adding Scott's latest changes and the sysfs interface for hotplug # --------------------------------------------
#

drivers/hotplug/cpci_hotplug.h +0 -1
diff -Nru a/drivers/hotplug/cpci_hotplug.h b/drivers/hotplug/cpci_hotplug.h
@@ -75,7 +75,6 @@
 extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
 extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
 extern int cpci_hp_unregister_bus(struct pci_bus *bus);
-extern struct slot *cpci_find_slot(struct pci_bus *bus, unsigned int devfn);
 extern int cpci_hp_start(void);
 extern int cpci_hp_stop(void);
 
drivers/hotplug/cpci_hotplug_core.c +0 -29
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
@@ -417,34 +417,6 @@
 	return 0;
 }
 
-struct slot *
-cpci_find_slot(struct pci_bus *bus, unsigned int devfn)
-{
-	struct slot *slot;
-	struct slot *found;
-	struct list_head *tmp;
-
-	if(!bus) {
-		return NULL;
-	}
-
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		return NULL;
-	}
-	found = NULL;
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		if(slot->bus == bus && slot->devfn == devfn) {
-			found = slot;
-			break;
-		}
-	}
-	spin_unlock(&list_lock);
-	return found;
-}
-
 /* This is the interrupt mode interrupt handler */
 void
 cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
@@ -915,6 +887,5 @@
 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_find_slot);
 EXPORT_SYMBOL_GPL(cpci_hp_start);
 EXPORT_SYMBOL_GPL(cpci_hp_stop);
drivers/hotplug/cpci_hotplug_pci.c +19 -10
diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c
@@ -446,7 +446,7 @@
 }
 
 static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
-			struct pci_bus_wrapped *wrapped_bus)
+				   struct pci_bus_wrapped *wrapped_bus)
 {
 	int rc;
 	struct pci_dev *dev = wrapped_dev->dev;
@@ -459,8 +459,8 @@
 	 * We need to fix up the hotplug representation with the Linux
 	 * representation.
 	 */
-	slot = cpci_find_slot(dev->bus, dev->devfn);
-	if(slot) {
+	if(wrapped_dev->data) {
+		slot = (struct slot*) wrapped_dev->data;
 		slot->dev = dev;
 	}
 
@@ -482,7 +482,7 @@
 }
 
 static int unconfigure_visit_pci_dev_phase1(struct pci_dev_wrapped *wrapped_dev,
-				 struct pci_bus_wrapped *wrapped_bus)
+					    struct pci_bus_wrapped *wrapped_bus)
 {
 	struct pci_dev *dev = wrapped_dev->dev;
 
@@ -525,8 +525,8 @@
 	/*
 	 * Now remove the hotplug representation.
 	 */
-	slot = cpci_find_slot(dev->bus, dev->devfn);
-	if(slot) {
+	if(wrapped_dev->data) {
+		slot = (struct slot*) wrapped_dev->data;
 		slot->dev = NULL;
 	} else {
 		dbg("No hotplug representation for %02x:%02x.%x",
@@ -634,6 +634,10 @@
 				continue;
 			wrapped_dev.dev = dev;
 			wrapped_bus.bus = slot->dev->bus;
+			if(i)
+				wrapped_dev.data = NULL;
+			else
+				wrapped_dev.data = (void*) slot;
 			rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
 		}
 	}
@@ -666,16 +670,21 @@
 		if(dev) {
 			wrapped_dev.dev = dev;
 			wrapped_bus.bus = dev->bus;
+			if(i)
+				wrapped_dev.data = NULL;
+			else
+				wrapped_dev.data = (void*) slot;
 			dbg("%s - unconfigure phase 1", __FUNCTION__);
 			rc = pci_visit_dev(&unconfigure_functions_phase1,
-					   &wrapped_dev, &wrapped_bus);
-			if(rc) {
+					   &wrapped_dev,
+					   &wrapped_bus);
+			if(rc)
 				break;
-			}
 
 			dbg("%s - unconfigure phase 2", __FUNCTION__);
 			rc = pci_visit_dev(&unconfigure_functions_phase2,
-					   &wrapped_dev, &wrapped_bus);
+					   &wrapped_dev,
+					   &wrapped_bus);
 			if(rc)
 				break;
 		}
drivers/hotplug/cpcihp_zt5550.c +79 -44

220 lines not on this page · raw message

drivers/hotplug/cpcihp_zt5550.h +45 -28

83 lines not on this page · raw message

drivers/hotplug/pci_hotplug.h +6 -3
diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
@@ -46,8 +46,11 @@
 };
 
 struct hotplug_slot;
-struct hotplug_slot_core;
-
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
@@ -131,7 +134,7 @@
 
 	/* Variables below this are for use only by the hotplug pci core. */
 	struct list_head		slot_list;
-	struct hotplug_slot_core	*core_priv;
+	struct kobject			kobj;
 };
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
drivers/hotplug/pci_hotplug_core.c +161 -866

1,271 lines not on this page · raw message

#1 lore raw
Quoted 14 lines · Rusty Lynch

Last week I finally got access to a decent (but old) technical specification for the ZT5550 redundant host controller. The document was published for the ZT5550C, but I am hoping that newer versions of the RHC just add more functionality to all the documented reserved bits in the document I am looking at.

The following patch adds a sysfs interface to most of the bits accessible via the indirect register (through the HCINDEX and HCDATA addresses in the Command and Status Register (CSR). The only bits I did not add access to were the ones that are cleared by reading. There are a lot of bits to get access to, which makes this patch a little bigger then I first expected, so I created a new config option so only people who actually want to mess with the RHC would pay for it.

Quoted 2 lines

Enabling this code will cause a new directory called zt5550_rhc to be created in the root of sysfs, with the following tree:

Ick, don't place directories in the root of sysfs, unless you want Pat to come after you with a big stick.

What's wrong with putting this directory either under the pci device that is the zt5550 (if it is a pci device), or at the least, under the devices/ directory.

Other than that, I like your macro abuse :)

thanks,

greg k-h

#2 lore raw
Quoted 18 lines · Greg KH
Quoted 14 lines · Rusty Lynch

Last week I finally got access to a decent (but old) technical specification for the ZT5550 redundant host controller. The document was published for the ZT5550C, but I am hoping that newer versions of the RHC just add more functionality to all the documented reserved bits in the document I am looking at.

The following patch adds a sysfs interface to most of the bits accessible via the indirect register (through the HCINDEX and HCDATA addresses in the Command and Status Register (CSR). The only bits I did not add access to were the ones that are cleared by reading. There are a lot of bits to get access to, which makes this patch a little bigger then I first expected, so I created a new config option so only people who actually want to mess with the RHC would pay for it.

Quoted 2 lines

Enabling this code will cause a new directory called zt5550_rhc to be created in the root of sysfs, with the following tree:

Quoted 6 lines

Ick, don't place directories in the root of sysfs, unless you want Pat to come after you with a big stick.

What's wrong with putting this directory either under the pci device that is the zt5550 (if it is a pci device), or at the least, under the devices/ directory.

It was just laziness. I can create a new subsystem that isn't rooted in any other subsystem without any other information. I'll go figure out how to root this in the zt5550 device directory.

Quoted 3 lines

Other than that, I like your macro abuse :)

Yea, one thing leads to another. If wouldn't have stopped myself then the entire file would have been implemented as one macro line.

Quoted 3 lines

thanks,

greg k-h