From 57f4019ed56118d19d11abaceede1ee02f8270fe Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Jul 2009 08:32:23 +0000 Subject: [PATCH] Moved /sys/class/infiniband_srpt/trace_level to /proc/scsi_tgt/ib_srpt/trace_level such that the behavior of the ib_srpt target is consistent with that of other SCST drivers. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@991 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 237 ++++++++++++++++----------------------------- 1 file changed, 82 insertions(+), 155 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 376e250f2..41daa8bc7 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -40,9 +40,11 @@ #include #include #include - #include - +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) +#include +#include +#endif #include "ib_srpt.h" #include "scst_debug.h" @@ -56,6 +58,8 @@ /* Flags to be used in SCST debug tracing statements. */ #define DEFAULT_SRPT_TRACE_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR \ | TRACE_MGMT | TRACE_SPECIAL) +/* Name of the entry that will be created under /proc/scsi_tgt/ib_srpt. */ +#define SRPT_PROC_TRACE_LEVEL_NAME "trace_level" #endif #define MELLANOX_SRPT_ID_STRING "Mellanox OFED SRP target" @@ -100,6 +104,7 @@ static void srpt_add_one(struct ib_device *device); static void srpt_remove_one(struct ib_device *device); static int srpt_disconnect_channel(struct srpt_rdma_ch *ch, int dreq); static void srpt_unregister_mad_agent(struct srpt_device *sdev); +static void srpt_unregister_procfs_entry(struct scst_tgt_template *tgt); static struct ib_client srpt_client = { .name = DRV_NAME, @@ -2215,6 +2220,8 @@ static int srpt_release(struct scst_tgt *scst_tgt) return -ENODEV; #endif + srpt_unregister_procfs_entry(scst_tgt->tgtt); + list_for_each_entry_safe(ch, tmp_ch, &sdev->rch_list, list) srpt_release_channel(ch, 1); @@ -2297,7 +2304,7 @@ static struct scst_tgt_template srpt_template = { .sg_tablesize = SRPT_DEF_SG_TABLESIZE, .xmit_response_atomic = 1, .rdy_to_xfer_atomic = 1, - .no_proc_entry = 1, + .no_proc_entry = 0, .detect = srpt_detect, .release = srpt_release, .xmit_response = srpt_xmit_response, @@ -2319,158 +2326,25 @@ static void srpt_release_class_dev(struct device *dev) } #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) -static const struct { int flag; const char *const label; } - srpt_trace_label[] = +static int srpt_trace_level_show(struct seq_file *seq, void *v) { - { TRACE_OUT_OF_MEM, "out_of_mem" }, - { TRACE_MINOR, "minor" }, - { TRACE_SG_OP, "sg" }, - { TRACE_MEMORY, "mem" }, - { TRACE_BUFF, "buff" }, - { TRACE_ENTRYEXIT, "entryexit" }, - { TRACE_PID, "pid" }, - { TRACE_LINE, "line" }, - { TRACE_FUNCTION, "function" }, - { TRACE_DEBUG, "debug" }, - { TRACE_SPECIAL, "special" }, - { TRACE_SCSI, "scsi" }, - { TRACE_MGMT, "mgmt" }, - { TRACE_MGMT_MINOR, "mgmt_minor" }, - { TRACE_MGMT_DEBUG, "mgmt_dbg" }, + return scst_proc_log_entry_read(seq, trace_flag, NULL); +} + +static ssize_t srpt_proc_trace_level_write(struct file *file, + const char __user *buf, size_t length, loff_t *off) +{ + return scst_proc_log_entry_write(file, buf, length, &trace_flag, + DEFAULT_SRPT_TRACE_FLAGS, NULL); +} + +static struct scst_proc_data srpt_log_proc_data = { + SCST_DEF_RW_SEQ_OP(srpt_proc_trace_level_write) + .show = srpt_trace_level_show, }; - -/** - * Convert a label into a trace flag. Consider exactly 'len' characters of - * the label and ignore case. Return zero if no match has been found. - */ -static unsigned long trace_label_to_flag(const char *const label, int len) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(srpt_trace_label); i++) - if (strncasecmp(srpt_trace_label[i].label, label, len) == 0) - return srpt_trace_label[i].flag; - - return 0; -} - -/** - * Parse multiple tracing flags separated by whitespace. Return zero upon - * error. - */ -static unsigned long parse_flags(const char *buf, int count) -{ - unsigned long result = 0; - unsigned long flag; - const char *p; - const char *e; - - for (p = buf; p < buf + count; p = e) { - while (p < buf + count && isspace(*p)) - p++; - e = p; - while (e < buf + count && !isspace(*e)) - e++; - if (e == p) - break; - flag = trace_label_to_flag(p, e - p); - if (!flag) - return 0; - result |= flag; - } - return result; -} - -/** - * Convert a flag into a label. A flag is an integer with exactly one bit set. - * Return NULL upon failure. - */ -static const char *trace_flag_to_label(unsigned long flag) -{ - int i; - - if (flag == 0) - return NULL; - - for (i = 0; i < ARRAY_SIZE(srpt_trace_label); i++) - if (srpt_trace_label[i].flag == flag) - return srpt_trace_label[i].label; - - return NULL; -} - -/** sysfs function for showing the "trace_level" attribute. */ -static ssize_t srpt_show_trace_flags(struct class *class, char *buf) -{ - int i; - int first = 1; - - if (trace_flag == 0) { - strcpy(buf, "none\n"); - return strlen(buf); - } - - *buf = 0; - for (i = 0; i < 8 * sizeof(trace_flag); i++) { - const char *label; - - label = trace_flag_to_label(trace_flag & (1UL << i)); - if (label) { - if (first) - first = 0; - else - strcat(buf, " | "); - strcat(buf, label); - } - } - strcat(buf, "\n"); - return strlen(buf); -} - -/** sysfs function for storing the "trace_level" attribute. */ -static ssize_t srpt_store_trace_flags(struct class *class, - const char *buf, size_t count) -{ - unsigned long flags; - - if (strncasecmp(buf, "all", 3) == 0) - trace_flag = TRACE_ALL; - else if (strncasecmp(buf, "none", 4) == 0 - || strncasecmp(buf, "null", 4) == 0) { - trace_flag = 0; - } else if (strncasecmp(buf, "default", 7) == 0) - trace_flag = DEFAULT_SRPT_TRACE_FLAGS; - else if (strncasecmp(buf, "set ", 4) == 0) { - flags = parse_flags(buf + 4, count - 4); - if (flags) - trace_flag = flags; - else - count = -EINVAL; - } else if (strncasecmp(buf, "add ", 4) == 0) { - flags = parse_flags(buf + 4, count - 4); - if (flags) - trace_flag |= flags; - else - count = -EINVAL; - } else if (strncasecmp(buf, "del ", 4) == 0) { - flags = parse_flags(buf + 4, count - 4); - if (flags) - trace_flag &= ~flags; - else - count = -EINVAL; - } else if (strncasecmp(buf, "value ", 4) == 0) - trace_flag = simple_strtoul(buf + 4, NULL, 0); - else - count = -EINVAL; - return count; -} #endif static struct class_attribute srpt_class_attrs[] = { -#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) - __ATTR(trace_level, 0600, srpt_show_trace_flags, - srpt_store_trace_flags), -#endif __ATTR_NULL, }; @@ -2757,6 +2631,48 @@ static void srpt_remove_one(struct ib_device *device) TRACE_EXIT(); } +/** + * Create procfs entries for srpt. Currently the only procfs entry created + * by this function is the "trace_level" entry. + */ +static int srpt_register_procfs_entry(struct scst_tgt_template *tgt) +{ + int res = 0; +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + struct proc_dir_entry *p, *root; + + root = scst_proc_get_tgt_root(tgt); + WARN_ON(!root); + if (root) { + /* + * Fill in the scst_proc_data::data pointer, which is used in + * a printk(KERN_INFO ...) statement in + * scst_proc_log_entry_write() in scst_proc.c. + */ + srpt_log_proc_data.data = (char *)tgt->name; + p = scst_create_proc_entry(root, SRPT_PROC_TRACE_LEVEL_NAME, + &srpt_log_proc_data); + if (!p) + res = -ENOMEM; + } else + res = -ENOMEM; + +#endif + return res; +} + +static void srpt_unregister_procfs_entry(struct scst_tgt_template *tgt) +{ +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + struct proc_dir_entry *root; + + root = scst_proc_get_tgt_root(tgt); + WARN_ON(!root); + if (root) + remove_proc_entry(SRPT_PROC_TRACE_LEVEL_NAME, root); +#endif +} + /* * Module initialization. * @@ -2774,20 +2690,26 @@ static int __init srpt_init_module(void) ret = class_register(&srpt_class); if (ret) { printk(KERN_ERR PFX "couldn't register class ib_srpt\n"); - return ret; + goto out; } ret = scst_register_target_template(&srpt_template); if (ret < 0) { printk(KERN_ERR PFX "couldn't register with scst\n"); ret = -ENODEV; - goto mem_out; + goto out_unregister_class; + } + + ret = srpt_register_procfs_entry(&srpt_template); + if (ret) { + printk(KERN_ERR PFX "couldn't register procfs entry\n"); + goto out_unregister_target; } ret = ib_register_client(&srpt_client); if (ret) { printk(KERN_ERR PFX "couldn't register IB client\n"); - goto scst_out; + goto out_unregister_target; } if (thread) { @@ -2803,10 +2725,15 @@ static int __init srpt_init_module(void) return 0; -scst_out: +out_unregister_target: + /* + * Note: the procfs entry is unregistered in srpt_release(), which is + * called by scst_unregister_target_template(). + */ scst_unregister_target_template(&srpt_template); -mem_out: +out_unregister_class: class_unregister(&srpt_class); +out: return ret; }