lkml.org 
[lkml]   [2003]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH][2.5.59-bk]Sysfs interface for ZT5550 Redundant Host Controller
    From
    Date
    Here is a second version of the zt5550 reduncant host controller sysfs
    interface patch. I have first of all removed several of the more advanced
    (and therefore more dangerous) chip features, and also moved the root
    of these files to the 'zt5550_hc' directory that was already being created
    in bus/pci/drivers/ so that the directory view now looks like:

    [root@cpci-b root]# tree /sysfs/bus/pci/drivers/zt5550_hc/rhc/
    /sysfs/bus/pci/drivers/zt5550_hc/rhc/
    |-- diag
    | |-- diag_b0_serr
    | |-- diag_cputemp
    | |-- diag_iochk
    | |-- diag_nmi
    | |-- diag_perr
    | |-- diag_power_fail
    | `-- diag_wd_timeout
    |-- fltc
    | |-- b0_serr
    | |-- cputemp
    | |-- eject_ah
    | |-- eject_bh
    | |-- hard_reset
    | |-- iochk
    | |-- nmi
    | |-- perr
    | |-- power_fail
    | |-- soft_reset
    | `-- wd_timeout
    |-- hcc
    | |-- diagnostics_mode
    | |-- power_down_bh
    | `-- reset_bh
    |-- isoc
    | |-- friendly
    | |-- hostile
    | `-- unlock
    `-- wdc
    |-- prescaler
    `-- terminal_count


    # 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.984
    # drivers/hotplug/cpcihp_zt5550.h 1.2 -> 1.4
    # drivers/hotplug/Kconfig 1.5 -> 1.6
    # drivers/hotplug/cpcihp_zt5550.c 1.2 -> 1.4
    # drivers/hotplug/Makefile 1.12 -> 1.13
    # (new) -> 1.2 drivers/hotplug/cpcihp_zt5550_rhc.c
    #
    # The following is the BitKeeper ChangeSet Log
    # --------------------------------------------
    # 03/02/04 rusty@penguin.co.intel.com 1.983
    # Adding a sysfs inteface for the zt5550 redundant host controller
    # --------------------------------------------
    # 03/02/05 rusty@penguin.co.intel.com 1.984
    # moving root of rhc sysfs files to zt5550_hc directory and remove
    # some of the more advanced access files.
    # --------------------------------------------
    #
    diff -Nru a/drivers/hotplug/Kconfig b/drivers/hotplug/Kconfig
    --- a/drivers/hotplug/Kconfig Wed Feb 5 12:38:17 2003
    +++ b/drivers/hotplug/Kconfig Wed Feb 5 12:38:17 2003
    @@ -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
    diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
    --- a/drivers/hotplug/Makefile Wed Feb 5 12:38:17 2003
    +++ b/drivers/hotplug/Makefile Wed Feb 5 12:38:17 2003
    @@ -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 \
    diff -Nru a/drivers/hotplug/cpcihp_zt5550.c b/drivers/hotplug/cpcihp_zt5550.c
    --- a/drivers/hotplug/cpcihp_zt5550.c Wed Feb 5 12:38:17 2003
    +++ b/drivers/hotplug/cpcihp_zt5550.c Wed Feb 5 12:38:17 2003
    @@ -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 <scottm@somanetworks.com>"
    #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;
    @@ -277,6 +263,7 @@
    }
    dbg("started cPCI hotplug system");

    +
    return 0;
    init_register_error:
    if(bus1)
    @@ -318,13 +305,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,&zt5550_hc_driver);
    +
    + return rv;
    }

    static void __exit
    zt5550_exit(void)
    {
    + remove_hc_files();
    pci_unregister_driver(&zt5550_hc_driver);
    release_region(ENUM_PORT, 1);
    }
    diff -Nru a/drivers/hotplug/cpcihp_zt5550.h b/drivers/hotplug/cpcihp_zt5550.h
    --- a/drivers/hotplug/cpcihp_zt5550.h Wed Feb 5 12:38:17 2003
    +++ b/drivers/hotplug/cpcihp_zt5550.h Wed Feb 5 12:38:17 2003
    @@ -33,6 +33,22 @@
    #ifndef _CPCIHP_ZT5550_H
    #define _CPCIHP_ZT5550_H

    +#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)
    +
    /* Direct registers */
    #define CSR_HCINDEX 0x00
    #define CSR_HCDATA 0x04
    @@ -44,12 +60,40 @@
    #define CSR_TIM0 0x10
    #define CSR_TIM1 0x14

    +/* Masks for bits in CSR_INTSTAT (interrupt status) direct register */
    +#define INTSTAT_SERIAL_FLAG 0x01
    +#define INTSTAT_FAULT_FLAG 0x02
    +#define INTSTAT_HCS_FLAG 0x04
    +#define INTSTAT_TIM0_FLAG 0x08
    +#define INTSTAT_TIM1_FLAG 0x10
    +#define INTSTAT_ENUM_FLAG 0x20
    +
    /* Masks for interrupt bits in CSR_INTMASK direct register */
    #define INTMASK_TIM0_INT_MASK 0x01
    #define INTMASK_TIM1_INT_MASK 0x02
    #define INTMASK_ENUM_INT_MASK 0x04
    #define INTMASK_ALL_INTS_MASK 0x07

    +/* Mask for bits in CSR_ENET (ethernet routing) direct register */
    +#define ENET_A_REAR 0x01
    +#define ENET_B_ROUTING 0x60
    +
    +/* Mask for bits in the CSR_T0_C (timer #0 control) direct register */
    +#define T0_C_ENABLE 0x0001
    +#define T0_C_TIMEOUT_MODE 0x0002
    +#define T0_C_CLOCK_SOURCE 0x000c
    +#define T0_C_READ_MODE 0x0030
    +#define T0_C_WRITE_MODE 0x0040
    +#define T0_C_OUTPUT_FLAG 0x0080
    +
    +/* Mask for bits in the CSR_T1_C (timer #1 control) direct register */
    +#define T1_C_ENABLE 0x0001
    +#define T1_C_TIMEOUT_MODE 0x0002
    +#define T1_C_CLOCK_SOURCE 0x000c
    +#define T1_C_READ_MODE 0x0030
    +#define T1_C_WRITE_MODE 0x0040
    +#define T1_C_OUTPUT_FLAG 0x0080
    +
    /* Indexed registers (through CSR_HCINDEX, CSR_HCDATA) */
    #define HCF_HCI 0x04
    #define HCF_HCS 0x08
    @@ -65,32 +109,233 @@
    #define HCF_SDO 0x38
    #define HCF_SDI 0x3C

    -/* Masks for interrupt bits in HCF_HCI indexed register */
    +/* Masks for interrupt bits in HCF_HCI */
    +/* (host controller interrupt) indexed register */
    #define HCI_SERIAL_INT_MASK 0x01
    #define HCI_FAULT_INT_MASK 0x02
    #define HCI_HCF_INT_MASK 0x04
    #define HCI_ALL_INTS_MASK 0x07

    -/* Masks for the bits in the HCF_HCS indexed register */
    -#define HCS_HA 0x00000001
    -#define HCS_ACTIVE 0x00000002
    -#define HCS_RH_STATE 0x00000004
    -#define HCS_HARD_RESET 0x00000008
    -#define HCS_SOFT_RESET 0x00000010
    -#define HCS_RH_ALIVE 0x00000020
    -#define HCS_SWITCH_OVER 0x00000040
    -#define HCS_TAKEOVER_TYPE 0x00000080
    -#define HCS_BUS1_ACTIVE 0x00000100
    -#define HCS_BUS2_ACTIVE 0x00000200
    -#define HCS_SPLIT_MODE_ERROR 0x00000400
    +/* Masks for the bits in the HCF_HCS */
    +/* (host controller status) indexed register */
    +#define HCS_HA_MASK 0x00000001
    +#define HCS_ACTIVE_MASK 0x00000002
    +#define HCS_RH_STATE_MASK 0x00000004
    +#define HCS_HARD_RESET_MASK 0x00000008
    +#define HCS_SOFT_RESET_MASK 0x00000010
    +#define HCS_RH_ALIVE_MASK 0x00000020
    +#define HCS_SWITCH_OVER_MASK 0x00000040
    +#define HCS_TAKEOVER_TYPE_MASK 0x00000080
    +#define HCS_BUS1_ACTIVE_MASK 0x00000100
    +#define HCS_BUS2_ACTIVE_MASK 0x00000200
    +#define HCS_SPLIT_MODE_ERR_MASK 0x00000400
    +
    +/* Masks for the bits in the HCF_HCC */
    +/* (host controller command) indexed register */
    +#define HCC_RESET_MASK 0x00000001
    +#define HCC_DIAG_MODE_MASK 0x00000002
    +#define HCC_CONFIG_MODE_MASK 0x00000004
    +#define HCC_S2_BP_RESET_MASK 0x00000008
    +#define HCC_S1_BP_RESET_MASK 0x00000010
    +#define HCC_WARM_BOOT_MASK 0x00000020
    +#define HCC_INIT_TAKEOVER_MASK 0x00000040
    +#define HCC_WD_ENABLE_MASK 0x00000080
    +#define HCC_RESET_BH_MASK 0x00000100
    +#define HCC_POWER_DOWN_BH_MASK 0x00000200
    +#define HCC_BH_S1_RESPONSE_MASK 0x00001000
    +#define HCC_AH_S1_RESPONSE_MASK 0x00002000
    +
    +/* Masks for the bits in the HCF_ARBC */
    +/* (arbitration configuration) indexed register */
    +#define ARBC_S1_GNT0_MASK 0x00000001
    +#define ARBC_S1_GNT1_MASK 0x00000002
    +#define ARBC_S1_GNT2_MASK 0x00000004
    +#define ARBC_S1_GNT3_MASK 0x00000008
    +#define ARBC_S1_GNT4_MASK 0x00000010
    +#define ARBC_S1_GNT5_MASK 0x00000020
    +#define ARBC_S1_GNT6_MASK 0x00000040
    +#define ARBC_S1_GNT7_MASK 0x00000080
    +#define ARBC_S2_GNT0_MASK 0x00000100
    +#define ARBC_S2_GNT1_MASK 0x00000200
    +#define ARBC_S2_GNT2_MASK 0x00000400
    +#define ARBC_S2_GNT3_MASK 0x00000800
    +#define ARBC_S2_GNT4_MASK 0x00001000
    +#define ARBC_S2_GNT5_MASK 0x00002000
    +#define ARBC_S2_GNT6_MASK 0x00004000
    +#define ARBC_S2_GNT7_MASK 0x00008000
    +
    +/* Masks for the bits in the HCF_ISOC */
    +/* (isolation configuration) indexed register */
    +#define ISOC_UNLOCK_MASK 0x00000001
    +#define ISOC_S1_BP_RESET_MASK 0x00000002
    +#define ISOC_S2_BP_RESET_MASK 0x00000004
    +#define ISOC_BP_INTERRUPT_MASK 0x00000008
    +#define ISOC_HOSTILE_MASK 0x00000030
    +#define ISOC_FRIENDLY_MASK 0x000000c0
    +
    +/* Masks for the bits in the HCF_FLTS (fault status) indexed register */
    +#define FLTS_WD_TIMEOUT_MASK 0x00000001
    +#define FLTS_PERR_MASK 0x00000002
    +#define FLTS_IOCHK_MASK 0x00000004
    +#define FLTS_NMI_MASK 0x00000008
    +#define FLTS_B0_SERR_MASK 0x00000010
    +#define FLTS_CPUTEMP_MASK 0x00000040
    +#define FLTS_POWER_FAIL_MASK 0x00000080
    +#define FLTS_EJECT_BH_MASK 0x00000100
    +#define FLTS_EJECT_AH_MASK 0x00000200
    +
    +/* Masks for the bits in the HCF_FLTC (fault configuration) indexed register */
    +#define FLTC_WD_TIMEOUT_MASK 0x00000007
    +#define FLTC_PERR_MASK 0x00000038
    +#define FLTC_IOCHK_MASK 0x000001c0
    +#define FLTC_NMI_MASK 0x00000e00
    +#define FLTC_B0_SERR_MASK 0x00007000
    +#define FLTC_CPUTEMP_MASK 0x001c0000
    +#define FLTC_POWER_FAIL_MASK 0x00e00000
    +#define FLTC_EJECT_BH_MASK 0x07000000
    +#define FLTC_EJECT_AH_MASK 0x38000000
    +#define FLTC_SOFT_RESET_MASK 0x40000000
    +#define FLTC_HARD_RESET_MASK 0x80000000
    +
    +/* Masks for the bits in the HCF_PMCC (PMC control) indexed register */
    +#define PMCC_PMC1_STATUS_MASK 0x00000001
    +#define PMCC_PMC1_COMMAND2_MASK 0x00000002
    +#define PMCC_PMC1_COMMAND4_MASK 0x00000004
    +#define PMCC_PMC2_STATUS_MASK 0x00000010
    +#define PMCC_PMC2_COMMAND2_MASK 0x00000020
    +#define PMCC_PMC2_COMMAND4_MASK 0x00000040
    +
    +/* Masks for the bits in the HCF_WDC (watchdog control) indexed register */
    +#define WDC_TERMINAL_COUNT_MASK 0x0000003f
    +#define WDC_PRESCALER_MASK 0x000000c0
    +
    +/* Masks for the bits in the HCF_DIAG (diagnostics command) indexed register */
    +#define DIAG_WD_TIMEOUT_MASK 0x00000001
    +#define DIAG_PERR_MASK 0x00000002
    +#define DIAG_IOCHK_MASK 0x00000004
    +#define DIAG_NMI_MASK 0x00000008
    +#define DIAG_B0_SERR_MASK 0x00000010
    +#define DIAG_CPUTEMP_MASK 0x00000040
    +#define DIAG_POWER_FAIL_MASK 0x00000080
    +
    +/* Masks for the bits in the HCF_SERC (diagnostics command) indexed register */
    +#define SERC_DATA_SENT 0x00000001
    +#define SERC_DATA_RECIEVED 0x00000002
    +#define SERC_SDO_FLAG_ENABLE 0x00000004
    +#define SERC_SDI_FLAG_ENABLE 0x00000008
    +#define SERC_HCSI_OFF 0x00000010
    +#define SERC_FIND_TOKEN 0x00000020

    /* CompactPCI bus segment device slot numbers */
    #define BUS1_SLOT 0x08
    #define BUS2_SLOT 0x0C

    +/* I/O port for setting and configuring watchdog timer */
    +#define WDT_PORT 0x79
    +
    +/* Masks for bits written/read from the watchdog timer port */
    +#define WDT_TERMINAL_COUNT 0x07
    +#define WDT_FIRST_STAGE_ENABLE 0x10
    +#define WDT_RESET_ENABLE 0x20
    +#define WDT_FIRST_STAGE_MONITOR 0x40
    +#define WDT_RESET_MONITOR 0x80
    +
    /* Digital I/O port storing ENUM# */
    #define ENUM_PORT 0xE1
    /* Mask to get to the ENUM# bit on the bus */
    #define ENUM_MASK 0x40

    +#define hcf_read(index, value, csr_hc_index, csr_hc_data) \
    + { \
    + writeb((u8) index, csr_hc_index); \
    + value = readl(csr_hc_data); \
    + dbg("hcf_read(0x%08x, 0x%08x)",index,value); \
    + }
    +
    +#define hcf_write(index, value, csr_hc_index, csr_hc_data) \
    + { \
    + writeb((u8) index, csr_hc_index); \
    + writel(value, csr_hc_data); \
    + dbg("hcf_write(0x%08x, 0x%08x)",index,value); \
    + }
    +
    +#define hcf_set_bit(index, bit, csr_hc_index, csr_hc_data) \
    + { \
    + int tmp; \
    + hcf_read(index, tmp, csr_hc_index, csr_hc_data); \
    + hcf_write(index, tmp|bit, csr_hc_index, csr_hc_data); \
    + dbg("hcf_set_bit(0x%08x, 0x%08x)",index,bit); \
    + }
    +
    +#define hcf_clear_bit(index, bit, csr_hc_index, csr_hc_data) \
    + { \
    + int tmp; \
    + hcf_read(index, tmp, csr_hc_index, csr_hc_data); \
    + hcf_write(index, tmp & ~bit, csr_hc_index, csr_hc_data); \
    + dbg("hcf_clear_bit(0x%08x, 0x%08x)",index,bit); \
    + }
    +
    +#define hcf_write_bits(index, mask, request, csr_hc_index, csr_hc_data) \
    + { \
    + int tmp; \
    + dbg("hcf_write_bits(0x%08x, 0x%08x, 0x%08x)", \
    + index,mask,request); \
    + request = request << (generic_ffs(mask) - 1); \
    + request &= mask; \
    + request |= ~mask; \
    + hcf_read(index, tmp, csr_hc_index, csr_hc_data); \
    + tmp |= mask; \
    + tmp &= request; \
    + hcf_write(index, tmp, csr_hc_index, csr_hc_data); \
    + }
    +
    +#define hcf_read_bits(index, mask, value, csr_hc_index, csr_hc_data) \
    + { \
    + hcf_read(index, value, csr_hc_index, csr_hc_data); \
    + value = (mask&value)>>(generic_ffs(mask) - 1); \
    + dbg("hcf_read_bits(0x%08x, 0x%08x, 0x%08x)", \
    + index,mask,value); \
    + }
    +
    +#define decl_hc_attribute(_name) \
    +static struct rhc_attribute _name##_attr = { \
    + .attr = { .name = __stringify(_name), .mode = 0644 }, \
    + .show = _name##_show, \
    + .store = _name##_store, \
    +}
    +
    +#define decl_hc_kobject(_name) \
    +static struct rhc _name##_obj = { \
    + .kobj.name = __stringify(_name), \
    +}
    +
    +
    +#define decl_hc_show_function(_name, _index, _mask) \
    +static ssize_t _name##_show(struct rhc * p, char * page) \
    +{ \
    + int tmp; \
    + hcf_read_bits(_index, _mask, tmp, p->index, p->data); \
    + return sprintf(page,"%d\n", tmp); \
    +}
    +
    +#define decl_hc_store_function(_name, _index, _mask) \
    +static ssize_t _name##_store(struct rhc * p, const char * page, size_t count) \
    +{ \
    + int request; \
    + if (sscanf(page, "%i", &request)) {\
    + hcf_write_bits(_index, _mask, request, p->index, p->data); \
    + return count; \
    + } \
    + return -EINVAL; \
    +}
    +
    +#ifdef CONFIG_HOTPLUG_PCI_CPCI_ZT5550_RHC
    +extern void create_hc_files(void *,void *,struct pci_driver *);
    +extern void remove_hc_files(void);
    +#else /* !CONFIG_HOTPLUG_PCI_CPCI_ZT5550_RHC */
    +static inline void create_hc_files(void *i,void *d,struct pci_driver *p){}
    +static inline void remove_hc_files(void){}
    +#endif
    +
    #endif /* _CPCIHP_ZT5550_H */
    +
    diff -Nru a/drivers/hotplug/cpcihp_zt5550_rhc.c b/drivers/hotplug/cpcihp_zt5550_rhc.c
    --- /dev/null Wed Dec 31 16:00:00 1969
    +++ b/drivers/hotplug/cpcihp_zt5550_rhc.c Wed Feb 5 12:38:17 2003
    @@ -0,0 +1,365 @@
    +/*
    + * cpcihp_zt5550.c
    + *
    + * Intel/Ziatech ZT5550 CompactPCI Redundant Host Controller Sysfs Interface
    + *
    + * Copyright 2002 SOMA Networks, Inc.
    + * Copyright 2001 Intel San Luis Obispo
    + * Copyright 2000,2001 MontaVista Software Inc.
    + *
    + * This program is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License as published by the
    + * Free Software Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + *
    + * THIS 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
    + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * You should have received a copy of the GNU General Public License along
    + * with this program; if not, write to the Free Software Foundation, Inc.,
    + * 675 Mass Ave, Cambridge, MA 02139, USA.
    + */
    +
    +#include <linux/config.h>
    +#include <linux/module.h>
    +#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"
    +
    +extern int debug;
    +extern void *csr_hc_index;
    +extern void *csr_hc_data;
    +
    +struct rhc {
    + void *index;
    + void *data;
    + struct kobject kobj;
    +};
    +struct rhc_attribute {
    + struct attribute attr;
    + ssize_t (*show) (struct rhc *,char *);
    + ssize_t (*store)(struct rhc *,const char *, size_t);
    +};
    +
    +static ssize_t rhc_attr_show(struct kobject * kobj,
    + struct attribute * attr,
    + char * page)
    +{
    + struct rhc * i = container_of(kobj,struct rhc,kobj);
    + struct rhc_attribute * rhc_attr =
    + container_of(attr,struct rhc_attribute,attr);
    +
    + return rhc_attr->show ? rhc_attr->show(i,page) : 0;
    +}
    +
    +static ssize_t rhc_attr_store(struct kobject * kobj,
    + struct attribute * attr,
    + const char * page,
    + size_t count)
    +{
    + struct rhc * i = container_of(kobj,struct rhc,kobj);
    + struct rhc_attribute * rhc_attr =
    + container_of(attr,struct rhc_attribute,attr);
    +
    + return rhc_attr->store ? rhc_attr->store(i,page,count) : 0;
    +}
    +
    +static struct sysfs_ops rhc_sysfs_ops = {
    + .show = rhc_attr_show,
    + .store = rhc_attr_store,
    +};
    +
    +static struct kobj_type rhc_ktype = {
    + .sysfs_ops = &rhc_sysfs_ops
    +};
    +
    +static struct subsystem rhc_subsys = {
    + .kset = {
    + .kobj = { .name = "rhc" },
    + .ktype = &rhc_ktype,
    + }
    +};
    +
    +/**********************************************************************
    + * Host Control Command attributes
    + * NOTE: The HCC register is by default locked. To change any
    + * value, first unlock by writing a '1' to the UNLOCK bit
    + * in the ISOC register.
    + */
    +decl_hc_kobject(hcc);
    +
    +/* Diagnostics Mode Command */
    +decl_hc_store_function(diagnostics_mode,HCF_HCC,HCC_DIAG_MODE_MASK);
    +decl_hc_show_function(diagnostics_mode,HCF_HCC,HCC_DIAG_MODE_MASK);
    +decl_hc_attribute(diagnostics_mode);
    +
    +/* Reset Backup Host Command*/
    +decl_hc_store_function(reset_bh,HCF_HCC,HCC_RESET_BH_MASK);
    +decl_hc_show_function(reset_bh,HCF_HCC,HCC_RESET_BH_MASK);
    +decl_hc_attribute(reset_bh);
    +
    +/* Power Down Backup Host Command */
    +decl_hc_store_function(power_down_bh,HCF_HCC,HCC_POWER_DOWN_BH_MASK);
    +decl_hc_show_function(power_down_bh,HCF_HCC,HCC_POWER_DOWN_BH_MASK);
    +decl_hc_attribute(power_down_bh);
    +
    +/**********************************************************************
    + * Isolation Configuration register (ISOC) attributes
    + */
    +decl_hc_kobject(isoc);
    +
    +/* Hostile Configuration (what happens on a hostile takeover)*/
    +decl_hc_store_function(hostile,HCF_ISOC,ISOC_HOSTILE_MASK);
    +decl_hc_show_function(hostile,HCF_ISOC,ISOC_HOSTILE_MASK);
    +decl_hc_attribute(hostile);
    +
    +/* Friendly Configuration (what happens on a friendly takeover)*/
    +decl_hc_store_function(friendly,HCF_ISOC,ISOC_FRIENDLY_MASK);
    +decl_hc_show_function(friendly,HCF_ISOC,ISOC_FRIENDLY_MASK);
    +decl_hc_attribute(friendly);
    +
    +/* HCC Unlock Command */
    +decl_hc_store_function(unlock,HCF_ISOC,ISOC_UNLOCK_MASK);
    +decl_hc_show_function(unlock,HCF_ISOC,ISOC_UNLOCK_MASK);
    +decl_hc_attribute(unlock);
    +
    +/**********************************************************************
    + * Fault Configuration register (FLTC) attributes
    + */
    +decl_hc_kobject(fltc);
    +
    +/* Watchdog Timeout Configuration */
    +decl_hc_store_function(wd_timeout,HCF_FLTC,FLTC_WD_TIMEOUT_MASK);
    +decl_hc_show_function(wd_timeout,HCF_FLTC,FLTC_WD_TIMEOUT_MASK);
    +decl_hc_attribute(wd_timeout);
    +
    +/* PERR Configuration */
    +decl_hc_store_function(perr,HCF_FLTC,FLTC_PERR_MASK);
    +decl_hc_show_function(perr,HCF_FLTC,FLTC_PERR_MASK);
    +decl_hc_attribute(perr);
    +
    +/* IOCHK Configuration */
    +decl_hc_store_function(iochk,HCF_FLTC,FLTC_IOCHK_MASK);
    +decl_hc_show_function(iochk,HCF_FLTC,FLTC_IOCHK_MASK);
    +decl_hc_attribute(iochk);
    +
    +/* NMI Configuration */
    +decl_hc_store_function(nmi,HCF_FLTC,FLTC_NMI_MASK);
    +decl_hc_show_function(nmi,HCF_FLTC,FLTC_NMI_MASK);
    +decl_hc_attribute(nmi);
    +
    +/* B0_SERR Configuration */
    +decl_hc_store_function(b0_serr,HCF_FLTC,FLTC_B0_SERR_MASK);
    +decl_hc_show_function(b0_serr,HCF_FLTC,FLTC_B0_SERR_MASK);
    +decl_hc_attribute(b0_serr);
    +
    +/* CPUTEMP Configuration */
    +decl_hc_store_function(cputemp,HCF_FLTC,FLTC_CPUTEMP_MASK);
    +decl_hc_show_function(cputemp,HCF_FLTC,FLTC_CPUTEMP_MASK);
    +decl_hc_attribute(cputemp);
    +
    +/* Power Fail Configuration */
    +decl_hc_store_function(power_fail,HCF_FLTC,FLTC_POWER_FAIL_MASK);
    +decl_hc_show_function(power_fail,HCF_FLTC,FLTC_POWER_FAIL_MASK);
    +decl_hc_attribute(power_fail);
    +
    +/* Eject BH Configuration */
    +decl_hc_store_function(eject_bh,HCF_FLTC,FLTC_EJECT_BH_MASK);
    +decl_hc_show_function(eject_bh,HCF_FLTC,FLTC_EJECT_BH_MASK);
    +decl_hc_attribute(eject_bh);
    +
    +/* Eject AH Configuration */
    +decl_hc_store_function(eject_ah,HCF_FLTC,FLTC_EJECT_AH_MASK);
    +decl_hc_show_function(eject_ah,HCF_FLTC,FLTC_EJECT_AH_MASK);
    +decl_hc_attribute(eject_ah);
    +
    +/* Soft Reset Configuration */
    +decl_hc_store_function(soft_reset,HCF_FLTC,FLTC_SOFT_RESET_MASK);
    +decl_hc_show_function(soft_reset,HCF_FLTC,FLTC_SOFT_RESET_MASK);
    +decl_hc_attribute(soft_reset);
    +
    +/* Hard Reset Configuration */
    +decl_hc_store_function(hard_reset,HCF_FLTC,FLTC_HARD_RESET_MASK);
    +decl_hc_show_function(hard_reset,HCF_FLTC,FLTC_HARD_RESET_MASK);
    +decl_hc_attribute(hard_reset);
    +
    +/**********************************************************************
    + * Diagnostics (DIAG) register attributes: Setting any of these bits
    + * will cause the associated fault to be simulated.
    + */
    +decl_hc_kobject(diag);
    +
    +/* Watchdog Timeout Diagnostic */
    +decl_hc_store_function(diag_wd_timeout,HCF_DIAG,DIAG_WD_TIMEOUT_MASK);
    +decl_hc_show_function(diag_wd_timeout,HCF_DIAG,DIAG_WD_TIMEOUT_MASK);
    +decl_hc_attribute(diag_wd_timeout);
    +
    +/* PERR Diagnostic */
    +decl_hc_store_function(diag_perr,HCF_DIAG,DIAG_PERR_MASK);
    +decl_hc_show_function(diag_perr,HCF_DIAG,DIAG_PERR_MASK);
    +decl_hc_attribute(diag_perr);
    +
    +/* IOCHK Diagnostic */
    +decl_hc_store_function(diag_iochk,HCF_DIAG,DIAG_IOCHK_MASK);
    +decl_hc_show_function(diag_iochk,HCF_DIAG,DIAG_IOCHK_MASK);
    +decl_hc_attribute(diag_iochk);
    +
    +/* NMI Diagnostic */
    +decl_hc_store_function(diag_nmi,HCF_DIAG,DIAG_NMI_MASK);
    +decl_hc_show_function(diag_nmi,HCF_DIAG,DIAG_NMI_MASK);
    +decl_hc_attribute(diag_nmi);
    +
    +/* B0 SERR Diagnostic */
    +decl_hc_store_function(diag_b0_serr,HCF_DIAG,DIAG_B0_SERR_MASK);
    +decl_hc_show_function(diag_b0_serr,HCF_DIAG,DIAG_B0_SERR_MASK);
    +decl_hc_attribute(diag_b0_serr);
    +
    +/* CPUTEMP Diagnostic */
    +decl_hc_store_function(diag_cputemp,HCF_DIAG,DIAG_CPUTEMP_MASK);
    +decl_hc_show_function(diag_cputemp,HCF_DIAG,DIAG_CPUTEMP_MASK);
    +decl_hc_attribute(diag_cputemp);
    +
    +/* Power Fail Diagnostic */
    +decl_hc_store_function(diag_power_fail,HCF_DIAG,DIAG_POWER_FAIL_MASK);
    +decl_hc_show_function(diag_power_fail,HCF_DIAG,DIAG_POWER_FAIL_MASK);
    +decl_hc_attribute(diag_power_fail);
    +
    +/**********************************************************************
    + * Watchdog Control (WDC) register attributes
    + */
    +decl_hc_kobject(wdc);
    +
    +/* Watchdog Terminal Count (prescaler counts to timeout) */
    +decl_hc_store_function(terminal_count,HCF_WDC,WDC_TERMINAL_COUNT_MASK);
    +decl_hc_show_function(terminal_count,HCF_WDC,WDC_TERMINAL_COUNT_MASK);
    +decl_hc_attribute(terminal_count);
    +
    +/* Watchdog Prescaler (clock period) */
    +decl_hc_store_function(prescaler,HCF_WDC,WDC_PRESCALER_MASK);
    +decl_hc_show_function(prescaler,HCF_WDC,WDC_PRESCALER_MASK);
    +decl_hc_attribute(prescaler);
    +
    +void create_hc_files(void *index, void *data, struct pci_driver *d)
    +{
    + if (!index || !data || !d)
    + return;
    +
    + rhc_subsys.kset.kobj.parent = &(d->driver.kobj);
    + if(subsystem_register(&rhc_subsys))
    + return;
    +
    + /* hcc */
    + hcc_obj.index = index;
    + hcc_obj.data = data;
    + kobj_set_kset_s(&hcc_obj, rhc_subsys);
    + kobject_register(&hcc_obj.kobj);
    + sysfs_create_file(&hcc_obj.kobj, &diagnostics_mode_attr.attr);
    + sysfs_create_file(&hcc_obj.kobj, &reset_bh_attr.attr);
    + sysfs_create_file(&hcc_obj.kobj, &power_down_bh_attr.attr);
    +
    + /* isoc */
    + isoc_obj.index = index;
    + isoc_obj.data = data;
    + kobj_set_kset_s(&isoc_obj, rhc_subsys);
    + kobject_register(&isoc_obj.kobj);
    + sysfs_create_file(&isoc_obj.kobj, &unlock_attr.attr);
    + sysfs_create_file(&isoc_obj.kobj, &hostile_attr.attr);
    + sysfs_create_file(&isoc_obj.kobj, &friendly_attr.attr);
    +
    + /* fltc */
    + fltc_obj.index = index;
    + fltc_obj.data = data;
    + kobj_set_kset_s(&fltc_obj, rhc_subsys);
    + kobject_register(&fltc_obj.kobj);
    + sysfs_create_file(&fltc_obj.kobj, &wd_timeout_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &perr_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &iochk_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &nmi_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &b0_serr_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &cputemp_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &power_fail_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &eject_bh_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &eject_ah_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &soft_reset_attr.attr);
    + sysfs_create_file(&fltc_obj.kobj, &hard_reset_attr.attr);
    +
    + /* wdc */
    + wdc_obj.index = index;
    + wdc_obj.data = data;
    + kobj_set_kset_s(&wdc_obj, rhc_subsys);
    + kobject_register(&wdc_obj.kobj);
    + sysfs_create_file(&wdc_obj.kobj, &terminal_count_attr.attr);
    + sysfs_create_file(&wdc_obj.kobj, &prescaler_attr.attr);
    +
    + /* diag */
    + diag_obj.index = index;
    + diag_obj.data = data;
    + kobj_set_kset_s(&diag_obj, rhc_subsys);
    + kobject_register(&diag_obj.kobj);
    + sysfs_create_file(&diag_obj.kobj, &diag_wd_timeout_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_perr_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_iochk_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_nmi_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_b0_serr_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_cputemp_attr.attr);
    + sysfs_create_file(&diag_obj.kobj, &diag_power_fail_attr.attr);
    +}
    +
    +void remove_hc_files(void)
    +{
    + /* hcc */
    + sysfs_remove_file(&hcc_obj.kobj, &diagnostics_mode_attr.attr);
    + sysfs_remove_file(&hcc_obj.kobj, &reset_bh_attr.attr);
    + sysfs_remove_file(&hcc_obj.kobj, &power_down_bh_attr.attr);
    + kobject_unregister(&hcc_obj.kobj);
    +
    + /* isoc */
    + sysfs_remove_file(&isoc_obj.kobj, &unlock_attr.attr);
    + sysfs_remove_file(&isoc_obj.kobj, &hostile_attr.attr);
    + sysfs_remove_file(&isoc_obj.kobj, &friendly_attr.attr);
    + kobject_unregister(&isoc_obj.kobj);
    +
    + /* fltc */
    + sysfs_remove_file(&fltc_obj.kobj, &wd_timeout_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &perr_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &iochk_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &nmi_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &b0_serr_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &cputemp_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &power_fail_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &eject_bh_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &eject_ah_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &soft_reset_attr.attr);
    + sysfs_remove_file(&fltc_obj.kobj, &hard_reset_attr.attr);
    + kobject_unregister(&fltc_obj.kobj);
    +
    + /* wdc */
    + sysfs_remove_file(&wdc_obj.kobj, &terminal_count_attr.attr);
    + sysfs_remove_file(&wdc_obj.kobj, &prescaler_attr.attr);
    + kobject_unregister(&wdc_obj.kobj);
    +
    + /* diag */
    + sysfs_remove_file(&diag_obj.kobj, &diag_wd_timeout_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_perr_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_iochk_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_nmi_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_b0_serr_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_cputemp_attr.attr);
    + sysfs_remove_file(&diag_obj.kobj, &diag_power_fail_attr.attr);
    + kobject_unregister(&diag_obj.kobj);
    +
    + subsystem_unregister(&rhc_subsys);
    +}
    +

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:32    [W:0.130 / U:0.672 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site