Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67605
b: refs/heads/master
c: fc5019c
h: refs/heads/master
i:
  67603: 06f2168
v: v3
  • Loading branch information
Cornelia Huck authored and Martin Schwidefsky committed Oct 12, 2007
1 parent 00678a4 commit 9e3508f
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fbf9772b8e7917f85f35913b30788c74ea34cad5
refs/heads/master: fc5019c5c7067bcea1e49fe9cd5190285f0c8927
141 changes: 77 additions & 64 deletions trunk/drivers/s390/cio/cmf.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
#include "ioasm.h"
#include "chsc.h"

/* parameter to enable cmf during boot, possible uses are:
/*
* parameter to enable cmf during boot, possible uses are:
* "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be
* used on any subchannel
* "s390cmf=<num>" -- enable cmf and allocate enough memory to measure
Expand Down Expand Up @@ -84,6 +85,7 @@ enum cmb_format {
CMF_EXTENDED,
CMF_AUTODETECT = -1,
};

/**
* format - actual format for all measurement blocks
*
Expand Down Expand Up @@ -111,13 +113,13 @@ module_param(format, bool, 0444);
* @align: align an allocated block so that the hardware can use it
*/
struct cmb_operations {
int (*alloc) (struct ccw_device*);
void(*free) (struct ccw_device*);
int (*set) (struct ccw_device*, u32);
u64 (*read) (struct ccw_device*, int);
int (*readall)(struct ccw_device*, struct cmbdata *);
void (*reset) (struct ccw_device*);
void * (*align) (void *);
int (*alloc) (struct ccw_device *);
void (*free) (struct ccw_device *);
int (*set) (struct ccw_device *, u32);
u64 (*read) (struct ccw_device *, int);
int (*readall)(struct ccw_device *, struct cmbdata *);
void (*reset) (struct ccw_device *);
void *(*align) (void *);

struct attribute_group *attr_group;
};
Expand All @@ -130,9 +132,11 @@ struct cmb_data {
unsigned long long last_update; /* when last_block was updated */
};

/* our user interface is designed in terms of nanoseconds,
/*
* Our user interface is designed in terms of nanoseconds,
* while the hardware measures total times in its own
* unit.*/
* unit.
*/
static inline u64 time_to_nsec(u32 value)
{
return ((u64)value) * 128000ull;
Expand All @@ -159,12 +163,13 @@ static inline u64 time_to_avg_nsec(u32 value, u32 count)
return ret;
}

/* activate or deactivate the channel monitor. When area is NULL,
/*
* Activate or deactivate the channel monitor. When area is NULL,
* the monitor is deactivated. The channel monitor needs to
* be active in order to measure subchannels, which also need
* to be enabled. */
static inline void
cmf_activate(void *area, unsigned int onoff)
* to be enabled.
*/
static inline void cmf_activate(void *area, unsigned int onoff)
{
register void * __gpr2 asm("2");
register long __gpr1 asm("1");
Expand All @@ -175,8 +180,8 @@ cmf_activate(void *area, unsigned int onoff)
asm("schm" : : "d" (__gpr2), "d" (__gpr1) );
}

