#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/ctype.h>
+#include <linux/sysctl.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/debug.h>
-#define MIN(a,b) (((a)<(b))?(a):(b))
#define DEBUG_PROLOG_ENTRY -1
/* typedefs */
while(count < len){
size = debug_format_entry(p_info);
- size = MIN((len - count), (size - entry_offset));
+ size = min((len - count), (size - entry_offset));
if(size){
if (copy_to_user(user_buf + count,
proceed_active_area(id);
}
+static int debug_stoppable=1;
+static int debug_active=1;
+
+#define CTL_S390DBF 5677
+#define CTL_S390DBF_STOPPABLE 5678
+#define CTL_S390DBF_ACTIVE 5679
+
+/*
+ * proc handler for the running debug_active sysctl
+ * always allow read, allow write only if debug_stoppable is set or
+ * if debug_active is already off
+ */
+static int s390dbf_procactive(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ if (!write || debug_stoppable || !debug_active)
+ return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+ else
+ return 0;
+}
+
+
+static struct ctl_table s390dbf_table[] = {
+ {
+ .ctl_name = CTL_S390DBF_STOPPABLE,
+ .procname = "debug_stoppable",
+ .data = &debug_stoppable,
+ .maxlen = sizeof(int),
+ .mode = S_IRUGO | S_IWUSR,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = CTL_S390DBF_ACTIVE,
+ .procname = "debug_active",
+ .data = &debug_active,
+ .maxlen = sizeof(int),
+ .mode = S_IRUGO | S_IWUSR,
+ .proc_handler = &s390dbf_procactive,
+ .strategy = &sysctl_intvec,
+ },
+ { .ctl_name = 0 }
+};
+
+static struct ctl_table s390dbf_dir_table[] = {
+ {
+ .ctl_name = CTL_S390DBF,
+ .procname = "s390dbf",
+ .maxlen = 0,
+ .mode = S_IRUGO | S_IXUGO,
+ .child = s390dbf_table,
+ },
+ { .ctl_name = 0 }
+};
+
+struct ctl_table_header *s390dbf_sysctl_header;
+
+void debug_stop_all(void)
+{
+ if (debug_stoppable)
+ debug_active = 0;
+}
+
+
/*
* debug_event_common:
* - write debug entry with given size
unsigned long flags;
debug_entry_t *active;
+ if (!debug_active)
+ return NULL;
spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
memset(DEBUG_DATA(active), 0, id->buf_size);
- memcpy(DEBUG_DATA(active), buf, MIN(len, id->buf_size));
+ memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
debug_finish_entry(id, active, level, 0);
spin_unlock_irqrestore(&id->lock, flags);
unsigned long flags;
debug_entry_t *active;
+ if (!debug_active)
+ return NULL;
spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
memset(DEBUG_DATA(active), 0, id->buf_size);
- memcpy(DEBUG_DATA(active), buf, MIN(len, id->buf_size));
+ memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
debug_finish_entry(id, active, level, 1);
spin_unlock_irqrestore(&id->lock, flags);
if((!id) || (level > id->level))
return NULL;
-
+ if (!debug_active)
+ return NULL;
numargs=debug_count_numargs(string);
spin_lock_irqsave(&id->lock, flags);
curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active);
va_start(ap,string);
curr_event->string=string;
- for(idx=0;idx<MIN(numargs,((id->buf_size / sizeof(long))-1));idx++)
+ for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++)
curr_event->args[idx]=va_arg(ap,long);
va_end(ap);
debug_finish_entry(id, active, level, 0);
if((!id) || (level > id->level))
return NULL;
+ if (!debug_active)
+ return NULL;
numargs=debug_count_numargs(string);
curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active);
va_start(ap,string);
curr_event->string=string;
- for(idx=0;idx<MIN(numargs,((id->buf_size / sizeof(long))-1));idx++)
+ for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++)
curr_event->args[idx]=va_arg(ap,long);
va_end(ap);
debug_finish_entry(id, active, level, 1);
{
int rc = 0;
+ s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1);
down(&debug_lock);
#ifdef CONFIG_PROC_FS
debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
int rc = 0;
int i;
unsigned long flags;
- mode_t mode = S_IFREG;
+ mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
struct proc_dir_entry *pde;
if (!id)
}
/* number of arguments used for sprintf (without the format string) */
- num_used_args = MIN(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1));
+ num_used_args = min(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1));
memset(index,0, DEBUG_SPRINTF_MAX_ARGS * sizeof(int));
#ifdef CONFIG_PROC_FS
remove_proc_entry(debug_proc_root_entry->name, NULL);
#endif /* CONFIG_PROC_FS */
+ unregister_sysctl_table(s390dbf_sysctl_header);
return;
}
EXPORT_SYMBOL(debug_register);
EXPORT_SYMBOL(debug_unregister);
EXPORT_SYMBOL(debug_set_level);
+EXPORT_SYMBOL(debug_stop_all);
EXPORT_SYMBOL(debug_register_view);
EXPORT_SYMBOL(debug_unregister_view);
EXPORT_SYMBOL(debug_event_common);