static int
set_schib(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address)
static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc,
unsigned long address)
{
int ret;
int retry;
Expand Down Expand Up @@ -484,15 +489,14 @@ static struct cmb_area cmb_area = {

/* ****** old style CMB handling ********/

/** int maxchannels
*
/*
* Basic channel measurement blocks are allocated in one contiguous
* block of memory, which can not be moved as long as any channel
* is active. Therefore, a maximum number of subchannels needs to
* be defined somewhere. This is a module parameter, defaulting to
* a resonable value of 1024, or 32 kb of memory.
* Current kernels don't allow kmalloc with more than 128kb, so the
* maximum is 4096
* maximum is 4096.
*/

module_param_named(maxchannels, cmb_area.num_channels, uint, 0444);
Expand All @@ -516,8 +520,9 @@ struct cmb {
u32 reserved[2];
};

/* insert a single device into the cmb_area list
* called with cmb_area.lock held from alloc_cmb
/*
* Insert a single device into the cmb_area list.
* Called with cmb_area.lock held from alloc_cmb.
*/
static int alloc_cmb_single(struct ccw_device *cdev,
struct cmb_data *cmb_data)
Expand All @@ -532,9 +537,11 @@ static int alloc_cmb_single(struct ccw_device *cdev,
goto out;
}

/* find first unused cmb in cmb_area.mem.
* this is a little tricky: cmb_area.list
* remains sorted by ->cmb->hw_data pointers */
/*
* Find first unused cmb in cmb_area.mem.
* This is a little tricky: cmb_area.list
* remains sorted by ->cmb->hw_data pointers.
*/
cmb = cmb_area.mem;
list_for_each_entry(node, &cmb_area.list, cmb_list) {
struct cmb_data *data;
Expand All @@ -558,8 +565,7 @@ static int alloc_cmb_single(struct ccw_device *cdev,
return ret;
}

static int
alloc_cmb (struct ccw_device *cdev)
static int alloc_cmb(struct ccw_device *cdev)
{
int ret;
struct cmb *mem;
Expand Down Expand Up @@ -670,7 +676,7 @@ static int set_cmb(struct ccw_device *cdev, u32 mme)
return set_schib_wait(cdev, mme, 0, offset);
}

static u64 read_cmb (struct ccw_device *cdev, int index)
static u64 read_cmb(struct ccw_device *cdev, int index)
{
struct cmb *cmb;
u32 val;
Expand Down Expand Up @@ -720,7 +726,7 @@ static u64 read_cmb (struct ccw_device *cdev, int index)
return ret;
}

static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
static int readall_cmb(struct ccw_device *cdev, struct cmbdata *data)
{
struct cmb *cmb;
struct cmb_data *cmb_data;
Expand Down Expand Up @@ -816,18 +822,20 @@ struct cmbe {
u32 reserved[7];
};

/* kmalloc only guarantees 8 byte alignment, but we need cmbe
/*
* kmalloc only guarantees 8 byte alignment, but we need cmbe
* pointers to be naturally aligned. Make sure to allocate
* enough space for two cmbes */
static inline struct cmbe* cmbe_align(struct cmbe *c)
* enough space for two cmbes.
*/
static inline struct cmbe *cmbe_align(struct cmbe *c)
{
unsigned long addr;
addr = ((unsigned long)c + sizeof (struct cmbe) - sizeof(long)) &
~(sizeof (struct cmbe) - sizeof(long));
return (struct cmbe*)addr;
}

static int alloc_cmbe (struct ccw_device *cdev)
static int alloc_cmbe(struct ccw_device *cdev)
{
struct cmbe *cmbe;
struct cmb_data *cmb_data;
Expand Down Expand Up @@ -873,7 +881,7 @@ static int alloc_cmbe (struct ccw_device *cdev)
return ret;
}

static void free_cmbe (struct ccw_device *cdev)
static void free_cmbe(struct ccw_device *cdev)
{
struct cmb_data *cmb_data;

Expand Down Expand Up @@ -912,7 +920,7 @@ static int set_cmbe(struct ccw_device *cdev, u32 mme)
}


static u64 read_cmbe (struct ccw_device *cdev, int index)
static u64 read_cmbe(struct ccw_device *cdev, int index)
{
struct cmbe *cmb;
struct cmb_data *cmb_data;
Expand Down Expand Up @@ -970,7 +978,7 @@ static u64 read_cmbe (struct ccw_device *cdev, int index)
return ret;
}

static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
static int readall_cmbe(struct ccw_device *cdev, struct cmbdata *data)
{
struct cmbe *cmb;
struct cmb_data *cmb_data;
Expand Down Expand Up @@ -1049,15 +1057,15 @@ static struct cmb_operations cmbops_extended = {
};


static ssize_t
cmb_show_attr(struct device *dev, char *buf, enum cmb_index idx)
static ssize_t cmb_show_attr(struct device *dev, char *buf, enum cmb_index idx)
{
return sprintf(buf, "%lld\n",
(unsigned long long) cmf_read(to_ccwdev(dev), idx));
}

static ssize_t
cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t cmb_show_avg_sample_interval(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ccw_device *cdev;
long interval;
Expand All @@ -1079,8 +1087,9 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "%ld\n", interval);
}

static ssize_t
cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t cmb_show_avg_utilization(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct cmbdata data;
u64 utilization;
Expand Down Expand Up @@ -1112,14 +1121,16 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char
}

#define cmf_attr(name) \
static ssize_t show_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
{ return cmb_show_attr((dev), buf, cmb_ ## name); } \
static DEVICE_ATTR(name, 0444, show_ ## name, NULL);
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ return cmb_show_attr((dev), buf, cmb_##name); } \
static DEVICE_ATTR(name, 0444, show_##name, NULL);

#define cmf_attr_avg(name) \
static ssize_t show_avg_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
{ return cmb_show_attr((dev), buf, cmb_ ## name); } \
static DEVICE_ATTR(avg_ ## name, 0444, show_avg_ ## name, NULL);
static ssize_t show_avg_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ return cmb_show_attr((dev), buf, cmb_##name); } \
static DEVICE_ATTR(avg_##name, 0444, show_avg_##name, NULL);

cmf_attr(ssch_rsch_count);
cmf_attr(sample_count);
Expand All @@ -1131,7 +1142,8 @@ cmf_attr_avg(device_active_only_time);
cmf_attr_avg(device_busy_time);
cmf_attr_avg(initial_command_response_time);

static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval, NULL);
static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval,
NULL);
static DEVICE_ATTR(avg_utilization, 0444, cmb_show_avg_utilization, NULL);

static struct attribute *cmf_attributes[] = {
Expand Down Expand Up @@ -1172,12 +1184,16 @@ static struct attribute_group cmf_attr_group_ext = {
.attrs = cmf_attributes_ext,
};

static ssize_t cmb_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t cmb_enable_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0);
}

static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t c)
static ssize_t cmb_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t c)
{
struct ccw_device *cdev;
int ret;
Expand All @@ -1203,8 +1219,7 @@ static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *att
DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store);

/* enable_cmf/disable_cmf: module interface for cmf (de)activation */
int
enable_cmf(struct ccw_device *cdev)
int enable_cmf(struct ccw_device *cdev)
{
int ret;

Expand All @@ -1225,8 +1240,7 @@ enable_cmf(struct ccw_device *cdev)
return ret;
}

int
disable_cmf(struct ccw_device *cdev)
int disable_cmf(struct ccw_device *cdev)
{
int ret;

Expand All @@ -1238,14 +1252,12 @@ disable_cmf(struct ccw_device *cdev)
return ret;
}

u64
cmf_read(struct ccw_device *cdev, int index)
u64 cmf_read(struct ccw_device *cdev, int index)
{
return cmbops->read(cdev, index);
}

int
cmf_readall(struct ccw_device *cdev, struct cmbdata *data)
int cmf_readall(struct ccw_device *cdev, struct cmbdata *data)
{
return cmbops->readall(cdev, data);
}
Expand All @@ -1257,15 +1269,16 @@ int cmf_reenable(struct ccw_device *cdev)
return cmbops->set(cdev, 2);
}

static int __init
init_cmf(void)
static int __init init_cmf(void)
{
char *format_string;
char *detect_string = "parameter";

/* We cannot really autoprobe this. If the user did not give a parameter,
see if we are running on z990 or up, otherwise fall back to basic mode. */

/*
* If the user did not give a parameter, see if we are running on a
* machine supporting extended measurement blocks, otherwise fall back
* to basic mode.
*/
if (format == CMF_AUTODETECT) {
if (!css_characteristics_avail ||
!css_general_characteristics.ext_mb) {
Expand All @@ -1284,7 +1297,7 @@ init_cmf(void)
cmbops = &cmbops_basic;
break;
case CMF_EXTENDED:
format_string = "extended";
format_string = "extended";
cmbops = &cmbops_extended;
break;
default:
Expand Down
8 changes: 4 additions & 4 deletions trunk/include/asm-s390/cmb.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ struct cmbdata {
};

/* enable channel measurement */
#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32)
#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER, 32)
/* enable channel measurement */
#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33)
#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER, 33)
/* read channel measurement data */
#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata)
#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)

#ifdef __KERNEL__
struct ccw_device;
Expand Down Expand Up @@ -87,7 +87,7 @@ extern u64 cmf_read(struct ccw_device *cdev, int index);
* Context:
* any
**/
extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data);
extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data);

#endif /* __KERNEL__ */
#endif /* S390_CMB_H */

0 comments on commit 9e3508f

Please sign in to comment.