diff options
385 files changed, 7395 insertions, 14539 deletions
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index e64559f0a82..ffe996a54fa 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -51,13 +51,11 @@ MODULE_LICENSE("GPL"); typedef struct _srm_env { char *name; unsigned long id; - struct proc_dir_entry *proc_entry; } srm_env_t; static struct proc_dir_entry *base_dir; static struct proc_dir_entry *named_dir; static struct proc_dir_entry *numbered_dir; -static char number[256][4]; static srm_env_t srm_named_entries[] = { { "auto_action", ENV_AUTO_ACTION }, @@ -77,21 +75,18 @@ static srm_env_t srm_named_entries[] = { { "tty_dev", ENV_TTY_DEV }, { NULL, 0 }, }; -static srm_env_t srm_numbered_entries[256]; - static int srm_env_proc_show(struct seq_file *m, void *v) { unsigned long ret; - srm_env_t *entry; + unsigned long id = (unsigned long)m->private; char *page; - entry = m->private; page = (char *)__get_free_page(GFP_USER); if (!page) return -ENOMEM; - ret = callback_getenv(entry->id, page, PAGE_SIZE); + ret = callback_getenv(id, page, PAGE_SIZE); if ((ret >> 61) == 0) { seq_write(m, page, ret); @@ -104,14 +99,14 @@ static int srm_env_proc_show(struct seq_file *m, void *v) static int srm_env_proc_open(struct inode *inode, struct file *file) { - return single_open(file, srm_env_proc_show, PDE(inode)->data); + return single_open(file, srm_env_proc_show, PDE_DATA(inode)); } static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { int res; - srm_env_t *entry = PDE(file_inode(file))->data; + unsigned long id = (unsigned long)PDE_DATA(file_inode(file)); char *buf = (char *) __get_free_page(GFP_USER); unsigned long ret1, ret2; @@ -127,7 +122,7 @@ static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer, goto out; buf[count] = '\0'; - ret1 = callback_setenv(entry->id, buf, count); + ret1 = callback_setenv(id, buf, count); if ((ret1 >> 61) == 0) { do ret2 = callback_save_env(); @@ -149,52 +144,6 @@ static const struct file_operations srm_env_proc_fops = { .write = srm_env_proc_write, }; -static void -srm_env_cleanup(void) -{ - srm_env_t *entry; - unsigned long var_num; - - if (base_dir) { - /* - * Remove named entries - */ - if (named_dir) { - entry = srm_named_entries; - while (entry->name != NULL && entry->id != 0) { - if (entry->proc_entry) { - remove_proc_entry(entry->name, - named_dir); - entry->proc_entry = NULL; - } - entry++; - } - remove_proc_entry(NAMED_DIR, base_dir); - } - - /* - * Remove numbered entries - */ - if (numbered_dir) { - for (var_num = 0; var_num <= 255; var_num++) { - entry = &srm_numbered_entries[var_num]; - - if (entry->proc_entry) { - remove_proc_entry(entry->name, - numbered_dir); - entry->proc_entry = NULL; - entry->name = NULL; - } - } - remove_proc_entry(NUMBERED_DIR, base_dir); - } - - remove_proc_entry(BASE_DIR, NULL); - } - - return; -} - static int __init srm_env_init(void) { @@ -213,19 +162,13 @@ srm_env_init(void) } /* - * Init numbers - */ - for (var_num = 0; var_num <= 255; var_num++) - sprintf(number[var_num], "%ld", var_num); - - /* * Create base directory */ base_dir = proc_mkdir(BASE_DIR, NULL); if (!base_dir) { printk(KERN_ERR "Couldn't create base dir /proc/%s\n", BASE_DIR); - goto cleanup; + return -ENOMEM; } /* @@ -254,9 +197,8 @@ srm_env_init(void) */ entry = srm_named_entries; while (entry->name && entry->id) { - entry->proc_entry = proc_create_data(entry->name, 0644, named_dir, - &srm_env_proc_fops, entry); - if (!entry->proc_entry) + if (!proc_create_data(entry->name, 0644, named_dir, + &srm_env_proc_fops, (void *)entry->id)) goto cleanup; entry++; } @@ -265,15 +207,11 @@ srm_env_init(void) * Create all numbered nodes */ for (var_num = 0; var_num <= 255; var_num++) { - entry = &srm_numbered_entries[var_num]; - entry->name = number[var_num]; - - entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir, - &srm_env_proc_fops, entry); - if (!entry->proc_entry) + char name[4]; + sprintf(name, "%ld", var_num); + if (!proc_create_data(name, 0644, numbered_dir, + &srm_env_proc_fops, (void *)var_num)) goto cleanup; - - entry->id = var_num; } printk(KERN_INFO "%s: version %s loaded successfully\n", NAME, @@ -282,18 +220,15 @@ srm_env_init(void) return 0; cleanup: - srm_env_cleanup(); - + remove_proc_subtree(BASE_DIR, NULL); return -ENOMEM; } static void __exit srm_env_exit(void) { - srm_env_cleanup(); + remove_proc_subtree(BASE_DIR, NULL); printk(KERN_INFO "%s: unloaded successfully\n", NAME); - - return; } module_init(srm_env_init); diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c index 42a1a1415fa..c7ff8073416 100644 --- a/arch/arm/kernel/atags_proc.c +++ b/arch/arm/kernel/atags_proc.c @@ -9,24 +9,18 @@ struct buffer { char data[]; }; -static int -read_buffer(char* page, char** start, off_t off, int count, - int* eof, void* data) +static ssize_t atags_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - struct buffer *buffer = (struct buffer *)data; - - if (off >= buffer->size) { - *eof = 1; - return 0; - } - - count = min((int) (buffer->size - off), count); - - memcpy(page, &buffer->data[off], count); - - return count; + struct buffer *b = PDE_DATA(file_inode(file)); + return simple_read_from_buffer(buf, count, ppos, b->data, b->size); } +static const struct file_operations atags_fops = { + .read = atags_read, + .llseek = default_llseek, +}; + #define BOOT_PARAMS_SIZE 1536 static char __initdata atags_copy[BOOT_PARAMS_SIZE]; @@ -66,9 +60,7 @@ static int __init init_atags_procfs(void) b->size = size; memcpy(b->data, atags_copy, size); - tags_entry = create_proc_read_entry("atags", 0400, - NULL, read_buffer, b); - + tags_entry = proc_create_data("atags", 0400, NULL, &atags_fops, b); if (!tags_entry) goto nomem; diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index ab1017bd166..087fc321e9e 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/sched.h> #include <linux/syscalls.h> #include <linux/perf_event.h> @@ -79,27 +80,27 @@ static unsigned long abtcounter; static pid_t previous_pid; #ifdef CONFIG_PROC_FS -static int proc_read_status(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int proc_status_show(struct seq_file *m, void *v) { - char *p = page; - int len; - - p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter); - p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter); - p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter); + seq_printf(m, "Emulated SWP:\t\t%lu\n", swpcounter); + seq_printf(m, "Emulated SWPB:\t\t%lu\n", swpbcounter); + seq_printf(m, "Aborted SWP{B}:\t\t%lu\n", abtcounter); if (previous_pid != 0) - p += sprintf(p, "Last process:\t\t%d\n", previous_pid); - - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; + seq_printf(m, "Last process:\t\t%d\n", previous_pid); + return 0; +} - return len; +static int proc_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_status_show, PDE_DATA(inode)); } + +static const struct file_operations proc_status_fops = { + .open = proc_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* @@ -266,14 +267,8 @@ static struct undef_hook swp_hook = { static int __init swp_emulation_init(void) { #ifdef CONFIG_PROC_FS - struct proc_dir_entry *res; - - res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL); - - if (!res) + if (!proc_create("cpu/swp_emulation", S_IRUGO, NULL, &proc_status_fops)) return -ENOMEM; - - res->read_proc = proc_read_status; #endif /* CONFIG_PROC_FS */ printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n"); diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c index 1e243f46a96..7777767ee89 100644 --- a/arch/arm/mach-msm/last_radio_log.c +++ b/arch/arm/mach-msm/last_radio_log.c @@ -31,20 +31,8 @@ extern void *smem_item(unsigned id, unsigned *size); static ssize_t last_radio_log_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - loff_t pos = *offset; - ssize_t count; - - if (pos >= radio_log_size) - return 0; - - count = min(len, (size_t)(radio_log_size - pos)); - if (copy_to_user(buf, radio_log_base + pos, count)) { - pr_err("%s: copy to user failed\n", __func__); - return -EFAULT; - } - - *offset += count; - return count; + return simple_read_from_buffer(buf, len, offset, + radio_log_base, radio_log_size); } static struct file_operations last_radio_log_fops = { @@ -67,7 +55,8 @@ void msm_init_last_radio_log(struct module *owner) return; } - entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL); + entry = proc_create("last_radio_log", S_IRUGO, NULL, + &last_radio_log_fops); if (!entry) { pr_err("%s: could not create proc entry for radio log\n", __func__); @@ -77,7 +66,6 @@ void msm_init_last_radio_log(struct module *owner) pr_err("%s: last radio log is %d bytes long\n", __func__, radio_log_size); last_radio_log_fops.owner = owner; - entry->proc_fops = &last_radio_log_fops; entry->size = radio_log_size; } EXPORT_SYMBOL(msm_init_last_radio_log); diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index db37f49da5a..dd712f10973 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -37,7 +37,8 @@ #include <linux/suspend.h> #include <linux/sched.h> -#include <linux/proc_fs.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/sysfs.h> #include <linux/module.h> @@ -423,23 +424,12 @@ void omap1_pm_suspend(void) omap_rev()); } -#if defined(DEBUG) && defined(CONFIG_PROC_FS) -static int g_read_completed; - +#ifdef CONFIG_DEBUG_FS /* * Read system PM registers for debugging */ -static int omap_pm_read_proc( - char *page_buffer, - char **my_first_byte, - off_t virtual_start, - int length, - int *eof, - void *data) +static int omap_pm_debug_show(struct seq_file *m, void *v) { - int my_buffer_offset = 0; - char * const my_base = page_buffer; - ARM_SAVE(ARM_CKCTL); ARM_SAVE(ARM_IDLECT1); ARM_SAVE(ARM_IDLECT2); @@ -480,10 +470,7 @@ static int omap_pm_read_proc( MPUI1610_SAVE(EMIFS_CONFIG); } - if (virtual_start == 0) { - g_read_completed = 0; - - my_buffer_offset += sprintf(my_base + my_buffer_offset, + seq_printf(m, "ARM_CKCTL_REG: 0x%-8x \n" "ARM_IDLECT1_REG: 0x%-8x \n" "ARM_IDLECT2_REG: 0x%-8x \n" @@ -513,8 +500,8 @@ static int omap_pm_read_proc( ULPD_SHOW(ULPD_STATUS_REQ), ULPD_SHOW(ULPD_POWER_CTRL)); - if (cpu_is_omap7xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, + if (cpu_is_omap7xx()) { + seq_printf(m, "MPUI7XX_CTRL_REG 0x%-8x \n" "MPUI7XX_DSP_STATUS_REG: 0x%-8x \n" "MPUI7XX_DSP_BOOT_CONFIG_REG: 0x%-8x \n" @@ -527,8 +514,8 @@ static int omap_pm_read_proc( MPUI7XX_SHOW(MPUI_DSP_API_CONFIG), MPUI7XX_SHOW(EMIFF_SDRAM_CONFIG), MPUI7XX_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap15xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, + } else if (cpu_is_omap15xx()) { + seq_printf(m, "MPUI1510_CTRL_REG 0x%-8x \n" "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" @@ -541,8 +528,8 @@ static int omap_pm_read_proc( MPUI1510_SHOW(MPUI_DSP_API_CONFIG), MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), MPUI1510_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap16xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, + } else if (cpu_is_omap16xx()) { + seq_printf(m, "MPUI1610_CTRL_REG 0x%-8x \n" "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" @@ -555,28 +542,37 @@ static int omap_pm_read_proc( MPUI1610_SHOW(MPUI_DSP_API_CONFIG), MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), MPUI1610_SHOW(EMIFS_CONFIG)); - } - - g_read_completed++; - } else if (g_read_completed >= 1) { - *eof = 1; - return 0; } - g_read_completed++; - *my_first_byte = page_buffer; - return my_buffer_offset; + return 0; +} + +static int omap_pm_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, omap_pm_debug_show, + &inode->i_private); } -static void omap_pm_init_proc(void) +static const struct file_operations omap_pm_debug_fops = { + .open = omap_pm_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void omap_pm_init_debugfs(void) { - /* XXX Appears to leak memory */ - create_proc_read_entry("driver/omap_pm", - S_IWUSR | S_IRUGO, NULL, - omap_pm_read_proc, NULL); + struct dentry *d; + + d = debugfs_create_dir("pm_debug", NULL); + if (!d) + return; + + (void) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, + d, NULL, &omap_pm_debug_fops); } -#endif /* DEBUG && CONFIG_PROC_FS */ +#endif /* CONFIG_DEBUG_FS */ /* * omap_pm_prepare - Do preliminary suspend work. @@ -701,8 +697,8 @@ static int __init omap_pm_init(void) suspend_set_ops(&omap_pm_ops); -#if defined(DEBUG) && defined(CONFIG_PROC_FS) - omap_pm_init_proc(); +#ifdef CONFIG_DEBUG_FS + omap_pm_init_debugfs(); #endif #ifdef CONFIG_OMAP_32K_TIMER diff --git a/arch/blackfin/kernel/cplbinfo.c b/arch/blackfin/kernel/cplbinfo.c index e1d0b24c607..404045dcc5e 100644 --- a/arch/blackfin/kernel/cplbinfo.c +++ b/arch/blackfin/kernel/cplbinfo.c @@ -116,14 +116,12 @@ static const struct seq_operations cplbinfo_sops = { static int cplbinfo_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *pde = PDE(file_inode(file)); char cplb_type; - unsigned int cpu; + unsigned int cpu = (unsigned long)PDE_DATA(file_inode(file)); int ret; struct seq_file *m; struct cplbinfo_data *cdata; - cpu = (unsigned int)pde->data; cplb_type = cpu & CPLBINFO_DCPLB_FLAG ? 'D' : 'I'; cpu &= ~CPLBINFO_DCPLB_FLAG; diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index 082f1890bac..ce6f512968a 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c @@ -25,6 +25,7 @@ #include <arch/svinto.h> #include <asm/fasttimer.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #define DEBUG_LOG_INCLUDED @@ -489,197 +490,162 @@ void schedule_usleep(unsigned long us) } #ifdef CONFIG_PROC_FS -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused); -static struct proc_dir_entry *fasttimer_proc_entry; -#endif /* CONFIG_PROC_FS */ - -#ifdef CONFIG_PROC_FS - /* This value is very much based on testing */ #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused) +static int proc_fasttimer_show(struct seq_file *m, void *v) { - unsigned long flags; - int i = 0; - int num_to_show; + unsigned long flags; + int i = 0; + int num_to_show; struct fasttime_t tv; - struct fast_timer *t, *nextt; - static char *bigbuf = NULL; - static unsigned long used; - - if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) - { - used = 0; - if (buf) - buf[0] = '\0'; - return 0; - } - - if (!offset || !used) - { - do_gettimeofday_fast(&tv); - - used = 0; - used += sprintf(bigbuf + used, "Fast timers added: %i\n", - fast_timers_added); - used += sprintf(bigbuf + used, "Fast timers started: %i\n", - fast_timers_started); - used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n", - fast_timer_ints); - used += sprintf(bigbuf + used, "Fast timers expired: %i\n", - fast_timers_expired); - used += sprintf(bigbuf + used, "Fast timers deleted: %i\n", - fast_timers_deleted); - used += sprintf(bigbuf + used, "Fast timer running: %s\n", - fast_timer_running ? "yes" : "no"); - used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", - (unsigned long)tv.tv_jiff, - (unsigned long)tv.tv_usec); + struct fast_timer *t, *nextt; + + do_gettimeofday_fast(&tv); + + seq_printf(m, "Fast timers added: %i\n", fast_timers_added); + seq_printf(m, "Fast timers started: %i\n", fast_timers_started); + seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints); + seq_printf(m, "Fast timers expired: %i\n", fast_timers_expired); + seq_printf(m, "Fast timers deleted: %i\n", fast_timers_deleted); + seq_printf(m, "Fast timer running: %s\n", + fast_timer_running ? "yes" : "no"); + seq_printf(m, "Current time: %lu.%06lu\n", + (unsigned long)tv.tv_jiff, + (unsigned long)tv.tv_usec); #ifdef FAST_TIMER_SANITY_CHECKS - used += sprintf(bigbuf + used, "Sanity failed: %i\n", - sanity_failed); + seq_printf(m, "Sanity failed: %i\n", sanity_failed); #endif - used += sprintf(bigbuf + used, "\n"); + seq_putc(m, '\n'); #ifdef DEBUG_LOG_INCLUDED - { - int end_i = debug_log_cnt; - i = 0; - - if (debug_log_cnt_wrapped) - { - i = debug_log_cnt; - } - - while ((i != end_i || (debug_log_cnt_wrapped && !used)) && - used+100 < BIG_BUF_SIZE) - { - used += sprintf(bigbuf + used, debug_log_string[i], - debug_log_value[i]); - i = (i+1) % DEBUG_LOG_MAX; - } - } - used += sprintf(bigbuf + used, "\n"); + { + int end_i = debug_log_cnt; + i = 0; + + if (debug_log_cnt_wrapped) + i = debug_log_cnt; + + while (i != end_i || debug_log_cnt_wrapped) { + if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0) + return 0; + i = (i+1) % DEBUG_LOG_MAX; + } + } + seq_putc(m, '\n'); #endif - num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++) - { - int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; + num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: + NUM_TIMER_STATS); + seq_printf(m, "Timers started: %i\n", fast_timers_started); + for (i = 0; i < num_to_show; i++) { + int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; #if 1 //ndef FAST_TIMER_LOG - used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i" - "\n", - timer_div_settings[cur], - timer_freq_settings[cur], - timer_delay_settings[cur] - ); + seq_printf(m, "div: %i freq: %i delay: %i" + "\n", + timer_div_settings[cur], + timer_freq_settings[cur], + timer_delay_settings[cur]); #endif #ifdef FAST_TIMER_LOG - t = &timer_started_log[cur]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); + t = &timer_started_log[cur]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; #endif - } - used += sprintf(bigbuf + used, "\n"); + } + seq_putc(m, '\n'); #ifdef FAST_TIMER_LOG - num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); - - num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); + num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: + NUM_TIMER_STATS); + seq_printf(m, "Timers added: %i\n", fast_timers_added); + for (i = 0; i < num_to_show; i++) { + t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); + + num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: + NUM_TIMER_STATS); + seq_printf(m, "Timers expired: %i\n", fast_timers_expired); + for (i = 0; i < num_to_show; i++) { + t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); #endif - used += sprintf(bigbuf + used, "Active timers:\n"); - local_irq_save(flags); - t = fast_timer_list; - while (t != NULL && (used+100 < BIG_BUF_SIZE)) - { - nextt = t->next; - local_irq_restore(flags); - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" + seq_puts(m, "Active timers:\n"); + local_irq_save(flags); + t = fast_timer_list; + while (t) { + nextt = t->next; + local_irq_restore(flags); + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" /* " func: 0x%08lX" */ - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data /* , t->function */ - ); - local_irq_save(flags); - if (t->next != nextt) - { - printk(KERN_WARNING "timer removed!\n"); - } - t = nextt; - } - local_irq_restore(flags); - } - - if (used - offset < len) - { - len = used - offset; - } + ) < 0) + return 0; + local_irq_save(flags); + if (t->next != nextt) + printk(KERN_WARNING "timer removed!\n"); + t = nextt; + } + local_irq_restore(flags); - memcpy(buf, bigbuf + offset, len); - *start = buf; - *eof = 1; + return 0; +} - return len; +static int proc_fasttimer_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE); } + +static const struct file_operations proc_fasttimer_fops = { + .open = proc_fasttimer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* PROC_FS */ #ifdef FAST_TIMER_TEST @@ -857,8 +823,7 @@ int fast_timer_init(void) } #endif #ifdef CONFIG_PROC_FS - if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) - fasttimer_proc_entry->read_proc = proc_fasttimer_read; + proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops); #endif /* PROC_FS */ if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0, "fast timer int", NULL)) diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c index ab1551ee43c..e43dd70acd9 100644 --- a/arch/cris/arch-v32/kernel/fasttimer.c +++ b/arch/cris/arch-v32/kernel/fasttimer.c @@ -23,6 +23,7 @@ #include <hwregs/timer_defs.h> #include <asm/fasttimer.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> /* * timer0 is running at 100MHz and generating jiffies timer ticks @@ -463,195 +464,161 @@ void schedule_usleep(unsigned long us) } #ifdef CONFIG_PROC_FS -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused); -static struct proc_dir_entry *fasttimer_proc_entry; -#endif /* CONFIG_PROC_FS */ - -#ifdef CONFIG_PROC_FS - /* This value is very much based on testing */ #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused) +static int proc_fasttimer_show(struct seq_file *m, void *v) { - unsigned long flags; - int i = 0; - int num_to_show; + unsigned long flags; + int i = 0; + int num_to_show; struct fasttime_t tv; - struct fast_timer *t, *nextt; - static char *bigbuf = NULL; - static unsigned long used; - - if (!bigbuf) { - bigbuf = vmalloc(BIG_BUF_SIZE); - if (!bigbuf) { - used = 0; - if (buf) - buf[0] = '\0'; - return 0; - } - } - - if (!offset || !used) { - do_gettimeofday_fast(&tv); - - used = 0; - used += sprintf(bigbuf + used, "Fast timers added: %i\n", - fast_timers_added); - used += sprintf(bigbuf + used, "Fast timers started: %i\n", - fast_timers_started); - used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n", - fast_timer_ints); - used += sprintf(bigbuf + used, "Fast timers expired: %i\n", - fast_timers_expired); - used += sprintf(bigbuf + used, "Fast timers deleted: %i\n", - fast_timers_deleted); - used += sprintf(bigbuf + used, "Fast timer running: %s\n", - fast_timer_running ? "yes" : "no"); - used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", - (unsigned long)tv.tv_jiff, - (unsigned long)tv.tv_usec); + struct fast_timer *t, *nextt; + + do_gettimeofday_fast(&tv); + + seq_printf(m, "Fast timers added: %i\n", fast_timers_added); + seq_printf(m, "Fast timers started: %i\n", fast_timers_started); + seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints); + seq_printf(m, "Fast timers expired: %i\n", fast_timers_expired); + seq_printf(m, "Fast timers deleted: %i\n", fast_timers_deleted); + seq_printf(m, "Fast timer running: %s\n", + fast_timer_running ? "yes" : "no"); + seq_printf(m, "Current time: %lu.%06lu\n", + (unsigned long)tv.tv_jiff, + (unsigned long)tv.tv_usec); #ifdef FAST_TIMER_SANITY_CHECKS - used += sprintf(bigbuf + used, "Sanity failed: %i\n", - sanity_failed); + seq_printf(m, "Sanity failed: %i\n", sanity_failed); #endif - used += sprintf(bigbuf + used, "\n"); + seq_putc(m, '\n'); #ifdef DEBUG_LOG_INCLUDED - { - int end_i = debug_log_cnt; - i = 0; - - if (debug_log_cnt_wrapped) - i = debug_log_cnt; - - while ((i != end_i || (debug_log_cnt_wrapped && !used)) && - used+100 < BIG_BUF_SIZE) - { - used += sprintf(bigbuf + used, debug_log_string[i], - debug_log_value[i]); - i = (i+1) % DEBUG_LOG_MAX; - } - } - used += sprintf(bigbuf + used, "\n"); + { + int end_i = debug_log_cnt; + i = 0; + + if (debug_log_cnt_wrapped) + i = debug_log_cnt; + + while ((i != end_i || debug_log_cnt_wrapped)) { + if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0) + return 0; + i = (i+1) % DEBUG_LOG_MAX; + } + } + seq_putc(m, '\n'); #endif - num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++) - { - int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; + num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: + NUM_TIMER_STATS); + seq_printf(m, "Timers started: %i\n", fast_timers_started); + for (i = 0; i < num_to_show; i++) { + int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; #if 1 //ndef FAST_TIMER_LOG - used += sprintf(bigbuf + used, "div: %i delay: %i" - "\n", - timer_div_settings[cur], - timer_delay_settings[cur] - ); + seq_printf(m, "div: %i delay: %i" + "\n", + timer_div_settings[cur], + timer_delay_settings[cur]); #endif #ifdef FAST_TIMER_LOG - t = &timer_started_log[cur]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); + t = &timer_started_log[cur]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; #endif - } - used += sprintf(bigbuf + used, "\n"); + } + seq_putc(m, '\n'); #ifdef FAST_TIMER_LOG - num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); - - num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); + num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: + NUM_TIMER_STATS); + seq_printf(m, "Timers added: %i\n", fast_timers_added); + for (i = 0; i < num_to_show; i++) { + t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); + + num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: + NUM_TIMER_STATS); + seq_printf(m, "Timers expired: %i\n", fast_timers_expired); + for (i = 0; i < num_to_show; i++){ + t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); #endif - used += sprintf(bigbuf + used, "Active timers:\n"); - local_irq_save(flags); - t = fast_timer_list; - while (t != NULL && (used+100 < BIG_BUF_SIZE)) - { - nextt = t->next; - local_irq_restore(flags); - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" + seq_puts(m, "Active timers:\n"); + local_irq_save(flags); + t = fast_timer_list; + while (t != NULL){ + nextt = t->next; + local_irq_restore(flags); + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" /* " func: 0x%08lX" */ - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data /* , t->function */ - ); - local_irq_save(flags); - if (t->next != nextt) - { - printk("timer removed!\n"); - } - t = nextt; - } - local_irq_restore(flags); - } + ) < 0) + return 0; + local_irq_save(flags); + if (t->next != nextt) + printk("timer removed!\n"); + t = nextt; + } + local_irq_restore(flags); + return 0; +} - if (used - offset < len) - { - len = used - offset; - } +static int proc_fasttimer_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE); +} - memcpy(buf, bigbuf + offset, len); - *start = buf; - *eof = 1; +static const struct file_operations proc_fasttimer_fops = { + .open = proc_fasttimer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - return len; -} #endif /* PROC_FS */ #ifdef FAST_TIMER_TEST @@ -816,9 +783,7 @@ int fast_timer_init(void) printk("fast_timer_init()\n"); #ifdef CONFIG_PROC_FS - fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0); - if (fasttimer_proc_entry) - fasttimer_proc_entry->read_proc = proc_fasttimer_read; + proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops); #endif /* PROC_FS */ if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt, IRQF_SHARED | IRQF_DISABLED, diff --git a/arch/h8300/kernel/gpio.c b/arch/h8300/kernel/gpio.c index 6a25dd5530e..b02c752cd32 100644 --- a/arch/h8300/kernel/gpio.c +++ b/arch/h8300/kernel/gpio.c @@ -11,6 +11,7 @@ #include <linux/stddef.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> @@ -138,30 +139,34 @@ static char *port_status(int portno) return result; } -static int gpio_proc_read(char *buf, char **start, off_t offset, - int len, int *unused_i, void *unused_v) +static int gpio_proc_show(struct seq_file *m, void *v) { - int c,outlen; static const char port_name[]="123456789ABCDEFGH"; - outlen = 0; + int c; + for (c = 0; c < MAX_PORT; c++) { if (ddrs[c] == NULL) - continue ; - len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c)); - buf += len; - outlen += len; + continue; + seq_printf(m, "P%c: %s\n", port_name[c], port_status(c)); } - return outlen; + return 0; } -static __init int register_proc(void) +static int gpio_proc_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *proc_gpio; + return single_open(file, gpio_proc_show, PDE_DATA(inode)); +} - proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL); - if (proc_gpio) - proc_gpio->read_proc = gpio_proc_read; - return proc_gpio != NULL; +static const struct file_operations gpio_proc_fops = { + .open = gpio_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static __init int register_proc(void) +{ + return proc_create("gpio", S_IRUGO, NULL, &gpio_proc_fops) != NULL; } __initcall(register_proc); diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 79521d5499f..b17129e3b7c 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -22,6 +22,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/efi.h> @@ -41,7 +42,7 @@ MODULE_LICENSE("GPL"); #define PALINFO_VERSION "0.5" -typedef int (*palinfo_func_t)(char*); +typedef int (*palinfo_func_t)(struct seq_file *); typedef struct { const char *name; /* name of the proc entry */ @@ -54,7 +55,7 @@ typedef struct { * A bunch of string array to get pretty printing */ -static char *cache_types[] = { +static const char *cache_types[] = { "", /* not used */ "Instruction", "Data", @@ -122,19 +123,16 @@ static const char *mem_attrib[]={ * - a pointer to the end of the buffer * */ -static char * -bitvector_process(char *p, u64 vector) +static void bitvector_process(struct seq_file *m, u64 vector) { int i,j; - const char *units[]={ "", "K", "M", "G", "T" }; + static const char *units[]={ "", "K", "M", "G", "T" }; for (i=0, j=0; i < 64; i++ , j=i/10) { - if (vector & 0x1) { - p += sprintf(p, "%d%s ", 1 << (i-j*10), units[j]); - } + if (vector & 0x1) + seq_printf(m, "%d%s ", 1 << (i-j*10), units[j]); vector >>= 1; } - return p; } /* @@ -149,8 +147,7 @@ bitvector_process(char *p, u64 vector) * - a pointer to the end of the buffer * */ -static char * -bitregister_process(char *p, u64 *reg_info, int max) +static void bitregister_process(struct seq_file *m, u64 *reg_info, int max) { int i, begin, skip = 0; u64 value = reg_info[0]; @@ -163,9 +160,9 @@ bitregister_process(char *p, u64 *reg_info, int max) if ((value & 0x1) == 0 && skip == 0) { if (begin <= i - 2) - p += sprintf(p, "%d-%d ", begin, i-1); + seq_printf(m, "%d-%d ", begin, i-1); else - p += sprintf(p, "%d ", i-1); + seq_printf(m, "%d ", i-1); skip = 1; begin = -1; } else if ((value & 0x1) && skip == 1) { @@ -176,19 +173,15 @@ bitregister_process(char *p, u64 *reg_info, int max) } if (begin > -1) { if (begin < 127) - p += sprintf(p, "%d-127", begin); + seq_printf(m, "%d-127", begin); else - p += sprintf(p, "127"); + seq_puts(m, "127"); } - - return p; } -static int -power_info(char *page) +static int power_info(struct seq_file *m) { s64 status; - char *p = page; u64 halt_info_buffer[8]; pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; int i; @@ -198,26 +191,25 @@ power_info(char *page) for (i=0; i < 8 ; i++ ) { if (halt_info[i].pal_power_mgmt_info_s.im == 1) { - p += sprintf(p, "Power level %d:\n" - "\tentry_latency : %d cycles\n" - "\texit_latency : %d cycles\n" - "\tpower consumption : %d mW\n" - "\tCache+TLB coherency : %s\n", i, - halt_info[i].pal_power_mgmt_info_s.entry_latency, - halt_info[i].pal_power_mgmt_info_s.exit_latency, - halt_info[i].pal_power_mgmt_info_s.power_consumption, - halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); + seq_printf(m, + "Power level %d:\n" + "\tentry_latency : %d cycles\n" + "\texit_latency : %d cycles\n" + "\tpower consumption : %d mW\n" + "\tCache+TLB coherency : %s\n", i, + halt_info[i].pal_power_mgmt_info_s.entry_latency, + halt_info[i].pal_power_mgmt_info_s.exit_latency, + halt_info[i].pal_power_mgmt_info_s.power_consumption, + halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); } else { - p += sprintf(p,"Power level %d: not implemented\n",i); + seq_printf(m,"Power level %d: not implemented\n", i); } } - return p - page; + return 0; } -static int -cache_info(char *page) +static int cache_info(struct seq_file *m) { - char *p = page; unsigned long i, levels, unique_caches; pal_cache_config_info_t cci; int j, k; @@ -228,73 +220,74 @@ cache_info(char *page) return 0; } - p += sprintf(p, "Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches); + seq_printf(m, "Cache levels : %ld\nUnique caches : %ld\n\n", + levels, unique_caches); for (i=0; i < levels; i++) { - for (j=2; j >0 ; j--) { - /* even without unification some level may not be present */ - if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) { + if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) continue; - } - p += sprintf(p, - "%s Cache level %lu:\n" - "\tSize : %u bytes\n" - "\tAttributes : ", - cache_types[j+cci.pcci_unified], i+1, - cci.pcci_cache_size); - - if (cci.pcci_unified) p += sprintf(p, "Unified "); - - p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]); - - p += sprintf(p, - "\tAssociativity : %d\n" - "\tLine size : %d bytes\n" - "\tStride : %d bytes\n", - cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride); + + seq_printf(m, + "%s Cache level %lu:\n" + "\tSize : %u bytes\n" + "\tAttributes : ", + cache_types[j+cci.pcci_unified], i+1, + cci.pcci_cache_size); + + if (cci.pcci_unified) + seq_puts(m, "Unified "); + + seq_printf(m, "%s\n", cache_mattrib[cci.pcci_cache_attr]); + + seq_printf(m, + "\tAssociativity : %d\n" + "\tLine size : %d bytes\n" + "\tStride : %d bytes\n", + cci.pcci_assoc, + 1<<cci.pcci_line_size, + 1<<cci.pcci_stride); if (j == 1) - p += sprintf(p, "\tStore latency : N/A\n"); + seq_puts(m, "\tStore latency : N/A\n"); else - p += sprintf(p, "\tStore latency : %d cycle(s)\n", - cci.pcci_st_latency); + seq_printf(m, "\tStore latency : %d cycle(s)\n", + cci.pcci_st_latency); - p += sprintf(p, - "\tLoad latency : %d cycle(s)\n" - "\tStore hints : ", cci.pcci_ld_latency); + seq_printf(m, + "\tLoad latency : %d cycle(s)\n" + "\tStore hints : ", cci.pcci_ld_latency); for(k=0; k < 8; k++ ) { if ( cci.pcci_st_hints & 0x1) - p += sprintf(p, "[%s]", cache_st_hints[k]); + seq_printf(m, "[%s]", cache_st_hints[k]); cci.pcci_st_hints >>=1; } - p += sprintf(p, "\n\tLoad hints : "); + seq_puts(m, "\n\tLoad hints : "); for(k=0; k < 8; k++ ) { if (cci.pcci_ld_hints & 0x1) - p += sprintf(p, "[%s]", cache_ld_hints[k]); + seq_printf(m, "[%s]", cache_ld_hints[k]); cci.pcci_ld_hints >>=1; } - p += sprintf(p, - "\n\tAlias boundary : %d byte(s)\n" - "\tTag LSB : %d\n" - "\tTag MSB : %d\n", - 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, - cci.pcci_tag_msb); + seq_printf(m, + "\n\tAlias boundary : %d byte(s)\n" + "\tTag LSB : %d\n" + "\tTag MSB : %d\n", + 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, + cci.pcci_tag_msb); /* when unified, data(j=2) is enough */ - if (cci.pcci_unified) break; + if (cci.pcci_unified) + break; } } - return p - page; + return 0; } -static int -vm_info(char *page) +static int vm_info(struct seq_file *m) { - char *p = page; u64 tr_pages =0, vw_pages=0, tc_pages; u64 attrib; pal_vm_info_1_u_t vm_info_1; @@ -309,7 +302,7 @@ vm_info(char *page) printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); } else { - p += sprintf(p, + seq_printf(m, "Physical Address Space : %d bits\n" "Virtual Address Space : %d bits\n" "Protection Key Registers(PKR) : %d\n" @@ -324,49 +317,49 @@ vm_info(char *page) vm_info_1.pal_vm_info_1_s.hash_tag_id, vm_info_2.pal_vm_info_2_s.rid_size); if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) - p += sprintf(p, "unlimited\n"); + seq_puts(m, "unlimited\n"); else - p += sprintf(p, "%d\n", + seq_printf(m, "%d\n", vm_info_2.pal_vm_info_2_s.max_purges ? vm_info_2.pal_vm_info_2_s.max_purges : 1); } if (ia64_pal_mem_attrib(&attrib) == 0) { - p += sprintf(p, "Supported memory attributes : "); + seq_puts(m, "Supported memory attributes : "); sep = ""; for (i = 0; i < 8; i++) { if (attrib & (1 << i)) { - p += sprintf(p, "%s%s", sep, mem_attrib[i]); + seq_printf(m, "%s%s", sep, mem_attrib[i]); sep = ", "; } } - p += sprintf(p, "\n"); + seq_putc(m, '\n'); } if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); } else { - p += sprintf(p, - "\nTLB walker : %simplemented\n" - "Number of DTR : %d\n" - "Number of ITR : %d\n" - "TLB insertable page sizes : ", - vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", - vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, - vm_info_1.pal_vm_info_1_s.max_itr_entry+1); - + seq_printf(m, + "\nTLB walker : %simplemented\n" + "Number of DTR : %d\n" + "Number of ITR : %d\n" + "TLB insertable page sizes : ", + vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", + vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, + vm_info_1.pal_vm_info_1_s.max_itr_entry+1); - p = bitvector_process(p, tr_pages); + bitvector_process(m, tr_pages); - p += sprintf(p, "\nTLB purgeable page sizes : "); + seq_puts(m, "\nTLB purgeable page sizes : "); - p = bitvector_process(p, vw_pages); + bitvector_process(m, vw_pages); } - if ((status=ia64_get_ptce(&ptce)) != 0) { + + if ((status = ia64_get_ptce(&ptce)) != 0) { printk(KERN_ERR "ia64_get_ptce=%ld\n", status); } else { - p += sprintf(p, + seq_printf(m, "\nPurge base address : 0x%016lx\n" "Purge outer loop count : %d\n" "Purge inner loop count : %d\n" @@ -375,7 +368,7 @@ vm_info(char *page) ptce.base, ptce.count[0], ptce.count[1], ptce.stride[0], ptce.stride[1]); - p += sprintf(p, + seq_printf(m, "TC Levels : %d\n" "Unique TC(s) : %d\n", vm_info_1.pal_vm_info_1_s.num_tc_levels, @@ -385,13 +378,11 @@ vm_info(char *page) for (j=2; j>0 ; j--) { tc_pages = 0; /* just in case */ - /* even without unification, some levels may not be present */ - if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) { + if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) continue; - } - p += sprintf(p, + seq_printf(m, "\n%s Translation Cache Level %d:\n" "\tHash sets : %d\n" "\tAssociativity : %d\n" @@ -403,15 +394,15 @@ vm_info(char *page) tc_info.tc_num_entries); if (tc_info.tc_pf) - p += sprintf(p, "PreferredPageSizeOptimized "); + seq_puts(m, "PreferredPageSizeOptimized "); if (tc_info.tc_unified) - p += sprintf(p, "Unified "); + seq_puts(m, "Unified "); if (tc_info.tc_reduce_tr) - p += sprintf(p, "TCReduction"); + seq_puts(m, "TCReduction"); - p += sprintf(p, "\n\tSupported page sizes: "); + seq_puts(m, "\n\tSupported page sizes: "); - p = bitvector_process(p, tc_pages); + bitvector_process(m, tc_pages); /* when unified date (j=2) is enough */ if (tc_info.tc_unified) @@ -419,16 +410,14 @@ vm_info(char *page) } } } - p += sprintf(p, "\n"); - return p - page; + seq_putc(m, '\n'); + return 0; } -static int -register_info(char *page) +static int register_info(struct seq_file *m) { - char *p = page; u64 reg_info[2]; u64 info; unsigned long phys_stacked; @@ -442,35 +431,31 @@ register_info(char *page) }; for(info=0; info < 4; info++) { - - if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) return 0; - - p += sprintf(p, "%-32s : ", info_type[info]); - - p = bitregister_process(p, reg_info, 128); - - p += sprintf(p, "\n"); + if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) + return 0; + seq_printf(m, "%-32s : ", info_type[info]); + bitregister_process(m, reg_info, 128); + seq_putc(m, '\n'); } - if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) { + if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) + seq_printf(m, + "RSE stacked physical registers : %ld\n" + "RSE load/store hints : %ld (%s)\n", + phys_stacked, hints.ph_data, + hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); - p += sprintf(p, - "RSE stacked physical registers : %ld\n" - "RSE load/store hints : %ld (%s)\n", - phys_stacked, hints.ph_data, - hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); - } if (ia64_pal_debug_info(&iregs, &dregs)) return 0; - p += sprintf(p, - "Instruction debug register pairs : %ld\n" - "Data debug register pairs : %ld\n", iregs, dregs); + seq_printf(m, + "Instruction debug register pairs : %ld\n" + "Data debug register pairs : %ld\n", iregs, dregs); - return p - page; + return 0; } -static char *proc_features_0[]={ /* Feature set 0 */ +static const char *const proc_features_0[]={ /* Feature set 0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, @@ -502,7 +487,7 @@ static char *proc_features_0[]={ /* Feature set 0 */ "Enable BERR promotion" }; -static char *proc_features_16[]={ /* Feature set 16 */ +static const char *const proc_features_16[]={ /* Feature set 16 */ "Disable ETM", "Enable ETM", "Enable MCA on half-way timer", @@ -522,7 +507,7 @@ static char *proc_features_16[]={ /* Feature set 16 */ NULL, NULL, NULL, NULL, NULL }; -static char **proc_features[]={ +static const char *const *const proc_features[]={ proc_features_0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -530,11 +515,10 @@ static char **proc_features[]={ NULL, NULL, NULL, NULL, }; -static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, - unsigned long set) +static void feature_set_info(struct seq_file *m, u64 avail, u64 status, u64 control, + unsigned long set) { - char *p = page; - char **vf, **v; + const char *const *vf, *const *v; int i; vf = v = proc_features[set]; @@ -547,13 +531,13 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, if (vf) v = vf + i; if ( v && *v ) { - p += sprintf(p, "%-40s : %s %s\n", *v, + seq_printf(m, "%-40s : %s %s\n", *v, avail & 0x1 ? (status & 0x1 ? - "On " : "Off"): "", + "On " : "Off"): "", avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); } else { - p += sprintf(p, "Feature set %2ld bit %2d\t\t\t" + seq_printf(m, "Feature set %2ld bit %2d\t\t\t" " : %s %s\n", set, i, avail & 0x1 ? (status & 0x1 ? @@ -562,36 +546,32 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, "Ctrl" : "NoCtrl"): ""); } } - return p; } -static int -processor_info(char *page) +static int processor_info(struct seq_file *m) { - char *p = page; u64 avail=1, status=1, control=1, feature_set=0; s64 ret; do { ret = ia64_pal_proc_get_features(&avail, &status, &control, feature_set); - if (ret < 0) { - return p - page; - } + if (ret < 0) + return 0; + if (ret == 1) { feature_set++; continue; } - p = feature_set_info(p, avail, status, control, feature_set); - + feature_set_info(m, avail, status, control, feature_set); feature_set++; } while(1); - return p - page; + return 0; } -static const char *bus_features[]={ +static const char *const bus_features[]={ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, @@ -617,125 +597,118 @@ static const char *bus_features[]={ }; -static int -bus_info(char *page) +static int bus_info(struct seq_file *m) { - char *p = page; - const char **v = bus_features; + const char *const *v = bus_features; pal_bus_features_u_t av, st, ct; u64 avail, status, control; int i; s64 ret; - if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) return 0; + if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) + return 0; avail = av.pal_bus_features_val; status = st.pal_bus_features_val; control = ct.pal_bus_features_val; for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { - if ( ! *v ) continue; - p += sprintf(p, "%-48s : %s%s %s\n", *v, - avail & 0x1 ? "" : "NotImpl", - avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", - avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); + if ( ! *v ) + continue; + seq_printf(m, "%-48s : %s%s %s\n", *v, + avail & 0x1 ? "" : "NotImpl", + avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", + avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); } - return p - page; + return 0; } -static int -version_info(char *page) +static int version_info(struct seq_file *m) { pal_version_u_t min_ver, cur_ver; - char *p = page; if (ia64_pal_version(&min_ver, &cur_ver) != 0) return 0; - p += sprintf(p, - "PAL_vendor : 0x%02x (min=0x%02x)\n" - "PAL_A : %02x.%02x (min=%02x.%02x)\n" - "PAL_B : %02x.%02x (min=%02x.%02x)\n", - cur_ver.pal_version_s.pv_pal_vendor, - min_ver.pal_version_s.pv_pal_vendor, - cur_ver.pal_version_s.pv_pal_a_model, - cur_ver.pal_version_s.pv_pal_a_rev, - min_ver.pal_version_s.pv_pal_a_model, - min_ver.pal_version_s.pv_pal_a_rev, - cur_ver.pal_version_s.pv_pal_b_model, - cur_ver.pal_version_s.pv_pal_b_rev, - min_ver.pal_version_s.pv_pal_b_model, - min_ver.pal_version_s.pv_pal_b_rev); - return p - page; + seq_printf(m, + "PAL_vendor : 0x%02x (min=0x%02x)\n" + "PAL_A : %02x.%02x (min=%02x.%02x)\n" + "PAL_B : %02x.%02x (min=%02x.%02x)\n", + cur_ver.pal_version_s.pv_pal_vendor, + min_ver.pal_version_s.pv_pal_vendor, + cur_ver.pal_version_s.pv_pal_a_model, + cur_ver.pal_version_s.pv_pal_a_rev, + min_ver.pal_version_s.pv_pal_a_model, + min_ver.pal_version_s.pv_pal_a_rev, + cur_ver.pal_version_s.pv_pal_b_model, + cur_ver.pal_version_s.pv_pal_b_rev, + min_ver.pal_version_s.pv_pal_b_model, + min_ver.pal_version_s.pv_pal_b_rev); + return 0; } -static int -perfmon_info(char *page) +static int perfmon_info(struct seq_file *m) { - char *p = page; u64 pm_buffer[16]; pal_perf_mon_info_u_t pm_info; - if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0; - - p += sprintf(p, - "PMC/PMD pairs : %d\n" - "Counter width : %d bits\n" - "Cycle event number : %d\n" - "Retired event number : %d\n" - "Implemented PMC : ", - pm_info.pal_perf_mon_info_s.generic, pm_info.pal_perf_mon_info_s.width, - pm_info.pal_perf_mon_info_s.cycles, pm_info.pal_perf_mon_info_s.retired); + if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) + return 0; - p = bitregister_process(p, pm_buffer, 256); - p += sprintf(p, "\nImplemented PMD : "); - p = bitregister_process(p, pm_buffer+4, 256); - p += sprintf(p, "\nCycles count capable : "); - p = bitregister_process(p, pm_buffer+8, 256); - p += sprintf(p, "\nRetired bundles count capable : "); + seq_printf(m, + "PMC/PMD pairs : %d\n" + "Counter width : %d bits\n" + "Cycle event number : %d\n" + "Retired event number : %d\n" + "Implemented PMC : ", + pm_info.pal_perf_mon_info_s.generic, + pm_info.pal_perf_mon_info_s.width, + pm_info.pal_perf_mon_info_s.cycles, + pm_info.pal_perf_mon_info_s.retired); + + bitregister_process(m, pm_buffer, 256); + seq_puts(m, "\nImplemented PMD : "); + bitregister_process(m, pm_buffer+4, 256); + seq_puts(m, "\nCycles count capable : "); + bitregister_process(m, pm_buffer+8, 256); + seq_puts(m, "\nRetired bundles count capable : "); #ifdef CONFIG_ITANIUM /* * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES * which is wrong, both PMC4 and PMD5 support it. */ - if (pm_buffer[12] == 0x10) pm_buffer[12]=0x30; + if (pm_buffer[12] == 0x10) + pm_buffer[12]=0x30; #endif - p = bitregister_process(p, pm_buffer+12, 256); - - p += sprintf(p, "\n"); - - return p - page; + bitregister_process(m, pm_buffer+12, 256); + seq_putc(m, '\n'); + return 0; } -static int -frequency_info(char *page) +static int frequency_info(struct seq_file *m) { - char *p = page; struct pal_freq_ratio proc, itc, bus; unsigned long base; if (ia64_pal_freq_base(&base) == -1) - p += sprintf(p, "Output clock : not implemented\n"); + seq_puts(m, "Output clock : not implemented\n"); else - p += sprintf(p, "Output clock : %ld ticks/s\n", base); + seq_printf(m, "Output clock : %ld ticks/s\n", base); if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; - p += sprintf(p, + seq_printf(m, "Processor/Clock ratio : %d/%d\n" "Bus/Clock ratio : %d/%d\n" "ITC/Clock ratio : %d/%d\n", proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); - - return p - page; + return 0; } -static int -tr_info(char *page) +static int tr_info(struct seq_file *m) { - char *p = page; long status; pal_tr_valid_u_t tr_valid; u64 tr_buffer[4]; @@ -794,39 +767,40 @@ tr_info(char *page) ifa_reg = (struct ifa_reg *)&tr_buffer[2]; - if (ifa_reg->valid == 0) continue; + if (ifa_reg->valid == 0) + continue; gr_reg = (struct gr_reg *)tr_buffer; itir_reg = (struct itir_reg *)&tr_buffer[1]; rid_reg = (struct rid_reg *)&tr_buffer[3]; pgm = -1 << (itir_reg->ps - 12); - p += sprintf(p, - "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" - "\tppn : 0x%lx\n" - "\tvpn : 0x%lx\n" - "\tps : ", - "ID"[i], j, - tr_valid.pal_tr_valid_s.access_rights_valid, - tr_valid.pal_tr_valid_s.priv_level_valid, - tr_valid.pal_tr_valid_s.dirty_bit_valid, - tr_valid.pal_tr_valid_s.mem_attr_valid, - (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); - - p = bitvector_process(p, 1<< itir_reg->ps); - - p += sprintf(p, - "\n\tpl : %d\n" - "\tar : %d\n" - "\trid : %x\n" - "\tp : %d\n" - "\tma : %d\n" - "\td : %d\n", - gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, - gr_reg->d); + seq_printf(m, + "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" + "\tppn : 0x%lx\n" + "\tvpn : 0x%lx\n" + "\tps : ", + "ID"[i], j, + tr_valid.pal_tr_valid_s.access_rights_valid, + tr_valid.pal_tr_valid_s.priv_level_valid, + tr_valid.pal_tr_valid_s.dirty_bit_valid, + tr_valid.pal_tr_valid_s.mem_attr_valid, + (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); + + bitvector_process(m, 1<< itir_reg->ps); + + seq_printf(m, + "\n\tpl : %d\n" + "\tar : %d\n" + "\trid : %x\n" + "\tp : %d\n" + "\tma : %d\n" + "\td : %d\n", + gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, + gr_reg->d); } } - return p - page; + return 0; } @@ -834,7 +808,7 @@ tr_info(char *page) /* * List {name,function} pairs for every entry in /proc/palinfo/cpu* */ -static palinfo_entry_t palinfo_entries[]={ +static const palinfo_entry_t palinfo_entries[]={ { "version_info", version_info, }, { "vm_info", vm_info, }, { "cache_info", cache_info, }, @@ -876,7 +850,7 @@ typedef union { */ typedef struct { palinfo_func_t func; /* pointer to function to call */ - char *page; /* buffer to store results */ + struct seq_file *m; /* buffer to store results */ int ret; /* return value from call */ } palinfo_smp_data_t; @@ -889,7 +863,7 @@ static void palinfo_smp_call(void *info) { palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; - data->ret = (*data->func)(data->page); + data->ret = (*data->func)(data->m); } /* @@ -899,13 +873,13 @@ palinfo_smp_call(void *info) * otherwise how many bytes in the "page" buffer were written */ static -int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) +int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) { palinfo_smp_data_t ptr; int ret; ptr.func = palinfo_entries[f->func_id].proc_read; - ptr.page = page; + ptr.m = m; ptr.ret = 0; /* just in case */ @@ -919,7 +893,7 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) } #else /* ! CONFIG_SMP */ static -int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) +int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) { printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); return 0; @@ -929,34 +903,35 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) /* * Entry point routine: all calls go through this function */ -static int -palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) +static int proc_palinfo_show(struct seq_file *m, void *v) { - int len=0; - pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data; + pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&m->private; /* * in SMP mode, we may need to call another CPU to get correct * information. PAL, by definition, is processor specific */ if (f->req_cpu == get_cpu()) - len = (*palinfo_entries[f->func_id].proc_read)(page); + (*palinfo_entries[f->func_id].proc_read)(m); else - len = palinfo_handle_smp(f, page); + palinfo_handle_smp(m, f); put_cpu(); + return 0; +} - if (len <= off+count) *eof = 1; - - *start = page + off; - len -= off; - - if (len>count) len = count; - if (len<0) len = 0; - - return len; +static int proc_palinfo_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_palinfo_show, PDE_DATA(inode)); } +static const struct file_operations proc_palinfo_fops = { + .open = proc_palinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static void __cpuinit create_palinfo_proc_entries(unsigned int cpu) { @@ -974,9 +949,8 @@ create_palinfo_proc_entries(unsigned int cpu) for (j=0; j < NR_PALINFO_ENTRIES; j++) { f.func_id = j; - create_proc_read_entry( - palinfo_entries[j].name, 0, cpu_dir, - palinfo_read_entry, (void *)f.value); + proc_create_data(palinfo_entries[j].name, 0, cpu_dir, + &proc_palinfo_fops, (void *)f.value); } } diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index aa527d7e91f..5035245cb25 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -40,6 +40,7 @@ #include <linux/cpu.h> #include <linux/types.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/module.h> #include <linux/smp.h> #include <linux/timer.h> @@ -53,7 +54,7 @@ MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>"); MODULE_DESCRIPTION("/proc interface to IA-64 SAL features"); MODULE_LICENSE("GPL"); -static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data); +static const struct file_operations proc_salinfo_fops; typedef struct { const char *name; /* name of the proc entry */ @@ -65,7 +66,7 @@ typedef struct { * List {name,feature} pairs for every entry in /proc/sal/<feature> * that this module exports */ -static salinfo_entry_t salinfo_entries[]={ +static const salinfo_entry_t salinfo_entries[]={ { "bus_lock", IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, }, { "irq_redirection", IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, }, { "ipi_redirection", IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, }, @@ -301,9 +302,7 @@ salinfo_event_open(struct inode *inode, struct file *file) static ssize_t salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file_inode(file); - struct proc_dir_entry *entry = PDE(inode); - struct salinfo_data *data = entry->data; + struct salinfo_data *data = PDE_DATA(file_inode(file)); char cmd[32]; size_t size; int i, n, cpu = -1; @@ -360,8 +359,7 @@ static const struct file_operations salinfo_event_fops = { static int salinfo_log_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = PDE(inode); - struct salinfo_data *data = entry->data; + struct salinfo_data *data = PDE_DATA(inode); if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -386,8 +384,7 @@ salinfo_log_open(struct inode *inode, struct file *file) static int salinfo_log_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = PDE(inode); - struct salinfo_data *data = entry->data; + struct salinfo_data *data = PDE_DATA(inode); if (data->state == STATE_NO_DATA) { vfree(data->log_buffer); @@ -463,9 +460,7 @@ retry: static ssize_t salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file_inode(file); - struct proc_dir_entry *entry = PDE(inode); - struct salinfo_data *data = entry->data; + struct salinfo_data *data = PDE_DATA(file_inode(file)); u8 *buf; u64 bufsize; @@ -524,9 +519,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) static ssize_t salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file_inode(file); - struct proc_dir_entry *entry = PDE(inode); - struct salinfo_data *data = entry->data; + struct salinfo_data *data = PDE_DATA(file_inode(file)); char cmd[32]; size_t size; u32 offset; @@ -637,8 +630,9 @@ salinfo_init(void) for (i=0; i < NR_SALINFO_ENTRIES; i++) { /* pass the feature bit in question as misc data */ - *sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir, - salinfo_read, (void *)salinfo_entries[i].feature); + *sdir++ = proc_create_data(salinfo_entries[i].name, 0, salinfo_dir, + &proc_salinfo_fops, + (void *)salinfo_entries[i].feature); } for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { @@ -684,22 +678,23 @@ salinfo_init(void) * 'data' contains an integer that corresponds to the feature we're * testing */ -static int -salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data) +static int proc_salinfo_show(struct seq_file *m, void *v) { - int len = 0; - - len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n"); - - if (len <= off+count) *eof = 1; - - *start = page + off; - len -= off; - - if (len>count) len = count; - if (len<0) len = 0; + unsigned long data = (unsigned long)v; + seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n"); + return 0; +} - return len; +static int proc_salinfo_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_salinfo_show, PDE_DATA(inode)); } +static const struct file_operations proc_salinfo_fops = { + .open = proc_salinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + module_init(salinfo_init); diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c index 20b88cb1881..daa8d6badb1 100644 --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/nodemask.h> #include <asm/io.h> #include <asm/sn/sn_sal.h> @@ -101,18 +102,18 @@ get_fit_entry(unsigned long nasid, int index, unsigned long *fentry, /* * These two routines display the FIT table for each node. */ -static int dump_fit_entry(char *page, unsigned long *fentry) +static void dump_fit_entry(struct seq_file *m, unsigned long *fentry) { unsigned type; type = FIT_TYPE(fentry[1]); - return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n", - type, - fit_type_name(type), - FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]), - fentry[0], - /* mult by sixteen to get size in bytes */ - (unsigned)(fentry[1] & 0xffffff) * 16); + seq_printf(m, "%02x %-25s %x.%02x %016lx %u\n", + type, + fit_type_name(type), + FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]), + fentry[0], + /* mult by sixteen to get size in bytes */ + (unsigned)(fentry[1] & 0xffffff) * 16); } @@ -124,31 +125,39 @@ static int dump_fit_entry(char *page, unsigned long *fentry) * OK except for 4kB pages (and no one is going to do that on SN * anyway). */ -static int -dump_fit(char *page, unsigned long nasid) +static int proc_fit_show(struct seq_file *m, void *v) { + unsigned long nasid = (unsigned long)m->private; unsigned long fentry[2]; int index; - char *p; - p = page; for (index=0;;index++) { BUG_ON(index * 60 > PAGE_SIZE); if (get_fit_entry(nasid, index, fentry, NULL, 0)) break; - p += dump_fit_entry(p, fentry); + dump_fit_entry(m, fentry); } + return 0; +} - return p - page; +static int proc_fit_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_fit_show, PDE_DATA(inode)); } -static int -dump_version(char *page, unsigned long nasid) +static const struct file_operations proc_fit_fops = { + .open = proc_fit_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int proc_version_show(struct seq_file *m, void *v) { + unsigned long nasid = (unsigned long)m->private; unsigned long fentry[2]; char banner[128]; int index; - int len; for (index = 0; ; index++) { if (get_fit_entry(nasid, index, fentry, banner, @@ -158,56 +167,24 @@ dump_version(char *page, unsigned long nasid) break; } - len = sprintf(page, "%x.%02x\n", FIT_MAJOR(fentry[1]), - FIT_MINOR(fentry[1])); - page += len; + seq_printf(m, "%x.%02x\n", FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1])); if (banner[0]) - len += snprintf(page, PAGE_SIZE-len, "%s\n", banner); - - return len; -} - -/* same as in proc_misc.c */ -static int -proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof, - int len) -{ - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; + seq_printf(m, "%s\n", banner); + return 0; } -static int -read_version_entry(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int proc_version_open(struct inode *inode, struct file *file) { - int len; - - /* data holds the NASID of the node */ - len = dump_version(page, (unsigned long)data); - len = proc_calc_metrics(page, start, off, count, eof, len); - return len; + return single_open(file, proc_version_show, PDE_DATA(inode)); } -static int -read_fit_entry(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - int len; - - /* data holds the NASID of the node */ - len = dump_fit(page, (unsigned long)data); - len = proc_calc_metrics(page, start, off, count, eof, len); - - return len; -} +static const struct file_operations proc_version_fops = { + .open = proc_version_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; /* module entry points */ int __init prominfo_init(void); @@ -216,58 +193,39 @@ void __exit prominfo_exit(void); module_init(prominfo_init); module_exit(prominfo_exit); -static struct proc_dir_entry **proc_entries; -static struct proc_dir_entry *sgi_prominfo_entry; - #define NODE_NAME_LEN 11 int __init prominfo_init(void) { - struct proc_dir_entry **entp; + struct proc_dir_entry *sgi_prominfo_entry; cnodeid_t cnodeid; - unsigned long nasid; - int size; - char name[NODE_NAME_LEN]; if (!ia64_platform_is("sn2")) return 0; - size = num_online_nodes() * sizeof(struct proc_dir_entry *); - proc_entries = kzalloc(size, GFP_KERNEL); - if (!proc_entries) - return -ENOMEM; - sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); + if (!sgi_prominfo_entry) + return -ENOMEM; - entp = proc_entries; for_each_online_node(cnodeid) { + struct proc_dir_entry *dir; + unsigned long nasid; + char name[NODE_NAME_LEN]; + sprintf(name, "node%d", cnodeid); - *entp = proc_mkdir(name, sgi_prominfo_entry); + dir = proc_mkdir(name, sgi_prominfo_entry); + if (!dir) + continue; nasid = cnodeid_to_nasid(cnodeid); - create_proc_read_entry("fit", 0, *entp, read_fit_entry, - (void *)nasid); - create_proc_read_entry("version", 0, *entp, - read_version_entry, (void *)nasid); - entp++; + proc_create_data("fit", 0, dir, + &proc_fit_fops, (void *)nasid); + proc_create_data("version", 0, dir, + &proc_version_fops, (void *)nasid); } - return 0; } void __exit prominfo_exit(void) { - struct proc_dir_entry **entp; - unsigned int cnodeid; - char name[NODE_NAME_LEN]; - - entp = proc_entries; - for_each_online_node(cnodeid) { - remove_proc_entry("fit", *entp); - remove_proc_entry("version", *entp); - sprintf(name, "node%d", cnodeid); - remove_proc_entry(name, sgi_prominfo_entry); - entp++; - } - remove_proc_entry("sgi_prominfo", NULL); - kfree(proc_entries); + remove_proc_subtree("sgi_prominfo", NULL); } diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c index aee7c8177b5..9fb714450e9 100644 --- a/arch/mips/kernel/smtc-proc.c +++ b/arch/mips/kernel/smtc-proc.c @@ -16,6 +16,7 @@ #include <asm/mipsregs.h> #include <asm/cacheflush.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/smtc_proc.h> @@ -30,51 +31,39 @@ unsigned long selfipis[NR_CPUS]; struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS]; -static struct proc_dir_entry *smtc_stats; - atomic_t smtc_fpu_recoveries; -static int proc_read_smtc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smtc_proc_show(struct seq_file *m, void *v) { - int totalen = 0; - int len; int i; extern unsigned long ebase; - len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status); - totalen += len; - page += len; - len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7()); - totalen += len; - page += len; - len = sprintf(page, "EBASE: 0x%08lx\n", ebase); - totalen += len; - page += len; - len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n"); - totalen += len; - page += len; - for (i=0; i < NR_CPUS; i++) { - len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints); - totalen += len; - page += len; - } - len = sprintf(page, "Self-IPIs by CPU:\n"); - totalen += len; - page += len; - for(i = 0; i < NR_CPUS; i++) { - len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis); - totalen += len; - page += len; - } - len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n", - atomic_read(&smtc_fpu_recoveries)); - totalen += len; - page += len; + seq_printf(m, "SMTC Status Word: 0x%08x\n", smtc_status); + seq_printf(m, "Config7: 0x%08x\n", read_c0_config7()); + seq_printf(m, "EBASE: 0x%08lx\n", ebase); + seq_printf(m, "Counter Interrupts taken per CPU (TC)\n"); + for (i=0; i < NR_CPUS; i++) + seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].timerints); + seq_printf(m, "Self-IPIs by CPU:\n"); + for(i = 0; i < NR_CPUS; i++) + seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis); + seq_printf(m, "%d Recoveries of \"stolen\" FPU\n", + atomic_read(&smtc_fpu_recoveries)); + return 0; +} - return totalen; +static int smtc_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, smtc_proc_show, NULL); } +static const struct file_operations smtc_proc_fops = { + .open = smtc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + void init_smtc_stats(void) { int i; @@ -86,6 +75,5 @@ void init_smtc_stats(void) atomic_set(&smtc_fpu_recoveries, 0); - smtc_stats = create_proc_read_entry("smtc", 0444, NULL, - proc_read_smtc, NULL); + proc_create("smtc", 0444, NULL, &smtc_proc_fops); } diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c index c592bc8b8c9..638c5db122c 100644 --- a/arch/mips/lasat/picvue_proc.c +++ b/arch/mips/lasat/picvue_proc.c @@ -58,13 +58,13 @@ static int pvc_line_proc_show(struct seq_file *m, void *v) static int pvc_line_proc_open(struct inode *inode, struct file *file) { - return single_open(file, pvc_line_proc_show, PDE(inode)->data); + return single_open(file, pvc_line_proc_show, PDE_DATA(inode)); } static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - int lineno = *(int *)PDE(file_inode(file))->data; + int lineno = *(int *)PDE_DATA(file_inode(file)); char kbuf[PVC_LINELEN]; size_t len; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 3d0346dbccf..9b973e0af9c 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -29,6 +29,7 @@ #include <linux/pfn.h> #include <linux/hardirq.h> #include <linux/gfp.h> +#include <linux/kcore.h> #include <asm/asm-offsets.h> #include <asm/bootinfo.h> diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index d0b6f8399b0..4eaab632736 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -53,56 +53,51 @@ static void pci_proc_init(void); /***************************************************************************** * - * FUNCTION: read_msp_pci_counts + * FUNCTION: show_msp_pci_counts * _________________________________________________________________________ * * DESCRIPTION: Prints the count of how many times each PCI * interrupt has asserted. Can be invoked by the * /proc filesystem. * - * INPUTS: page - part of STDOUT calculation - * off - part of STDOUT calculation - * count - part of STDOUT calculation - * data - unused + * INPUTS: m - synthetic file construction data + * v - iterator * - * OUTPUTS: start - new start location - * eof - end of file pointer - * - * RETURNS: len - STDOUT length + * RETURNS: 0 or error * ****************************************************************************/ -static int read_msp_pci_counts(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int show_msp_pci_counts(struct seq_file *m, void *v) { int i; - int len = 0; unsigned int intcount, total = 0; for (i = 0; i < 32; ++i) { intcount = pci_int_count[i]; if (intcount != 0) { - len += sprintf(page + len, "[%d] = %u\n", i, intcount); + seq_printf(m, "[%d] = %u\n", i, intcount); total += intcount; } } - len += sprintf(page + len, "total = %u\n", total); - if (len <= off+count) - *eof = 1; - - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; + seq_printf(m, "total = %u\n", total); + return 0; +} - return len; +static int msp_pci_rd_cnt_open(struct inode *inode, struct file *file) +{ + return single_open(file, show_msp_pci_counts, NULL); } +static const struct file_operations msp_pci_rd_cnt_fops = { + .open = msp_pci_rd_cnt_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + /***************************************************************************** * - * FUNCTION: gen_pci_cfg_wr + * FUNCTION: gen_pci_cfg_wr_show * _________________________________________________________________________ * * DESCRIPTION: Generates a configuration write cycle for debug purposes. @@ -112,37 +107,30 @@ static int read_msp_pci_counts(char *page, char **start, off_t off, * PCI bus. Intent is that this function by invocable from * the /proc filesystem. * - * INPUTS: page - part of STDOUT calculation - * off - part of STDOUT calculation - * count - part of STDOUT calculation - * data - unused + * INPUTS: m - synthetic file construction data + * v - iterator * - * OUTPUTS: start - new start location - * eof - end of file pointer - * - * RETURNS: len - STDOUT length + * RETURNS: 0 or error * ****************************************************************************/ -static int gen_pci_cfg_wr(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int gen_pci_cfg_wr_show(struct seq_file *m, void *v) { unsigned char where = 0; /* Write to static Device/Vendor ID */ unsigned char bus_num = 0; /* Bus 0 */ unsigned char dev_fn = 0xF; /* Arbitrary device number */ u32 wr_data = 0xFF00AA00; /* Arbitrary data */ struct msp_pci_regs *preg = (void *)PCI_BASE_REG; - int len = 0; unsigned long value; int intr; - len += sprintf(page + len, "PMC MSP PCI: Beginning\n"); + seq_puts(m, "PMC MSP PCI: Beginning\n"); if (proc_init == 0) { pci_proc_init(); proc_init = ~0; } - len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n"); + seq_puts(m, "PMC MSP PCI: Before Cfg Wr\n"); /* * Generate PCI Configuration Write Cycle @@ -168,21 +156,22 @@ static int gen_pci_cfg_wr(char *page, char **start, off_t off, */ intr = preg->if_status; - len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n"); - - /* Handle STDOUT calculations */ - if (len <= off+count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; + seq_puts(m, "PMC MSP PCI: After Cfg Wr\n"); + return 0; +} - return len; +static int gen_pci_cfg_wr_open(struct inode *inode, struct file *file) +{ + return single_open(file, gen_pci_cfg_wr_show, NULL); } +static const struct file_operations gen_pci_cfg_wr_fops = { + .open = gen_pci_cfg_wr_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + /***************************************************************************** * * FUNCTION: pci_proc_init @@ -199,10 +188,8 @@ static int gen_pci_cfg_wr(char *page, char **start, off_t off, ****************************************************************************/ static void pci_proc_init(void) { - create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL, - read_msp_pci_counts, NULL); - create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL, - gen_pci_cfg_wr, NULL); + proc_create("pmc_msp_pci_rd_cnt", 0, NULL, &msp_pci_rd_cnt_fops); + proc_create("pmc_msp_pci_cfg_wr", 0, NULL, &gen_pci_cfg_wr_fops); } #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c index e651105b3f0..cb1e3cb37d7 100644 --- a/arch/mips/sibyte/sb1250/bus_watcher.c +++ b/arch/mips/sibyte/sb1250/bus_watcher.c @@ -30,6 +30,7 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/io.h> #include <asm/sibyte/sb1250.h> @@ -99,63 +100,60 @@ void check_bus_watcher(void) printk("Bus watcher indicates no error\n"); } -static int bw_print_buffer(char *page, struct bw_stats_struct *stats) +#ifdef CONFIG_PROC_FS + +/* For simplicity, I want to assume a single read is required each + time */ +static int bw_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "SiByte Bus Watcher statistics\n"); - len += sprintf(page+len, "-----------------------------\n"); - len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n", - stats->l2_cor_d, stats->l2_bad_d); - len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n", - stats->l2_cor_t, stats->l2_bad_t); - len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n", - stats->mem_cor_d, stats->mem_bad_d); - len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error); - len += sprintf(page+len, "\nLast recorded signature:\n"); - len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n", - (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), - (int)(G_SCD_BERR_TID(stats->status) >> 6), - (int)G_SCD_BERR_RID(stats->status), - (int)G_SCD_BERR_DCODE(stats->status)); + struct bw_stats_struct *stats = m->private; + + seq_puts(m, "SiByte Bus Watcher statistics\n"); + seq_puts(m, "-----------------------------\n"); + seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n", + stats->l2_cor_d, stats->l2_bad_d); + seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n", + stats->l2_cor_t, stats->l2_bad_t); + seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n", + stats->mem_cor_d, stats->mem_bad_d); + seq_printf(m, "IO-err %8ld\n", stats->bus_error); + seq_puts(m, "\nLast recorded signature:\n"); + seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), + (int)(G_SCD_BERR_TID(stats->status) >> 6), + (int)G_SCD_BERR_RID(stats->status), + (int)G_SCD_BERR_DCODE(stats->status)); /* XXXKW indicate multiple errors between printings, or stats collection (or both)? */ if (stats->status & M_SCD_BERR_MULTERRS) - len += sprintf(page+len, "Multiple errors observed since last check.\n"); + seq_puts(m, "Multiple errors observed since last check.\n"); if (stats->status_printed) { - len += sprintf(page+len, "(no change since last printing)\n"); + seq_puts(m, "(no change since last printing)\n"); } else { stats->status_printed = 1; } - return len; + return 0; } -#ifdef CONFIG_PROC_FS - -/* For simplicity, I want to assume a single read is required each - time */ -static int bw_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int bw_proc_open(struct inode *inode, struct file *file) { - int len; - - if (off == 0) { - len = bw_print_buffer(page, data); - *start = page; - } else { - len = 0; - *eof = 1; - } - return len; + return single_open(file, bw_proc_show, PDE_DATA(inode)); } +static const struct file_operations bw_proc_fops = { + .open = bw_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static void create_proc_decoder(struct bw_stats_struct *stats) { struct proc_dir_entry *ent; - ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL, - bw_read_proc, stats); + ent = proc_create_data("bus_watcher", S_IWUSR | S_IRUGO, NULL, + &bw_proc_fops, stats); if (!ent) { printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n"); return; @@ -210,11 +208,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data) stats->bus_error += G_SCD_MEM_BUSERR(cntr); csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS)); -#ifndef CONFIG_PROC_FS - bw_print_buffer(bw_buf, stats); - printk(bw_buf); -#endif - return IRQ_HANDLED; } diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index d47ba1aa825..8fa314fbfb1 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c @@ -30,11 +30,13 @@ #endif #include <linux/init.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/reboot.h> #include <linux/notifier.h> #include <linux/cache.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/pdc_chassis.h> #include <asm/processor.h> @@ -244,38 +246,38 @@ int pdc_chassis_send_status(int message) #ifdef CONFIG_PDC_CHASSIS_WARN #ifdef CONFIG_PROC_FS -static int pdc_chassis_warn_pread(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int pdc_chassis_warn_show(struct seq_file *m, void *v) { - char *out = page; - int len, ret; unsigned long warn; u32 warnreg; - ret = pdc_chassis_warn(&warn); - if (ret != PDC_OK) + if (pdc_chassis_warn(&warn) != PDC_OK) return -EIO; warnreg = (warn & 0xFFFFFFFF); if ((warnreg >> 24) & 0xFF) - out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); - - out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); - out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); - out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); - - len = out - page - off; - if (len < count) { - *eof = 1; - if (len <= 0) return 0; - } else { - len = count; - } - *start = page + off; - return len; + seq_printf(m, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", + (warnreg >> 24) & 0xFF); + + seq_printf(m, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); + seq_printf(m, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); + seq_printf(m, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); + return 0; +} + +static int pdc_chassis_warn_open(struct inode *inode, struct file *file) +{ + return single_open(file, pdc_chassis_warn_show, NULL); } +static const struct file_operations pdc_chassis_warn_fops = { + .open = pdc_chassis_warn_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int __init pdc_chassis_create_procfs(void) { unsigned long test; @@ -290,8 +292,7 @@ static int __init pdc_chassis_create_procfs(void) printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n", PDC_CHASSIS_VER); - create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, - NULL); + proc_create("chassis", 0400, NULL, &pdc_chassis_warn_fops); return 0; } diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index f5725bce9ed..801a757c363 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -41,8 +41,6 @@ /* #define LPARCFG_DEBUG */ -static struct proc_dir_entry *proc_ppc64_lparcfg; - /* * Track sum of all purrs across all processors. This is used to further * calculate usage values by different applications @@ -688,27 +686,22 @@ static const struct file_operations lparcfg_fops = { static int __init lparcfg_init(void) { - struct proc_dir_entry *ent; umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; /* Allow writing if we have FW_FEATURE_SPLPAR */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) mode |= S_IWUSR; - ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops); - if (!ent) { + if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) { printk(KERN_ERR "Failed to create powerpc/lparcfg\n"); return -EIO; } - - proc_ppc64_lparcfg = ent; return 0; } static void __exit lparcfg_cleanup(void) { - if (proc_ppc64_lparcfg) - remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); + remove_proc_subtree("powerpc/lparcfg", NULL); } module_init(lparcfg_init); diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index f19d0bdc324..feb8580fdc8 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -32,8 +32,6 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) { loff_t new; - struct proc_dir_entry *dp = PDE(file_inode(file)); - switch(whence) { case 0: new = off; @@ -42,12 +40,12 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) new = file->f_pos + off; break; case 2: - new = dp->size + off; + new = PAGE_SIZE + off; break; default: return -EINVAL; } - if ( new < 0 || new > dp->size ) + if ( new < 0 || new > PAGE_SIZE ) return -EINVAL; return (file->f_pos = new); } @@ -55,19 +53,18 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size); + return simple_read_from_buffer(buf, nbytes, ppos, + PDE_DATA(file_inode(file)), PAGE_SIZE); } static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - - if ((vma->vm_end - vma->vm_start) > dp->size) + if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) return -EINVAL; - remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT, - dp->size, vma->vm_page_prot); + remap_pfn_range(vma, vma->vm_start, + __pa(PDE_DATA(file_inode(file))) >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot); return 0; } @@ -86,7 +83,7 @@ static int __init proc_ppc64_init(void) &page_map_fops, vdso_data); if (!pde) return 1; - pde->size = PAGE_SIZE; + proc_set_size(pde, PAGE_SIZE); return 0; } diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index c642f013298..5b770262c67 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -102,9 +102,10 @@ static struct kmem_cache *flash_block_cache = NULL; #define FLASH_BLOCK_LIST_VERSION (1UL) -/* Local copy of the flash block list. - * We only allow one open of the flash proc file and create this - * list as we go. The rtas_firmware_flash_list varable will be +/* + * Local copy of the flash block list. + * + * The rtas_firmware_flash_list varable will be * set once the data is fully read. * * For convenience as we build the list we use virtual addrs, @@ -125,23 +126,23 @@ struct rtas_update_flash_t struct rtas_manage_flash_t { int status; /* Returned status */ - unsigned int op; /* Reject or commit image */ }; /* Status int must be first member of struct */ struct rtas_validate_flash_t { int status; /* Returned status */ - char buf[VALIDATE_BUF_SIZE]; /* Candidate image buffer */ + char *buf; /* Candidate image buffer */ unsigned int buf_size; /* Size of image buf */ unsigned int update_results; /* Update results token */ }; -static DEFINE_SPINLOCK(flash_file_open_lock); -static struct proc_dir_entry *firmware_flash_pde; -static struct proc_dir_entry *firmware_update_pde; -static struct proc_dir_entry *validate_pde; -static struct proc_dir_entry *manage_pde; +static struct rtas_update_flash_t rtas_update_flash_data; +static struct rtas_manage_flash_t rtas_manage_flash_data; +static struct rtas_validate_flash_t rtas_validate_flash_data; +static DEFINE_MUTEX(rtas_update_flash_mutex); +static DEFINE_MUTEX(rtas_manage_flash_mutex); +static DEFINE_MUTEX(rtas_validate_flash_mutex); /* Do simple sanity checks on the flash image. */ static int flash_list_valid(struct flash_block_list *flist) @@ -191,10 +192,10 @@ static void free_flash_list(struct flash_block_list *f) static int rtas_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_update_flash_t *uf; - - uf = (struct rtas_update_flash_t *) dp->data; + struct rtas_update_flash_t *const uf = &rtas_update_flash_data; + + mutex_lock(&rtas_update_flash_mutex); + if (uf->flist) { /* File was opened in write mode for a new flash attempt */ /* Clear saved list */ @@ -214,13 +215,14 @@ static int rtas_flash_release(struct inode *inode, struct file *file) uf->flist = NULL; } - atomic_dec(&dp->count); + mutex_unlock(&rtas_update_flash_mutex); return 0; } -static void get_flash_status_msg(int status, char *buf) +static size_t get_flash_status_msg(int status, char *buf) { - char *msg; + const char *msg; + size_t len; switch (status) { case FLASH_AUTH: @@ -242,34 +244,51 @@ static void get_flash_status_msg(int status, char *buf) msg = "ready: firmware image ready for flash on reboot\n"; break; default: - sprintf(buf, "error: unexpected status value %d\n", status); - return; + return sprintf(buf, "error: unexpected status value %d\n", + status); } - strcpy(buf, msg); + len = strlen(msg); + memcpy(buf, msg, len + 1); + return len; } /* Reading the proc file will show status (not the firmware contents) */ -static ssize_t rtas_flash_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t rtas_flash_read_msg(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_update_flash_t *uf; + struct rtas_update_flash_t *const uf = &rtas_update_flash_data; char msg[RTAS_MSG_MAXLEN]; + size_t len; + int status; - uf = dp->data; + mutex_lock(&rtas_update_flash_mutex); + status = uf->status; + mutex_unlock(&rtas_update_flash_mutex); - if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) { - get_flash_status_msg(uf->status, msg); - } else { /* FIRMWARE_UPDATE_NAME */ - sprintf(msg, "%d\n", uf->status); - } + /* Read as text message */ + len = get_flash_status_msg(status, msg); + return simple_read_from_buffer(buf, count, ppos, msg, len); +} + +static ssize_t rtas_flash_read_num(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct rtas_update_flash_t *const uf = &rtas_update_flash_data; + char msg[RTAS_MSG_MAXLEN]; + int status; + mutex_lock(&rtas_update_flash_mutex); + status = uf->status; + mutex_unlock(&rtas_update_flash_mutex); + + /* Read as number */ + sprintf(msg, "%d\n", status); return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg)); } /* constructor for flash_block_cache */ -void rtas_block_ctor(void *ptr) +static void rtas_block_ctor(void *ptr) { memset(ptr, 0, RTAS_BLK_SIZE); } @@ -282,16 +301,15 @@ void rtas_block_ctor(void *ptr) static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_update_flash_t *uf; + struct rtas_update_flash_t *const uf = &rtas_update_flash_data; char *p; - int next_free; + int next_free, rc; struct flash_block_list *fl; - uf = (struct rtas_update_flash_t *) dp->data; + mutex_lock(&rtas_update_flash_mutex); if (uf->status == FLASH_AUTH || count == 0) - return count; /* discard data */ + goto out; /* discard data */ /* In the case that the image is not ready for flashing, the memory * allocated for the block list will be freed upon the release of the @@ -300,7 +318,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, if (uf->flist == NULL) { uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!uf->flist) - return -ENOMEM; + goto nomem; } fl = uf->flist; @@ -311,7 +329,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, /* Need to allocate another block_list */ fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!fl->next) - return -ENOMEM; + goto nomem; fl = fl->next; next_free = 0; } @@ -320,52 +338,37 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, count = RTAS_BLK_SIZE; p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!p) - return -ENOMEM; + goto nomem; if(copy_from_user(p, buffer, count)) { kmem_cache_free(flash_block_cache, p); - return -EFAULT; + rc = -EFAULT; + goto error; } fl->blocks[next_free].data = p; fl->blocks[next_free].length = count; fl->num_blocks++; - +out: + mutex_unlock(&rtas_update_flash_mutex); return count; -} - -static int rtas_excl_open(struct inode *inode, struct file *file) -{ - struct proc_dir_entry *dp = PDE(inode); - - /* Enforce exclusive open with use count of PDE */ - spin_lock(&flash_file_open_lock); - if (atomic_read(&dp->count) > 2) { - spin_unlock(&flash_file_open_lock); - return -EBUSY; - } - - atomic_inc(&dp->count); - spin_unlock(&flash_file_open_lock); - - return 0; -} - -static int rtas_excl_release(struct inode *inode, struct file *file) -{ - struct proc_dir_entry *dp = PDE(inode); - atomic_dec(&dp->count); - - return 0; +nomem: + rc = -ENOMEM; +error: + mutex_unlock(&rtas_update_flash_mutex); + return rc; } -static void manage_flash(struct rtas_manage_flash_t *args_buf) +/* + * Flash management routines. + */ +static void manage_flash(struct rtas_manage_flash_t *args_buf, unsigned int op) { s32 rc; do { - rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, - 1, NULL, args_buf->op); + rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1, + NULL, op); } while (rtas_busy_delay(rc)); args_buf->status = rc; @@ -374,55 +377,62 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) static ssize_t manage_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_manage_flash_t *args_buf; + struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data; char msg[RTAS_MSG_MAXLEN]; - int msglen; + int msglen, status; - args_buf = dp->data; - if (args_buf == NULL) - return 0; - - msglen = sprintf(msg, "%d\n", args_buf->status); + mutex_lock(&rtas_manage_flash_mutex); + status = args_buf->status; + mutex_unlock(&rtas_manage_flash_mutex); + msglen = sprintf(msg, "%d\n", status); return simple_read_from_buffer(buf, count, ppos, msg, msglen); } static ssize_t manage_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_manage_flash_t *args_buf; - const char reject_str[] = "0"; - const char commit_str[] = "1"; + struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data; + static const char reject_str[] = "0"; + static const char commit_str[] = "1"; char stkbuf[10]; - int op; + int op, rc; + + mutex_lock(&rtas_manage_flash_mutex); - args_buf = (struct rtas_manage_flash_t *) dp->data; if ((args_buf->status == MANAGE_AUTH) || (count == 0)) - return count; + goto out; op = -1; if (buf) { if (count > 9) count = 9; - if (copy_from_user (stkbuf, buf, count)) { - return -EFAULT; - } + rc = -EFAULT; + if (copy_from_user (stkbuf, buf, count)) + goto error; if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) op = RTAS_REJECT_TMP_IMG; else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) op = RTAS_COMMIT_TMP_IMG; } - if (op == -1) /* buf is empty, or contains invalid string */ - return -EINVAL; - - args_buf->op = op; - manage_flash(args_buf); + if (op == -1) { /* buf is empty, or contains invalid string */ + rc = -EINVAL; + goto error; + } + manage_flash(args_buf, op); +out: + mutex_unlock(&rtas_manage_flash_mutex); return count; + +error: + mutex_unlock(&rtas_manage_flash_mutex); + return rc; } +/* + * Validation routines. + */ static void validate_flash(struct rtas_validate_flash_t *args_buf) { int token = rtas_token("ibm,validate-flash-image"); @@ -462,14 +472,14 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, static ssize_t validate_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_validate_flash_t *args_buf; + struct rtas_validate_flash_t *const args_buf = + &rtas_validate_flash_data; char msg[RTAS_MSG_MAXLEN]; int msglen; - args_buf = dp->data; - + mutex_lock(&rtas_validate_flash_mutex); msglen = get_validate_flash_msg(args_buf, msg); + mutex_unlock(&rtas_validate_flash_mutex); return simple_read_from_buffer(buf, count, ppos, msg, msglen); } @@ -477,24 +487,18 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, static ssize_t validate_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_validate_flash_t *args_buf; + struct rtas_validate_flash_t *const args_buf = + &rtas_validate_flash_data; int rc; - args_buf = (struct rtas_validate_flash_t *) dp->data; - - if (dp->data == NULL) { - dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), - GFP_KERNEL); - if (dp->data == NULL) - return -ENOMEM; - } + mutex_lock(&rtas_validate_flash_mutex); /* We are only interested in the first 4K of the * candidate image */ if ((*off >= VALIDATE_BUF_SIZE) || (args_buf->status == VALIDATE_AUTH)) { *off += count; + mutex_unlock(&rtas_validate_flash_mutex); return count; } @@ -517,31 +521,29 @@ static ssize_t validate_flash_write(struct file *file, const char __user *buf, *off += count; rc = count; done: - if (rc < 0) { - kfree(dp->data); - dp->data = NULL; - } + mutex_unlock(&rtas_validate_flash_mutex); return rc; } static int validate_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - struct rtas_validate_flash_t *args_buf; + struct rtas_validate_flash_t *const args_buf = + &rtas_validate_flash_data; - args_buf = (struct rtas_validate_flash_t *) dp->data; + mutex_lock(&rtas_validate_flash_mutex); if (args_buf->status == VALIDATE_READY) { args_buf->buf_size = VALIDATE_BUF_SIZE; validate_flash(args_buf); } - /* The matching atomic_inc was in rtas_excl_open() */ - atomic_dec(&dp->count); - + mutex_unlock(&rtas_validate_flash_mutex); return 0; } +/* + * On-reboot flash update applicator. + */ static void rtas_flash_firmware(int reboot_type) { unsigned long image_size; @@ -634,75 +636,57 @@ static void rtas_flash_firmware(int reboot_type) spin_unlock(&rtas_data_buf_lock); } -static void remove_flash_pde(struct proc_dir_entry *dp) -{ - if (dp) { - kfree(dp->data); - remove_proc_entry(dp->name, dp->parent); - } -} - -static int initialize_flash_pde_data(const char *rtas_call_name, - size_t buf_size, - struct proc_dir_entry *dp) -{ +/* + * Manifest of proc files to create + */ +struct rtas_flash_file { + const char *filename; + const char *rtas_call_name; int *status; - int token; - - dp->data = kzalloc(buf_size, GFP_KERNEL); - if (dp->data == NULL) - return -ENOMEM; - - /* - * This code assumes that the status int is the first member of the - * struct - */ - status = (int *) dp->data; - token = rtas_token(rtas_call_name); - if (token == RTAS_UNKNOWN_SERVICE) - *status = FLASH_AUTH; - else - *status = FLASH_NO_OP; - - return 0; -} - -static struct proc_dir_entry *create_flash_pde(const char *filename, - const struct file_operations *fops) -{ - return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops); -} - -static const struct file_operations rtas_flash_operations = { - .owner = THIS_MODULE, - .read = rtas_flash_read, - .write = rtas_flash_write, - .open = rtas_excl_open, - .release = rtas_flash_release, - .llseek = default_llseek, -}; - -static const struct file_operations manage_flash_operations = { - .owner = THIS_MODULE, - .read = manage_flash_read, - .write = manage_flash_write, - .open = rtas_excl_open, - .release = rtas_excl_release, - .llseek = default_llseek, + const struct file_operations fops; }; -static const struct file_operations validate_flash_operations = { - .owner = THIS_MODULE, - .read = validate_flash_read, - .write = validate_flash_write, - .open = rtas_excl_open, - .release = validate_flash_release, - .llseek = default_llseek, +static const struct rtas_flash_file rtas_flash_files[] = { + { + .filename = "powerpc/rtas/" FIRMWARE_FLASH_NAME, + .rtas_call_name = "ibm,update-flash-64-and-reboot", + .status = &rtas_update_flash_data.status, + .fops.read = rtas_flash_read_msg, + .fops.write = rtas_flash_write, + .fops.release = rtas_flash_release, + .fops.llseek = default_llseek, + }, + { + .filename = "powerpc/rtas/" FIRMWARE_UPDATE_NAME, + .rtas_call_name = "ibm,update-flash-64-and-reboot", + .status = &rtas_update_flash_data.status, + .fops.read = rtas_flash_read_num, + .fops.write = rtas_flash_write, + .fops.release = rtas_flash_release, + .fops.llseek = default_llseek, + }, + { + .filename = "powerpc/rtas/" VALIDATE_FLASH_NAME, + .rtas_call_name = "ibm,validate-flash-image", + .status = &rtas_validate_flash_data.status, + .fops.read = validate_flash_read, + .fops.write = validate_flash_write, + .fops.release = validate_flash_release, + .fops.llseek = default_llseek, + }, + { + .filename = "powerpc/rtas/" MANAGE_FLASH_NAME, + .rtas_call_name = "ibm,manage-flash-image", + .status = &rtas_manage_flash_data.status, + .fops.read = manage_flash_read, + .fops.write = manage_flash_write, + .fops.llseek = default_llseek, + } }; static int __init rtas_flash_init(void) { - int rc; + int i; if (rtas_token("ibm,update-flash-64-and-reboot") == RTAS_UNKNOWN_SERVICE) { @@ -710,93 +694,65 @@ static int __init rtas_flash_init(void) return 1; } - firmware_flash_pde = create_flash_pde("powerpc/rtas/" - FIRMWARE_FLASH_NAME, - &rtas_flash_operations); - if (firmware_flash_pde == NULL) { - rc = -ENOMEM; - goto cleanup; - } + rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); + if (!rtas_validate_flash_data.buf) + return -ENOMEM; - rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", - sizeof(struct rtas_update_flash_t), - firmware_flash_pde); - if (rc != 0) - goto cleanup; - - firmware_update_pde = create_flash_pde("powerpc/rtas/" - FIRMWARE_UPDATE_NAME, - &rtas_flash_operations); - if (firmware_update_pde == NULL) { - rc = -ENOMEM; - goto cleanup; + flash_block_cache = kmem_cache_create("rtas_flash_cache", + RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, + rtas_block_ctor); + if (!flash_block_cache) { + printk(KERN_ERR "%s: failed to create block cache\n", + __func__); + goto enomem_buf; } - rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", - sizeof(struct rtas_update_flash_t), - firmware_update_pde); - if (rc != 0) - goto cleanup; - - validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME, - &validate_flash_operations); - if (validate_pde == NULL) { - rc = -ENOMEM; - goto cleanup; - } + for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) { + const struct rtas_flash_file *f = &rtas_flash_files[i]; + int token; - rc = initialize_flash_pde_data("ibm,validate-flash-image", - sizeof(struct rtas_validate_flash_t), - validate_pde); - if (rc != 0) - goto cleanup; - - manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME, - &manage_flash_operations); - if (manage_pde == NULL) { - rc = -ENOMEM; - goto cleanup; - } + if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops)) + goto enomem; - rc = initialize_flash_pde_data("ibm,manage-flash-image", - sizeof(struct rtas_manage_flash_t), - manage_pde); - if (rc != 0) - goto cleanup; + /* + * This code assumes that the status int is the first member of the + * struct + */ + token = rtas_token(f->rtas_call_name); + if (token == RTAS_UNKNOWN_SERVICE) + *f->status = FLASH_AUTH; + else + *f->status = FLASH_NO_OP; + } rtas_flash_term_hook = rtas_flash_firmware; - - flash_block_cache = kmem_cache_create("rtas_flash_cache", - RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, - rtas_block_ctor); - if (!flash_block_cache) { - printk(KERN_ERR "%s: failed to create block cache\n", - __func__); - rc = -ENOMEM; - goto cleanup; - } return 0; -cleanup: - remove_flash_pde(firmware_flash_pde); - remove_flash_pde(firmware_update_pde); - remove_flash_pde(validate_pde); - remove_flash_pde(manage_pde); +enomem: + while (--i >= 0) { + const struct rtas_flash_file *f = &rtas_flash_files[i]; + remove_proc_entry(f->filename, NULL); + } - return rc; + kmem_cache_destroy(flash_block_cache); +enomem_buf: + kfree(rtas_validate_flash_data.buf); + return -ENOMEM; } static void __exit rtas_flash_cleanup(void) { + int i; + rtas_flash_term_hook = NULL; - if (flash_block_cache) - kmem_cache_destroy(flash_block_cache); + for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) { + const struct rtas_flash_file *f = &rtas_flash_files[i]; + remove_proc_entry(f->filename, NULL); + } - remove_flash_pde(firmware_flash_pde); - remove_flash_pde(firmware_update_pde); - remove_flash_pde(validate_pde); - remove_flash_pde(manage_pde); + kmem_cache_destroy(flash_block_cache); + kfree(rtas_validate_flash_data.buf); } module_init(rtas_flash_init); diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 8cc18abd6dd..da98e26f6e4 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -1467,7 +1467,7 @@ static int kvm_htab_release(struct inode *inode, struct file *filp) return 0; } -static struct file_operations kvm_htab_fops = { +static const struct file_operations kvm_htab_fops = { .read = kvm_htab_read, .write = kvm_htab_write, .llseek = default_llseek, diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 72ffc899c08..b2d3f3b2de7 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -92,7 +92,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) return 0; } -static struct file_operations kvm_spapr_tce_fops = { +static const struct file_operations kvm_spapr_tce_fops = { .mmap = kvm_spapr_tce_mmap, .release = kvm_spapr_tce_release, }; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 80dcc53a1ab..b62bd1b97c6 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1483,7 +1483,7 @@ static int kvm_rma_release(struct inode *inode, struct file *filp) return 0; } -static struct file_operations kvm_rma_fops = { +static const struct file_operations kvm_rma_fops = { .mmap = kvm_rma_mmap, .release = kvm_rma_release, }; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 68c57d38745..d43d2d0b90e 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -149,7 +149,6 @@ static int __fops ## _open(struct inode *inode, struct file *file) \ return spufs_attr_open(inode, file, __get, __set, __fmt); \ } \ static const struct file_operations __fops = { \ - .owner = THIS_MODULE, \ .open = __fops ## _open, \ .release = spufs_attr_release, \ .read = spufs_attr_read, \ @@ -2591,7 +2590,6 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait) } static const struct file_operations spufs_switch_log_fops = { - .owner = THIS_MODULE, .open = spufs_switch_log_open, .read = spufs_switch_log_read, .poll = spufs_switch_log_poll, diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index d6491bd481d..f93cdf55628 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void) ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); if (ent) - ent->size = 0; + proc_set_size(ent, 0); return 0; } diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 47f3cda2a68..b502ab61aaf 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c @@ -41,13 +41,12 @@ static unsigned int ibm_scan_log_dump; /* RTAS token */ -static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ +static unsigned int *scanlog_buffer; /* The data buffer */ static ssize_t scanlog_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file_inode(file)); - unsigned int *data = (unsigned int *)dp->data; + unsigned int *data = scanlog_buffer; int status; unsigned long len, off; unsigned int wait_time; @@ -135,8 +134,7 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf, static int scanlog_open(struct inode * inode, struct file * file) { - struct proc_dir_entry *dp = PDE(inode); - unsigned int *data = (unsigned int *)dp->data; + unsigned int *data = scanlog_buffer; if (data[0] != 0) { /* This imperfect test stops a second copy of the @@ -152,11 +150,9 @@ static int scanlog_open(struct inode * inode, struct file * file) static int scanlog_release(struct inode * inode, struct file * file) { - struct proc_dir_entry *dp = PDE(inode); - unsigned int *data = (unsigned int *)dp->data; + unsigned int *data = scanlog_buffer; data[0] = 0; - return 0; } @@ -172,7 +168,6 @@ const struct file_operations scanlog_fops = { static int __init scanlog_init(void) { struct proc_dir_entry *ent; - void *data; int err = -ENOMEM; ibm_scan_log_dump = rtas_token("ibm,scan-log-dump"); @@ -180,29 +175,24 @@ static int __init scanlog_init(void) return -ENODEV; /* Ideally we could allocate a buffer < 4G */ - data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); - if (!data) + scanlog_buffer = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); + if (!scanlog_buffer) goto err; - ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, - &scanlog_fops, data); + ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, + &scanlog_fops); if (!ent) goto err; - - proc_ppc64_scan_log_dump = ent; - return 0; err: - kfree(data); + kfree(scanlog_buffer); return err; } static void __exit scanlog_cleanup(void) { - if (proc_ppc64_scan_log_dump) { - kfree(proc_ppc64_scan_log_dump->data); - remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent); - } + remove_proc_entry("powerpc/rtas/scan-log-dump", NULL); + kfree(scanlog_buffer); } module_init(scanlog_init); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 17644c8e10e..2d72d9e96c1 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1323,22 +1323,6 @@ ENTRY(compat_sys_keyctl_wrapper) llgfr %r6,%r6 # u32 jg compat_sys_keyctl # branch to system call -ENTRY(compat_sys_preadv_wrapper) - llgfr %r2,%r2 # unsigned long - llgtr %r3,%r3 # compat_iovec * - llgfr %r4,%r4 # unsigned long - llgfr %r5,%r5 # u32 - llgfr %r6,%r6 # u32 - jg compat_sys_preadv # branch to system call - -ENTRY(compat_sys_pwritev_wrapper) - llgfr %r2,%r2 # unsigned long - llgtr %r3,%r3 # compat_iovec * - llgfr %r4,%r4 # unsigned long - llgfr %r5,%r5 # u32 - llgfr %r6,%r6 # u32 - jg compat_sys_pwritev # branch to system call - ENTRY(sys_perf_event_open_wrapper) llgtr %r2,%r2 # const struct perf_event_attr * lgfr %r3,%r3 # pid_t diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 4f5ef62934a..f7fb58903f6 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -162,10 +162,8 @@ asmlinkage void do_softirq(void) #ifdef CONFIG_PROC_FS void init_irq_proc(void) { - struct proc_dir_entry *root_irq_dir; - - root_irq_dir = proc_mkdir("irq", NULL); - create_prof_cpu_mask(root_irq_dir); + if (proc_mkdir("irq", NULL)) + create_prof_cpu_mask(); } #endif diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 46480d81df0..d112fc66f99 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -10,6 +10,7 @@ #include <linux/crash_dump.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <asm/checksum.h> #include <asm/lowcore.h> #include <asm/os_info.h> diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index d2baabed714..9f214e992ee 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -336,8 +336,8 @@ SYSCALL(sys_inotify_init1,sys_inotify_init1,sys_inotify_init1_wrapper) SYSCALL(sys_pipe2,sys_pipe2,sys_pipe2_wrapper) /* 325 */ SYSCALL(sys_dup3,sys_dup3,sys_dup3_wrapper) SYSCALL(sys_epoll_create1,sys_epoll_create1,sys_epoll_create1_wrapper) -SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper) -SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper) +SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv) +SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev) SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo) /* 330 */ SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index 1592aad7dbc..d8f988a37d1 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -31,7 +31,7 @@ #include <linux/mm.h> #include <linux/mman.h> #include <linux/pagemap.h> -#include <linux/proc_fs.h> +#include <linux/kcore.h> #include <linux/sched.h> #include <linux/initrd.h> diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index f46848f088e..851e5106e58 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/spinlock.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/list.h> #include <linux/platform_device.h> #include <linux/mm.h> @@ -308,11 +309,9 @@ int dma_extend(unsigned int chan, unsigned long op, void *param) } EXPORT_SYMBOL(dma_extend); -static int dma_read_proc(char *buf, char **start, off_t off, - int len, int *eof, void *data) +static int dma_proc_show(struct seq_file *m, void *v) { - struct dma_info *info; - char *p = buf; + struct dma_info *info = v; if (list_empty(®istered_dmac_list)) return 0; @@ -332,14 +331,26 @@ static int dma_read_proc(char *buf, char **start, off_t off, if (!(channel->flags & DMA_CONFIGURED)) continue; - p += sprintf(p, "%2d: %14s %s\n", i, - info->name, channel->dev_id); + seq_printf(m, "%2d: %14s %s\n", i, + info->name, channel->dev_id); } } - return p - buf; + return 0; +} + +static int dma_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, dma_proc_show, NULL); } +static const struct file_operations dma_proc_fops = { + .open = dma_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + int register_dmac(struct dma_info *info) { unsigned int total_channels, i; @@ -412,8 +423,7 @@ EXPORT_SYMBOL(unregister_dmac); static int __init dma_api_init(void) { printk(KERN_NOTICE "DMA: Registering DMA API.\n"); - return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0) - ? 0 : -ENOMEM; + return proc_create("dma", 0, NULL, &dma_proc_fops) ? 0 : -ENOMEM; } subsys_initcall(dma_api_init); diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c index aea14855e65..ec2b2530242 100644 --- a/arch/sh/mm/alignment.c +++ b/arch/sh/mm/alignment.c @@ -140,7 +140,7 @@ static int alignment_proc_open(struct inode *inode, struct file *file) static ssize_t alignment_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - int *data = PDE(file_inode(file))->data; + int *data = PDE_DATA(file_inode(file)); char mode; if (count > 0) { diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 0f094db918c..2096468de9b 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -693,7 +693,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v) static int sparc_io_proc_open(struct inode *inode, struct file *file) { - return single_open(file, sparc_io_proc_show, PDE(inode)->data); + return single_open(file, sparc_io_proc_show, PDE_DATA(inode)); } static const struct file_operations sparc_io_proc_fops = { diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index e490ac9327c..f8933be3ca8 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -6,6 +6,7 @@ */ #include <linux/kernel_stat.h> +#include <linux/slab.h> #include <linux/seq_file.h> #include <asm/timer.h> diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 20273ee37de..38ac189d957 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c @@ -914,7 +914,7 @@ static int hardwall_proc_show(struct seq_file *sf, void *v) static int hardwall_proc_open(struct inode *inode, struct file *file) { - return single_open(file, hardwall_proc_show, PDE(inode)->data); + return single_open(file, hardwall_proc_show, PDE_DATA(inode)); } static const struct file_operations hardwall_proc_fops = { diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 4bd82ac0210..d7d21851e60 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -782,8 +782,7 @@ static int create_proc_mconsole(void) ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops); if (ent == NULL) { - printk(KERN_INFO "create_proc_mconsole : create_proc_entry " - "failed\n"); + printk(KERN_INFO "create_proc_mconsole : proc_create failed\n"); return 0; } return 0; diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 81e94d972f1..805078e0801 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -322,11 +322,8 @@ static int load_aout_binary(struct linux_binprm *bprm) if (N_MAGIC(ex) == OMAGIC) { unsigned long text_addr, map_size; - loff_t pos; text_addr = N_TXTADDR(ex); - - pos = 32; map_size = ex.a_text+ex.a_data; error = vm_brk(text_addr & PAGE_MASK, map_size); @@ -336,15 +333,12 @@ static int load_aout_binary(struct linux_binprm *bprm) return error; } - error = bprm->file->f_op->read(bprm->file, - (char __user *)text_addr, - ex.a_text+ex.a_data, &pos); + error = read_code(bprm->file, text_addr, 32, + ex.a_text + ex.a_data); if ((signed long)error < 0) { send_sig(SIGKILL, current, 0); return error; } - - flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); } else { #ifdef WARN_OLD static unsigned long error_time, error_time2; @@ -366,15 +360,9 @@ static int load_aout_binary(struct linux_binprm *bprm) #endif if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { - loff_t pos = fd_offset; - vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); - bprm->file->f_op->read(bprm->file, - (char __user *)N_TXTADDR(ex), - ex.a_text+ex.a_data, &pos); - flush_icache_range((unsigned long) N_TXTADDR(ex), - (unsigned long) N_TXTADDR(ex) + - ex.a_text+ex.a_data); + read_code(bprm->file, N_TXTADDR(ex), fd_offset, + ex.a_text+ex.a_data); goto beyond_if; } @@ -451,8 +439,6 @@ static int load_aout_library(struct file *file) start_addr = ex.a_entry & 0xfffff000; if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { - loff_t pos = N_TXTOFF(ex); - #ifdef WARN_OLD static unsigned long error_time; if (time_after(jiffies, error_time + 5*HZ)) { @@ -465,12 +451,8 @@ static int load_aout_library(struct file *file) #endif vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); - file->f_op->read(file, (char __user *)start_addr, - ex.a_text + ex.a_data, &pos); - flush_icache_range((unsigned long) start_addr, - (unsigned long) start_addr + ex.a_text + - ex.a_data); - + read_code(file, start_addr, N_TXTOFF(ex), + ex.a_text + ex.a_data); retval = 0; goto out; } diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index caad9a0ee19..bb00c4672ad 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -32,6 +32,7 @@ #include <linux/memory_hotplug.h> #include <linux/nmi.h> #include <linux/gfp.h> +#include <linux/kcore.h> #include <asm/processor.h> #include <asm/bios_ebda.h> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 6b85db0a7cc..55856b2310d 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -34,6 +34,7 @@ #include <linux/efi-bgrt.h> #include <linux/export.h> #include <linux/bootmem.h> +#include <linux/slab.h> #include <linux/memblock.h> #include <linux/spinlock.h> #include <linux/uaccess.h> diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2b200386061..39a0e7f1f0a 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -27,6 +27,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/reboot.h> +#include <linux/slab.h> #include <asm/setup.h> #include <asm/page.h> diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c index f58ffc3b68a..4a06d70ddf5 100644 --- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -214,20 +214,27 @@ static int simdisk_detach(struct simdisk *dev) return err; } -static int proc_read_simdisk(char *page, char **start, off_t off, - int count, int *eof, void *data) +static ssize_t proc_read_simdisk(struct file *file, char __user *buf, + size_t size, loff_t *ppos) { - int len; - struct simdisk *dev = (struct simdisk *) data; - len = sprintf(page, "%s\n", dev->filename ? dev->filename : ""); - return len; + struct simdisk *dev = PDE_DATA(file_inode(file)); + char *s = dev->filename; + if (s) { + ssize_t n = simple_read_from_buffer(buf, size, ppos, + s, strlen(s)); + if (n < 0) + return n; + buf += n; + size -= n; + } + return simple_read_from_buffer(buf, size, ppos, "\n", 1); } -static int proc_write_simdisk(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t proc_write_simdisk(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) { char *tmp = kmalloc(count + 1, GFP_KERNEL); - struct simdisk *dev = (struct simdisk *) data; + struct simdisk *dev = PDE_DATA(file_inode(file)); int err; if (tmp == NULL) @@ -256,6 +263,12 @@ out_free: return err; } +static const struct file_operations fops = { + .read = proc_read_simdisk, + .write = proc_write_simdisk, + .llseek = default_llseek, +}; + static int __init simdisk_setup(struct simdisk *dev, int which, struct proc_dir_entry *procdir) { @@ -289,10 +302,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which, set_capacity(dev->gd, 0); add_disk(dev->gd); - dev->procfile = create_proc_entry(tmp, 0644, procdir); - dev->procfile->data = dev; - dev->procfile->read_proc = proc_read_simdisk; - dev->procfile->write_proc = proc_write_simdisk; + dev->procfile = proc_create_data(tmp, 0644, procdir, &fops, dev); return 0; out_alloc_disk: diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 6d5bf649196..00d2efd674d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -194,7 +194,7 @@ static int acpi_ac_seq_show(struct seq_file *seq, void *offset) static int acpi_ac_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_ac_seq_show, PDE(inode)->data); + return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); } static int acpi_ac_add_fs(struct acpi_device *device) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 0cc384b7294..e7100459ac4 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -929,7 +929,7 @@ static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ } \ static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ { \ - return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ + return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ } DECLARE_FILE_FUNCTIONS(info); diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 92a659aa639..d2e617b5b3f 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -129,7 +129,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) static int acpi_button_state_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); + return single_open(file, acpi_button_state_seq_show, PDE_DATA(inode)); } static const struct file_operations acpi_button_state_fops = { diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 52ce76725c2..aa1227a7e3f 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c @@ -120,7 +120,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data); + return single_open(file, acpi_system_alarm_seq_show, PDE_DATA(inode)); } static int get_date_field(char **p, u32 * value) @@ -397,7 +397,7 @@ static int acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file) { return single_open(file, acpi_system_wakeup_device_seq_show, - PDE(inode)->data); + PDE_DATA(inode)); } static const struct file_operations acpi_system_wakeup_device_fops = { diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index e523245643a..b6241eeb113 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -521,19 +521,6 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, return 0; } -static void -acpi_sbs_remove_fs(struct proc_dir_entry **dir, - struct proc_dir_entry *parent_dir) -{ - if (*dir) { - remove_proc_entry(ACPI_SBS_FILE_INFO, *dir); - remove_proc_entry(ACPI_SBS_FILE_STATE, *dir); - remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir); - remove_proc_entry((*dir)->name, parent_dir); - *dir = NULL; - } -} - /* Smart Battery Interface */ static struct proc_dir_entry *acpi_battery_dir = NULL; @@ -584,7 +571,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_battery_read_info, PDE(inode)->data); + return single_open(file, acpi_battery_read_info, PDE_DATA(inode)); } static int acpi_battery_read_state(struct seq_file *seq, void *offset) @@ -623,7 +610,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_battery_read_state, PDE(inode)->data); + return single_open(file, acpi_battery_read_state, PDE_DATA(inode)); } static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) @@ -688,7 +675,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); + return single_open(file, acpi_battery_read_alarm, PDE_DATA(inode)); } static const struct file_operations acpi_battery_info_fops = { @@ -736,7 +723,7 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset) static int acpi_ac_state_open_fs(struct inode *inode, struct file *file) { - return single_open(file, acpi_ac_read_state, PDE(inode)->data); + return single_open(file, acpi_ac_read_state, PDE_DATA(inode)); } static const struct file_operations acpi_ac_state_fops = { @@ -836,8 +823,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) power_supply_unregister(&battery->bat); } #ifdef CONFIG_ACPI_PROCFS_POWER - if (battery->proc_entry) - acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); + proc_remove(battery->proc_entry); + battery->proc_entry = NULL; #endif } @@ -873,8 +860,8 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) if (sbs->charger.dev) power_supply_unregister(&sbs->charger); #ifdef CONFIG_ACPI_PROCFS_POWER - if (sbs->charger_entry) - acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); + proc_remove(sbs->charger_entry); + sbs->charger_entry = NULL; #endif } diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 08608de87e4..dc4f70179e7 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -322,23 +322,11 @@ static u8 k2_stat_check_status(struct ata_port *ap) } #ifdef CONFIG_PPC_OF -/* - * k2_sata_proc_info - * inout : decides on the direction of the dataflow and the meaning of the - * variables - * buffer: If inout==FALSE data is being written to it else read from it - * *start: If inout==FALSE start of the valid data in the buffer - * offset: If inout==FALSE offset from the beginning of the imaginary file - * from which we start writing into the buffer - * length: If inout==FALSE max number of bytes to be written into the buffer - * else number of bytes in the buffer - */ -static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start, - off_t offset, int count, int inout) +static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost) { struct ata_port *ap; struct device_node *np; - int len, index; + int index; /* Find the ata_port */ ap = ata_shost_to_port(shost); @@ -356,15 +344,12 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start, const u32 *reg = of_get_property(np, "reg", NULL); if (!reg) continue; - if (index == *reg) + if (index == *reg) { + seq_printf(m, "devspec: %s\n", np->full_name); break; + } } - if (np == NULL) - return 0; - - len = sprintf(page, "devspec: %s\n", np->full_name); - - return len; + return 0; } #endif /* CONFIG_PPC_OF */ @@ -372,7 +357,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start, static struct scsi_host_template k2_sata_sht = { ATA_BMDMA_SHT(DRV_NAME), #ifdef CONFIG_PPC_OF - .proc_info = k2_sata_proc_info, + .show_info = k2_sata_show_info, #endif }; diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 5b5ee79ff23..eb3950113e4 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -6473,7 +6473,7 @@ static int dac960_initial_status_proc_show(struct seq_file *m, void *v) static int dac960_initial_status_proc_open(struct inode *inode, struct file *file) { - return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data); + return single_open(file, dac960_initial_status_proc_show, PDE_DATA(inode)); } static const struct file_operations dac960_initial_status_proc_fops = { @@ -6519,7 +6519,7 @@ static int dac960_current_status_proc_show(struct seq_file *m, void *v) static int dac960_current_status_proc_open(struct inode *inode, struct file *file) { - return single_open(file, dac960_current_status_proc_show, PDE(inode)->data); + return single_open(file, dac960_current_status_proc_show, PDE_DATA(inode)); } static const struct file_operations dac960_current_status_proc_fops = { @@ -6540,14 +6540,14 @@ static int dac960_user_command_proc_show(struct seq_file *m, void *v) static int dac960_user_command_proc_open(struct inode *inode, struct file *file) { - return single_open(file, dac960_user_command_proc_show, PDE(inode)->data); + return single_open(file, dac960_user_command_proc_show, PDE_DATA(inode)); } static ssize_t dac960_user_command_proc_write(struct file *file, const char __user *Buffer, size_t Count, loff_t *pos) { - DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file_inode(file))->data; + DAC960_Controller_T *Controller = PDE_DATA(file_inode(file)); unsigned char CommandBuffer[80]; int Length; if (Count > sizeof(CommandBuffer)-1) return -EINVAL; diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1c1b8e544aa..e18c99140c0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -493,7 +493,7 @@ static int cciss_seq_open(struct inode *inode, struct file *file) struct seq_file *seq = file->private_data; if (!ret) - seq->private = PDE(inode)->data; + seq->private = PDE_DATA(inode); return ret; } diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index da3311129a0..ecd845cd28d 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -54,13 +54,11 @@ static CommandList_struct *cmd_special_alloc(ctlr_info_t *h); static void cmd_free(ctlr_info_t *h, CommandList_struct *c); static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c); -static int cciss_scsi_proc_info( - struct Scsi_Host *sh, +static int cciss_scsi_write_info(struct Scsi_Host *sh, char *buffer, /* data buffer */ - char **start, /* where data in buffer starts */ - off_t offset, /* offset from start of imaginary file */ - int length, /* length of data in buffer */ - int func); /* 0 == read, 1 == write */ + int length); /* length of data in buffer */ +static int cciss_scsi_show_info(struct seq_file *m, + struct Scsi_Host *sh); static int cciss_scsi_queue_command (struct Scsi_Host *h, struct scsi_cmnd *cmd); @@ -82,7 +80,8 @@ static struct scsi_host_template cciss_driver_template = { .module = THIS_MODULE, .name = "cciss", .proc_name = "cciss", - .proc_info = cciss_scsi_proc_info, + .write_info = cciss_scsi_write_info, + .show_info = cciss_scsi_show_info, .queuecommand = cciss_scsi_queue_command, .this_id = 7, .cmd_per_lun = 1, @@ -1302,59 +1301,54 @@ cciss_scsi_user_command(ctlr_info_t *h, int hostno, char *buffer, int length) return length; } - static int -cciss_scsi_proc_info(struct Scsi_Host *sh, +cciss_scsi_write_info(struct Scsi_Host *sh, char *buffer, /* data buffer */ - char **start, /* where data in buffer starts */ - off_t offset, /* offset from start of imaginary file */ - int length, /* length of data in buffer */ - int func) /* 0 == read, 1 == write */ + int length) /* length of data in buffer */ { + ctlr_info_t *h = (ctlr_info_t *) sh->hostdata[0]; + if (h == NULL) /* This really shouldn't ever happen. */ + return -EINVAL; - int buflen, datalen; - ctlr_info_t *h; + return cciss_scsi_user_command(h, sh->host_no, + buffer, length); +} + +static int +cciss_scsi_show_info(struct seq_file *m, struct Scsi_Host *sh) +{ + + ctlr_info_t *h = (ctlr_info_t *) sh->hostdata[0]; int i; - h = (ctlr_info_t *) sh->hostdata[0]; if (h == NULL) /* This really shouldn't ever happen. */ return -EINVAL; - if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ - buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n", - h->ctlr, sh->host_no); - - /* this information is needed by apps to know which cciss - device corresponds to which scsi host number without - having to open a scsi target device node. The device - information is not a duplicate of /proc/scsi/scsi because - the two may be out of sync due to scsi hotplug, rather - this info is for an app to be able to use to know how to - get them back in sync. */ - - for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { - struct cciss_scsi_dev_t *sd = - &ccissscsi[h->ctlr].dev[i]; - buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d " - "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - sh->host_no, sd->bus, sd->target, sd->lun, - sd->devtype, - sd->scsi3addr[0], sd->scsi3addr[1], - sd->scsi3addr[2], sd->scsi3addr[3], - sd->scsi3addr[4], sd->scsi3addr[5], - sd->scsi3addr[6], sd->scsi3addr[7]); - } - datalen = buflen - offset; - if (datalen < 0) { /* they're reading past EOF. */ - datalen = 0; - *start = buffer+buflen; - } else - *start = buffer + offset; - return(datalen); - } else /* User is writing to /proc/scsi/cciss*?/?* ... */ - return cciss_scsi_user_command(h, sh->host_no, - buffer, length); -} + seq_printf(m, "cciss%d: SCSI host: %d\n", + h->ctlr, sh->host_no); + + /* this information is needed by apps to know which cciss + device corresponds to which scsi host number without + having to open a scsi target device node. The device + information is not a duplicate of /proc/scsi/scsi because + the two may be out of sync due to scsi hotplug, rather + this info is for an app to be able to use to know how to + get them back in sync. */ + + for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { + struct cciss_scsi_dev_t *sd = + &ccissscsi[h->ctlr].dev[i]; + seq_printf(m, "c%db%dt%dl%d %02d " + "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", + sh->host_no, sd->bus, sd->target, sd->lun, + sd->devtype, + sd->scsi3addr[0], sd->scsi3addr[1], + sd->scsi3addr[2], sd->scsi3addr[3], + sd->scsi3addr[4], sd->scsi3addr[5], + sd->scsi3addr[6], sd->scsi3addr[7]); + } + return 0; +} /* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci dma mapping and fills in the scatter gather entries of the diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 3f087133a25..3b9e8ebcb96 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -296,7 +296,7 @@ static int ida_proc_show(struct seq_file *m, void *v) static int ida_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ida_proc_show, PDE(inode)->data); + return single_open(file, ida_proc_show, PDE_DATA(inode)); } static const struct file_operations ida_proc_fops = { diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index 56672a61eb9..928adb815b0 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -314,7 +314,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) static int drbd_proc_open(struct inode *inode, struct file *file) { if (try_module_get(THIS_MODULE)) - return single_open(file, drbd_seq_show, PDE(inode)->data); + return single_open(file, drbd_seq_show, PDE_DATA(inode)); return -ENODEV; } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index dfe758382ea..b2955b3f2cb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -230,9 +230,11 @@ static int __do_lo_send_write(struct file *file, ssize_t bw; mm_segment_t old_fs = get_fs(); + file_start_write(file); set_fs(get_ds()); bw = file->f_op->write(file, buf, len, &pos); set_fs(old_fs); + file_end_write(file); if (likely(bw == len)) return 0; printk(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n", diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 2e7de7a59bf..e0588c6dd86 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2648,7 +2648,7 @@ static int pkt_seq_show(struct seq_file *m, void *p) static int pkt_seq_open(struct inode *inode, struct file *file) { - return single_open(file, pkt_seq_show, PDE(inode)->data); + return single_open(file, pkt_seq_show, PDE_DATA(inode)); } static const struct file_operations pkt_proc_fops = { diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 75e112d6600..06a2e53e5f3 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -525,7 +525,7 @@ static int ps3vram_proc_show(struct seq_file *m, void *v) static int ps3vram_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ps3vram_proc_show, PDE(inode)->data); + return single_open(file, ps3vram_proc_show, PDE_DATA(inode)); } static const struct file_operations ps3vram_proc_fops = { diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 24ffd8cec51..544b4ce617f 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -6,6 +6,7 @@ #include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/capability.h> #include <linux/init.h> #include <linux/mutex.h> @@ -329,9 +330,7 @@ ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } #ifdef THERM_USE_PROC -static int -proc_therm_ds1620_read(char *buf, char **start, off_t offset, - int len, int *eof, void *unused) +static int ds1620_proc_therm_show(struct seq_file *m, void *v) { struct therm th; int temp; @@ -339,17 +338,25 @@ proc_therm_ds1620_read(char *buf, char **start, off_t offset, ds1620_read_state(&th); temp = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9)); - len = sprintf(buf, "Thermostat: HI %i.%i, LOW %i.%i; " - "temperature: %i.%i C, fan %s\n", - th.hi >> 1, th.hi & 1 ? 5 : 0, - th.lo >> 1, th.lo & 1 ? 5 : 0, - temp >> 1, temp & 1 ? 5 : 0, - fan_state[netwinder_get_fan()]); + seq_printf(m, "Thermostat: HI %i.%i, LOW %i.%i; temperature: %i.%i C, fan %s\n", + th.hi >> 1, th.hi & 1 ? 5 : 0, + th.lo >> 1, th.lo & 1 ? 5 : 0, + temp >> 1, temp & 1 ? 5 : 0, + fan_state[netwinder_get_fan()]); + return 0; +} - return len; +static int ds1620_proc_therm_open(struct inode *inode, struct file *file) +{ + return single_open(file, ds1620_proc_therm_show, NULL); } -static struct proc_dir_entry *proc_therm_ds1620; +static const struct file_operations ds1620_proc_therm_fops = { + .open = ds1620_proc_therm_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif static const struct file_operations ds1620_fops = { @@ -397,10 +404,7 @@ static int __init ds1620_init(void) return ret; #ifdef THERM_USE_PROC - proc_therm_ds1620 = create_proc_entry("therm", 0, NULL); - if (proc_therm_ds1620) - proc_therm_ds1620->read_proc = proc_therm_ds1620_read; - else + if (!proc_create("therm", 0, NULL, &ds1620_proc_therm_fops)) printk(KERN_ERR "therm: unable to register /proc/therm\n"); #endif diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index a082d00b0f1..ea54a6e3f5a 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c @@ -34,6 +34,7 @@ #include <linux/init.h> #include <linux/rtc.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/efi.h> #include <linux/uaccess.h> @@ -296,12 +297,10 @@ static struct miscdevice efi_rtc_dev= { /* * We export RAW EFI information to /proc/driver/efirtc */ -static int -efi_rtc_get_status(char *buf) +static int efi_rtc_proc_show(struct seq_file *m, void *v) { efi_time_t eft, alm; efi_time_cap_t cap; - char *p = buf; efi_bool_t enabled, pending; unsigned long flags; @@ -316,64 +315,63 @@ efi_rtc_get_status(char *buf) spin_unlock_irqrestore(&efi_rtc_lock,flags); - p += sprintf(p, - "Time : %u:%u:%u.%09u\n" - "Date : %u-%u-%u\n" - "Daylight : %u\n", - eft.hour, eft.minute, eft.second, eft.nanosecond, - eft.year, eft.month, eft.day, - eft.daylight); + seq_printf(m, + "Time : %u:%u:%u.%09u\n" + "Date : %u-%u-%u\n" + "Daylight : %u\n", + eft.hour, eft.minute, eft.second, eft.nanosecond, + eft.year, eft.month, eft.day, + eft.daylight); if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) - p += sprintf(p, "Timezone : unspecified\n"); + seq_puts(m, "Timezone : unspecified\n"); else /* XXX fixme: convert to string? */ - p += sprintf(p, "Timezone : %u\n", eft.timezone); + seq_printf(m, "Timezone : %u\n", eft.timezone); - p += sprintf(p, - "Alarm Time : %u:%u:%u.%09u\n" - "Alarm Date : %u-%u-%u\n" - "Alarm Daylight : %u\n" - "Enabled : %s\n" - "Pending : %s\n", - alm.hour, alm.minute, alm.second, alm.nanosecond, - alm.year, alm.month, alm.day, - alm.daylight, - enabled == 1 ? "yes" : "no", - pending == 1 ? "yes" : "no"); + seq_printf(m, + "Alarm Time : %u:%u:%u.%09u\n" + "Alarm Date : %u-%u-%u\n" + "Alarm Daylight : %u\n" + "Enabled : %s\n" + "Pending : %s\n", + alm.hour, alm.minute, alm.second, alm.nanosecond, + alm.year, alm.month, alm.day, + alm.daylight, + enabled == 1 ? "yes" : "no", + pending == 1 ? "yes" : "no"); if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) - p += sprintf(p, "Timezone : unspecified\n"); + seq_puts(m, "Timezone : unspecified\n"); else /* XXX fixme: convert to string? */ - p += sprintf(p, "Timezone : %u\n", alm.timezone); + seq_printf(m, "Timezone : %u\n", alm.timezone); /* * now prints the capabilities */ - p += sprintf(p, - "Resolution : %u\n" - "Accuracy : %u\n" - "SetstoZero : %u\n", - cap.resolution, cap.accuracy, cap.sets_to_zero); + seq_printf(m, + "Resolution : %u\n" + "Accuracy : %u\n" + "SetstoZero : %u\n", + cap.resolution, cap.accuracy, cap.sets_to_zero); - return p - buf; + return 0; } -static int -efi_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int efi_rtc_proc_open(struct inode *inode, struct file *file) { - int len = efi_rtc_get_status(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; + return single_open(file, efi_rtc_proc_show, NULL); } +static const struct file_operations efi_rtc_proc_fops = { + .open = efi_rtc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int __init efi_rtc_init(void) { @@ -389,8 +387,7 @@ efi_rtc_init(void) return ret; } - dir = create_proc_read_entry ("driver/efirtc", 0, NULL, - efi_rtc_read_proc, NULL); + dir = proc_create("driver/efirtc", 0, NULL, &efi_rtc_proc_fops); if (dir == NULL) { printk(KERN_ERR "efirtc: can't create /proc/driver/efirtc.\n"); misc_deregister(&efi_rtc_dev); diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 21cb980f115..bc9b84d56ee 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c @@ -52,6 +52,7 @@ #include <linux/init.h> #include <linux/poll.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/workqueue.h> @@ -386,18 +387,15 @@ static int gen_rtc_release(struct inode *inode, struct file *file) * Info exported via "/proc/driver/rtc". */ -static int gen_rtc_proc_output(char *buf) +static int gen_rtc_proc_show(struct seq_file *m, void *v) { - char *p; struct rtc_time tm; unsigned int flags; struct rtc_pll_info pll; - p = buf; - flags = get_rtc_time(&tm); - p += sprintf(p, + seq_printf(m, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" "rtc_epoch\t: %04u\n", @@ -406,23 +404,23 @@ static int gen_rtc_proc_output(char *buf) tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - p += sprintf(p, "alarm\t\t: "); + seq_puts(m, "alarm\t\t: "); if (tm.tm_hour <= 24) - p += sprintf(p, "%02d:", tm.tm_hour); + seq_printf(m, "%02d:", tm.tm_hour); else - p += sprintf(p, "**:"); + seq_puts(m, "**:"); if (tm.tm_min <= 59) - p += sprintf(p, "%02d:", tm.tm_min); + seq_printf(m, "%02d:", tm.tm_min); else - p += sprintf(p, "**:"); + seq_puts(m, "**:"); if (tm.tm_sec <= 59) - p += sprintf(p, "%02d\n", tm.tm_sec); + seq_printf(m, "%02d\n", tm.tm_sec); else - p += sprintf(p, "**\n"); + seq_puts(m, "**\n"); - p += sprintf(p, + seq_printf(m, "DST_enable\t: %s\n" "BCD\t\t: %s\n" "24hr\t\t: %s\n" @@ -442,7 +440,7 @@ static int gen_rtc_proc_output(char *buf) 0L /* freq */, (flags & RTC_BATT_BAD) ? "bad" : "okay"); if (!get_rtc_pll(&pll)) - p += sprintf(p, + seq_printf(m, "PLL adjustment\t: %d\n" "PLL max +ve adjustment\t: %d\n" "PLL max -ve adjustment\t: %d\n" @@ -455,26 +453,26 @@ static int gen_rtc_proc_output(char *buf) pll.pll_posmult, pll.pll_negmult, pll.pll_clock); - return p - buf; + return 0; } -static int gen_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int gen_rtc_proc_open(struct inode *inode, struct file *file) { - int len = gen_rtc_proc_output (page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; + return single_open(file, gen_rtc_proc_show, NULL); } +static const struct file_operations gen_rtc_proc_fops = { + .open = gen_rtc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int __init gen_rtc_proc_init(void) { struct proc_dir_entry *r; - r = create_proc_read_entry("driver/rtc", 0, NULL, gen_rtc_read_proc, NULL); + r = proc_create("driver/rtc", 0, NULL, &gen_rtc_proc_fops); if (!r) return -ENOMEM; return 0; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 053201b062a..4d439d2fcfd 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1917,7 +1917,7 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v) static int smi_ipmb_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_ipmb_proc_show, PDE(inode)->data); + return single_open(file, smi_ipmb_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_ipmb_proc_ops = { @@ -1938,7 +1938,7 @@ static int smi_version_proc_show(struct seq_file *m, void *v) static int smi_version_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_version_proc_show, PDE(inode)->data); + return single_open(file, smi_version_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_version_proc_ops = { @@ -2013,7 +2013,7 @@ static int smi_stats_proc_show(struct seq_file *m, void *v) static int smi_stats_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_stats_proc_show, PDE(inode)->data); + return single_open(file, smi_stats_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_stats_proc_ops = { @@ -4541,7 +4541,7 @@ static void __exit cleanup_ipmi(void) del_timer_sync(&ipmi_timer); #ifdef CONFIG_PROC_FS - remove_proc_entry(proc_ipmi_root->name, NULL); + proc_remove(proc_ipmi_root); #endif /* CONFIG_PROC_FS */ driver_unregister(&ipmidriver.driver); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 0ac9b45a585..313538abe63 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2839,7 +2839,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v) static int smi_type_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_type_proc_show, PDE(inode)->data); + return single_open(file, smi_type_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_type_proc_ops = { @@ -2882,7 +2882,7 @@ static int smi_si_stats_proc_show(struct seq_file *m, void *v) static int smi_si_stats_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_si_stats_proc_show, PDE(inode)->data); + return single_open(file, smi_si_stats_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_si_stats_proc_ops = { @@ -2910,7 +2910,7 @@ static int smi_params_proc_show(struct seq_file *m, void *v) static int smi_params_proc_open(struct inode *inode, struct file *file) { - return single_open(file, smi_params_proc_show, PDE(inode)->data); + return single_open(file, smi_params_proc_show, PDE_DATA(inode)); } static const struct file_operations smi_params_proc_ops = { diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 67615d6d038..202d2c85ba2 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -1,6 +1,7 @@ #include <linux/efi.h> #include <linux/module.h> #include <linux/pstore.h> +#include <linux/slab.h> #include <linux/ucs2_string.h> #define DUMP_NAME_LEN 52 diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 5e94897244c..b623c599e57 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -67,6 +67,7 @@ #include <linux/efi.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/ucs2_string.h> #define EFIVARS_VERSION "0.08" diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index ff5456b7df7..d7f2324b4fb 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c @@ -49,7 +49,7 @@ /** * Proc file list. */ -static struct drm_info_list drm_proc_list[] = { +static const struct drm_info_list drm_proc_list[] = { {"name", drm_name_info, 0}, {"vm", drm_vm_info, 0}, {"clients", drm_clients_info, 0}, @@ -63,7 +63,7 @@ static struct drm_info_list drm_proc_list[] = { static int drm_proc_open(struct inode *inode, struct file *file) { - struct drm_info_node* node = PDE(inode)->data; + struct drm_info_node* node = PDE_DATA(inode); return single_open(file, node->info_ent->show, node); } @@ -89,13 +89,13 @@ static const struct file_operations drm_proc_fops = { * Create a given set of proc files represented by an array of * gdm_proc_lists in the given root directory. */ -static int drm_proc_create_files(struct drm_info_list *files, int count, +static int drm_proc_create_files(const struct drm_info_list *files, int count, struct proc_dir_entry *root, struct drm_minor *minor) { struct drm_device *dev = minor->dev; struct proc_dir_entry *ent; struct drm_info_node *tmp; - int i, ret; + int i; for (i = 0; i < count; i++) { u32 features = files[i].driver_features; @@ -105,10 +105,9 @@ static int drm_proc_create_files(struct drm_info_list *files, int count, continue; tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); - if (tmp == NULL) { - ret = -1; - goto fail; - } + if (!tmp) + return -1; + tmp->minor = minor; tmp->info_ent = &files[i]; list_add(&tmp->list, &minor->proc_nodes.list); @@ -116,28 +115,20 @@ static int drm_proc_create_files(struct drm_info_list *files, int count, ent = proc_create_data(files[i].name, S_IRUGO, root, &drm_proc_fops, tmp); if (!ent) { - DRM_ERROR("Cannot create /proc/dri/%s/%s\n", - root->name, files[i].name); + DRM_ERROR("Cannot create /proc/dri/%u/%s\n", + minor->index, files[i].name); list_del(&tmp->list); kfree(tmp); - ret = -1; - goto fail; + return -1; } - } return 0; - -fail: - for (i = 0; i < count; i++) - remove_proc_entry(drm_proc_list[i].name, minor->proc_root); - return ret; } /** * Initialize the DRI proc filesystem for a device * * \param dev DRM device - * \param minor device minor number * \param root DRI proc dir entry. * \param dev_root resulting DRI device proc dir entry. * \return root entry pointer on success, or NULL on failure. @@ -146,14 +137,13 @@ fail: * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -int drm_proc_init(struct drm_minor *minor, int minor_id, - struct proc_dir_entry *root) +int drm_proc_init(struct drm_minor *minor, struct proc_dir_entry *root) { - char name[64]; + char name[12]; int ret; INIT_LIST_HEAD(&minor->proc_nodes.list); - sprintf(name, "%d", minor_id); + sprintf(name, "%u", minor->index); minor->proc_root = proc_mkdir(name, root); if (!minor->proc_root) { DRM_ERROR("Cannot create /proc/dri/%s\n", name); @@ -163,7 +153,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES, minor->proc_root, minor); if (ret) { - remove_proc_entry(name, root); + remove_proc_subtree(name, root); minor->proc_root = NULL; DRM_ERROR("Failed to create core drm proc files\n"); return ret; @@ -172,7 +162,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, return 0; } -static int drm_proc_remove_files(struct drm_info_list *files, int count, +static int drm_proc_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor) { struct list_head *pos, *q; @@ -213,8 +203,7 @@ int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); sprintf(name, "%d", minor->index); - remove_proc_entry(name, root); - + remove_proc_subtree(name, root); return 0; } diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 7d30802a018..16f3ec579b3 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -352,7 +352,7 @@ int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) idr_replace(&drm_minors_idr, new_minor, minor_id); if (type == DRM_MINOR_LEGACY) { - ret = drm_proc_init(new_minor, minor_id, drm_proc_root); + ret = drm_proc_init(new_minor, drm_proc_root); if (ret) { DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); goto err_mem; diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 8126824dacc..b2311392638 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1408,7 +1408,7 @@ static int idecd_capacity_proc_show(struct seq_file *m, void *v) static int idecd_capacity_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idecd_capacity_proc_show, PDE(inode)->data); + return single_open(file, idecd_capacity_proc_show, PDE_DATA(inode)); } static const struct file_operations idecd_capacity_proc_fops = { diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index 8b570a17bcd..0d1fae6cba6 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c @@ -53,7 +53,7 @@ static int idedisk_cache_proc_show(struct seq_file *m, void *v) static int idedisk_cache_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idedisk_cache_proc_show, PDE(inode)->data); + return single_open(file, idedisk_cache_proc_show, PDE_DATA(inode)); } static const struct file_operations idedisk_cache_proc_fops = { @@ -74,7 +74,7 @@ static int idedisk_capacity_proc_show(struct seq_file *m, void *v) static int idedisk_capacity_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idedisk_capacity_proc_show, PDE(inode)->data); + return single_open(file, idedisk_capacity_proc_show, PDE_DATA(inode)); } static const struct file_operations idedisk_capacity_proc_fops = { @@ -115,7 +115,7 @@ static int idedisk_sv_proc_show(struct seq_file *m, void *v) static int idedisk_sv_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idedisk_sv_proc_show, PDE(inode)->data); + return single_open(file, idedisk_sv_proc_show, PDE_DATA(inode)); } static const struct file_operations idedisk_sv_proc_fops = { @@ -133,7 +133,7 @@ static int idedisk_st_proc_show(struct seq_file *m, void *v) static int idedisk_st_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idedisk_st_proc_show, PDE(inode)->data); + return single_open(file, idedisk_st_proc_show, PDE_DATA(inode)); } static const struct file_operations idedisk_st_proc_fops = { diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c index 1600720f3e8..e7a25ea757d 100644 --- a/drivers/ide/ide-floppy_proc.c +++ b/drivers/ide/ide-floppy_proc.c @@ -15,7 +15,7 @@ static int idefloppy_capacity_proc_show(struct seq_file *m, void *v) static int idefloppy_capacity_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idefloppy_capacity_proc_show, PDE(inode)->data); + return single_open(file, idefloppy_capacity_proc_show, PDE_DATA(inode)); } static const struct file_operations idefloppy_capacity_proc_fops = { diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 2abcc4790f1..97c07007777 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -58,7 +58,7 @@ static int ide_imodel_proc_show(struct seq_file *m, void *v) static int ide_imodel_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_imodel_proc_show, PDE(inode)->data); + return single_open(file, ide_imodel_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_imodel_proc_fops = { @@ -82,7 +82,7 @@ static int ide_mate_proc_show(struct seq_file *m, void *v) static int ide_mate_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_mate_proc_show, PDE(inode)->data); + return single_open(file, ide_mate_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_mate_proc_fops = { @@ -103,7 +103,7 @@ static int ide_channel_proc_show(struct seq_file *m, void *v) static int ide_channel_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_channel_proc_show, PDE(inode)->data); + return single_open(file, ide_channel_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_channel_proc_fops = { @@ -143,7 +143,7 @@ static int ide_identify_proc_show(struct seq_file *m, void *v) static int ide_identify_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_identify_proc_show, PDE(inode)->data); + return single_open(file, ide_identify_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_identify_proc_fops = { @@ -325,7 +325,7 @@ static int ide_settings_proc_show(struct seq_file *m, void *v) static int ide_settings_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_settings_proc_show, PDE(inode)->data); + return single_open(file, ide_settings_proc_show, PDE_DATA(inode)); } #define MAX_LEN 30 @@ -333,7 +333,7 @@ static int ide_settings_proc_open(struct inode *inode, struct file *file) static ssize_t ide_settings_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - ide_drive_t *drive = (ide_drive_t *) PDE(file_inode(file))->data; + ide_drive_t *drive = PDE_DATA(file_inode(file)); char name[MAX_LEN + 1]; int for_real = 0, mul_factor, div_factor; unsigned long n; @@ -474,7 +474,7 @@ static int ide_geometry_proc_show(struct seq_file *m, void *v) static int ide_geometry_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_geometry_proc_show, PDE(inode)->data); + return single_open(file, ide_geometry_proc_show, PDE_DATA(inode)); } const struct file_operations ide_geometry_proc_fops = { @@ -497,7 +497,7 @@ static int ide_dmodel_proc_show(struct seq_file *seq, void *v) static int ide_dmodel_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_dmodel_proc_show, PDE(inode)->data); + return single_open(file, ide_dmodel_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_dmodel_proc_fops = { @@ -525,7 +525,7 @@ static int ide_driver_proc_show(struct seq_file *m, void *v) static int ide_driver_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_driver_proc_show, PDE(inode)->data); + return single_open(file, ide_driver_proc_show, PDE_DATA(inode)); } static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) @@ -558,7 +558,7 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) static ssize_t ide_driver_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - ide_drive_t *drive = (ide_drive_t *) PDE(file_inode(file))->data; + ide_drive_t *drive = PDE_DATA(file_inode(file)); char name[32]; if (!capable(CAP_SYS_ADMIN)) @@ -601,7 +601,7 @@ static int ide_media_proc_show(struct seq_file *m, void *v) static int ide_media_proc_open(struct inode *inode, struct file *file) { - return single_open(file, ide_media_proc_show, PDE(inode)->data); + return single_open(file, ide_media_proc_show, PDE_DATA(inode)); } static const struct file_operations ide_media_proc_fops = { diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ce8237d3615..89f859591bb 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1847,7 +1847,7 @@ static int idetape_name_proc_show(struct seq_file *m, void *v) static int idetape_name_proc_open(struct inode *inode, struct file *file) { - return single_open(file, idetape_name_proc_show, PDE(inode)->data); + return single_open(file, idetape_name_proc_show, PDE_DATA(inode)); } static const struct file_operations idetape_name_proc_fops = { diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 2e3334b8f82..770479df865 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -41,6 +41,7 @@ #include <linux/time.h> #include <linux/miscdevice.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/poll.h> #include <linux/rtc.h> #include <linux/mutex.h> @@ -74,9 +75,6 @@ static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); static int hp_sdc_rtc_open(struct inode *inode, struct file *file); static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on); -static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - static void hp_sdc_rtc_isr (int irq, void *dev_id, uint8_t status, uint8_t data) { @@ -427,22 +425,19 @@ static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on) return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue); } -static int hp_sdc_rtc_proc_output (char *buf) +static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) { #define YN(bit) ("no") #define NY(bit) ("yes") - char *p; struct rtc_time tm; struct timeval tv; memset(&tm, 0, sizeof(struct rtc_time)); - p = buf; - if (hp_sdc_rtc_read_bbrtc(&tm)) { - p += sprintf(p, "BBRTC\t\t: READ FAILED!\n"); + seq_puts(m, "BBRTC\t\t: READ FAILED!\n"); } else { - p += sprintf(p, + seq_printf(m, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" "rtc_epoch\t: %04lu\n", @@ -452,41 +447,41 @@ static int hp_sdc_rtc_proc_output (char *buf) } if (hp_sdc_rtc_read_rt(&tv)) { - p += sprintf(p, "i8042 rtc\t: READ FAILED!\n"); + seq_puts(m, "i8042 rtc\t: READ FAILED!\n"); } else { - p += sprintf(p, "i8042 rtc\t: %ld.%02d seconds\n", + seq_printf(m, "i8042 rtc\t: %ld.%02d seconds\n", tv.tv_sec, (int)tv.tv_usec/1000); } if (hp_sdc_rtc_read_fhs(&tv)) { - p += sprintf(p, "handshake\t: READ FAILED!\n"); + seq_puts(m, "handshake\t: READ FAILED!\n"); } else { - p += sprintf(p, "handshake\t: %ld.%02d seconds\n", + seq_printf(m, "handshake\t: %ld.%02d seconds\n", tv.tv_sec, (int)tv.tv_usec/1000); } if (hp_sdc_rtc_read_mt(&tv)) { - p += sprintf(p, "alarm\t\t: READ FAILED!\n"); + seq_puts(m, "alarm\t\t: READ FAILED!\n"); } else { - p += sprintf(p, "alarm\t\t: %ld.%02d seconds\n", + seq_printf(m, "alarm\t\t: %ld.%02d seconds\n", tv.tv_sec, (int)tv.tv_usec/1000); } if (hp_sdc_rtc_read_dt(&tv)) { - p += sprintf(p, "delay\t\t: READ FAILED!\n"); + seq_puts(m, "delay\t\t: READ FAILED!\n"); } else { - p += sprintf(p, "delay\t\t: %ld.%02d seconds\n", + seq_printf(m, "delay\t\t: %ld.%02d seconds\n", tv.tv_sec, (int)tv.tv_usec/1000); } if (hp_sdc_rtc_read_ct(&tv)) { - p += sprintf(p, "periodic\t: READ FAILED!\n"); + seq_puts(m, "periodic\t: READ FAILED!\n"); } else { - p += sprintf(p, "periodic\t: %ld.%02d seconds\n", + seq_printf(m, "periodic\t: %ld.%02d seconds\n", tv.tv_sec, (int)tv.tv_usec/1000); } - p += sprintf(p, + seq_printf(m, "DST_enable\t: %s\n" "BCD\t\t: %s\n" "24hr\t\t: %s\n" @@ -506,23 +501,23 @@ static int hp_sdc_rtc_proc_output (char *buf) 1UL, 1 ? "okay" : "dead"); - return p - buf; + return 0; #undef YN #undef NY } -static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int hp_sdc_rtc_proc_open(struct inode *inode, struct file *file) { - int len = hp_sdc_rtc_proc_output (page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; + return single_open(file, hp_sdc_rtc_proc_show, NULL); } +static const struct file_operations hp_sdc_rtc_proc_fops = { + .open = hp_sdc_rtc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int hp_sdc_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -715,8 +710,7 @@ static int __init hp_sdc_rtc_init(void) if (misc_register(&hp_sdc_rtc_dev) != 0) printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n"); - create_proc_read_entry ("driver/rtc", 0, NULL, - hp_sdc_rtc_read_proc, NULL); + proc_create("driver/rtc", 0, NULL, &hp_sdc_rtc_proc_fops); printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " "(RTC v " RTC_VERSION ")\n"); diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 03a0a01a405..3286903a95d 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -2334,7 +2334,7 @@ static int gigaset_proc_show(struct seq_file *m, void *v) static int gigaset_proc_open(struct inode *inode, struct file *file) { - return single_open(file, gigaset_proc_show, PDE(inode)->data); + return single_open(file, gigaset_proc_show, PDE_DATA(inode)); } static const struct file_operations gigaset_proc_fops = { diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index 821f7ac33b3..4d9b195547c 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c @@ -702,7 +702,7 @@ static int b1ctl_proc_show(struct seq_file *m, void *v) static int b1ctl_proc_open(struct inode *inode, struct file *file) { - return single_open(file, b1ctl_proc_show, PDE(inode)->data); + return single_open(file, b1ctl_proc_show, PDE_DATA(inode)); } const struct file_operations b1ctl_proc_fops = { diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index 0896aa86fc0..19b113faeb7 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c @@ -944,7 +944,7 @@ static int b1dmactl_proc_show(struct seq_file *m, void *v) static int b1dmactl_proc_open(struct inode *inode, struct file *file) { - return single_open(file, b1dmactl_proc_show, PDE(inode)->data); + return single_open(file, b1dmactl_proc_show, PDE_DATA(inode)); } const struct file_operations b1dmactl_proc_fops = { diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 1d7fc44e3ee..5d00d72fe48 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c @@ -1129,7 +1129,7 @@ static int c4_proc_show(struct seq_file *m, void *v) static int c4_proc_open(struct inode *inode, struct file *file) { - return single_open(file, c4_proc_show, PDE(inode)->data); + return single_open(file, c4_proc_show, PDE_DATA(inode)); } static const struct file_operations c4_proc_fops = { diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c index 3a4165c6119..56ce98a4e24 100644 --- a/drivers/isdn/hardware/eicon/divasproc.c +++ b/drivers/isdn/hardware/eicon/divasproc.c @@ -145,7 +145,7 @@ void remove_divas_proc(void) static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; if ((count == 1) || (count == 2)) { @@ -172,7 +172,7 @@ static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer, static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; if ((count == 1) || (count == 2)) { @@ -210,7 +210,7 @@ static int d_l1_down_proc_show(struct seq_file *m, void *v) static int d_l1_down_proc_open(struct inode *inode, struct file *file) { - return single_open(file, d_l1_down_proc_show, PDE(inode)->data); + return single_open(file, d_l1_down_proc_show, PDE_DATA(inode)); } static const struct file_operations d_l1_down_proc_fops = { @@ -236,7 +236,7 @@ static int grp_opt_proc_show(struct seq_file *m, void *v) static int grp_opt_proc_open(struct inode *inode, struct file *file) { - return single_open(file, grp_opt_proc_show, PDE(inode)->data); + return single_open(file, grp_opt_proc_show, PDE_DATA(inode)); } static const struct file_operations grp_opt_proc_fops = { @@ -251,7 +251,7 @@ static const struct file_operations grp_opt_proc_fops = { static ssize_t info_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; char c[4]; @@ -335,7 +335,7 @@ static int info_proc_show(struct seq_file *m, void *v) static int info_proc_open(struct inode *inode, struct file *file) { - return single_open(file, info_proc_show, PDE(inode)->data); + return single_open(file, info_proc_show, PDE_DATA(inode)); } static const struct file_operations info_proc_fops = { diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 931f916c9c2..00aad10507d 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -469,7 +469,7 @@ static int hycapi_proc_show(struct seq_file *m, void *v) static int hycapi_proc_open(struct inode *inode, struct file *file) { - return single_open(file, hycapi_proc_show, PDE(inode)->data); + return single_open(file, hycapi_proc_show, PDE_DATA(inode)); } static const struct file_operations hycapi_proc_fops = { diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 8023d2510fb..73079213ec9 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -229,23 +229,12 @@ static int hysdn_conf_open(struct inode *ino, struct file *filep) { hysdn_card *card; - struct proc_dir_entry *pd; struct conf_writedata *cnf; char *cp, *tmp; /* now search the addressed card */ mutex_lock(&hysdn_conf_mutex); - card = card_root; - while (card) { - pd = card->procconf; - if (pd == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - mutex_unlock(&hysdn_conf_mutex); - return (-ENODEV); /* device is unknown/invalid */ - } + card = PDE_DATA(ino); if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x", filep->f_cred->fsuid, filep->f_cred->fsgid, @@ -317,21 +306,9 @@ hysdn_conf_close(struct inode *ino, struct file *filep) hysdn_card *card; struct conf_writedata *cnf; int retval = 0; - struct proc_dir_entry *pd; mutex_lock(&hysdn_conf_mutex); - /* search the addressed card */ - card = card_root; - while (card) { - pd = card->procconf; - if (pd == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - mutex_unlock(&hysdn_conf_mutex); - return (-ENODEV); /* device is unknown/invalid */ - } + card = PDE_DATA(ino); if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x", filep->f_cred->fsuid, filep->f_cred->fsgid, @@ -394,10 +371,11 @@ hysdn_procconf_init(void) while (card) { sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid); - if ((card->procconf = (void *) proc_create(conf_name, + if ((card->procconf = (void *) proc_create_data(conf_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry, - &conf_fops)) != NULL) { + &conf_fops, + card)) != NULL) { hysdn_proclog_init(card); /* init the log file entry */ } card = card->next; /* next entry */ diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 9a3ce93665c..b61e8d5e84a 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -173,27 +173,14 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off) { struct log_data *inf; int len; - struct proc_dir_entry *pde = PDE(file_inode(file)); - struct procdata *pd = NULL; - hysdn_card *card; + hysdn_card *card = PDE_DATA(file_inode(file)); if (!*((struct log_data **) file->private_data)) { + struct procdata *pd = card->proclog; if (file->f_flags & O_NONBLOCK) return (-EAGAIN); - /* sorry, but we need to search the card */ - card = card_root; - while (card) { - pd = card->proclog; - if (pd->log == pde) - break; - card = card->next; /* search next entry */ - } - if (card) - interruptible_sleep_on(&(pd->rd_queue)); - else - return (-EAGAIN); - + interruptible_sleep_on(&(pd->rd_queue)); } if (!(inf = *((struct log_data **) file->private_data))) return (0); @@ -215,27 +202,15 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off) static int hysdn_log_open(struct inode *ino, struct file *filep) { - hysdn_card *card; - struct procdata *pd = NULL; - unsigned long flags; + hysdn_card *card = PDE_DATA(ino); mutex_lock(&hysdn_log_mutex); - card = card_root; - while (card) { - pd = card->proclog; - if (pd->log == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - mutex_unlock(&hysdn_log_mutex); - return (-ENODEV); /* device is unknown/invalid */ - } - filep->private_data = card; /* remember our own card */ - if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> write log level only */ + filep->private_data = card; /* remember our own card */ } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { + struct procdata *pd = card->proclog; + unsigned long flags; /* read access -> log/debug read */ spin_lock_irqsave(&card->hysdn_lock, flags); @@ -275,21 +250,13 @@ hysdn_log_close(struct inode *ino, struct file *filep) } else { /* read access -> log/debug read, mark one further file as closed */ - pd = NULL; inf = *((struct log_data **) filep->private_data); /* get first log entry */ if (inf) pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ else { /* no info available -> search card */ - card = card_root; - while (card) { - pd = card->proclog; - if (pd->log == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (card) - pd = card->proclog; /* pointer to procfs log */ + card = PDE_DATA(file_inode(filep)); + pd = card->proclog; /* pointer to procfs log */ } if (pd) pd->if_used--; /* decrement interface usage count by one */ @@ -319,24 +286,12 @@ static unsigned int hysdn_log_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; - struct proc_dir_entry *pde = PDE(file_inode(file)); - hysdn_card *card; - struct procdata *pd = NULL; + hysdn_card *card = PDE_DATA(file_inode(file)); + struct procdata *pd = card->proclog; if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) return (mask); /* no polling for write supported */ - /* we need to search the card */ - card = card_root; - while (card) { - pd = card->proclog; - if (pd->log == pde) - break; - card = card->next; /* search next entry */ - } - if (!card) - return (mask); /* card not found */ - poll_wait(file, &(pd->rd_queue), wait); if (*((struct log_data **) file->private_data)) @@ -373,9 +328,9 @@ hysdn_proclog_init(hysdn_card *card) if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid); - pd->log = proc_create(pd->log_name, + pd->log = proc_create_data(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry, - &log_fops); + &log_fops, card); init_waitqueue_head(&(pd->rd_queue)); diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 1094667d8f3..9438d7ec330 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -64,7 +64,6 @@ mISDN_open(struct inode *ino, struct file *filep) dev->work = 0; init_waitqueue_head(&dev->wait); filep->private_data = dev; - __module_get(THIS_MODULE); return nonseekable_open(ino, filep); } @@ -72,19 +71,28 @@ static int mISDN_close(struct inode *ino, struct file *filep) { struct mISDNtimerdev *dev = filep->private_data; + struct list_head *list = &dev->pending; struct mISDNtimer *timer, *next; if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep); - list_for_each_entry_safe(timer, next, &dev->pending, list) { - del_timer(&timer->tl); + + spin_lock_irq(&dev->lock); + while (!list_empty(list)) { + timer = list_first_entry(list, struct mISDNtimer, list); + spin_unlock_irq(&dev->lock); + del_timer_sync(&timer->tl); + spin_lock_irq(&dev->lock); + /* it might have been moved to ->expired */ + list_del(&timer->list); kfree(timer); } + spin_unlock_irq(&dev->lock); + list_for_each_entry_safe(timer, next, &dev->expired, list) { kfree(timer); } kfree(dev); - module_put(THIS_MODULE); return 0; } @@ -92,36 +100,41 @@ static ssize_t mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off) { struct mISDNtimerdev *dev = filep->private_data; + struct list_head *list = &dev->expired; struct mISDNtimer *timer; - u_long flags; int ret = 0; if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__, filep, buf, (int)count, off); - if (list_empty(&dev->expired) && (dev->work == 0)) { + if (count < sizeof(int)) + return -ENOSPC; + + spin_lock_irq(&dev->lock); + while (list_empty(list) && (dev->work == 0)) { + spin_unlock_irq(&dev->lock); if (filep->f_flags & O_NONBLOCK) return -EAGAIN; wait_event_interruptible(dev->wait, (dev->work || - !list_empty(&dev->expired))); + !list_empty(list))); if (signal_pending(current)) return -ERESTARTSYS; + spin_lock_irq(&dev->lock); } - if (count < sizeof(int)) - return -ENOSPC; if (dev->work) dev->work = 0; - if (!list_empty(&dev->expired)) { - spin_lock_irqsave(&dev->lock, flags); - timer = (struct mISDNtimer *)dev->expired.next; + if (!list_empty(list)) { + timer = list_first_entry(list, struct mISDNtimer, list); list_del(&timer->list); - spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock_irq(&dev->lock); if (put_user(timer->id, (int __user *)buf)) ret = -EFAULT; else ret = sizeof(int); kfree(timer); + } else { + spin_unlock_irq(&dev->lock); } return ret; } @@ -153,7 +166,8 @@ dev_expire_timer(unsigned long data) u_long flags; spin_lock_irqsave(&timer->dev->lock, flags); - list_move_tail(&timer->list, &timer->dev->expired); + if (timer->id >= 0) + list_move_tail(&timer->list, &timer->dev->expired); spin_unlock_irqrestore(&timer->dev->lock, flags); wake_up_interruptible(&timer->dev->wait); } @@ -162,7 +176,6 @@ static int misdn_add_timer(struct mISDNtimerdev *dev, int timeout) { int id; - u_long flags; struct mISDNtimer *timer; if (!timeout) { @@ -173,19 +186,16 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL); if (!timer) return -ENOMEM; - spin_lock_irqsave(&dev->lock, flags); - timer->id = dev->next_id++; + timer->dev = dev; + setup_timer(&timer->tl, dev_expire_timer, (long)timer); + spin_lock_irq(&dev->lock); + id = timer->id = dev->next_id++; if (dev->next_id < 0) dev->next_id = 1; list_add_tail(&timer->list, &dev->pending); - spin_unlock_irqrestore(&dev->lock, flags); - timer->dev = dev; - timer->tl.data = (long)timer; - timer->tl.function = dev_expire_timer; - init_timer(&timer->tl); timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000); add_timer(&timer->tl); - id = timer->id; + spin_unlock_irq(&dev->lock); } return id; } @@ -193,26 +203,21 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) static int misdn_del_timer(struct mISDNtimerdev *dev, int id) { - u_long flags; struct mISDNtimer *timer; - int ret = 0; - spin_lock_irqsave(&dev->lock, flags); + spin_lock_irq(&dev->lock); list_for_each_entry(timer, &dev->pending, list) { if (timer->id == id) { list_del_init(&timer->list); - /* RED-PEN AK: race -- timer can be still running on - * other CPU. Needs reference count I think - */ - del_timer(&timer->tl); - ret = timer->id; + timer->id = -1; + spin_unlock_irq(&dev->lock); + del_timer_sync(&timer->tl); kfree(timer); - goto unlock; + return id; } } -unlock: - spin_unlock_irqrestore(&dev->lock, flags); - return ret; + spin_unlock_irq(&dev->lock); + return 0; } static long @@ -262,6 +267,7 @@ mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } static const struct file_operations mISDN_fops = { + .owner = THIS_MODULE, .read = mISDN_read, .poll = mISDN_poll, .unlocked_ioctl = mISDN_ioctl, diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 22b8ce4191c..c31fbab6aa8 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -869,7 +869,7 @@ static int pmu_battery_proc_show(struct seq_file *m, void *v) static int pmu_battery_proc_open(struct inode *inode, struct file *file) { - return single_open(file, pmu_battery_proc_show, PDE(inode)->data); + return single_open(file, pmu_battery_proc_show, PDE_DATA(inode)); } static const struct file_operations pmu_battery_proc_fops = { diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 57601c0704c..1f925e85697 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2527,11 +2527,8 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) if (dvbdev->users == -1) { wake_up(&fepriv->wait_queue); - if (fepriv->exit != DVB_FE_NO_EXIT) { - fops_put(file->f_op); - file->f_op = NULL; + if (fepriv->exit != DVB_FE_NO_EXIT) wake_up(&dvbdev->wait_queue); - } if (fe->ops.ts_bus_ctrl) fe->ops.ts_bus_ctrl(fe, 0); } diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index c3cc3b52662..f91c80c0e9e 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -1479,11 +1479,8 @@ static int dvb_net_close(struct inode *inode, struct file *file) dvb_generic_release(inode, file); - if(dvbdev->users == 1 && dvbnet->exit == 1) { - fops_put(file->f_op); - file->f_op = NULL; + if(dvbdev->users == 1 && dvbnet->exit == 1) wake_up(&dvbdev->wait_queue); - } return 0; } diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c index b9be535e32b..68dbc2dbc98 100644 --- a/drivers/media/pci/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c @@ -259,79 +259,46 @@ void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev) static int cx25821_get_audio_data(struct cx25821_dev *dev, const struct sram_channel *sram_ch) { - struct file *myfile; + struct file *file; int frame_index_temp = dev->_audioframe_index; int i = 0; - int line_size = AUDIO_LINE_SIZE; int frame_size = AUDIO_DATA_BUF_SZ; int frame_offset = frame_size * frame_index_temp; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; + char mybuf[AUDIO_LINE_SIZE]; loff_t file_offset = dev->_audioframe_count * frame_size; - loff_t pos; - mm_segment_t old_fs; + char *p = NULL; if (dev->_audiofile_status == END_OF_FILE) return 0; - myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); + file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(file)) { + pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n", + __func__, dev->_audiofilename, -PTR_ERR(file)); + return PTR_ERR(file); + } - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_audiofilename, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } + if (dev->_audiodata_buf_virt_addr) + p = (char *)dev->_audiodata_buf_virt_addr + frame_offset; - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered!\n", + for (i = 0; i < dev->_audio_lines_count; i++) { + int n = kernel_read(file, file_offset, mybuf, AUDIO_LINE_SIZE); + if (n < AUDIO_LINE_SIZE) { + pr_info("Done: exit %s() since no more bytes to read from Audio file\n", __func__); - filp_close(myfile, NULL); - return -EIO; + dev->_audiofile_status = END_OF_FILE; + fput(file); + return 0; } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (i = 0; i < dev->_audio_lines_count; i++) { - pos = file_offset; - - vfs_read_retval = vfs_read(myfile, mybuf, line_size, - &pos); - - if (vfs_read_retval > 0 && vfs_read_retval == line_size - && dev->_audiodata_buf_virt_addr != NULL) { - memcpy((void *)(dev->_audiodata_buf_virt_addr + - frame_offset / 4), mybuf, - vfs_read_retval); - } - - file_offset += vfs_read_retval; - frame_offset += vfs_read_retval; - - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Audio file\n", - __func__); - break; - } + dev->_audiofile_status = IN_PROGRESS; + if (p) { + memcpy(p, mybuf, n); + p += n; } - - if (i > 0) - dev->_audioframe_count++; - - dev->_audiofile_status = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - filp_close(myfile, NULL); + file_offset += n; } + dev->_audioframe_count++; + fput(file); return 0; } @@ -354,81 +321,41 @@ static void cx25821_audioups_handler(struct work_struct *work) static int cx25821_openfile_audio(struct cx25821_dev *dev, const struct sram_channel *sram_ch) { - struct file *myfile; - int i = 0, j = 0; - int line_size = AUDIO_LINE_SIZE; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; - loff_t pos; - loff_t offset = (unsigned long)0; - mm_segment_t old_fs; - - myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); - - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_audiofilename, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (j = 0; j < NUM_AUDIO_FRAMES; j++) { - for (i = 0; i < dev->_audio_lines_count; i++) { - pos = offset; - - vfs_read_retval = vfs_read(myfile, mybuf, - line_size, &pos); - - if (vfs_read_retval > 0 && - vfs_read_retval == line_size && - dev->_audiodata_buf_virt_addr != NULL) { - memcpy((void *)(dev-> - _audiodata_buf_virt_addr - + offset / 4), mybuf, - vfs_read_retval); - } + char *p = (void *)dev->_audiodata_buf_virt_addr; + struct file *file; + loff_t offset; + int i, j; + + file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(file)) { + pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n", + __func__, dev->_audiofilename, PTR_ERR(file)); + return PTR_ERR(file); + } - offset += vfs_read_retval; + for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) { + for (i = 0; i < dev->_audio_lines_count; i++) { + char buf[AUDIO_LINE_SIZE]; + int n = kernel_read(file, offset, buf, + AUDIO_LINE_SIZE); - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Audio file\n", - __func__); - break; - } + if (n < AUDIO_LINE_SIZE) { + pr_info("Done: exit %s() since no more bytes to read from Audio file\n", + __func__); + dev->_audiofile_status = END_OF_FILE; + fput(file); + return 0; } - if (i > 0) - dev->_audioframe_count++; + if (p) + memcpy(p + offset, buf, n); - if (vfs_read_retval < line_size) - break; + offset += n; } - - dev->_audiofile_status = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - myfile->f_pos = 0; - filp_close(myfile, NULL); + dev->_audioframe_count++; } - + dev->_audiofile_status = IN_PROGRESS; + fput(file); return 0; } diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c index eb822862a64..0e763a784e2 100644 --- a/drivers/media/pci/ttpci/av7110_ir.c +++ b/drivers/media/pci/ttpci/av7110_ir.c @@ -375,7 +375,7 @@ int av7110_ir_init(struct av7110 *av7110) if (av_cnt == 1) { e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops); if (e) - e->size = 4 + 256 * sizeof(u16); + proc_set_size(e, 4 + 256 * sizeof(u16)); } tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); diff --git a/drivers/media/pci/zoran/zoran_procfs.c b/drivers/media/pci/zoran/zoran_procfs.c index 1512b5d4053..f7ceee0cdef 100644 --- a/drivers/media/pci/zoran/zoran_procfs.c +++ b/drivers/media/pci/zoran/zoran_procfs.c @@ -130,14 +130,14 @@ static int zoran_show(struct seq_file *p, void *v) static int zoran_open(struct inode *inode, struct file *file) { - struct zoran *data = PDE(inode)->data; + struct zoran *data = PDE_DATA(inode); return single_open(file, zoran_show, data); } static ssize_t zoran_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct zoran *zr = PDE(file_inode(file))->data; + struct zoran *zr = PDE_DATA(file_inode(file)); char *string, *sp; char *line, *ldelim, *varname, *svar, *tdelim; diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index ff4d93d1907..e4561264e12 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -307,7 +307,7 @@ static void ir_lirc_close(void *data) return; } -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .write = ir_lirc_transmit_ir, .unlocked_ioctl = ir_lirc_ioctl, diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 5247d94fea2..8dc057b273f 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -152,7 +152,7 @@ static int lirc_thread(void *irctl) } -static struct file_operations lirc_dev_fops = { +static const struct file_operations lirc_dev_fops = { .owner = THIS_MODULE, .read = lirc_dev_fop_read, .write = lirc_dev_fop_write, diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index fb69baa06ca..767ff4d839f 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -6656,7 +6656,7 @@ static int mpt_summary_proc_show(struct seq_file *m, void *v) static int mpt_summary_proc_open(struct inode *inode, struct file *file) { - return single_open(file, mpt_summary_proc_show, PDE(inode)->data); + return single_open(file, mpt_summary_proc_show, PDE_DATA(inode)); } static const struct file_operations mpt_summary_proc_fops = { @@ -6805,7 +6805,7 @@ static int mpt_iocinfo_proc_show(struct seq_file *m, void *v) static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file) { - return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data); + return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode)); } static const struct file_operations mpt_iocinfo_proc_fops = { diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b383b6961e5..dcc8385adeb 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -597,13 +597,6 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) } static int -mptctl_release(struct inode *inode, struct file *filep) -{ - fasync_helper(-1, filep, 0, &async_queue); - return 0; -} - -static int mptctl_fasync(int fd, struct file *filep, int mode) { MPT_ADAPTER *ioc; @@ -2822,7 +2815,6 @@ static const struct file_operations mptctl_fops = { .llseek = no_llseek, .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, - .release = mptctl_release, #ifdef CONFIG_COMPAT .compat_ioctl = compat_mpctl_ioctl, #endif diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index c13cd9bc590..fd75108c355 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -109,7 +109,7 @@ static int mptfc_host_reset(struct scsi_cmnd *SCpnt); static struct scsi_host_template mptfc_driver_template = { .module = THIS_MODULE, .proc_name = "mptfc", - .proc_info = mptscsih_proc_info, + .show_info = mptscsih_show_info, .name = "MPT FC Host", .info = mptscsih_info, .queuecommand = mptfc_qcmd, diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index fa43c391c8e..ffee6f781e3 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1977,7 +1977,7 @@ done: static struct scsi_host_template mptsas_driver_template = { .module = THIS_MODULE, .proc_name = "mptsas", - .proc_info = mptscsih_proc_info, + .show_info = mptscsih_show_info, .name = "MPT SAS Host", .info = mptscsih_info, .queuecommand = mptsas_qcmd, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 164afa71bba..727819cc703 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1284,101 +1284,17 @@ mptscsih_info(struct Scsi_Host *SChost) return h->info_kbuf; } -struct info_str { - char *buffer; - int length; - int offset; - int pos; -}; - -static void -mptscsih_copy_mem_info(struct info_str *info, char *data, int len) -{ - if (info->pos + len > info->length) - len = info->length - info->pos; - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - data += (info->offset - info->pos); - len -= (info->offset - info->pos); - } - - if (len > 0) { - memcpy(info->buffer + info->pos, data, len); - info->pos += len; - } -} - -static int -mptscsih_copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[81]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - mptscsih_copy_mem_info(info, buf, len); - return len; -} - -static int -mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len) -{ - struct info_str info; - - info.buffer = pbuf; - info.length = len; - info.offset = offset; - info.pos = 0; - - mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name); - mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word); - mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts); - mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth); - - return ((info.pos > info.offset) ? info.pos - info.offset : 0); -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mptscsih_proc_info - Return information about MPT adapter - * @host: scsi host struct - * @buffer: if write, user data; if read, buffer for user - * @start: returns the buffer address - * @offset: if write, 0; if read, the current offset into the buffer from - * the previous read. - * @length: if write, return length; - * @func: write = 1; read = 0 - * - * (linux scsi_host_template.info routine) - */ -int -mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int func) +int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host) { MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; - int size = 0; - if (func) { - /* - * write is not supported - */ - } else { - if (start) - *start = buffer; - - size = mptscsih_host_info(ioc, buffer, offset, length); - } + seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name); + seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word); + seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts); + seq_printf(m, "MaxQ=%d\n", ioc->req_depth); - return size; + return 0; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -3348,7 +3264,7 @@ EXPORT_SYMBOL(mptscsih_shutdown); EXPORT_SYMBOL(mptscsih_suspend); EXPORT_SYMBOL(mptscsih_resume); #endif -EXPORT_SYMBOL(mptscsih_proc_info); +EXPORT_SYMBOL(mptscsih_show_info); EXPORT_SYMBOL(mptscsih_info); EXPORT_SYMBOL(mptscsih_qcmd); EXPORT_SYMBOL(mptscsih_slave_destroy); diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 43e75ff3992..83f503162f7 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -111,7 +111,7 @@ extern void mptscsih_shutdown(struct pci_dev *); extern int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); extern int mptscsih_resume(struct pci_dev *pdev); #endif -extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); +extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *); extern const char * mptscsih_info(struct Scsi_Host *SChost); extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index c3aabde2dc4..5653e505f91 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -831,7 +831,7 @@ static void mptspi_slave_destroy(struct scsi_device *sdev) static struct scsi_host_template mptspi_driver_template = { .module = THIS_MODULE, .proc_name = "mptspi", - .proc_info = mptscsih_proc_info, + .show_info = mptscsih_show_info, .name = "MPT SPI Host", .info = mptscsih_info, .queuecommand = mptspi_qcmd, diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 8001aa6bfb4..b7d87cd227a 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c @@ -1599,98 +1599,98 @@ static int i2o_seq_show_sensors(struct seq_file *seq, void *v) static int i2o_seq_open_hrt(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_hrt, PDE(inode)->data); + return single_open(file, i2o_seq_show_hrt, PDE_DATA(inode)); }; static int i2o_seq_open_lct(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_lct, PDE(inode)->data); + return single_open(file, i2o_seq_show_lct, PDE_DATA(inode)); }; static int i2o_seq_open_status(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_status, PDE(inode)->data); + return single_open(file, i2o_seq_show_status, PDE_DATA(inode)); }; static int i2o_seq_open_hw(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_hw, PDE(inode)->data); + return single_open(file, i2o_seq_show_hw, PDE_DATA(inode)); }; static int i2o_seq_open_ddm_table(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_ddm_table, PDE(inode)->data); + return single_open(file, i2o_seq_show_ddm_table, PDE_DATA(inode)); }; static int i2o_seq_open_driver_store(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_driver_store, PDE(inode)->data); + return single_open(file, i2o_seq_show_driver_store, PDE_DATA(inode)); }; static int i2o_seq_open_drivers_stored(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_drivers_stored, PDE(inode)->data); + return single_open(file, i2o_seq_show_drivers_stored, PDE_DATA(inode)); }; static int i2o_seq_open_groups(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_groups, PDE(inode)->data); + return single_open(file, i2o_seq_show_groups, PDE_DATA(inode)); }; static int i2o_seq_open_phys_device(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_phys_device, PDE(inode)->data); + return single_open(file, i2o_seq_show_phys_device, PDE_DATA(inode)); }; static int i2o_seq_open_claimed(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_claimed, PDE(inode)->data); + return single_open(file, i2o_seq_show_claimed, PDE_DATA(inode)); }; static int i2o_seq_open_users(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_users, PDE(inode)->data); + return single_open(file, i2o_seq_show_users, PDE_DATA(inode)); }; static int i2o_seq_open_priv_msgs(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_priv_msgs, PDE(inode)->data); + return single_open(file, i2o_seq_show_priv_msgs, PDE_DATA(inode)); }; static int i2o_seq_open_authorized_users(struct inode *inode, struct file *file) { return single_open(file, i2o_seq_show_authorized_users, - PDE(inode)->data); + PDE_DATA(inode)); }; static int i2o_seq_open_dev_identity(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_dev_identity, PDE(inode)->data); + return single_open(file, i2o_seq_show_dev_identity, PDE_DATA(inode)); }; static int i2o_seq_open_ddm_identity(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_ddm_identity, PDE(inode)->data); + return single_open(file, i2o_seq_show_ddm_identity, PDE_DATA(inode)); }; static int i2o_seq_open_uinfo(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_uinfo, PDE(inode)->data); + return single_open(file, i2o_seq_show_uinfo, PDE_DATA(inode)); }; static int i2o_seq_open_sgl_limits(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_sgl_limits, PDE(inode)->data); + return single_open(file, i2o_seq_show_sgl_limits, PDE_DATA(inode)); }; static int i2o_seq_open_sensors(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_sensors, PDE(inode)->data); + return single_open(file, i2o_seq_show_sensors, PDE_DATA(inode)); }; static int i2o_seq_open_dev_name(struct inode *inode, struct file *file) { - return single_open(file, i2o_seq_show_dev_name, PDE(inode)->data); + return single_open(file, i2o_seq_show_dev_name, PDE_DATA(inode)); }; static const struct file_operations i2o_seq_fops_lct = { @@ -1895,25 +1895,6 @@ static int i2o_proc_create_entries(struct proc_dir_entry *dir, } /** - * i2o_proc_subdir_remove - Remove child entries from a proc entry - * @dir: proc dir entry from which the childs should be removed - * - * Iterate over each i2o proc entry under dir and remove it. If the child - * also has entries, remove them too. - */ -static void i2o_proc_subdir_remove(struct proc_dir_entry *dir) -{ - struct proc_dir_entry *pe, *tmp; - pe = dir->subdir; - while (pe) { - tmp = pe->next; - i2o_proc_subdir_remove(pe); - remove_proc_entry(pe->name, dir); - pe = tmp; - } -}; - -/** * i2o_proc_device_add - Add an I2O device to the proc dir * @dir: proc dir entry to which the device should be added * @dev: I2O device which should be added @@ -1932,14 +1913,12 @@ static void i2o_proc_device_add(struct proc_dir_entry *dir, osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff); - devdir = proc_mkdir(buff, dir); + devdir = proc_mkdir_data(buff, 0, dir, dev); if (!devdir) { osm_warn("Could not allocate procdir!\n"); return; } - devdir->data = dev; - i2o_proc_create_entries(devdir, generic_dev_entries, dev); /* Inform core that we want updates about this device's status */ @@ -1973,12 +1952,10 @@ static int i2o_proc_iop_add(struct proc_dir_entry *dir, osm_debug("adding IOP /proc/i2o/%s\n", c->name); - iopdir = proc_mkdir(c->name, dir); + iopdir = proc_mkdir_data(c->name, 0, dir, c); if (!iopdir) return -1; - iopdir->data = c; - i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c); list_for_each_entry(dev, &c->devices, list) @@ -1988,31 +1965,6 @@ static int i2o_proc_iop_add(struct proc_dir_entry *dir, } /** - * i2o_proc_iop_remove - Removes an I2O controller from the i2o proc tree - * @dir: parent proc dir entry - * @c: I2O controller which should be removed - * - * Iterate over each i2o proc entry and search controller c. If it is found - * remove it from the tree. - */ -static void i2o_proc_iop_remove(struct proc_dir_entry *dir, - struct i2o_controller *c) -{ - struct proc_dir_entry *pe, *tmp; - - pe = dir->subdir; - while (pe) { - tmp = pe->next; - if (pe->data == c) { - i2o_proc_subdir_remove(pe); - remove_proc_entry(pe->name, dir); - } - osm_debug("removing IOP /proc/i2o/%s\n", c->name); - pe = tmp; - } -} - -/** * i2o_proc_fs_create - Create the i2o proc fs. * * Iterate over each I2O controller and create the entries for it. @@ -2042,12 +1994,7 @@ static int __init i2o_proc_fs_create(void) */ static int __exit i2o_proc_fs_destroy(void) { - struct i2o_controller *c; - - list_for_each_entry(c, &i2o_controllers, list) - i2o_proc_iop_remove(i2o_proc_dir_root, c); - - remove_proc_entry("i2o", NULL); + remove_proc_subtree("i2o", NULL); return 0; }; diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 4a87e5c0a32..4cd4a3d2a76 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -593,7 +593,6 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file) struct lis3lv02d *lis3 = container_of(file->private_data, struct lis3lv02d, miscdev); - fasync_helper(-1, file, 0, &lis3->async_queue); clear_bit(0, &lis3->misc_opened); /* release the device */ if (lis3->pm_dev) pm_runtime_put(lis3->pm_dev); diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c index 950dbe9ecb3..797d7962cc8 100644 --- a/drivers/misc/sgi-gru/gruprocfs.c +++ b/drivers/misc/sgi-gru/gruprocfs.c @@ -355,7 +355,7 @@ static void delete_proc_files(void) for (p = proc_files; p->name; p++) if (p->entry) remove_proc_entry(p->name, proc_gru); - remove_proc_entry("gru", proc_gru->parent); + proc_remove(proc_gru); } } diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 61d5f56473e..322ca65b0cc 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -36,6 +36,7 @@ #include <linux/idr.h> #include <linux/backing-dev.h> #include <linux/gfp.h> +#include <linux/slab.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index 3cea38d3734..94d06f1307b 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -218,15 +218,13 @@ static const struct seq_operations bond_info_seq_ops = { static int bond_info_open(struct inode *inode, struct file *file) { struct seq_file *seq; - struct proc_dir_entry *proc; int res; res = seq_open(file, &bond_info_seq_ops); if (!res) { /* recover the pointer buried in proc_dir_entry data */ seq = file->private_data; - proc = PDE(inode); - seq->private = proc->data; + seq->private = PDE_DATA(inode); } return res; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 2f99f8881df..5f4758492e4 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -383,7 +383,7 @@ static int vlsi_seq_show(struct seq_file *seq, void *v) static int vlsi_seq_open(struct inode *inode, struct file *file) { - return single_open(file, vlsi_seq_show, PDE(inode)->data); + return single_open(file, vlsi_seq_show, PDE_DATA(inode)); } static const struct file_operations vlsi_proc_fops = { @@ -1678,7 +1678,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) IRDA_WARNING("%s: failed to create proc entry\n", __func__); } else { - ent->size = 0; + proc_set_size(ent, 0); } idev->proc_entry = ent; } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 53295418f57..6125adb520a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -4506,108 +4506,75 @@ static int setup_proc_entry( struct net_device *dev, apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, airo_entry); if (!apriv->proc_entry) - goto fail; - apriv->proc_entry->uid = proc_kuid; - apriv->proc_entry->gid = proc_kgid; + return -ENOMEM; + proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid); /* Setup the StatsDelta */ entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev); if (!entry) - goto fail_stats_delta; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the Stats */ entry = proc_create_data("Stats", S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev); if (!entry) - goto fail_stats; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the Status */ entry = proc_create_data("Status", S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev); if (!entry) - goto fail_status; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the Config */ entry = proc_create_data("Config", proc_perm, apriv->proc_entry, &proc_config_ops, dev); if (!entry) - goto fail_config; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the SSID */ entry = proc_create_data("SSID", proc_perm, apriv->proc_entry, &proc_SSID_ops, dev); if (!entry) - goto fail_ssid; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the APList */ entry = proc_create_data("APList", proc_perm, apriv->proc_entry, &proc_APList_ops, dev); if (!entry) - goto fail_aplist; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the BSSList */ entry = proc_create_data("BSSList", proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev); if (!entry) - goto fail_bsslist; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); /* Setup the WepKey */ entry = proc_create_data("WepKey", proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev); if (!entry) - goto fail_wepkey; - entry->uid = proc_kuid; - entry->gid = proc_kgid; - + goto fail; + proc_set_user(entry, proc_kuid, proc_kgid); return 0; -fail_wepkey: - remove_proc_entry("BSSList", apriv->proc_entry); -fail_bsslist: - remove_proc_entry("APList", apriv->proc_entry); -fail_aplist: - remove_proc_entry("SSID", apriv->proc_entry); -fail_ssid: - remove_proc_entry("Config", apriv->proc_entry); -fail_config: - remove_proc_entry("Status", apriv->proc_entry); -fail_status: - remove_proc_entry("Stats", apriv->proc_entry); -fail_stats: - remove_proc_entry("StatsDelta", apriv->proc_entry); -fail_stats_delta: - remove_proc_entry(apriv->proc_name, airo_entry); fail: + remove_proc_subtree(apriv->proc_name, airo_entry); return -ENOMEM; } static int takedown_proc_entry( struct net_device *dev, - struct airo_info *apriv ) { - if ( !apriv->proc_entry->namelen ) return 0; - remove_proc_entry("Stats",apriv->proc_entry); - remove_proc_entry("StatsDelta",apriv->proc_entry); - remove_proc_entry("Status",apriv->proc_entry); - remove_proc_entry("Config",apriv->proc_entry); - remove_proc_entry("SSID",apriv->proc_entry); - remove_proc_entry("APList",apriv->proc_entry); - remove_proc_entry("BSSList",apriv->proc_entry); - remove_proc_entry("WepKey",apriv->proc_entry); - remove_proc_entry(apriv->proc_name,airo_entry); + struct airo_info *apriv ) +{ + remove_proc_subtree(apriv->proc_name, airo_entry); return 0; } @@ -4663,8 +4630,7 @@ static ssize_t proc_write( struct file *file, static int proc_status_open(struct inode *inode, struct file *file) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *apriv = dev->ml_priv; CapabilityRid cap_rid; StatusRid status_rid; @@ -4746,8 +4712,7 @@ static int proc_stats_rid_open( struct inode *inode, u16 rid ) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *apriv = dev->ml_priv; StatsRid stats; int i, j; @@ -4809,8 +4774,7 @@ static inline int sniffing_mode(struct airo_info *ai) static void proc_config_on_close(struct inode *inode, struct file *file) { struct proc_data *data = file->private_data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; char *line; @@ -5021,8 +4985,7 @@ static const char *get_rmode(__le16 mode) static int proc_config_open(struct inode *inode, struct file *file) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; int i; __le16 mode; @@ -5112,8 +5075,7 @@ static int proc_config_open(struct inode *inode, struct file *file) static void proc_SSID_on_close(struct inode *inode, struct file *file) { struct proc_data *data = file->private_data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; SsidRid SSID_rid; int i; @@ -5148,8 +5110,7 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file) static void proc_APList_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = file->private_data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; APListRid APList_rid; int i; @@ -5283,8 +5244,7 @@ static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock) static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; int i, rc; char key[16]; @@ -5335,8 +5295,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { static int proc_wepkey_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; char *ptr; WepKeyRid wkr; @@ -5384,8 +5343,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) static int proc_SSID_open(struct inode *inode, struct file *file) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; int i; char *ptr; @@ -5428,8 +5386,7 @@ static int proc_SSID_open(struct inode *inode, struct file *file) static int proc_APList_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; int i; char *ptr; @@ -5468,8 +5425,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { static int proc_BSSList_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = PDE(inode); - struct net_device *dev = dp->data; + struct net_device *dev = PDE_DATA(inode); struct airo_info *ai = dev->ml_priv; char *ptr; BSSListRid BSSList_rid; @@ -5706,10 +5662,8 @@ static int __init airo_init_module( void ) airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); - if (airo_entry) { - airo_entry->uid = proc_kuid; - airo_entry->gid = proc_kgid; - } + if (airo_entry) + proc_set_user(airo_entry, proc_kuid, proc_kgid); for (i = 0; i < 4 && io[i] && irq[i]; i++) { airo_print_info("", "Trying to configure ISA adapter at irq=%d " diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 4be07f5e22b..727b1f53e6a 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -216,7 +216,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, wil_debugfs_iomem_x32_set, "0x%08llx\n"); static struct dentry *wil_debugfs_create_iomem_x32(const char *name, - mode_t mode, + umode_t mode, struct dentry *parent, void __iomem *value) { @@ -359,7 +359,7 @@ static const struct file_operations fops_ioblob = { static struct dentry *wil_debugfs_create_ioblob(const char *name, - mode_t mode, + umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob) { diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 4374079dfc2..23a3498f14d 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -63,6 +63,7 @@ #include <net/iw_handler.h> #include <linux/crc32.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/device.h> #include <linux/moduleparam.h> #include <linux/firmware.h> @@ -1409,30 +1410,28 @@ static int atmel_validate_channel(struct atmel_private *priv, int channel) return 0; } -static int atmel_proc_output (char *buf, struct atmel_private *priv) +static int atmel_proc_show(struct seq_file *m, void *v) { + struct atmel_private *priv = m->private; int i; - char *p = buf; char *s, *r, *c; - p += sprintf(p, "Driver version:\t\t%d.%d\n", - DRIVER_MAJOR, DRIVER_MINOR); + seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR); if (priv->station_state != STATION_STATE_DOWN) { - p += sprintf(p, "Firmware version:\t%d.%d build %d\n" - "Firmware location:\t", - priv->host_info.major_version, - priv->host_info.minor_version, - priv->host_info.build_version); + seq_printf(m, + "Firmware version:\t%d.%d build %d\n" + "Firmware location:\t", + priv->host_info.major_version, + priv->host_info.minor_version, + priv->host_info.build_version); if (priv->card_type != CARD_TYPE_EEPROM) - p += sprintf(p, "on card\n"); + seq_puts(m, "on card\n"); else if (priv->firmware) - p += sprintf(p, "%s loaded by host\n", - priv->firmware_id); + seq_printf(m, "%s loaded by host\n", priv->firmware_id); else - p += sprintf(p, "%s loaded by hotplug\n", - priv->firmware_id); + seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id); switch (priv->card_type) { case CARD_TYPE_PARALLEL_FLASH: @@ -1453,12 +1452,12 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv) if (priv->reg_domain == channel_table[i].reg_domain) r = channel_table[i].name; - p += sprintf(p, "MAC memory type:\t%s\n", c); - p += sprintf(p, "Regulatory domain:\t%s\n", r); - p += sprintf(p, "Host CRC checking:\t%s\n", - priv->do_rx_crc ? "On" : "Off"); - p += sprintf(p, "WPA-capable firmware:\t%s\n", - priv->use_wpa ? "Yes" : "No"); + seq_printf(m, "MAC memory type:\t%s\n", c); + seq_printf(m, "Regulatory domain:\t%s\n", r); + seq_printf(m, "Host CRC checking:\t%s\n", + priv->do_rx_crc ? "On" : "Off"); + seq_printf(m, "WPA-capable firmware:\t%s\n", + priv->use_wpa ? "Yes" : "No"); } switch (priv->station_state) { @@ -1490,26 +1489,22 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv) s = "<unknown>"; } - p += sprintf(p, "Current state:\t\t%s\n", s); - return p - buf; + seq_printf(m, "Current state:\t\t%s\n", s); + return 0; } -static int atmel_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int atmel_proc_open(struct inode *inode, struct file *file) { - struct atmel_private *priv = data; - int len = atmel_proc_output (page, priv); - if (len <= off+count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; + return single_open(file, atmel_proc_show, PDE_DATA(inode)); } +static const struct file_operations atmel_proc_fops = { + .open = atmel_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static const struct net_device_ops atmel_netdev_ops = { .ndo_open = atmel_open, .ndo_stop = atmel_close, @@ -1525,7 +1520,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, struct device *sys_dev, int (*card_present)(void *), void *card) { - struct proc_dir_entry *ent; struct net_device *dev; struct atmel_private *priv; int rc; @@ -1630,8 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, netif_carrier_off(dev); - ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv); - if (!ent) + if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv)); printk(KERN_WARNING "atmel: unable to create /proc entry.\n"); printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n", diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index dd9a18f8dbc..19c45e363aa 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -17,6 +17,7 @@ */ #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/delay.h> #include <linux/random.h> #include <linux/if_arp.h> @@ -64,28 +65,32 @@ static void prism2_send_mgmt(struct net_device *dev, #ifndef PRISM2_NO_PROCFS_DEBUG -static int ap_debug_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ap_data *ap = (struct ap_data *) data; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast); - p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast); - p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ); - p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets); - p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack); - p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds); - p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs); - p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc); +static int ap_debug_proc_show(struct seq_file *m, void *v) +{ + struct ap_data *ap = m->private; + + seq_printf(m, "BridgedUnicastFrames=%u\n", ap->bridged_unicast); + seq_printf(m, "BridgedMulticastFrames=%u\n", ap->bridged_multicast); + seq_printf(m, "max_inactivity=%u\n", ap->max_inactivity / HZ); + seq_printf(m, "bridge_packets=%u\n", ap->bridge_packets); + seq_printf(m, "nullfunc_ack=%u\n", ap->nullfunc_ack); + seq_printf(m, "autom_ap_wds=%u\n", ap->autom_ap_wds); + seq_printf(m, "auth_algs=%u\n", ap->local->auth_algs); + seq_printf(m, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc); + return 0; +} - return (p - page); +static int ap_debug_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ap_debug_proc_show, PDE_DATA(inode)); } + +static const struct file_operations ap_debug_proc_fops = { + .open = ap_debug_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* PRISM2_NO_PROCFS_DEBUG */ @@ -325,50 +330,81 @@ void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap, } -static int ap_control_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int ap_control_proc_show(struct seq_file *m, void *v) { - char *p = page; - struct ap_data *ap = (struct ap_data *) data; + struct ap_data *ap = m->private; char *policy_txt; struct mac_entry *entry; - if (off != 0) { - *eof = 1; + if (v == SEQ_START_TOKEN) { + switch (ap->mac_restrictions.policy) { + case MAC_POLICY_OPEN: + policy_txt = "open"; + break; + case MAC_POLICY_ALLOW: + policy_txt = "allow"; + break; + case MAC_POLICY_DENY: + policy_txt = "deny"; + break; + default: + policy_txt = "unknown"; + break; + } + seq_printf(m, "MAC policy: %s\n", policy_txt); + seq_printf(m, "MAC entries: %u\n", ap->mac_restrictions.entries); + seq_puts(m, "MAC list:\n"); return 0; } - switch (ap->mac_restrictions.policy) { - case MAC_POLICY_OPEN: - policy_txt = "open"; - break; - case MAC_POLICY_ALLOW: - policy_txt = "allow"; - break; - case MAC_POLICY_DENY: - policy_txt = "deny"; - break; - default: - policy_txt = "unknown"; - break; - } - p += sprintf(p, "MAC policy: %s\n", policy_txt); - p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries); - p += sprintf(p, "MAC list:\n"); + entry = v; + seq_printf(m, "%pM\n", entry->addr); + return 0; +} + +static void *ap_control_proc_start(struct seq_file *m, loff_t *_pos) +{ + struct ap_data *ap = m->private; spin_lock_bh(&ap->mac_restrictions.lock); - list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) { - if (p - page > PAGE_SIZE - 80) { - p += sprintf(p, "All entries did not fit one page.\n"); - break; - } + return seq_list_start_head(&ap->mac_restrictions.mac_list, *_pos); +} - p += sprintf(p, "%pM\n", entry->addr); - } +static void *ap_control_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + struct ap_data *ap = m->private; + return seq_list_next(v, &ap->mac_restrictions.mac_list, _pos); +} + +static void ap_control_proc_stop(struct seq_file *m, void *v) +{ + struct ap_data *ap = m->private; spin_unlock_bh(&ap->mac_restrictions.lock); +} - return (p - page); +static const struct seq_operations ap_control_proc_seqops = { + .start = ap_control_proc_start, + .next = ap_control_proc_next, + .stop = ap_control_proc_stop, + .show = ap_control_proc_show, +}; + +static int ap_control_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &ap_control_proc_seqops); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); + } + return ret; } +static const struct file_operations ap_control_proc_fops = { + .open = ap_control_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac) { @@ -510,61 +546,84 @@ void ap_control_kickall(struct ap_data *ap) #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -#define PROC_LIMIT (PAGE_SIZE - 80) - -static int prism2_ap_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_ap_proc_show(struct seq_file *m, void *v) { - char *p = page; - struct ap_data *ap = (struct ap_data *) data; - struct sta_info *sta; + struct sta_info *sta = v; int i; - if (off > PROC_LIMIT) { - *eof = 1; + if (v == SEQ_START_TOKEN) { + seq_printf(m, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); return 0; } - p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); - spin_lock_bh(&ap->sta_table_lock); - list_for_each_entry(sta, &ap->sta_list, list) { - if (!sta->ap) - continue; + if (!sta->ap) + return 0; - p += sprintf(p, "%pM %d %d %d %d '", - sta->addr, - sta->u.ap.channel, sta->last_rx_signal, - sta->last_rx_silence, sta->last_rx_rate); - for (i = 0; i < sta->u.ap.ssid_len; i++) - p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 && - sta->u.ap.ssid[i] < 127) ? - "%c" : "<%02x>"), - sta->u.ap.ssid[i]); - p += sprintf(p, "'"); - if (sta->capability & WLAN_CAPABILITY_ESS) - p += sprintf(p, " [ESS]"); - if (sta->capability & WLAN_CAPABILITY_IBSS) - p += sprintf(p, " [IBSS]"); - if (sta->capability & WLAN_CAPABILITY_PRIVACY) - p += sprintf(p, " [WEP]"); - p += sprintf(p, "\n"); - - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "hostap: ap proc did not fit\n"); - break; - } - } - spin_unlock_bh(&ap->sta_table_lock); + seq_printf(m, "%pM %d %d %d %d '", + sta->addr, + sta->u.ap.channel, sta->last_rx_signal, + sta->last_rx_silence, sta->last_rx_rate); - if ((p - page) <= off) { - *eof = 1; - return 0; + for (i = 0; i < sta->u.ap.ssid_len; i++) { + if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127) + seq_putc(m, sta->u.ap.ssid[i]); + else + seq_printf(m, "<%02x>", sta->u.ap.ssid[i]); } - *start = page + off; + seq_putc(m, '\''); + if (sta->capability & WLAN_CAPABILITY_ESS) + seq_puts(m, " [ESS]"); + if (sta->capability & WLAN_CAPABILITY_IBSS) + seq_puts(m, " [IBSS]"); + if (sta->capability & WLAN_CAPABILITY_PRIVACY) + seq_puts(m, " [WEP]"); + seq_putc(m, '\n'); + return 0; +} + +static void *prism2_ap_proc_start(struct seq_file *m, loff_t *_pos) +{ + struct ap_data *ap = m->private; + spin_lock_bh(&ap->sta_table_lock); + return seq_list_start_head(&ap->sta_list, *_pos); +} - return (p - page - off); +static void *prism2_ap_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + struct ap_data *ap = m->private; + return seq_list_next(v, &ap->sta_list, _pos); } + +static void prism2_ap_proc_stop(struct seq_file *m, void *v) +{ + struct ap_data *ap = m->private; + spin_unlock_bh(&ap->sta_table_lock); +} + +static const struct seq_operations prism2_ap_proc_seqops = { + .start = prism2_ap_proc_start, + .next = prism2_ap_proc_next, + .stop = prism2_ap_proc_stop, + .show = prism2_ap_proc_show, +}; + +static int prism2_ap_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &prism2_ap_proc_seqops); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); + } + return ret; +} + +static const struct file_operations prism2_ap_proc_fops = { + .open = prism2_ap_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ @@ -836,15 +895,12 @@ void hostap_init_ap_proc(local_info_t *local) return; #ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("ap_debug", 0, ap->proc, - ap_debug_proc_read, ap); + proc_create_data("ap_debug", 0, ap->proc, &ap_debug_proc_fops, ap); #endif /* PRISM2_NO_PROCFS_DEBUG */ #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - create_proc_read_entry("ap_control", 0, ap->proc, - ap_control_proc_read, ap); - create_proc_read_entry("ap", 0, ap->proc, - prism2_ap_proc_read, ap); + proc_create_data("ap_control", 0, ap->proc, &ap_control_proc_fops, ap); + proc_create_data("ap", 0, ap->proc, &prism2_ap_proc_fops, ap); #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ } @@ -982,79 +1038,86 @@ static void prism2_send_mgmt(struct net_device *dev, #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ -static int prism2_sta_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_sta_proc_show(struct seq_file *m, void *v) { - char *p = page; - struct sta_info *sta = (struct sta_info *) data; + struct sta_info *sta = m->private; int i; /* FIX: possible race condition.. the STA data could have just expired, * but proc entry was still here so that the read could have started; * some locking should be done here.. */ - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "%s=%pM\nusers=%d\naid=%d\n" - "flags=0x%04x%s%s%s%s%s%s%s\n" - "capability=0x%02x\nlisten_interval=%d\nsupported_rates=", - sta->ap ? "AP" : "STA", - sta->addr, atomic_read(&sta->users), sta->aid, - sta->flags, - sta->flags & WLAN_STA_AUTH ? " AUTH" : "", - sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "", - sta->flags & WLAN_STA_PS ? " PS" : "", - sta->flags & WLAN_STA_TIM ? " TIM" : "", - sta->flags & WLAN_STA_PERM ? " PERM" : "", - sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "", - sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "", - sta->capability, sta->listen_interval); + seq_printf(m, + "%s=%pM\nusers=%d\naid=%d\n" + "flags=0x%04x%s%s%s%s%s%s%s\n" + "capability=0x%02x\nlisten_interval=%d\nsupported_rates=", + sta->ap ? "AP" : "STA", + sta->addr, atomic_read(&sta->users), sta->aid, + sta->flags, + sta->flags & WLAN_STA_AUTH ? " AUTH" : "", + sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "", + sta->flags & WLAN_STA_PS ? " PS" : "", + sta->flags & WLAN_STA_TIM ? " TIM" : "", + sta->flags & WLAN_STA_PERM ? " PERM" : "", + sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "", + sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "", + sta->capability, sta->listen_interval); /* supported_rates: 500 kbit/s units with msb ignored */ for (i = 0; i < sizeof(sta->supported_rates); i++) if (sta->supported_rates[i] != 0) - p += sprintf(p, "%d%sMbps ", - (sta->supported_rates[i] & 0x7f) / 2, - sta->supported_rates[i] & 1 ? ".5" : ""); - p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n" - "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n" - "tx_packets=%lu\n" - "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n" - "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n" - "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n" - "tx[11M]=%d\n" - "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n", - jiffies, sta->last_auth, sta->last_assoc, sta->last_rx, - sta->last_tx, - sta->rx_packets, sta->tx_packets, sta->rx_bytes, - sta->tx_bytes, skb_queue_len(&sta->tx_buf), - sta->last_rx_silence, - sta->last_rx_signal, sta->last_rx_rate / 10, - sta->last_rx_rate % 10 ? ".5" : "", - sta->tx_rate, sta->tx_count[0], sta->tx_count[1], - sta->tx_count[2], sta->tx_count[3], sta->rx_count[0], - sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]); + seq_printf(m, "%d%sMbps ", + (sta->supported_rates[i] & 0x7f) / 2, + sta->supported_rates[i] & 1 ? ".5" : ""); + seq_printf(m, + "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n" + "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n" + "tx_packets=%lu\n" + "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n" + "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n" + "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n" + "tx[11M]=%d\n" + "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n", + jiffies, sta->last_auth, sta->last_assoc, sta->last_rx, + sta->last_tx, + sta->rx_packets, sta->tx_packets, sta->rx_bytes, + sta->tx_bytes, skb_queue_len(&sta->tx_buf), + sta->last_rx_silence, + sta->last_rx_signal, sta->last_rx_rate / 10, + sta->last_rx_rate % 10 ? ".5" : "", + sta->tx_rate, sta->tx_count[0], sta->tx_count[1], + sta->tx_count[2], sta->tx_count[3], sta->rx_count[0], + sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]); if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats) - p = sta->crypt->ops->print_stats(p, sta->crypt->priv); + sta->crypt->ops->print_stats(m, sta->crypt->priv); #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT if (sta->ap) { if (sta->u.ap.channel >= 0) - p += sprintf(p, "channel=%d\n", sta->u.ap.channel); - p += sprintf(p, "ssid="); - for (i = 0; i < sta->u.ap.ssid_len; i++) - p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 && - sta->u.ap.ssid[i] < 127) ? - "%c" : "<%02x>"), - sta->u.ap.ssid[i]); - p += sprintf(p, "\n"); + seq_printf(m, "channel=%d\n", sta->u.ap.channel); + seq_puts(m, "ssid="); + for (i = 0; i < sta->u.ap.ssid_len; i++) { + if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127) + seq_putc(m, sta->u.ap.ssid[i]); + else + seq_printf(m, "<%02x>", sta->u.ap.ssid[i]); + } + seq_putc(m, '\n'); } #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - return (p - page); + return 0; +} + +static int prism2_sta_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, prism2_sta_proc_show, PDE_DATA(inode)); } +static const struct file_operations prism2_sta_proc_fops = { + .open = prism2_sta_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; static void handle_add_proc_queue(struct work_struct *work) { @@ -1076,9 +1139,9 @@ static void handle_add_proc_queue(struct work_struct *work) if (sta) { sprintf(name, "%pM", sta->addr); - sta->proc = create_proc_read_entry( + sta->proc = proc_create_data( name, 0, ap->proc, - prism2_sta_proc_read, sta); + &prism2_sta_proc_fops, sta); atomic_dec(&sta->users); } diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c index e73bf739fd9..705fe668b96 100644 --- a/drivers/net/wireless/hostap/hostap_download.c +++ b/drivers/net/wireless/hostap/hostap_download.c @@ -174,20 +174,70 @@ static int prism2_pda_ok(u8 *buf) } -static int prism2_download_aux_dump(struct net_device *dev, - unsigned int addr, int len, u8 *buf) -{ - int res; +#define prism2_download_aux_dump_npages 65536 - prism2_enable_aux_port(dev, 1); - res = hfa384x_from_aux(dev, addr, len, buf); - prism2_enable_aux_port(dev, 0); - if (res) - return -1; +struct prism2_download_aux_dump { + local_info_t *local; + u16 page[0x80]; +}; + +static int prism2_download_aux_dump_proc_show(struct seq_file *m, void *v) +{ + struct prism2_download_aux_dump *ctx = m->private; + hfa384x_from_aux(ctx->local->dev, (unsigned long)v - 1, 0x80, ctx->page); + seq_write(m, ctx->page, 0x80); return 0; } +static void *prism2_download_aux_dump_proc_start(struct seq_file *m, loff_t *_pos) +{ + struct prism2_download_aux_dump *ctx = m->private; + prism2_enable_aux_port(ctx->local->dev, 1); + if (*_pos >= prism2_download_aux_dump_npages) + return NULL; + return (void *)((unsigned long)*_pos + 1); +} + +static void *prism2_download_aux_dump_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + ++*_pos; + if (*_pos >= prism2_download_aux_dump_npages) + return NULL; + return (void *)((unsigned long)*_pos + 1); +} + +static void prism2_download_aux_dump_proc_stop(struct seq_file *m, void *v) +{ + struct prism2_download_aux_dump *ctx = m->private; + prism2_enable_aux_port(ctx->local->dev, 0); +} + +static const struct seq_operations prism2_download_aux_dump_proc_seqops = { + .start = prism2_download_aux_dump_proc_start, + .next = prism2_download_aux_dump_proc_next, + .stop = prism2_download_aux_dump_proc_stop, + .show = prism2_download_aux_dump_proc_show, +}; + +static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open_private(file, &prism2_download_aux_dump_proc_seqops, + sizeof(struct prism2_download_aux_dump)); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); + } + return ret; +} + +static const struct file_operations prism2_download_aux_dump_proc_fops = { + .open = prism2_download_aux_dump_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + static u8 * prism2_read_pda(struct net_device *dev) { diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 8e7000fd441..507ab99eef4 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -38,6 +38,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/if_arp.h> #include <linux/delay.h> #include <linux/random.h> @@ -129,8 +130,7 @@ static void prism2_check_sta_fw_version(local_info_t *local); #ifdef PRISM2_DOWNLOAD_SUPPORT /* hostap_download.c */ -static int prism2_download_aux_dump(struct net_device *dev, - unsigned int addr, int len, u8 *buf); +static const struct file_operations prism2_download_aux_dump_proc_fops; static u8 * prism2_read_pda(struct net_device *dev); static int prism2_download(local_info_t *local, struct prism2_download_param *param); @@ -2894,19 +2894,12 @@ static void hostap_tick_timer(unsigned long data) #ifndef PRISM2_NO_PROCFS_DEBUG -static int prism2_registers_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_registers_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; - - if (off != 0) { - *eof = 1; - return 0; - } + local_info_t *local = m->private; #define SHOW_REG(n) \ -p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF)) + seq_printf(m, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF)) SHOW_REG(CMD); SHOW_REG(PARAM0); @@ -2952,8 +2945,21 @@ p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF)) SHOW_REG(PCI_M1_CTL); #endif /* PRISM2_PCI */ - return (p - page); + return 0; } + +static int prism2_registers_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, prism2_registers_proc_show, PDE_DATA(inode)); +} + +static const struct file_operations prism2_registers_proc_fops = { + .open = prism2_registers_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + #endif /* PRISM2_NO_PROCFS_DEBUG */ @@ -3128,7 +3134,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, local->func->reset_port = prism2_reset_port; local->func->schedule_reset = prism2_schedule_reset; #ifdef PRISM2_DOWNLOAD_SUPPORT - local->func->read_aux = prism2_download_aux_dump; + local->func->read_aux_fops = &prism2_download_aux_dump_proc_fops; local->func->download = prism2_download; #endif /* PRISM2_DOWNLOAD_SUPPORT */ local->func->tx = prism2_tx_80211; @@ -3274,8 +3280,8 @@ static int hostap_hw_ready(struct net_device *dev) } hostap_init_proc(local); #ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("registers", 0, local->proc, - prism2_registers_proc_read, local); + proc_create_data("registers", 0, local->proc, + &prism2_registers_proc_fops, local); #endif /* PRISM2_NO_PROCFS_DEBUG */ hostap_init_ap_proc(local); return 0; diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index dc447c1b5ab..7491dab2c10 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c @@ -12,259 +12,297 @@ #ifndef PRISM2_NO_PROCFS_DEBUG -static int prism2_debug_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_debug_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; + local_info_t *local = m->private; int i; - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "next_txfid=%d next_alloc=%d\n", - local->next_txfid, local->next_alloc); + seq_printf(m, "next_txfid=%d next_alloc=%d\n", + local->next_txfid, local->next_alloc); for (i = 0; i < PRISM2_TXFID_COUNT; i++) - p += sprintf(p, "FID: tx=%04X intransmit=%04X\n", - local->txfid[i], local->intransmitfid[i]); - p += sprintf(p, "FW TX rate control: %d\n", local->fw_tx_rate_control); - p += sprintf(p, "beacon_int=%d\n", local->beacon_int); - p += sprintf(p, "dtim_period=%d\n", local->dtim_period); - p += sprintf(p, "wds_max_connections=%d\n", - local->wds_max_connections); - p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled); - p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck); + seq_printf(m, "FID: tx=%04X intransmit=%04X\n", + local->txfid[i], local->intransmitfid[i]); + seq_printf(m, "FW TX rate control: %d\n", local->fw_tx_rate_control); + seq_printf(m, "beacon_int=%d\n", local->beacon_int); + seq_printf(m, "dtim_period=%d\n", local->dtim_period); + seq_printf(m, "wds_max_connections=%d\n", local->wds_max_connections); + seq_printf(m, "dev_enabled=%d\n", local->dev_enabled); + seq_printf(m, "sw_tick_stuck=%d\n", local->sw_tick_stuck); for (i = 0; i < WEP_KEYS; i++) { if (local->crypt_info.crypt[i] && local->crypt_info.crypt[i]->ops) { - p += sprintf(p, "crypt[%d]=%s\n", i, - local->crypt_info.crypt[i]->ops->name); + seq_printf(m, "crypt[%d]=%s\n", i, + local->crypt_info.crypt[i]->ops->name); } } - p += sprintf(p, "pri_only=%d\n", local->pri_only); - p += sprintf(p, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI); - p += sprintf(p, "sram_type=%d\n", local->sram_type); - p += sprintf(p, "no_pri=%d\n", local->no_pri); + seq_printf(m, "pri_only=%d\n", local->pri_only); + seq_printf(m, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI); + seq_printf(m, "sram_type=%d\n", local->sram_type); + seq_printf(m, "no_pri=%d\n", local->no_pri); - return (p - page); + return 0; } + +static int prism2_debug_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, prism2_debug_proc_show, PDE_DATA(inode)); +} + +static const struct file_operations prism2_debug_proc_fops = { + .open = prism2_debug_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* PRISM2_NO_PROCFS_DEBUG */ -static int prism2_stats_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_stats_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; + local_info_t *local = m->private; struct comm_tallies_sums *sums = &local->comm_tallies; - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "TxUnicastFrames=%u\n", sums->tx_unicast_frames); - p += sprintf(p, "TxMulticastframes=%u\n", sums->tx_multicast_frames); - p += sprintf(p, "TxFragments=%u\n", sums->tx_fragments); - p += sprintf(p, "TxUnicastOctets=%u\n", sums->tx_unicast_octets); - p += sprintf(p, "TxMulticastOctets=%u\n", sums->tx_multicast_octets); - p += sprintf(p, "TxDeferredTransmissions=%u\n", - sums->tx_deferred_transmissions); - p += sprintf(p, "TxSingleRetryFrames=%u\n", - sums->tx_single_retry_frames); - p += sprintf(p, "TxMultipleRetryFrames=%u\n", - sums->tx_multiple_retry_frames); - p += sprintf(p, "TxRetryLimitExceeded=%u\n", - sums->tx_retry_limit_exceeded); - p += sprintf(p, "TxDiscards=%u\n", sums->tx_discards); - p += sprintf(p, "RxUnicastFrames=%u\n", sums->rx_unicast_frames); - p += sprintf(p, "RxMulticastFrames=%u\n", sums->rx_multicast_frames); - p += sprintf(p, "RxFragments=%u\n", sums->rx_fragments); - p += sprintf(p, "RxUnicastOctets=%u\n", sums->rx_unicast_octets); - p += sprintf(p, "RxMulticastOctets=%u\n", sums->rx_multicast_octets); - p += sprintf(p, "RxFCSErrors=%u\n", sums->rx_fcs_errors); - p += sprintf(p, "RxDiscardsNoBuffer=%u\n", - sums->rx_discards_no_buffer); - p += sprintf(p, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa); - p += sprintf(p, "RxDiscardsWEPUndecryptable=%u\n", - sums->rx_discards_wep_undecryptable); - p += sprintf(p, "RxMessageInMsgFragments=%u\n", - sums->rx_message_in_msg_fragments); - p += sprintf(p, "RxMessageInBadMsgFragments=%u\n", - sums->rx_message_in_bad_msg_fragments); + seq_printf(m, "TxUnicastFrames=%u\n", sums->tx_unicast_frames); + seq_printf(m, "TxMulticastframes=%u\n", sums->tx_multicast_frames); + seq_printf(m, "TxFragments=%u\n", sums->tx_fragments); + seq_printf(m, "TxUnicastOctets=%u\n", sums->tx_unicast_octets); + seq_printf(m, "TxMulticastOctets=%u\n", sums->tx_multicast_octets); + seq_printf(m, "TxDeferredTransmissions=%u\n", + sums->tx_deferred_transmissions); + seq_printf(m, "TxSingleRetryFrames=%u\n", sums->tx_single_retry_frames); + seq_printf(m, "TxMultipleRetryFrames=%u\n", + sums->tx_multiple_retry_frames); + seq_printf(m, "TxRetryLimitExceeded=%u\n", + sums->tx_retry_limit_exceeded); + seq_printf(m, "TxDiscards=%u\n", sums->tx_discards); + seq_printf(m, "RxUnicastFrames=%u\n", sums->rx_unicast_frames); + seq_printf(m, "RxMulticastFrames=%u\n", sums->rx_multicast_frames); + seq_printf(m, "RxFragments=%u\n", sums->rx_fragments); + seq_printf(m, "RxUnicastOctets=%u\n", sums->rx_unicast_octets); + seq_printf(m, "RxMulticastOctets=%u\n", sums->rx_multicast_octets); + seq_printf(m, "RxFCSErrors=%u\n", sums->rx_fcs_errors); + seq_printf(m, "RxDiscardsNoBuffer=%u\n", sums->rx_discards_no_buffer); + seq_printf(m, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa); + seq_printf(m, "RxDiscardsWEPUndecryptable=%u\n", + sums->rx_discards_wep_undecryptable); + seq_printf(m, "RxMessageInMsgFragments=%u\n", + sums->rx_message_in_msg_fragments); + seq_printf(m, "RxMessageInBadMsgFragments=%u\n", + sums->rx_message_in_bad_msg_fragments); /* FIX: this may grow too long for one page(?) */ - return (p - page); + return 0; +} + +static int prism2_stats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, prism2_stats_proc_show, PDE_DATA(inode)); } +static const struct file_operations prism2_stats_proc_fops = { + .open = prism2_stats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -static int prism2_wds_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + +static int prism2_wds_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; - struct list_head *ptr; + struct list_head *ptr = v; struct hostap_interface *iface; - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } + iface = list_entry(ptr, struct hostap_interface, list); + if (iface->type == HOSTAP_INTERFACE_WDS) + seq_printf(m, "%s\t%pM\n", + iface->dev->name, iface->u.wds.remote_addr); + return 0; +} +static void *prism2_wds_proc_start(struct seq_file *m, loff_t *_pos) +{ + local_info_t *local = m->private; read_lock_bh(&local->iface_lock); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type != HOSTAP_INTERFACE_WDS) - continue; - p += sprintf(p, "%s\t%pM\n", - iface->dev->name, - iface->u.wds.remote_addr); - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "%s: wds proc did not fit\n", - local->dev->name); - break; - } - } - read_unlock_bh(&local->iface_lock); + return seq_list_start(&local->hostap_interfaces, *_pos); +} - if ((p - page) <= off) { - *eof = 1; - return 0; - } +static void *prism2_wds_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + local_info_t *local = m->private; + return seq_list_next(v, &local->hostap_interfaces, _pos); +} - *start = page + off; +static void prism2_wds_proc_stop(struct seq_file *m, void *v) +{ + local_info_t *local = m->private; + read_unlock_bh(&local->iface_lock); +} - return (p - page - off); +static const struct seq_operations prism2_wds_proc_seqops = { + .start = prism2_wds_proc_start, + .next = prism2_wds_proc_next, + .stop = prism2_wds_proc_stop, + .show = prism2_wds_proc_show, +}; + +static int prism2_wds_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &prism2_wds_proc_seqops); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); + } + return ret; } +static const struct file_operations prism2_wds_proc_fops = { + .open = prism2_wds_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -static int prism2_bss_list_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + +static int prism2_bss_list_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; - struct list_head *ptr; + local_info_t *local = m->private; + struct list_head *ptr = v; struct hostap_bss_info *bss; int i; - if (off > PROC_LIMIT) { - *eof = 1; + if (ptr == &local->bss_list) { + seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" + "SSID(hex)\tWPA IE\n"); return 0; } - p += sprintf(p, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" - "SSID(hex)\tWPA IE\n"); + bss = list_entry(ptr, struct hostap_bss_info, list); + seq_printf(m, "%pM\t%lu\t%u\t0x%x\t", + bss->bssid, bss->last_update, + bss->count, bss->capab_info); + + for (i = 0; i < bss->ssid_len; i++) + seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? + bss->ssid[i] : '_'); + + seq_putc(m, '\t'); + for (i = 0; i < bss->ssid_len; i++) + seq_printf(m, "%02x", bss->ssid[i]); + seq_putc(m, '\t'); + for (i = 0; i < bss->wpa_ie_len; i++) + seq_printf(m, "%02x", bss->wpa_ie[i]); + seq_putc(m, '\n'); + return 0; +} + +static void *prism2_bss_list_proc_start(struct seq_file *m, loff_t *_pos) +{ + local_info_t *local = m->private; spin_lock_bh(&local->lock); - list_for_each(ptr, &local->bss_list) { - bss = list_entry(ptr, struct hostap_bss_info, list); - p += sprintf(p, "%pM\t%lu\t%u\t0x%x\t", - bss->bssid, bss->last_update, - bss->count, bss->capab_info); - for (i = 0; i < bss->ssid_len; i++) { - p += sprintf(p, "%c", - bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? - bss->ssid[i] : '_'); - } - p += sprintf(p, "\t"); - for (i = 0; i < bss->ssid_len; i++) { - p += sprintf(p, "%02x", bss->ssid[i]); - } - p += sprintf(p, "\t"); - for (i = 0; i < bss->wpa_ie_len; i++) { - p += sprintf(p, "%02x", bss->wpa_ie[i]); - } - p += sprintf(p, "\n"); - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "%s: BSS proc did not fit\n", - local->dev->name); - break; - } - } - spin_unlock_bh(&local->lock); + return seq_list_start_head(&local->bss_list, *_pos); +} - if ((p - page) <= off) { - *eof = 1; - return 0; - } +static void *prism2_bss_list_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + local_info_t *local = m->private; + return seq_list_next(v, &local->bss_list, _pos); +} - *start = page + off; +static void prism2_bss_list_proc_stop(struct seq_file *m, void *v) +{ + local_info_t *local = m->private; + spin_unlock_bh(&local->lock); +} + +static const struct seq_operations prism2_bss_list_proc_seqops = { + .start = prism2_bss_list_proc_start, + .next = prism2_bss_list_proc_next, + .stop = prism2_bss_list_proc_stop, + .show = prism2_bss_list_proc_show, +}; - return (p - page - off); +static int prism2_bss_list_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &prism2_bss_list_proc_seqops); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); + } + return ret; } +static const struct file_operations prism2_bss_list_proc_fops = { + .open = prism2_bss_list_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -static int prism2_crypt_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + +static int prism2_crypt_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; + local_info_t *local = m->private; int i; - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } - - p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx); + seq_printf(m, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx); for (i = 0; i < WEP_KEYS; i++) { if (local->crypt_info.crypt[i] && local->crypt_info.crypt[i]->ops && local->crypt_info.crypt[i]->ops->print_stats) { - p = local->crypt_info.crypt[i]->ops->print_stats( - p, local->crypt_info.crypt[i]->priv); + local->crypt_info.crypt[i]->ops->print_stats( + m, local->crypt_info.crypt[i]->priv); } } + return 0; +} - if ((p - page) <= off) { - *eof = 1; - return 0; - } - - *start = page + off; - - return (p - page - off); +static int prism2_crypt_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, prism2_crypt_proc_show, PDE_DATA(inode)); } +static const struct file_operations prism2_crypt_proc_fops = { + .open = prism2_crypt_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -static int prism2_pda_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + +static ssize_t prism2_pda_proc_read(struct file *file, char __user *buf, + size_t count, loff_t *_pos) { - local_info_t *local = (local_info_t *) data; + local_info_t *local = PDE_DATA(file_inode(file)); + size_t off; - if (local->pda == NULL || off >= PRISM2_PDA_SIZE) { - *eof = 1; + if (local->pda == NULL || *_pos >= PRISM2_PDA_SIZE) return 0; - } - if (off + count > PRISM2_PDA_SIZE) + off = *_pos; + if (count > PRISM2_PDA_SIZE - off) count = PRISM2_PDA_SIZE - off; - - memcpy(page, local->pda + off, count); + if (copy_to_user(buf, local->pda + off, count) != 0) + return -EFAULT; + *_pos += count; return count; } +static const struct file_operations prism2_pda_proc_fops = { + .read = prism2_pda_proc_read, + .llseek = generic_file_llseek, +}; -static int prism2_aux_dump_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - local_info_t *local = (local_info_t *) data; - - if (local->func->read_aux == NULL) { - *eof = 1; - return 0; - } - if (local->func->read_aux(local->dev, off, count, page)) { - *eof = 1; - return 0; - } - *start = page; - - return count; +static ssize_t prism2_aux_dump_proc_no_read(struct file *file, char __user *buf, + size_t bufsize, loff_t *_pos) +{ + return 0; } +static const struct file_operations prism2_aux_dump_proc_fops = { + .read = prism2_aux_dump_proc_no_read, +}; + #ifdef PRISM2_IO_DEBUG static int prism2_io_debug_proc_read(char *page, char **start, off_t off, @@ -306,82 +344,108 @@ static int prism2_io_debug_proc_read(char *page, char **start, off_t off, #ifndef PRISM2_NO_STATION_MODES -static int prism2_scan_results_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int prism2_scan_results_proc_show(struct seq_file *m, void *v) { - char *p = page; - local_info_t *local = (local_info_t *) data; - int entry, i, len, total = 0; + local_info_t *local = m->private; + unsigned long entry; + int i, len; struct hfa384x_hostscan_result *scanres; - u8 *pos; + u8 *p; - p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates " - "SSID\n"); + if (v == SEQ_START_TOKEN) { + seq_printf(m, + "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates SSID\n"); + return 0; + } + entry = (unsigned long)v - 2; + scanres = &local->last_scan_results[entry]; + + seq_printf(m, "%d %d %d %d 0x%02x %d %pM %d ", + le16_to_cpu(scanres->chid), + (s16) le16_to_cpu(scanres->anl), + (s16) le16_to_cpu(scanres->sl), + le16_to_cpu(scanres->beacon_interval), + le16_to_cpu(scanres->capability), + le16_to_cpu(scanres->rate), + scanres->bssid, + le16_to_cpu(scanres->atim)); + + p = scanres->sup_rates; + for (i = 0; i < sizeof(scanres->sup_rates); i++) { + if (p[i] == 0) + break; + seq_printf(m, "<%02x>", p[i]); + } + seq_putc(m, ' '); + + p = scanres->ssid; + len = le16_to_cpu(scanres->ssid_len); + if (len > 32) + len = 32; + for (i = 0; i < len; i++) { + unsigned char c = p[i]; + if (c >= 32 && c < 127) + seq_putc(m, c); + else + seq_printf(m, "<%02x>", c); + } + seq_putc(m, '\n'); + return 0; +} + +static void *prism2_scan_results_proc_start(struct seq_file *m, loff_t *_pos) +{ + local_info_t *local = m->private; spin_lock_bh(&local->lock); - for (entry = 0; entry < local->last_scan_results_count; entry++) { - scanres = &local->last_scan_results[entry]; - if (total + (p - page) <= off) { - total += p - page; - p = page; - } - if (total + (p - page) > off + count) - break; - if ((p - page) > (PAGE_SIZE - 200)) - break; + /* We have a header (pos 0) + N results to show (pos 1...N) */ + if (*_pos > local->last_scan_results_count) + return NULL; + return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ +} - p += sprintf(p, "%d %d %d %d 0x%02x %d %pM %d ", - le16_to_cpu(scanres->chid), - (s16) le16_to_cpu(scanres->anl), - (s16) le16_to_cpu(scanres->sl), - le16_to_cpu(scanres->beacon_interval), - le16_to_cpu(scanres->capability), - le16_to_cpu(scanres->rate), - scanres->bssid, - le16_to_cpu(scanres->atim)); - - pos = scanres->sup_rates; - for (i = 0; i < sizeof(scanres->sup_rates); i++) { - if (pos[i] == 0) - break; - p += sprintf(p, "<%02x>", pos[i]); - } - p += sprintf(p, " "); - - pos = scanres->ssid; - len = le16_to_cpu(scanres->ssid_len); - if (len > 32) - len = 32; - for (i = 0; i < len; i++) { - unsigned char c = pos[i]; - if (c >= 32 && c < 127) - p += sprintf(p, "%c", c); - else - p += sprintf(p, "<%02x>", c); - } - p += sprintf(p, "\n"); - } +static void *prism2_scan_results_proc_next(struct seq_file *m, void *v, loff_t *_pos) +{ + local_info_t *local = m->private; + + ++*_pos; + if (*_pos > local->last_scan_results_count) + return NULL; + return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ +} + +static void prism2_scan_results_proc_stop(struct seq_file *m, void *v) +{ + local_info_t *local = m->private; spin_unlock_bh(&local->lock); +} - total += (p - page); - if (total >= off + count) - *eof = 1; +static const struct seq_operations prism2_scan_results_proc_seqops = { + .start = prism2_scan_results_proc_start, + .next = prism2_scan_results_proc_next, + .stop = prism2_scan_results_proc_stop, + .show = prism2_scan_results_proc_show, +}; - if (total < off) { - *eof = 1; - return 0; +static int prism2_scan_results_proc_open(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &prism2_scan_results_proc_seqops); + if (ret == 0) { + struct seq_file *m = file->private_data; + m->private = PDE_DATA(inode); } + return ret; +} + +static const struct file_operations prism2_scan_results_proc_fops = { + .open = prism2_scan_results_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - len = total - off; - if (len > (p - page)) - len = p - page; - *start = p - len; - if (len > count) - len = count; - return len; -} #endif /* PRISM2_NO_STATION_MODES */ @@ -403,53 +467,36 @@ void hostap_init_proc(local_info_t *local) } #ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("debug", 0, local->proc, - prism2_debug_proc_read, local); + proc_create_data("debug", 0, local->proc, + &prism2_debug_proc_fops, local); #endif /* PRISM2_NO_PROCFS_DEBUG */ - create_proc_read_entry("stats", 0, local->proc, - prism2_stats_proc_read, local); - create_proc_read_entry("wds", 0, local->proc, - prism2_wds_proc_read, local); - create_proc_read_entry("pda", 0, local->proc, - prism2_pda_proc_read, local); - create_proc_read_entry("aux_dump", 0, local->proc, - prism2_aux_dump_proc_read, local); - create_proc_read_entry("bss_list", 0, local->proc, - prism2_bss_list_proc_read, local); - create_proc_read_entry("crypt", 0, local->proc, - prism2_crypt_proc_read, local); + proc_create_data("stats", 0, local->proc, + &prism2_stats_proc_fops, local); + proc_create_data("wds", 0, local->proc, + &prism2_wds_proc_fops, local); + proc_create_data("pda", 0, local->proc, + &prism2_pda_proc_fops, local); + proc_create_data("aux_dump", 0, local->proc, + local->func->read_aux_fops ?: &prism2_aux_dump_proc_fops, + local); + proc_create_data("bss_list", 0, local->proc, + &prism2_bss_list_proc_fops, local); + proc_create_data("crypt", 0, local->proc, + &prism2_crypt_proc_fops, local); #ifdef PRISM2_IO_DEBUG - create_proc_read_entry("io_debug", 0, local->proc, - prism2_io_debug_proc_read, local); + proc_create_data("io_debug", 0, local->proc, + &prism2_io_debug_proc_fops, local); #endif /* PRISM2_IO_DEBUG */ #ifndef PRISM2_NO_STATION_MODES - create_proc_read_entry("scan_results", 0, local->proc, - prism2_scan_results_proc_read, local); + proc_create_data("scan_results", 0, local->proc, + &prism2_scan_results_proc_fops, local); #endif /* PRISM2_NO_STATION_MODES */ } void hostap_remove_proc(local_info_t *local) { - if (local->proc != NULL) { -#ifndef PRISM2_NO_STATION_MODES - remove_proc_entry("scan_results", local->proc); -#endif /* PRISM2_NO_STATION_MODES */ -#ifdef PRISM2_IO_DEBUG - remove_proc_entry("io_debug", local->proc); -#endif /* PRISM2_IO_DEBUG */ - remove_proc_entry("pda", local->proc); - remove_proc_entry("aux_dump", local->proc); - remove_proc_entry("wds", local->proc); - remove_proc_entry("stats", local->proc); - remove_proc_entry("bss_list", local->proc); - remove_proc_entry("crypt", local->proc); -#ifndef PRISM2_NO_PROCFS_DEBUG - remove_proc_entry("debug", local->proc); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - if (hostap_proc != NULL) - remove_proc_entry(local->proc->name, hostap_proc); - } + remove_proc_subtree(local->ddev->name, hostap_proc); } diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 7bb0b4b3f2c..57904015380 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -596,8 +596,7 @@ struct prism2_helper_functions { struct prism2_download_param *param); int (*tx)(struct sk_buff *skb, struct net_device *dev); int (*set_tim)(struct net_device *dev, int aid, int set); - int (*read_aux)(struct net_device *dev, unsigned addr, int len, - u8 *buf); + const struct file_operations *read_aux_fops; int need_tx_headroom; /* number of bytes of headroom needed before * IEEE 802.11 header */ diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index ebada812b3a..9b557a1bb7f 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -2778,7 +2778,7 @@ static ssize_t int_proc_write(struct file *file, const char __user *buffer, nr = nr * 10 + c; p++; } while (--len); - *(int *)PDE(file_inode(file))->data = nr; + *(int *)PDE_DATA(file_inode(file)) = nr; return count; } diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c index 44d01afafe9..43926cd25ae 100644 --- a/drivers/nubus/nubus.c +++ b/drivers/nubus/nubus.c @@ -19,7 +19,6 @@ #include <asm/setup.h> #include <asm/page.h> #include <asm/hwtest.h> -#include <linux/proc_fs.h> #include <asm/mac_via.h> #include <asm/mac_oss.h> @@ -954,56 +953,6 @@ void __init nubus_probe_slot(int slot) } } -#if defined(CONFIG_PROC_FS) - -/* /proc/nubus stuff */ - -static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len) -{ - if(len < 100) - return -1; - - sprintf(ptr, "Slot %X: %s\n", - board->slot, board->name); - - return strlen(ptr); -} - -static int nubus_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int nprinted, len, begin = 0; - int size = PAGE_SIZE; - struct nubus_board* board; - - len = sprintf(page, "Nubus devices found:\n"); - /* Walk the list of NuBus boards */ - for (board = nubus_boards; board != NULL; board = board->next) - { - nprinted = sprint_nubus_board(board, page + len, size - len); - if (nprinted < 0) - break; - len += nprinted; - if (len+begin < off) { - begin += len; - len = 0; - } - if (len+begin >= off+count) - break; - } - if (len+begin < off) - *eof = 1; - off -= begin; - *start = page + off; - len -= off; - if (len>count) - len = count; - if (len<0) - len = 0; - return len; -} -#endif - void __init nubus_scan_bus(void) { int slot; @@ -1041,11 +990,7 @@ static int __init nubus_init(void) nubus_devices = NULL; nubus_boards = NULL; nubus_scan_bus(); - -#ifdef CONFIG_PROC_FS - create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL); nubus_proc_init(); -#endif return 0; } diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c index 208dd12825b..b8286ed6591 100644 --- a/drivers/nubus/proc.c +++ b/drivers/nubus/proc.c @@ -52,7 +52,6 @@ static int nubus_devices_proc_open(struct inode *inode, struct file *file) } static const struct file_operations nubus_devices_proc_fops = { - .owner = THIS_MODULE, .open = nubus_devices_proc_open, .read = seq_read, .llseek = seq_lseek, @@ -61,6 +60,10 @@ static const struct file_operations nubus_devices_proc_fops = { static struct proc_dir_entry *proc_bus_nubus_dir; +static const struct file_operations nubus_proc_subdir_fops = { +#warning Need to set some I/O handlers here +}; + static void nubus_proc_subdir(struct nubus_dev* dev, struct proc_dir_entry* parent, struct nubus_dir* dir) @@ -73,9 +76,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev, struct proc_dir_entry* e; sprintf(name, "%x", ent.type); - e = create_proc_entry(name, S_IFREG | S_IRUGO | - S_IWUSR, parent); - if (!e) return; + e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent, + &nubus_proc_subdir_fops); + if (!e) + return; } } @@ -158,6 +162,73 @@ int nubus_proc_detach_device(struct nubus_dev *dev) } EXPORT_SYMBOL(nubus_proc_detach_device); +/* + * /proc/nubus stuff + */ +static int nubus_proc_show(struct seq_file *m, void *v) +{ + const struct nubus_board *board = v; + + /* Display header on line 1 */ + if (v == SEQ_START_TOKEN) + seq_puts(m, "Nubus devices found:\n"); + else + seq_printf(m, "Slot %X: %s\n", board->slot, board->name); + return 0; +} + +static void *nubus_proc_start(struct seq_file *m, loff_t *_pos) +{ + struct nubus_board *board; + unsigned pos; + + if (*_pos > LONG_MAX) + return NULL; + pos = *_pos; + if (pos == 0) + return SEQ_START_TOKEN; + for (board = nubus_boards; board; board = board->next) + if (--pos == 0) + break; + return board; +} + +static void *nubus_proc_next(struct seq_file *p, void *v, loff_t *_pos) +{ + /* Walk the list of NuBus boards */ + struct nubus_board *board = v; + + ++*_pos; + if (v == SEQ_START_TOKEN) + board = nubus_boards; + else if (board) + board = board->next; + return board; +} + +static void nubus_proc_stop(struct seq_file *p, void *v) +{ +} + +static const struct seq_operations nubus_proc_seqops = { + .start = nubus_proc_start, + .next = nubus_proc_next, + .stop = nubus_proc_stop, + .show = nubus_proc_show, +}; + +static int nubus_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nubus_proc_seqops); +} + +static const struct file_operations nubus_proc_fops = { + .open = nubus_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + void __init proc_bus_nubus_add_devices(void) { struct nubus_dev *dev; @@ -168,6 +239,7 @@ void __init proc_bus_nubus_add_devices(void) void __init nubus_proc_init(void) { + proc_create("nubus", 0, NULL, &nubus_proc_fops); if (!MACH_IS_MAC) return; proc_bus_nubus_dir = proc_mkdir("bus/nubus", NULL); diff --git a/drivers/of/base.c b/drivers/of/base.c index 1733081eb87..0a2bdd106b2 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1453,16 +1453,7 @@ int of_attach_node(struct device_node *np) #ifdef CONFIG_PROC_DEVICETREE static void of_remove_proc_dt_entry(struct device_node *dn) { - struct device_node *parent = dn->parent; - struct property *prop = dn->properties; - - while (prop) { - remove_proc_entry(prop->name, dn->pde); - prop = prop->next; - } - - if (dn->pde) - remove_proc_entry(dn->pde->name, parent->pde); + proc_remove(dn->pde); } #else static void of_remove_proc_dt_entry(struct device_node *dn) diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index d4d800c54d8..b4824313199 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -172,14 +172,14 @@ static int led_proc_show(struct seq_file *m, void *v) static int led_proc_open(struct inode *inode, struct file *file) { - return single_open(file, led_proc_show, PDE(inode)->data); + return single_open(file, led_proc_show, PDE_DATA(inode)); } static ssize_t led_proc_write(struct file *file, const char *buf, size_t count, loff_t *pos) { - void *data = PDE(file_inode(file))->data; + void *data = PDE_DATA(file_inode(file)); char *cur, lbuf[32]; int d; diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 0b009470e6d..08126087ec3 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -46,9 +46,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence) static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - const struct inode *ino = file_inode(file); - const struct proc_dir_entry *dp = PDE(ino); - struct pci_dev *dev = dp->data; + struct pci_dev *dev = PDE_DATA(file_inode(file)); unsigned int pos = *ppos; unsigned int cnt, size; @@ -59,7 +57,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp */ if (capable(CAP_SYS_ADMIN)) - size = dp->size; + size = dev->cfg_size; else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) size = 128; else @@ -133,10 +131,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos) { struct inode *ino = file_inode(file); - const struct proc_dir_entry *dp = PDE(ino); - struct pci_dev *dev = dp->data; + struct pci_dev *dev = PDE_DATA(ino); int pos = *ppos; - int size = dp->size; + int size = dev->cfg_size; int cnt; if (pos >= size) @@ -200,7 +197,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof pci_config_pm_runtime_put(dev); *ppos = pos; - i_size_write(ino, dp->size); + i_size_write(ino, dev->cfg_size); return nbytes; } @@ -212,8 +209,7 @@ struct pci_filp_private { static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - const struct proc_dir_entry *dp = PDE(file_inode(file)); - struct pci_dev *dev = dp->data; + struct pci_dev *dev = PDE_DATA(file_inode(file)); #ifdef HAVE_PCI_MMAP struct pci_filp_private *fpriv = file->private_data; #endif /* HAVE_PCI_MMAP */ @@ -253,9 +249,7 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, #ifdef HAVE_PCI_MMAP static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) { - struct inode *inode = file_inode(file); - const struct proc_dir_entry *dp = PDE(inode); - struct pci_dev *dev = dp->data; + struct pci_dev *dev = PDE_DATA(file_inode(file)); struct pci_filp_private *fpriv = file->private_data; int i, ret; @@ -425,7 +419,7 @@ int pci_proc_attach_device(struct pci_dev *dev) &proc_bus_pci_operations, dev); if (!e) return -ENOMEM; - e->size = dev->cfg_size; + proc_set_size(e, dev->cfg_size); dev->procent = e; return 0; @@ -433,20 +427,14 @@ int pci_proc_attach_device(struct pci_dev *dev) int pci_proc_detach_device(struct pci_dev *dev) { - struct proc_dir_entry *e; - - if ((e = dev->procent)) { - remove_proc_entry(e->name, dev->bus->procdir); - dev->procent = NULL; - } + proc_remove(dev->procent); + dev->procent = NULL; return 0; } int pci_proc_detach_bus(struct pci_bus* bus) { - struct proc_dir_entry *de = bus->procdir; - if (de) - remove_proc_entry(de->name, proc_bus_pci_dir); + proc_remove(bus->procdir); return 0; } diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index edec135b168..54d31c0a984 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -844,14 +844,14 @@ static int dispatch_proc_show(struct seq_file *m, void *v) static int dispatch_proc_open(struct inode *inode, struct file *file) { - return single_open(file, dispatch_proc_show, PDE(inode)->data); + return single_open(file, dispatch_proc_show, PDE_DATA(inode)); } static ssize_t dispatch_proc_write(struct file *file, const char __user *userbuf, size_t count, loff_t *pos) { - struct ibm_struct *ibm = PDE(file_inode(file))->data; + struct ibm_struct *ibm = PDE_DATA(file_inode(file)); char *kernbuf; int ret; diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 242abac62d8..eb3467ea6d8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -553,7 +553,7 @@ static int lcd_proc_show(struct seq_file *m, void *v) static int lcd_proc_open(struct inode *inode, struct file *file) { - return single_open(file, lcd_proc_show, PDE(inode)->data); + return single_open(file, lcd_proc_show, PDE_DATA(inode)); } static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) @@ -583,7 +583,7 @@ static int set_lcd_status(struct backlight_device *bd) static ssize_t lcd_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data; + struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); char cmd[42]; size_t len; int value; @@ -644,13 +644,13 @@ static int video_proc_show(struct seq_file *m, void *v) static int video_proc_open(struct inode *inode, struct file *file) { - return single_open(file, video_proc_show, PDE(inode)->data); + return single_open(file, video_proc_show, PDE_DATA(inode)); } static ssize_t video_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data; + struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); char *cmd, *buffer; int ret; int value; @@ -744,13 +744,13 @@ static int fan_proc_show(struct seq_file *m, void *v) static int fan_proc_open(struct inode *inode, struct file *file) { - return single_open(file, fan_proc_show, PDE(inode)->data); + return single_open(file, fan_proc_show, PDE_DATA(inode)); } static ssize_t fan_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data; + struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); char cmd[42]; size_t len; int value; @@ -816,13 +816,13 @@ static int keys_proc_show(struct seq_file *m, void *v) static int keys_proc_open(struct inode *inode, struct file *file) { - return single_open(file, keys_proc_show, PDE(inode)->data); + return single_open(file, keys_proc_show, PDE_DATA(inode)); } static ssize_t keys_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data; + struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); char cmd[42]; size_t len; int value; @@ -859,7 +859,7 @@ static int version_proc_show(struct seq_file *m, void *v) static int version_proc_open(struct inode *inode, struct file *file) { - return single_open(file, version_proc_show, PDE(inode)->data); + return single_open(file, version_proc_show, PDE_DATA(inode)); } static const struct file_operations version_proc_fops = { diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c index 65f735ac6b3..2365ef37ae2 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c @@ -55,9 +55,7 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf, size_t nbytes, loff_t * ppos) { - struct inode *ino = file_inode(file); - struct proc_dir_entry *dp = PDE(ino); - struct pnp_dev *dev = dp->data; + struct pnp_dev *dev = PDE_DATA(file_inode(file)); int pos = *ppos; int cnt, size = 256; @@ -107,7 +105,7 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev) &isapnp_proc_bus_file_operations, dev); if (!e) return -ENOMEM; - e->size = 256; + proc_set_size(e, 256); return 0; } diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c index 1c03ee822e5..c212db0fc65 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -237,13 +237,13 @@ static int pnpbios_proc_show(struct seq_file *m, void *v) static int pnpbios_proc_open(struct inode *inode, struct file *file) { - return single_open(file, pnpbios_proc_show, PDE(inode)->data); + return single_open(file, pnpbios_proc_show, PDE_DATA(inode)); } static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - void *data = PDE(file_inode(file))->data; + void *data = PDE_DATA(file_inode(file)); struct pnp_bios_node *node; int boot = (long)data >> 8; u8 nodenum = (long)data; diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c index e1b4705ae3e..38a8bbe7481 100644 --- a/drivers/pps/clients/pps_parport.c +++ b/drivers/pps/clients/pps_parport.c @@ -32,6 +32,7 @@ #include <linux/init.h> #include <linux/irqnr.h> #include <linux/time.h> +#include <linux/slab.h> #include <linux/parport.h> #include <linux/pps_kernel.h> diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index e96236ac2e7..ffa69e1c924 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c @@ -110,7 +110,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) static int rtc_proc_open(struct inode *inode, struct file *file) { int ret; - struct rtc_device *rtc = PDE(inode)->data; + struct rtc_device *rtc = PDE_DATA(inode); if (!try_module_get(THIS_MODULE)) return -ENODEV; diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index ccaae9d63d2..4221b02085a 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -224,7 +224,7 @@ static int qperf_seq_open(struct inode *inode, struct file *filp) file_inode(filp)->i_private); } -static struct file_operations debugfs_perf_fops = { +static const struct file_operations debugfs_perf_fops = { .owner = THIS_MODULE, .open = qperf_seq_open, .read = seq_read, diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index d7ca247efa3..344d87599cd 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3201,26 +3201,30 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_de BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>. */ -static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag) +static int BusLogic_write_info(struct Scsi_Host *shost, char *ProcBuffer, int BytesAvailable) { struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata; struct BusLogic_TargetStatistics *TargetStatistics; - int TargetID, Length; - char *Buffer; TargetStatistics = HostAdapter->TargetStatistics; - if (WriteFlag) { - HostAdapter->ExternalHostAdapterResets = 0; - HostAdapter->HostAdapterInternalErrors = 0; - memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics)); - return 0; - } - Buffer = HostAdapter->MessageBuffer; - Length = HostAdapter->MessageBufferLength; - Length += sprintf(&Buffer[Length], "\n\ + HostAdapter->ExternalHostAdapterResets = 0; + HostAdapter->HostAdapterInternalErrors = 0; + memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics)); + return 0; +} + +static int BusLogic_show_info(struct seq_file *m, struct Scsi_Host *shost) +{ + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata; + struct BusLogic_TargetStatistics *TargetStatistics; + int TargetID; + + TargetStatistics = HostAdapter->TargetStatistics; + seq_write(m, HostAdapter->MessageBuffer, HostAdapter->MessageBufferLength); + seq_printf(m, "\n\ Current Driver Queue Depth: %d\n\ Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs); - Length += sprintf(&Buffer[Length], "\n\n\ + seq_printf(m, "\n\n\ DATA TRANSFER STATISTICS\n\ \n\ Target Tagged Queuing Queue Depth Active Attempted Completed\n\ @@ -3229,66 +3233,62 @@ Target Tagged Queuing Queue Depth Active Attempted Completed\n\ struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; if (!TargetFlags->TargetExists) continue; - Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID) + seq_printf(m, " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID) ? " Permitted" : " Disabled")) : "Not Supported")); - Length += sprintf(&Buffer[Length], + seq_printf(m, " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted); } - Length += sprintf(&Buffer[Length], "\n\ + seq_printf(m, "\n\ Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\ ====== ============= ============== =================== ===================\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; if (!TargetFlags->TargetExists) continue; - Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands); + seq_printf(m, " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands); if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0) - Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units); + seq_printf(m, " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units); else - Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units); + seq_printf(m, " %9u", TargetStatistics[TargetID].TotalBytesRead.Units); if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0) - Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units); + seq_printf(m, " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units); else - Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units); + seq_printf(m, " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units); } - Length += sprintf(&Buffer[Length], "\n\ + seq_printf(m, "\n\ Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\ ====== ======= ========= ========= ========= ========= =========\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; if (!TargetFlags->TargetExists) continue; - Length += - sprintf(&Buffer[Length], + seq_printf(m, " %2d Read %9u %9u %9u %9u %9u\n", TargetID, TargetStatistics[TargetID].ReadCommandSizeBuckets[0], TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]); - Length += - sprintf(&Buffer[Length], + seq_printf(m, " %2d Write %9u %9u %9u %9u %9u\n", TargetID, TargetStatistics[TargetID].WriteCommandSizeBuckets[0], TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]); } - Length += sprintf(&Buffer[Length], "\n\ + seq_printf(m, "\n\ Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\ ====== ======= ========= ========= ========= ========= =========\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; if (!TargetFlags->TargetExists) continue; - Length += - sprintf(&Buffer[Length], + seq_printf(m, " %2d Read %9u %9u %9u %9u %9u\n", TargetID, TargetStatistics[TargetID].ReadCommandSizeBuckets[5], TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]); - Length += - sprintf(&Buffer[Length], + seq_printf(m, " %2d Write %9u %9u %9u %9u %9u\n", TargetID, TargetStatistics[TargetID].WriteCommandSizeBuckets[5], TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]); } - Length += sprintf(&Buffer[Length], "\n\n\ + seq_printf(m, "\n\n\ ERROR RECOVERY STATISTICS\n\ \n\ Command Aborts Bus Device Resets Host Adapter Resets\n\ @@ -3299,20 +3299,12 @@ Target Requested Completed Requested Completed Requested Completed\n\ struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; if (!TargetFlags->TargetExists) continue; - Length += sprintf(&Buffer[Length], "\ + seq_printf(m, "\ %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted); } - Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets); - Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors); - if (Length >= BusLogic_MessageBufferSize) - BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize); - if ((Length -= Offset) <= 0) - return 0; - if (Length >= BytesAvailable) - Length = BytesAvailable; - memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length); - *StartPointer = ProcBuffer; - return Length; + seq_printf(m, "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets); + seq_printf(m, "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors); + return 0; } @@ -3566,7 +3558,8 @@ static int __init BusLogic_ParseDriverOptions(char *OptionsString) static struct scsi_host_template Bus_Logic_template = { .module = THIS_MODULE, .proc_name = "BusLogic", - .proc_info = BusLogic_ProcDirectoryInfo, + .write_info = BusLogic_write_info, + .show_info = BusLogic_show_info, .name = "BusLogic", .info = BusLogic_DriverInfo, .queuecommand = BusLogic_QueueCommand, diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 649fcb31f26..6c6c13c3be1 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -1321,7 +1321,6 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T Co static const char *BusLogic_DriverInfo(struct Scsi_Host *); static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *); static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *); -static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int); static int BusLogic_SlaveConfigure(struct scsi_device *); static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *); static irqreturn_t BusLogic_InterruptHandler(int, void *); diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 450353e04dd..1e9d6ad9302 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -695,33 +695,35 @@ static void NCR5380_print_status(struct Scsi_Host *instance) * Return the number of bytes read from or written */ +static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, + char *buffer, int length) +{ +#ifdef DTC_PUBLIC_RELEASE + dtc_wmaxi = dtc_maxi = 0; +#endif +#ifdef PAS16_PUBLIC_RELEASE + pas_wmaxi = pas_maxi = 0; +#endif + return (-ENOSYS); /* Currently this is a no-op */ +} + #undef SPRINTF -#define SPRINTF(args...) do { if(pos < buffer + length-80) pos += sprintf(pos, ## args); } while(0) +#define SPRINTF(args...) seq_printf(m, ## args) static -char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length); +void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m); static -char *lprint_command(unsigned char *cmd, char *pos, char *buffer, int len); +void lprint_command(unsigned char *cmd, struct seq_file *m); static -char *lprint_opcode(int opcode, char *pos, char *buffer, int length); +void lprint_opcode(int opcode, struct seq_file *m); -static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance, - char *buffer, char **start, off_t offset, int length, int inout) +static int __maybe_unused NCR5380_show_info(struct seq_file *m, + struct Scsi_Host *instance) { - char *pos = buffer; struct NCR5380_hostdata *hostdata; Scsi_Cmnd *ptr; hostdata = (struct NCR5380_hostdata *) instance->hostdata; - if (inout) { /* Has data been written to the file ? */ -#ifdef DTC_PUBLIC_RELEASE - dtc_wmaxi = dtc_maxi = 0; -#endif -#ifdef PAS16_PUBLIC_RELEASE - pas_wmaxi = pas_maxi = 0; -#endif - return (-ENOSYS); /* Currently this is a no-op */ - } SPRINTF("NCR5380 core release=%d. ", NCR5380_PUBLIC_RELEASE); if (((struct NCR5380_hostdata *) instance->hostdata)->flags & FLAG_NCR53C400) SPRINTF("ncr53c400 release=%d. ", NCR53C400_PUBLIC_RELEASE); @@ -755,46 +757,37 @@ static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance, if (!hostdata->connected) SPRINTF("scsi%d: no currently connected command\n", instance->host_no); else - pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, pos, buffer, length); + lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m); SPRINTF("scsi%d: issue_queue\n", instance->host_no); for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); + lprint_Scsi_Cmnd(ptr, m); SPRINTF("scsi%d: disconnected_queue\n", instance->host_no); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); + lprint_Scsi_Cmnd(ptr, m); spin_unlock_irq(instance->host_lock); - - *start = buffer; - if (pos - buffer < offset) - return 0; - else if (pos - buffer - offset < length) - return pos - buffer - offset; - return length; + return 0; } -static char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length) +static void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m) { SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun); SPRINTF(" command = "); - pos = lprint_command(cmd->cmnd, pos, buffer, length); - return (pos); + lprint_command(cmd->cmnd, m); } -static char *lprint_command(unsigned char *command, char *pos, char *buffer, int length) +static void lprint_command(unsigned char *command, struct seq_file *m) { int i, s; - pos = lprint_opcode(command[0], pos, buffer, length); + lprint_opcode(command[0], m); for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) SPRINTF("%02x ", command[i]); SPRINTF("\n"); - return (pos); } -static char *lprint_opcode(int opcode, char *pos, char *buffer, int length) +static void lprint_opcode(int opcode, struct seq_file *m) { SPRINTF("%2d (0x%02x)", opcode, opcode); - return (pos); } diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index fd40a32b1f6..14964d0a0e9 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -314,8 +314,10 @@ static void NCR5380_print(struct Scsi_Host *instance); static int NCR5380_abort(Scsi_Cmnd * cmd); static int NCR5380_bus_reset(Scsi_Cmnd * cmd); static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *); -static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance, - char *buffer, char **start, off_t offset, int length, int inout); +static int __maybe_unused NCR5380_show_info(struct seq_file *, + struct Scsi_Host *); +static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, + char *buffer, int length); static void NCR5380_reselect(struct Scsi_Host *instance); static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag); diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 3e09aa21c1c..30fa38a0ad3 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -166,7 +166,8 @@ static int a2091_bus_reset(struct scsi_cmnd *cmd) static struct scsi_host_template a2091_scsi_template = { .module = THIS_MODULE, .name = "Commodore A2091/A590 SCSI", - .proc_info = wd33c93_proc_info, + .show_info = wd33c93_show_info, + .write_info = wd33c93_write_info, .proc_name = "A2901", .queuecommand = wd33c93_queuecommand, .eh_abort_handler = wd33c93_abort, diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index e29fe0e708f..c487916a9d4 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -181,7 +181,8 @@ static int a3000_bus_reset(struct scsi_cmnd *cmd) static struct scsi_host_template amiga_a3000_scsi_template = { .module = THIS_MODULE, .name = "Amiga 3000 built-in SCSI", - .proc_info = wd33c93_proc_info, + .show_info = wd33c93_show_info, + .write_info = wd33c93_write_info, .proc_name = "A3000", .queuecommand = wd33c93_queuecommand, .eh_abort_handler = wd33c93_abort, diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index dcfaee66a8b..c67e401954c 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2178,22 +2178,6 @@ do { \ #define ASC_INFO_SIZE 128 /* advansys_info() line size */ -#ifdef CONFIG_PROC_FS -/* /proc/scsi/advansys/[0...] related definitions */ -#define ASC_PRTBUF_SIZE 2048 -#define ASC_PRTLINE_SIZE 160 - -#define ASC_PRT_NEXT() \ - if (cp) { \ - totlen += len; \ - leftlen -= len; \ - if (leftlen == 0) { \ - return totlen; \ - } \ - cp += len; \ - } -#endif /* CONFIG_PROC_FS */ - /* Asc Library return codes */ #define ASC_TRUE 1 #define ASC_FALSE 0 @@ -2384,7 +2368,6 @@ struct asc_board { } eep_config; ulong last_reset; /* Saved last reset time */ /* /proc/scsi/advansys/[0...] */ - char *prtbuf; /* /proc print buffer */ #ifdef ADVANSYS_STATS struct asc_stats asc_stats; /* Board statistics */ #endif /* ADVANSYS_STATS */ @@ -2875,64 +2858,21 @@ static const char *advansys_info(struct Scsi_Host *shost) } #ifdef CONFIG_PROC_FS -/* - * asc_prt_line() - * - * If 'cp' is NULL print to the console, otherwise print to a buffer. - * - * Return 0 if printing to the console, otherwise return the number of - * bytes written to the buffer. - * - * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack - * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. - */ -static int asc_prt_line(char *buf, int buflen, char *fmt, ...) -{ - va_list args; - int ret; - char s[ASC_PRTLINE_SIZE]; - - va_start(args, fmt); - ret = vsprintf(s, fmt, args); - BUG_ON(ret >= ASC_PRTLINE_SIZE); - if (buf == NULL) { - (void)printk(s); - ret = 0; - } else { - ret = min(buflen, ret); - memcpy(buf, s, ret); - } - va_end(args); - return ret; -} /* * asc_prt_board_devices() * * Print driver information for devices attached to the board. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_board_devices(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - int leftlen; - int totlen; - int len; int chip_scsi_id; int i; - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, - "\nDevice Information for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + "\nDevice Information for AdvanSys SCSI Host %d:\n", + shost->host_no); if (ASC_NARROW_BOARD(boardp)) { chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; @@ -2940,60 +2880,42 @@ static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; } - len = asc_prt_line(cp, leftlen, "Target IDs Detected:"); - ASC_PRT_NEXT(); + seq_printf(m, "Target IDs Detected:"); for (i = 0; i <= ADV_MAX_TID; i++) { - if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) { - len = asc_prt_line(cp, leftlen, " %X,", i); - ASC_PRT_NEXT(); - } + if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) + seq_printf(m, " %X,", i); } - len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id); - ASC_PRT_NEXT(); - - return totlen; + seq_printf(m, " (%X=Host Adapter)\n", chip_scsi_id); } /* * Display Wide Board BIOS Information. */ -static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_adv_bios(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - int leftlen; - int totlen; - int len; ushort major, minor, letter; - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: "); - ASC_PRT_NEXT(); + seq_printf(m, "\nROM BIOS Version: "); /* * If the BIOS saved a valid signature, then fill in * the BIOS code segment base address. */ if (boardp->bios_signature != 0x55AA) { - len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n"); - ASC_PRT_NEXT(); + seq_printf(m, "Disabled or Pre-3.1\n"); + seq_printf(m, + "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"); + seq_printf(m, + "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n"); } else { major = (boardp->bios_version >> 12) & 0xF; minor = (boardp->bios_version >> 8) & 0xF; letter = (boardp->bios_version & 0xFF); - len = asc_prt_line(cp, leftlen, "%d.%d%c\n", + seq_printf(m, "%d.%d%c\n", major, minor, letter >= 26 ? '?' : letter + 'A'); - ASC_PRT_NEXT(); - /* * Current available ROM BIOS release is 3.1I for UW * and 3.2I for U2W. This code doesn't differentiate @@ -3001,16 +2923,12 @@ static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) */ if (major < 3 || (major <= 3 && minor < 1) || (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) { - len = asc_prt_line(cp, leftlen, - "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "ftp://ftp.connectcom.net/pub\n"); - ASC_PRT_NEXT(); + seq_printf(m, + "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"); + seq_printf(m, + "ftp://ftp.connectcom.net/pub\n"); } } - - return totlen; } /* @@ -3115,20 +3033,11 @@ static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) * asc_prt_asc_board_eeprom() * * Print board EEPROM configuration. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_asc_board_eeprom(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); ASC_DVC_VAR *asc_dvc_varp; - int leftlen; - int totlen; - int len; ASCEEP_CONFIG *ep; int i; #ifdef CONFIG_ISA @@ -3139,129 +3048,75 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; ep = &boardp->eep_config.asc_eep; - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, - "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", + shost->host_no); if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr) - == ASC_TRUE) { - len = - asc_prt_line(cp, leftlen, " Serial Number: %s\n", - serialstr); - ASC_PRT_NEXT(); - } else { - if (ep->adapter_info[5] == 0xBB) { - len = asc_prt_line(cp, leftlen, - " Default Settings Used for EEPROM-less Adapter.\n"); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Serial Number Signature Not Present.\n"); - ASC_PRT_NEXT(); - } - } - - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, - ep->max_tag_qng); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Target ID: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %d", i); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Disconnects: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Command Queuing: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Start Motor: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + == ASC_TRUE) + seq_printf(m, " Serial Number: %s\n", serialstr); + else if (ep->adapter_info[5] == 0xBB) + seq_printf(m, + " Default Settings Used for EEPROM-less Adapter.\n"); + else + seq_printf(m, + " Serial Number Signature Not Present.\n"); + + seq_printf(m, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, + ep->max_tag_qng); + + seq_printf(m, + " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam); + + seq_printf(m, " Target ID: "); + for (i = 0; i <= ASC_MAX_TID; i++) + seq_printf(m, " %d", i); + seq_printf(m, "\n"); + + seq_printf(m, " Disconnects: "); + for (i = 0; i <= ASC_MAX_TID; i++) + seq_printf(m, " %c", + (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); + + seq_printf(m, " Command Queuing: "); + for (i = 0; i <= ASC_MAX_TID; i++) + seq_printf(m, " %c", + (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); + + seq_printf(m, " Start Motor: "); + for (i = 0; i <= ASC_MAX_TID; i++) + seq_printf(m, " %c", + (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); + + seq_printf(m, " Synchronous Transfer:"); + for (i = 0; i <= ASC_MAX_TID; i++) + seq_printf(m, " %c", + (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); #ifdef CONFIG_ISA if (asc_dvc_varp->bus_type & ASC_IS_ISA) { - len = asc_prt_line(cp, leftlen, - " Host ISA DMA speed: %d MB/S\n", - isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]); - ASC_PRT_NEXT(); + seq_printf(m, + " Host ISA DMA speed: %d MB/S\n", + isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]); } #endif /* CONFIG_ISA */ - - return totlen; } /* * asc_prt_adv_board_eeprom() * * Print board EEPROM configuration. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_adv_board_eeprom(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); ADV_DVC_VAR *adv_dvc_varp; - int leftlen; - int totlen; - int len; int i; char *termstr; uchar serialstr[13]; @@ -3281,13 +3136,9 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen ep_38C1600 = &boardp->eep_config.adv_38C1600_eep; } - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, - "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", + shost->host_no); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { wordp = &ep_3550->serial_number_word1; @@ -3297,38 +3148,28 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen wordp = &ep_38C1600->serial_number_word1; } - if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) { - len = - asc_prt_line(cp, leftlen, " Serial Number: %s\n", - serialstr); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Serial Number Signature Not Present.\n"); - ASC_PRT_NEXT(); - } + if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) + seq_printf(m, " Serial Number: %s\n", serialstr); + else + seq_printf(m, " Serial Number Signature Not Present.\n"); - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_3550->adapter_scsi_id, - ep_3550->max_host_qng, ep_3550->max_dvc_qng); - ASC_PRT_NEXT(); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_38C0800->adapter_scsi_id, - ep_38C0800->max_host_qng, - ep_38C0800->max_dvc_qng); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_38C1600->adapter_scsi_id, - ep_38C1600->max_host_qng, - ep_38C1600->max_dvc_qng); - ASC_PRT_NEXT(); - } + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) + seq_printf(m, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_3550->adapter_scsi_id, + ep_3550->max_host_qng, ep_3550->max_dvc_qng); + else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) + seq_printf(m, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_38C0800->adapter_scsi_id, + ep_38C0800->max_host_qng, + ep_38C0800->max_dvc_qng); + else + seq_printf(m, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_38C1600->adapter_scsi_id, + ep_38C1600->max_host_qng, + ep_38C1600->max_dvc_qng); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { word = ep_3550->termination; } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { @@ -3352,34 +3193,26 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen break; } - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_3550->termination, termstr, - ep_3550->bios_ctrl); - ASC_PRT_NEXT(); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_38C0800->termination_lvd, termstr, - ep_38C0800->bios_ctrl); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_38C1600->termination_lvd, termstr, - ep_38C1600->bios_ctrl); - ASC_PRT_NEXT(); - } + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) + seq_printf(m, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_3550->termination, termstr, + ep_3550->bios_ctrl); + else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) + seq_printf(m, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_38C0800->termination_lvd, termstr, + ep_38C0800->bios_ctrl); + else + seq_printf(m, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_38C1600->termination_lvd, termstr, + ep_38C1600->bios_ctrl); - len = asc_prt_line(cp, leftlen, " Target ID: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %X", i); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Target ID: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %X", i); + seq_printf(m, "\n"); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { word = ep_3550->disc_enable; @@ -3388,15 +3221,11 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen } else { word = ep_38C1600->disc_enable; } - len = asc_prt_line(cp, leftlen, " Disconnects: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Disconnects: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { word = ep_3550->tagqng_able; @@ -3405,15 +3234,11 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen } else { word = ep_38C1600->tagqng_able; } - len = asc_prt_line(cp, leftlen, " Command Queuing: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Queuing: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { word = ep_3550->start_motor; @@ -3422,42 +3247,28 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen } else { word = ep_38C1600->start_motor; } - len = asc_prt_line(cp, leftlen, " Start Motor: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Start Motor: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep_3550-> - sdtr_able & ADV_TID_TO_TIDMASK(i)) ? - 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Synchronous Transfer:"); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? + 'Y' : 'N'); + seq_printf(m, "\n"); } if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, " Ultra Transfer: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep_3550-> - ultra_able & ADV_TID_TO_TIDMASK(i)) - ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Ultra Transfer: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) + ? 'Y' : 'N'); + seq_printf(m, "\n"); } if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { @@ -3467,21 +3278,16 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen } else { word = ep_38C1600->wdtr_able; } - len = asc_prt_line(cp, leftlen, " Wide Transfer: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, " Wide Transfer: "); + for (i = 0; i <= ADV_MAX_TID; i++) + seq_printf(m, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + seq_printf(m, "\n"); if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 || adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) { - len = asc_prt_line(cp, leftlen, - " Synchronous Transfer Speed (Mhz):\n "); - ASC_PRT_NEXT(); + seq_printf(m, + " Synchronous Transfer Speed (Mhz):\n "); for (i = 0; i <= ADV_MAX_TID; i++) { char *speed_str; @@ -3517,99 +3323,64 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen speed_str = "Unk"; break; } - len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str); - ASC_PRT_NEXT(); - if (i == 7) { - len = asc_prt_line(cp, leftlen, "\n "); - ASC_PRT_NEXT(); - } + seq_printf(m, "%X:%s ", i, speed_str); + if (i == 7) + seq_printf(m, "\n "); sdtr_speed >>= 4; } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); } - - return totlen; } /* * asc_prt_driver_conf() - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - int leftlen; - int totlen; - int len; int chip_scsi_id; - leftlen = cplen; - totlen = len = 0; + seq_printf(m, + "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", + shost->host_no); - len = asc_prt_line(cp, leftlen, - "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + " host_busy %u, last_reset %lu, max_id %u, max_lun %u, max_channel %u\n", + shost->host_busy, shost->last_reset, shost->max_id, + shost->max_lun, shost->max_channel); - len = asc_prt_line(cp, leftlen, - " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n", - shost->host_busy, shost->last_reset, shost->max_id, - shost->max_lun, shost->max_channel); - ASC_PRT_NEXT(); + seq_printf(m, + " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", + shost->unique_id, shost->can_queue, shost->this_id, + shost->sg_tablesize, shost->cmd_per_lun); - len = asc_prt_line(cp, leftlen, - " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", - shost->unique_id, shost->can_queue, shost->this_id, - shost->sg_tablesize, shost->cmd_per_lun); - ASC_PRT_NEXT(); + seq_printf(m, + " unchecked_isa_dma %d, use_clustering %d\n", + shost->unchecked_isa_dma, shost->use_clustering); - len = asc_prt_line(cp, leftlen, - " unchecked_isa_dma %d, use_clustering %d\n", - shost->unchecked_isa_dma, shost->use_clustering); - ASC_PRT_NEXT(); + seq_printf(m, + " flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n", + boardp->flags, boardp->last_reset, jiffies, + boardp->asc_n_io_port); - len = asc_prt_line(cp, leftlen, - " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n", - boardp->flags, boardp->last_reset, jiffies, - boardp->asc_n_io_port); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port); - ASC_PRT_NEXT(); + seq_printf(m, " io_port 0x%lx\n", shost->io_port); if (ASC_NARROW_BOARD(boardp)) { chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; } else { chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; } - - return totlen; } /* * asc_prt_asc_board_info() * * Print dynamic board configuration information. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_asc_board_info(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); int chip_scsi_id; - int leftlen; - int totlen; - int len; ASC_DVC_VAR *v; ASC_DVC_CFG *c; int i; @@ -3619,105 +3390,79 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) c = &boardp->dvc_cfg.asc_dvc_cfg; chip_scsi_id = c->chip_scsi_id; - leftlen = cplen; - totlen = len = 0; + seq_printf(m, + "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", + shost->host_no); - len = asc_prt_line(cp, leftlen, - "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " - "mcode_version 0x%x, err_code %u\n", - c->chip_version, c->mcode_date, c->mcode_version, - v->err_code); - ASC_PRT_NEXT(); + seq_printf(m, " chip_version %u, mcode_date 0x%x, " + "mcode_version 0x%x, err_code %u\n", + c->chip_version, c->mcode_date, c->mcode_version, + v->err_code); /* Current number of commands waiting for the host. */ - len = asc_prt_line(cp, leftlen, - " Total Command Pending: %d\n", v->cur_total_qng); - ASC_PRT_NEXT(); + seq_printf(m, + " Total Command Pending: %d\n", v->cur_total_qng); - len = asc_prt_line(cp, leftlen, " Command Queuing:"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Queuing:"); for (i = 0; i <= ASC_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (v-> - use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? - 'Y' : 'N'); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%c", + i, + (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); /* Current number of commands waiting for a device. */ - len = asc_prt_line(cp, leftlen, " Command Queue Pending:"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Queue Pending:"); for (i = 0; i <= ASC_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%u", i, v->cur_dvc_qng[i]); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); /* Current limit on number of commands that can be sent to a device. */ - len = asc_prt_line(cp, leftlen, " Command Queue Limit:"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Queue Limit:"); for (i = 0; i <= ASC_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%u", i, v->max_dvc_qng[i]); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); /* Indicate whether the device has returned queue full status. */ - len = asc_prt_line(cp, leftlen, " Command Queue Full:"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Queue Full:"); for (i = 0; i <= ASC_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) { - len = asc_prt_line(cp, leftlen, " %X:Y-%d", - i, boardp->queue_full_cnt[i]); - } else { - len = asc_prt_line(cp, leftlen, " %X:N", i); - } - ASC_PRT_NEXT(); + if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) + seq_printf(m, " %X:Y-%d", + i, boardp->queue_full_cnt[i]); + else + seq_printf(m, " %X:N", i); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); + seq_printf(m, " Synchronous Transfer:"); for (i = 0; i <= ASC_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (v-> - sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%c", + i, + (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); for (i = 0; i <= ASC_MAX_TID; i++) { uchar syn_period_ix; @@ -3728,69 +3473,48 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) continue; } - len = asc_prt_line(cp, leftlen, " %X:", i); - ASC_PRT_NEXT(); + seq_printf(m, " %X:", i); if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) { - len = asc_prt_line(cp, leftlen, " Asynchronous"); - ASC_PRT_NEXT(); + seq_printf(m, " Asynchronous"); } else { syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1); - len = asc_prt_line(cp, leftlen, - " Transfer Period Factor: %d (%d.%d Mhz),", - v->sdtr_period_tbl[syn_period_ix], - 250 / - v->sdtr_period_tbl[syn_period_ix], - ASC_TENTHS(250, - v-> - sdtr_period_tbl - [syn_period_ix])); - ASC_PRT_NEXT(); + seq_printf(m, + " Transfer Period Factor: %d (%d.%d Mhz),", + v->sdtr_period_tbl[syn_period_ix], + 250 / v->sdtr_period_tbl[syn_period_ix], + ASC_TENTHS(250, + v->sdtr_period_tbl[syn_period_ix])); - len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", - boardp-> - sdtr_data[i] & ASC_SYN_MAX_OFFSET); - ASC_PRT_NEXT(); + seq_printf(m, " REQ/ACK Offset: %d", + boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET); } if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*\n"); + seq_printf(m, "*\n"); renegotiate = 1; } else { - len = asc_prt_line(cp, leftlen, "\n"); + seq_printf(m, "\n"); } - ASC_PRT_NEXT(); } if (renegotiate) { - len = asc_prt_line(cp, leftlen, - " * = Re-negotiation pending before next command.\n"); - ASC_PRT_NEXT(); + seq_printf(m, + " * = Re-negotiation pending before next command.\n"); } - - return totlen; } /* * asc_prt_adv_board_info() * * Print dynamic board configuration information. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - int leftlen; - int totlen; - int len; int i; ADV_DVC_VAR *v; ADV_DVC_CFG *c; @@ -3809,47 +3533,35 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) iop_base = v->iop_base; chip_scsi_id = v->chip_scsi_id; - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, - "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", + shost->host_no); - len = asc_prt_line(cp, leftlen, - " iop_base 0x%lx, cable_detect: %X, err_code %u\n", - v->iop_base, - AdvReadWordRegister(iop_base, - IOPW_SCSI_CFG1) & CABLE_DETECT, - v->err_code); - ASC_PRT_NEXT(); + seq_printf(m, + " iop_base 0x%lx, cable_detect: %X, err_code %u\n", + (unsigned long)v->iop_base, + AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT, + v->err_code); - len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " - "mcode_version 0x%x\n", c->chip_version, - c->mcode_date, c->mcode_version); - ASC_PRT_NEXT(); + seq_printf(m, " chip_version %u, mcode_date 0x%x, " + "mcode_version 0x%x\n", c->chip_version, + c->mcode_date, c->mcode_version); AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - len = asc_prt_line(cp, leftlen, " Queuing Enabled:"); - ASC_PRT_NEXT(); + seq_printf(m, " Queuing Enabled:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%c", + i, + (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); - len = asc_prt_line(cp, leftlen, " Queue Limit:"); - ASC_PRT_NEXT(); + seq_printf(m, " Queue Limit:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { @@ -3859,14 +3571,11 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte); - len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%d", i, lrambyte); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); - len = asc_prt_line(cp, leftlen, " Command Pending:"); - ASC_PRT_NEXT(); + seq_printf(m, " Command Pending:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { @@ -3876,33 +3585,26 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte); - len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%d", i, lrambyte); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - len = asc_prt_line(cp, leftlen, " Wide Enabled:"); - ASC_PRT_NEXT(); + seq_printf(m, " Wide Enabled:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%c", + i, + (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done); - len = asc_prt_line(cp, leftlen, " Transfer Bit Width:"); - ASC_PRT_NEXT(); + seq_printf(m, " Transfer Bit Width:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { @@ -3913,37 +3615,30 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), lramword); - len = asc_prt_line(cp, leftlen, " %X:%d", - i, (lramword & 0x8000) ? 16 : 8); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%d", + i, (lramword & 0x8000) ? 16 : 8); if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) && (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*"); - ASC_PRT_NEXT(); + seq_printf(m, "*"); renegotiate = 1; } } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - len = asc_prt_line(cp, leftlen, " Synchronous Enabled:"); - ASC_PRT_NEXT(); + seq_printf(m, " Synchronous Enabled:"); for (i = 0; i <= ADV_MAX_TID; i++) { if ((chip_scsi_id == i) || ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { continue; } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); + seq_printf(m, " %X:%c", + i, + (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + seq_printf(m, "\n"); AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done); for (i = 0; i <= ADV_MAX_TID; i++) { @@ -3959,358 +3654,170 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) continue; } - len = asc_prt_line(cp, leftlen, " %X:", i); - ASC_PRT_NEXT(); + seq_printf(m, " %X:", i); if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */ - len = asc_prt_line(cp, leftlen, " Asynchronous"); - ASC_PRT_NEXT(); + seq_printf(m, " Asynchronous"); } else { - len = - asc_prt_line(cp, leftlen, - " Transfer Period Factor: "); - ASC_PRT_NEXT(); + seq_printf(m, " Transfer Period Factor: "); if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */ - len = - asc_prt_line(cp, leftlen, "9 (80.0 Mhz),"); - ASC_PRT_NEXT(); + seq_printf(m, "9 (80.0 Mhz),"); } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */ - len = - asc_prt_line(cp, leftlen, "10 (40.0 Mhz),"); - ASC_PRT_NEXT(); + seq_printf(m, "10 (40.0 Mhz),"); } else { /* 20 Mhz or below. */ period = (((lramword >> 8) * 25) + 50) / 4; if (period == 0) { /* Should never happen. */ - len = - asc_prt_line(cp, leftlen, - "%d (? Mhz), "); - ASC_PRT_NEXT(); + seq_printf(m, "%d (? Mhz), ", period); } else { - len = asc_prt_line(cp, leftlen, - "%d (%d.%d Mhz),", - period, 250 / period, - ASC_TENTHS(250, - period)); - ASC_PRT_NEXT(); + seq_printf(m, + "%d (%d.%d Mhz),", + period, 250 / period, + ASC_TENTHS(250, period)); } } - len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", - lramword & 0x1F); - ASC_PRT_NEXT(); + seq_printf(m, " REQ/ACK Offset: %d", + lramword & 0x1F); } if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*\n"); + seq_printf(m, "*\n"); renegotiate = 1; } else { - len = asc_prt_line(cp, leftlen, "\n"); + seq_printf(m, "\n"); } - ASC_PRT_NEXT(); } if (renegotiate) { - len = asc_prt_line(cp, leftlen, - " * = Re-negotiation pending before next command.\n"); - ASC_PRT_NEXT(); + seq_printf(m, + " * = Re-negotiation pending before next command.\n"); } - - return totlen; -} - -/* - * asc_proc_copy() - * - * Copy proc information to a read buffer taking into account the current - * read offset in the file and the remaining space in the read buffer. - */ -static int -asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, - char *cp, int cplen) -{ - int cnt = 0; - - ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n", - (unsigned)offset, (unsigned)advoffset, cplen); - if (offset <= advoffset) { - /* Read offset below current offset, copy everything. */ - cnt = min(cplen, leftlen); - ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", - (ulong)curbuf, (ulong)cp, cnt); - memcpy(curbuf, cp, cnt); - } else if (offset < advoffset + cplen) { - /* Read offset within current range, partial copy. */ - cnt = (advoffset + cplen) - offset; - cp = (cp + cplen) - cnt; - cnt = min(cnt, leftlen); - ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", - (ulong)curbuf, (ulong)cp, cnt); - memcpy(curbuf, cp, cnt); - } - return cnt; } #ifdef ADVANSYS_STATS /* * asc_prt_board_stats() - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) +static void asc_prt_board_stats(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); struct asc_stats *s = &boardp->asc_stats; - int leftlen = cplen; - int len, totlen = 0; + seq_printf(m, + "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", + shost->host_no); - len = asc_prt_line(cp, leftlen, - "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + seq_printf(m, + " queuecommand %u, reset %u, biosparam %u, interrupt %u\n", + s->queuecommand, s->reset, s->biosparam, + s->interrupt); - len = asc_prt_line(cp, leftlen, - " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", - s->queuecommand, s->reset, s->biosparam, - s->interrupt); - ASC_PRT_NEXT(); + seq_printf(m, + " callback %u, done %u, build_error %u, build_noreq %u, build_nosg %u\n", + s->callback, s->done, s->build_error, + s->adv_build_noreq, s->adv_build_nosg); - len = asc_prt_line(cp, leftlen, - " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", - s->callback, s->done, s->build_error, - s->adv_build_noreq, s->adv_build_nosg); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", - s->exe_noerror, s->exe_busy, s->exe_error, - s->exe_unknown); - ASC_PRT_NEXT(); + seq_printf(m, + " exe_noerror %u, exe_busy %u, exe_error %u, exe_unknown %u\n", + s->exe_noerror, s->exe_busy, s->exe_error, + s->exe_unknown); /* * Display data transfer statistics. */ if (s->xfer_cnt > 0) { - len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ", - s->xfer_cnt, s->xfer_elem); - ASC_PRT_NEXT(); + seq_printf(m, " xfer_cnt %u, xfer_elem %u, ", + s->xfer_cnt, s->xfer_elem); - len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n", - s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2)); - ASC_PRT_NEXT(); + seq_printf(m, "xfer_bytes %u.%01u kb\n", + s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2)); /* Scatter gather transfer statistics */ - len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", - s->xfer_elem / s->xfer_cnt, - ASC_TENTHS(s->xfer_elem, s->xfer_cnt)); - ASC_PRT_NEXT(); + seq_printf(m, " avg_num_elem %u.%01u, ", + s->xfer_elem / s->xfer_cnt, + ASC_TENTHS(s->xfer_elem, s->xfer_cnt)); - len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", - (s->xfer_sect / 2) / s->xfer_elem, - ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem)); - ASC_PRT_NEXT(); + seq_printf(m, "avg_elem_size %u.%01u kb, ", + (s->xfer_sect / 2) / s->xfer_elem, + ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem)); - len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", - (s->xfer_sect / 2) / s->xfer_cnt, - ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt)); - ASC_PRT_NEXT(); + seq_printf(m, "avg_xfer_size %u.%01u kb\n", + (s->xfer_sect / 2) / s->xfer_cnt, + ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt)); } - - return totlen; } #endif /* ADVANSYS_STATS */ /* - * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...} + * advansys_show_info() - /proc/scsi/advansys/{0,1,2,3,...} * - * *buffer: I/O buffer - * **start: if inout == FALSE pointer into buffer where user read should start - * offset: current offset into a /proc/scsi/advansys/[0...] file - * length: length of buffer - * hostno: Scsi_Host host_no - * inout: TRUE - user is writing; FALSE - user is reading + * m: seq_file to print into + * shost: Scsi_Host * * Return the number of bytes read from or written to a * /proc/scsi/advansys/[0...] file. - * - * Note: This function uses the per board buffer 'prtbuf' which is - * allocated when the board is initialized in advansys_detect(). The - * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is - * used to write to the buffer. The way asc_proc_copy() is written - * if 'prtbuf' is too small it will not be overwritten. Instead the - * user just won't get all the available statistics. */ static int -advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, - off_t offset, int length, int inout) +advansys_show_info(struct seq_file *m, struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - char *cp; - int cplen; - int cnt; - int totcnt; - int leftlen; - char *curbuf; - off_t advoffset; ASC_DBG(1, "begin\n"); /* - * User write not supported. - */ - if (inout == TRUE) - return -ENOSYS; - - /* * User read of /proc/scsi/advansys/[0...] file. */ - /* Copy read data starting at the beginning of the buffer. */ - *start = buffer; - curbuf = buffer; - advoffset = 0; - totcnt = 0; - leftlen = length; - /* * Get board configuration information. * * advansys_info() returns the board string from its own static buffer. */ - cp = (char *)advansys_info(shost); - strcat(cp, "\n"); - cplen = strlen(cp); /* Copy board information. */ - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; - + seq_printf(m, "%s\n", (char *)advansys_info(shost)); /* * Display Wide Board BIOS Information. */ - if (!ASC_NARROW_BOARD(boardp)) { - cp = boardp->prtbuf; - cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, - cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; - } + if (!ASC_NARROW_BOARD(boardp)) + asc_prt_adv_bios(m, shost); /* * Display driver information for each device attached to the board. */ - cp = boardp->prtbuf; - cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + asc_prt_board_devices(m, shost); /* * Display EEPROM configuration for the board. */ - cp = boardp->prtbuf; - if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); - } else { - cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); - } - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + if (ASC_NARROW_BOARD(boardp)) + asc_prt_asc_board_eeprom(m, shost); + else + asc_prt_adv_board_eeprom(m, shost); /* * Display driver configuration and information for the board. */ - cp = boardp->prtbuf; - cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + asc_prt_driver_conf(m, shost); #ifdef ADVANSYS_STATS /* * Display driver statistics for the board. */ - cp = boardp->prtbuf; - cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + asc_prt_board_stats(m, shost); #endif /* ADVANSYS_STATS */ /* * Display Asc Library dynamic configuration information * for the board. */ - cp = boardp->prtbuf; - if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE); - } else { - cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); - } - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG(1, "totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; - - ASC_DBG(1, "totcnt %d\n", totcnt); - - return totcnt; + if (ASC_NARROW_BOARD(boardp)) + asc_prt_asc_board_info(m, shost); + else + asc_prt_adv_board_info(m, shost); + return 0; } #endif /* CONFIG_PROC_FS */ @@ -11743,7 +11250,7 @@ static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) static struct scsi_host_template advansys_template = { .proc_name = DRV_NAME, #ifdef CONFIG_PROC_FS - .proc_info = advansys_proc_info, + .show_info = advansys_show_info, #endif .name = DRV_NAME, .info = advansys_info, @@ -11939,20 +11446,6 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop, #endif /* CONFIG_PCI */ } -#ifdef CONFIG_PROC_FS - /* - * Allocate buffer for printing information from - * /proc/scsi/advansys/[0...]. - */ - boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); - if (!boardp->prtbuf) { - shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n", - ASC_PRTBUF_SIZE); - ret = -ENOMEM; - goto err_unmap; - } -#endif /* CONFIG_PROC_FS */ - if (ASC_NARROW_BOARD(boardp)) { /* * Set the board bus type and PCI IRQ before @@ -12010,7 +11503,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop, } if (ret) - goto err_free_proc; + goto err_unmap; /* * Save the EEPROM configuration so that it can be displayed @@ -12055,7 +11548,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop, ASC_DBG(2, "AscInitSetConfig()\n"); ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0; if (ret) - goto err_free_proc; + goto err_unmap; } else { ADVEEP_3550_CONFIG *ep_3550; ADVEEP_38C0800_CONFIG *ep_38C0800; @@ -12290,7 +11783,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop, shost_printk(KERN_ERR, shost, "request_dma() " "%d failed %d\n", shost->dma_channel, ret); - goto err_free_proc; + goto err_unmap; } AscEnableIsaDma(shost->dma_channel); } @@ -12371,8 +11864,6 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop, if (shost->dma_channel != NO_ISA_DMA) free_dma(shost->dma_channel); #endif - err_free_proc: - kfree(boardp->prtbuf); err_unmap: if (boardp->ioremap_addr) iounmap(boardp->ioremap_addr); @@ -12406,7 +11897,6 @@ static int advansys_release(struct Scsi_Host *shost) iounmap(board->ioremap_addr); advansys_wide_free_mem(board); } - kfree(board->prtbuf); scsi_host_put(shost); ASC_DBG(1, "end\n"); return 0; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index a284be17699..3f7b6fee0a7 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -2977,11 +2977,10 @@ static void show_queues(struct Scsi_Host *shpnt) } #undef SPRINTF -#define SPRINTF(args...) pos += sprintf(pos, ## args) +#define SPRINTF(args...) seq_printf(m, ##args) -static int get_command(char *pos, Scsi_Cmnd * ptr) +static void get_command(struct seq_file *m, Scsi_Cmnd * ptr) { - char *start = pos; int i; SPRINTF("%p: target=%d; lun=%d; cmnd=( ", @@ -3011,13 +3010,10 @@ static int get_command(char *pos, Scsi_Cmnd * ptr) if (ptr->SCp.phase & syncneg) SPRINTF("syncneg|"); SPRINTF("; next=0x%p\n", SCNEXT(ptr)); - - return (pos - start); } -static int get_ports(struct Scsi_Host *shpnt, char *pos) +static void get_ports(struct seq_file *m, struct Scsi_Host *shpnt) { - char *start = pos; int s; SPRINTF("\n%s: %s(%s) ", CURRENT_SC ? "on bus" : "waiting", states[STATE].name, states[PREVSTATE].name); @@ -3273,11 +3269,9 @@ static int get_ports(struct Scsi_Host *shpnt, char *pos) if (s & ENREQINIT) SPRINTF("ENREQINIT "); SPRINTF(")\n"); - - return (pos - start); } -static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt) +static int aha152x_set_info(struct Scsi_Host *shpnt, char *buffer, int length) { if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0) return -EINVAL; @@ -3320,26 +3314,11 @@ static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt) return length; } -#undef SPRINTF -#define SPRINTF(args...) \ - do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0) - -static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, - off_t offset, int length, int inout) +static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt) { int i; - char *pos = buffer; Scsi_Cmnd *ptr; unsigned long flags; - int thislength; - - DPRINTK(debug_procinfo, - KERN_DEBUG "aha152x_proc_info: buffer=%p offset=%ld length=%d hostno=%d inout=%d\n", - buffer, offset, length, shpnt->host_no, inout); - - - if (inout) - return aha152x_set_info(buffer, length, shpnt); SPRINTF(AHA152X_REVID "\n"); @@ -3392,25 +3371,25 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start if (ISSUE_SC) { SPRINTF("not yet issued commands:\n"); for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr)) - pos += get_command(pos, ptr); + get_command(m, ptr); } else SPRINTF("no not yet issued commands\n"); DO_UNLOCK(flags); if (CURRENT_SC) { SPRINTF("current command:\n"); - pos += get_command(pos, CURRENT_SC); + get_command(m, CURRENT_SC); } else SPRINTF("no current command\n"); if (DISCONNECTED_SC) { SPRINTF("disconnected commands:\n"); for (ptr = DISCONNECTED_SC; ptr; ptr = SCNEXT(ptr)) - pos += get_command(pos, ptr); + get_command(m, ptr); } else SPRINTF("no disconnected commands\n"); - pos += get_ports(shpnt, pos); + get_ports(m, shpnt); #if defined(AHA152X_STAT) SPRINTF("statistics:\n" @@ -3440,24 +3419,7 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start HOSTDATA(shpnt)->time[i]); } #endif - - DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: pos=%p\n", pos); - - thislength = pos - (buffer + offset); - DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: length=%d thislength=%d\n", length, thislength); - - if(thislength<0) { - DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: output too short\n"); - *start = NULL; - return 0; - } - - thislength = thislength<length ? thislength : length; - - DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: return %d\n", thislength); - - *start = buffer + offset; - return thislength < length ? thislength : length; + return 0; } static int aha152x_adjust_queue(struct scsi_device *device) @@ -3470,7 +3432,8 @@ static struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, .proc_name = "aha152x", - .proc_info = aha152x_proc_info, + .show_info = aha152x_show_info, + .write_info = aha152x_set_info, .queuecommand = aha152x_queue, .eh_abort_handler = aha152x_abort, .eh_device_reset_handler = aha152x_device_reset, diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index df775e6ba57..5f3101797c9 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -106,33 +106,14 @@ static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu) return hdata->ecb_dma_addr + offset; } -static int aha1740_proc_info(struct Scsi_Host *shpnt, char *buffer, - char **start, off_t offset, - int length, int inout) +static int aha1740_show_info(struct seq_file *m, struct Scsi_Host *shpnt) { - int len; - struct aha1740_hostdata *host; - - if (inout) - return-ENOSYS; - - host = HOSTDATA(shpnt); - - len = sprintf(buffer, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n" + struct aha1740_hostdata *host = HOSTDATA(shpnt); + seq_printf(m, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n" "Extended translation %sabled.\n", shpnt->io_port, shpnt->irq, host->edev->slot, host->translation ? "en" : "dis"); - - if (offset > len) { - *start = buffer; - return 0; - } - - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; - return len; + return 0; } static int aha1740_makecode(unchar *sense, unchar *status) @@ -556,7 +537,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy) static struct scsi_host_template aha1740_template = { .module = THIS_MODULE, .proc_name = "aha1740", - .proc_info = aha1740_proc_info, + .show_info = aha1740_show_info, .name = "Adaptec 174x (EISA)", .queuecommand = aha1740_queuecommand, .bios_param = aha1740_biosparam, diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 9328121804b..69d5c43a65e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -906,7 +906,8 @@ struct scsi_host_template aic79xx_driver_template = { .module = THIS_MODULE, .name = "aic79xx", .proc_name = "aic79xx", - .proc_info = ahd_linux_proc_info, + .show_info = ahd_linux_show_info, + .write_info = ahd_proc_write_seeprom, .info = ahd_linux_info, .queuecommand = ahd_linux_queue, .eh_abort_handler = ahd_linux_abort, @@ -1702,19 +1703,13 @@ ahd_send_async(struct ahd_softc *ahd, char channel, switch (code) { case AC_TRANSFER_NEG: { - char buf[80]; struct scsi_target *starget; - struct info_str info; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; unsigned int target_ppr_options; BUG_ON(target == CAM_TARGET_WILDCARD); - info.buffer = buf; - info.length = sizeof(buf); - info.offset = 0; - info.pos = 0; tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id, target, &tstate); diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 28e43498cdf..c58fa33c659 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -379,14 +379,6 @@ void ahd_insb(struct ahd_softc * ahd, long port, int ahd_linux_register_host(struct ahd_softc *, struct scsi_host_template *); -/*************************** Pretty Printing **********************************/ -struct info_str { - char *buffer; - int length; - off_t offset; - int pos; -}; - /******************************** Locking *************************************/ static inline void ahd_lockinit(struct ahd_softc *ahd) @@ -513,8 +505,8 @@ ahd_flush_device_writes(struct ahd_softc *ahd) } /**************************** Proc FS Support *********************************/ -int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, - off_t, int, int); +int ahd_proc_write_seeprom(struct Scsi_Host *, char *, int); +int ahd_linux_show_info(struct seq_file *,struct Scsi_Host *); /*********************** Transaction Access Wrappers **************************/ static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t); diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 59c85d5a153..e9778b4f7e3 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -42,16 +42,12 @@ #include "aic79xx_osm.h" #include "aic79xx_inline.h" -static void copy_mem_info(struct info_str *info, char *data, int len); -static int copy_info(struct info_str *info, char *fmt, ...); static void ahd_dump_target_state(struct ahd_softc *ahd, - struct info_str *info, + struct seq_file *m, u_int our_id, char channel, u_int target_id); -static void ahd_dump_device_state(struct info_str *info, +static void ahd_dump_device_state(struct seq_file *m, struct scsi_device *sdev); -static int ahd_proc_write_seeprom(struct ahd_softc *ahd, - char *buffer, int length); /* * Table of syncrates that don't follow the "divisible by 4" @@ -93,58 +89,15 @@ ahd_calc_syncsrate(u_int period_factor) return (10000000 / (period_factor * 4 * 10)); } - -static void -copy_mem_info(struct info_str *info, char *data, int len) -{ - if (info->pos + len > info->offset + info->length) - len = info->offset + info->length - info->pos; - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - off_t partial; - - partial = info->offset - info->pos; - data += partial; - info->pos += partial; - len -= partial; - } - - if (len > 0) { - memcpy(info->buffer, data, len); - info->pos += len; - info->buffer += len; - } -} - -static int -copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[256]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - return (len); -} - static void -ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) +ahd_format_transinfo(struct seq_file *m, struct ahd_transinfo *tinfo) { u_int speed; u_int freq; u_int mb; if (tinfo->period == AHD_PERIOD_UNKNOWN) { - copy_info(info, "Renegotiation Pending\n"); + seq_printf(m, "Renegotiation Pending\n"); return; } speed = 3300; @@ -156,34 +109,34 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) speed *= (0x01 << tinfo->width); mb = speed / 1000; if (mb > 0) - copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000); + seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000); else - copy_info(info, "%dKB/s transfers", speed); + seq_printf(m, "%dKB/s transfers", speed); if (freq != 0) { int printed_options; printed_options = 0; - copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000); + seq_printf(m, " (%d.%03dMHz", freq / 1000, freq % 1000); if ((tinfo->ppr_options & MSG_EXT_PPR_RD_STRM) != 0) { - copy_info(info, " RDSTRM"); + seq_printf(m, " RDSTRM"); printed_options++; } if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { - copy_info(info, "%s", printed_options ? "|DT" : " DT"); + seq_printf(m, "%s", printed_options ? "|DT" : " DT"); printed_options++; } if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - copy_info(info, "%s", printed_options ? "|IU" : " IU"); + seq_printf(m, "%s", printed_options ? "|IU" : " IU"); printed_options++; } if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) { - copy_info(info, "%s", + seq_printf(m, "%s", printed_options ? "|RTI" : " RTI"); printed_options++; } if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { - copy_info(info, "%s", + seq_printf(m, "%s", printed_options ? "|QAS" : " QAS"); printed_options++; } @@ -191,19 +144,19 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) if (tinfo->width > 0) { if (freq != 0) { - copy_info(info, ", "); + seq_printf(m, ", "); } else { - copy_info(info, " ("); + seq_printf(m, " ("); } - copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width)); + seq_printf(m, "%dbit)", 8 * (0x01 << tinfo->width)); } else if (freq != 0) { - copy_info(info, ")"); + seq_printf(m, ")"); } - copy_info(info, "\n"); + seq_printf(m, "\n"); } static void -ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, +ahd_dump_target_state(struct ahd_softc *ahd, struct seq_file *m, u_int our_id, char channel, u_int target_id) { struct scsi_target *starget; @@ -213,17 +166,17 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, tinfo = ahd_fetch_transinfo(ahd, channel, our_id, target_id, &tstate); - copy_info(info, "Target %d Negotiation Settings\n", target_id); - copy_info(info, "\tUser: "); - ahd_format_transinfo(info, &tinfo->user); + seq_printf(m, "Target %d Negotiation Settings\n", target_id); + seq_printf(m, "\tUser: "); + ahd_format_transinfo(m, &tinfo->user); starget = ahd->platform_data->starget[target_id]; if (starget == NULL) return; - copy_info(info, "\tGoal: "); - ahd_format_transinfo(info, &tinfo->goal); - copy_info(info, "\tCurr: "); - ahd_format_transinfo(info, &tinfo->curr); + seq_printf(m, "\tGoal: "); + ahd_format_transinfo(m, &tinfo->goal); + seq_printf(m, "\tCurr: "); + ahd_format_transinfo(m, &tinfo->curr); for (lun = 0; lun < AHD_NUM_LUNS; lun++) { struct scsi_device *dev; @@ -233,29 +186,30 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, if (dev == NULL) continue; - ahd_dump_device_state(info, dev); + ahd_dump_device_state(m, dev); } } static void -ahd_dump_device_state(struct info_str *info, struct scsi_device *sdev) +ahd_dump_device_state(struct seq_file *m, struct scsi_device *sdev) { struct ahd_linux_device *dev = scsi_transport_device_data(sdev); - copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", + seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n", sdev->sdev_target->channel + 'A', sdev->sdev_target->id, sdev->lun); - copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); - copy_info(info, "\t\tCommands Active %d\n", dev->active); - copy_info(info, "\t\tCommand Openings %d\n", dev->openings); - copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags); - copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); + seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued); + seq_printf(m, "\t\tCommands Active %d\n", dev->active); + seq_printf(m, "\t\tCommand Openings %d\n", dev->openings); + seq_printf(m, "\t\tMax Tagged Openings %d\n", dev->maxtags); + seq_printf(m, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); } -static int -ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) +int +ahd_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length) { + struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; ahd_mode_state saved_modes; int have_seeprom; u_long s; @@ -319,64 +273,45 @@ done: * Return information to handle /proc support for the driver. */ int -ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, - off_t offset, int length, int inout) +ahd_linux_show_info(struct seq_file *m, struct Scsi_Host *shost) { struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; - struct info_str info; char ahd_info[256]; u_int max_targ; u_int i; - int retval; - /* Has data been written to the file? */ - if (inout == TRUE) { - retval = ahd_proc_write_seeprom(ahd, buffer, length); - goto done; - } - - if (start) - *start = buffer; - - info.buffer = buffer; - info.length = length; - info.offset = offset; - info.pos = 0; - - copy_info(&info, "Adaptec AIC79xx driver version: %s\n", + seq_printf(m, "Adaptec AIC79xx driver version: %s\n", AIC79XX_DRIVER_VERSION); - copy_info(&info, "%s\n", ahd->description); + seq_printf(m, "%s\n", ahd->description); ahd_controller_info(ahd, ahd_info); - copy_info(&info, "%s\n", ahd_info); - copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", + seq_printf(m, "%s\n", ahd_info); + seq_printf(m, "Allocated SCBs: %d, SG List Length: %d\n\n", ahd->scb_data.numscbs, AHD_NSEG); max_targ = 16; if (ahd->seep_config == NULL) - copy_info(&info, "No Serial EEPROM\n"); + seq_printf(m, "No Serial EEPROM\n"); else { - copy_info(&info, "Serial EEPROM:\n"); + seq_printf(m, "Serial EEPROM:\n"); for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) { if (((i % 8) == 0) && (i != 0)) { - copy_info(&info, "\n"); + seq_printf(m, "\n"); } - copy_info(&info, "0x%.4x ", + seq_printf(m, "0x%.4x ", ((uint16_t*)ahd->seep_config)[i]); } - copy_info(&info, "\n"); + seq_printf(m, "\n"); } - copy_info(&info, "\n"); + seq_printf(m, "\n"); if ((ahd->features & AHD_WIDE) == 0) max_targ = 8; for (i = 0; i < max_targ; i++) { - ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', + ahd_dump_target_state(ahd, m, ahd->our_id, 'A', /*target_id*/i); } - retval = info.pos > info.offset ? info.pos - info.offset : 0; -done: - return (retval); + return 0; } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 5a477cdc780..c0c62583b54 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -803,7 +803,8 @@ struct scsi_host_template aic7xxx_driver_template = { .module = THIS_MODULE, .name = "aic7xxx", .proc_name = "aic7xxx", - .proc_info = ahc_linux_proc_info, + .show_info = ahc_linux_show_info, + .write_info = ahc_proc_write_seeprom, .info = ahc_linux_info, .queuecommand = ahc_linux_queue, .eh_abort_handler = ahc_linux_abort, @@ -1631,10 +1632,8 @@ ahc_send_async(struct ahc_softc *ahc, char channel, switch (code) { case AC_TRANSFER_NEG: { - char buf[80]; struct scsi_target *starget; struct ahc_linux_target *targ; - struct info_str info; struct ahc_initiator_tinfo *tinfo; struct ahc_tmode_tstate *tstate; int target_offset; @@ -1642,10 +1641,6 @@ ahc_send_async(struct ahc_softc *ahc, char channel, BUG_ON(target == CAM_TARGET_WILDCARD); - info.buffer = buf; - info.length = sizeof(buf); - info.offset = 0; - info.pos = 0; tinfo = ahc_fetch_transinfo(ahc, channel, channel == 'A' ? ahc->our_id : ahc->our_id_b, diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index bca0fb83f55..bc4cca92ff0 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -383,14 +383,6 @@ void ahc_insb(struct ahc_softc * ahc, long port, int ahc_linux_register_host(struct ahc_softc *, struct scsi_host_template *); -/*************************** Pretty Printing **********************************/ -struct info_str { - char *buffer; - int length; - off_t offset; - int pos; -}; - /******************************** Locking *************************************/ /* Lock protecting internal data structures */ @@ -523,8 +515,8 @@ ahc_flush_device_writes(struct ahc_softc *ahc) } /**************************** Proc FS Support *********************************/ -int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, - off_t, int, int); +int ahc_proc_write_seeprom(struct Scsi_Host *, char *, int); +int ahc_linux_show_info(struct seq_file *, struct Scsi_Host *); /*************************** Domain Validation ********************************/ /*********************** Transaction Access Wrappers *************************/ diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index f2525f8ed1c..383a3d11652 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -43,16 +43,12 @@ #include "aic7xxx_inline.h" #include "aic7xxx_93cx6.h" -static void copy_mem_info(struct info_str *info, char *data, int len); -static int copy_info(struct info_str *info, char *fmt, ...); static void ahc_dump_target_state(struct ahc_softc *ahc, - struct info_str *info, + struct seq_file *m, u_int our_id, char channel, u_int target_id, u_int target_offset); -static void ahc_dump_device_state(struct info_str *info, +static void ahc_dump_device_state(struct seq_file *m, struct scsi_device *dev); -static int ahc_proc_write_seeprom(struct ahc_softc *ahc, - char *buffer, int length); /* * Table of syncrates that don't follow the "divisible by 4" @@ -94,51 +90,8 @@ ahc_calc_syncsrate(u_int period_factor) return (10000000 / (period_factor * 4 * 10)); } - -static void -copy_mem_info(struct info_str *info, char *data, int len) -{ - if (info->pos + len > info->offset + info->length) - len = info->offset + info->length - info->pos; - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - off_t partial; - - partial = info->offset - info->pos; - data += partial; - info->pos += partial; - len -= partial; - } - - if (len > 0) { - memcpy(info->buffer, data, len); - info->pos += len; - info->buffer += len; - } -} - -static int -copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[256]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - return (len); -} - static void -ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) +ahc_format_transinfo(struct seq_file *m, struct ahc_transinfo *tinfo) { u_int speed; u_int freq; @@ -153,12 +106,12 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) speed *= (0x01 << tinfo->width); mb = speed / 1000; if (mb > 0) - copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000); + seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000); else - copy_info(info, "%dKB/s transfers", speed); + seq_printf(m, "%dKB/s transfers", speed); if (freq != 0) { - copy_info(info, " (%d.%03dMHz%s, offset %d", + seq_printf(m, " (%d.%03dMHz%s, offset %d", freq / 1000, freq % 1000, (tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0 ? " DT" : "", tinfo->offset); @@ -166,19 +119,19 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) if (tinfo->width > 0) { if (freq != 0) { - copy_info(info, ", "); + seq_printf(m, ", "); } else { - copy_info(info, " ("); + seq_printf(m, " ("); } - copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width)); + seq_printf(m, "%dbit)", 8 * (0x01 << tinfo->width)); } else if (freq != 0) { - copy_info(info, ")"); + seq_printf(m, ")"); } - copy_info(info, "\n"); + seq_printf(m, "\n"); } static void -ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, +ahc_dump_target_state(struct ahc_softc *ahc, struct seq_file *m, u_int our_id, char channel, u_int target_id, u_int target_offset) { @@ -190,18 +143,18 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, tinfo = ahc_fetch_transinfo(ahc, channel, our_id, target_id, &tstate); if ((ahc->features & AHC_TWIN) != 0) - copy_info(info, "Channel %c ", channel); - copy_info(info, "Target %d Negotiation Settings\n", target_id); - copy_info(info, "\tUser: "); - ahc_format_transinfo(info, &tinfo->user); + seq_printf(m, "Channel %c ", channel); + seq_printf(m, "Target %d Negotiation Settings\n", target_id); + seq_printf(m, "\tUser: "); + ahc_format_transinfo(m, &tinfo->user); starget = ahc->platform_data->starget[target_offset]; if (!starget) return; - copy_info(info, "\tGoal: "); - ahc_format_transinfo(info, &tinfo->goal); - copy_info(info, "\tCurr: "); - ahc_format_transinfo(info, &tinfo->curr); + seq_printf(m, "\tGoal: "); + ahc_format_transinfo(m, &tinfo->goal); + seq_printf(m, "\tCurr: "); + ahc_format_transinfo(m, &tinfo->curr); for (lun = 0; lun < AHC_NUM_LUNS; lun++) { struct scsi_device *sdev; @@ -211,29 +164,30 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, if (sdev == NULL) continue; - ahc_dump_device_state(info, sdev); + ahc_dump_device_state(m, sdev); } } static void -ahc_dump_device_state(struct info_str *info, struct scsi_device *sdev) +ahc_dump_device_state(struct seq_file *m, struct scsi_device *sdev) { struct ahc_linux_device *dev = scsi_transport_device_data(sdev); - copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", + seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n", sdev->sdev_target->channel + 'A', sdev->sdev_target->id, sdev->lun); - copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); - copy_info(info, "\t\tCommands Active %d\n", dev->active); - copy_info(info, "\t\tCommand Openings %d\n", dev->openings); - copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags); - copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); + seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued); + seq_printf(m, "\t\tCommands Active %d\n", dev->active); + seq_printf(m, "\t\tCommand Openings %d\n", dev->openings); + seq_printf(m, "\t\tMax Tagged Openings %d\n", dev->maxtags); + seq_printf(m, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); } -static int -ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length) +int +ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length) { + struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata; struct seeprom_descriptor sd; int have_seeprom; u_long s; @@ -332,53 +286,36 @@ done: * Return information to handle /proc support for the driver. */ int -ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, - off_t offset, int length, int inout) +ahc_linux_show_info(struct seq_file *m, struct Scsi_Host *shost) { struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata; - struct info_str info; char ahc_info[256]; u_int max_targ; u_int i; - int retval; - /* Has data been written to the file? */ - if (inout == TRUE) { - retval = ahc_proc_write_seeprom(ahc, buffer, length); - goto done; - } - - if (start) - *start = buffer; - - info.buffer = buffer; - info.length = length; - info.offset = offset; - info.pos = 0; - - copy_info(&info, "Adaptec AIC7xxx driver version: %s\n", + seq_printf(m, "Adaptec AIC7xxx driver version: %s\n", AIC7XXX_DRIVER_VERSION); - copy_info(&info, "%s\n", ahc->description); + seq_printf(m, "%s\n", ahc->description); ahc_controller_info(ahc, ahc_info); - copy_info(&info, "%s\n", ahc_info); - copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", + seq_printf(m, "%s\n", ahc_info); + seq_printf(m, "Allocated SCBs: %d, SG List Length: %d\n\n", ahc->scb_data->numscbs, AHC_NSEG); if (ahc->seep_config == NULL) - copy_info(&info, "No Serial EEPROM\n"); + seq_printf(m, "No Serial EEPROM\n"); else { - copy_info(&info, "Serial EEPROM:\n"); + seq_printf(m, "Serial EEPROM:\n"); for (i = 0; i < sizeof(*ahc->seep_config)/2; i++) { if (((i % 8) == 0) && (i != 0)) { - copy_info(&info, "\n"); + seq_printf(m, "\n"); } - copy_info(&info, "0x%.4x ", + seq_printf(m, "0x%.4x ", ((uint16_t*)ahc->seep_config)[i]); } - copy_info(&info, "\n"); + seq_printf(m, "\n"); } - copy_info(&info, "\n"); + seq_printf(m, "\n"); max_targ = 16; if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0) @@ -398,10 +335,8 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, target_id = i % 8; } - ahc_dump_target_state(ahc, &info, our_id, + ahc_dump_target_state(ahc, m, our_id, channel, target_id, i); } - retval = info.pos > info.offset ? info.pos - info.offset : 0; -done: - return (retval); + return 0; } diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 5b212f0df89..33ec9c64340 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -11108,7 +11108,7 @@ MODULE_VERSION(AIC7XXX_H_VERSION); static struct scsi_host_template driver_template = { - .proc_info = aic7xxx_proc_info, + .show_info = aic7xxx_show_info, .detect = aic7xxx_detect, .release = aic7xxx_release, .info = aic7xxx_info, diff --git a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c index b07e4f04fd0..976f45ccf2c 100644 --- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c @@ -30,62 +30,23 @@ *-M*************************************************************************/ -#define BLS (&aic7xxx_buffer[size]) #define HDRB \ " 0 - 4K 4 - 16K 16 - 64K 64 - 256K 256K - 1M 1M+" -#ifdef PROC_DEBUG -extern int vsprintf(char *, const char *, va_list); - -static void -proc_debug(const char *fmt, ...) -{ - va_list ap; - char buf[256]; - - va_start(ap, fmt); - vsprintf(buf, fmt, ap); - printk(buf); - va_end(ap); -} -#else /* PROC_DEBUG */ -# define proc_debug(fmt, args...) -#endif /* PROC_DEBUG */ - -static int aic7xxx_buffer_size = 0; -static char *aic7xxx_buffer = NULL; - /*+F************************************************************************* * Function: - * aic7xxx_set_info - * - * Description: - * Set parameters for the driver from the /proc filesystem. - *-F*************************************************************************/ -static int -aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) -{ - proc_debug("aic7xxx_set_info(): %s\n", buffer); - return (-ENOSYS); /* Currently this is a no-op */ -} - - -/*+F************************************************************************* - * Function: - * aic7xxx_proc_info + * aic7xxx_show_info * * Description: * Return information to handle /proc support for the driver. *-F*************************************************************************/ int -aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, - int inout) +aic7xxx_show_info(struct seq_file *m, struct Scsi_Host *HBAptr) { struct aic7xxx_host *p; struct aic_dev_data *aic_dev; struct scsi_device *sdptr; - int size = 0; unsigned char i; unsigned char tindex; @@ -94,66 +55,21 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t if (!p) { - size += sprintf(buffer, "Can't find adapter for host number %d\n", HBAptr->host_no); - if (size > length) - { - return (size); - } - else - { - return (length); - } - } - - if (inout == TRUE) /* Has data been written to the file? */ - { - return (aic7xxx_set_info(buffer, length, HBAptr)); + seq_printf(m, "Can't find adapter for host number %d\n", HBAptr->host_no); + return 0; } p = (struct aic7xxx_host *) HBAptr->hostdata; - /* - * It takes roughly 1K of space to hold all relevant card info, not - * counting any proc stats, so we start out with a 1.5k buffer size and - * if proc_stats is defined, then we sweep the stats structure to see - * how many drives we will be printing out for and add 384 bytes per - * device with active stats. - * - * Hmmmm...that 1.5k seems to keep growing as items get added so they - * can be easily viewed for debugging purposes. So, we bumped that - * 1.5k to 4k so we can quit having to bump it all the time. - */ - - size = 4096; - list_for_each_entry(aic_dev, &p->aic_devs, list) - size += 512; - if (aic7xxx_buffer_size != size) - { - if (aic7xxx_buffer != NULL) - { - kfree(aic7xxx_buffer); - aic7xxx_buffer_size = 0; - } - aic7xxx_buffer = kmalloc(size, GFP_KERNEL); - } - if (aic7xxx_buffer == NULL) - { - size = sprintf(buffer, "AIC7xxx - kmalloc error at line %d\n", - __LINE__); - return size; - } - aic7xxx_buffer_size = size; - - size = 0; - size += sprintf(BLS, "Adaptec AIC7xxx driver version: "); - size += sprintf(BLS, "%s/", AIC7XXX_C_VERSION); - size += sprintf(BLS, "%s", AIC7XXX_H_VERSION); - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Adapter Configuration:\n"); - size += sprintf(BLS, " SCSI Adapter: %s\n", + seq_printf(m, "Adaptec AIC7xxx driver version: "); + seq_printf(m, "%s/", AIC7XXX_C_VERSION); + seq_printf(m, "%s", AIC7XXX_H_VERSION); + seq_printf(m, "\n"); + seq_printf(m, "Adapter Configuration:\n"); + seq_printf(m, " SCSI Adapter: %s\n", board_names[p->board_name_index]); if (p->flags & AHC_TWIN) - size += sprintf(BLS, " Twin Channel Controller "); + seq_printf(m, " Twin Channel Controller "); else { char *channel = ""; @@ -184,86 +100,86 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t ultra = "Ultra-2 LVD/SE "; else if (p->features & AHC_ULTRA) ultra = "Ultra "; - size += sprintf(BLS, " %s%sController%s ", + seq_printf(m, " %s%sController%s ", ultra, wide, channel); } switch(p->chip & ~AHC_CHIPID_MASK) { case AHC_VL: - size += sprintf(BLS, "at VLB slot %d\n", p->pci_device_fn); + seq_printf(m, "at VLB slot %d\n", p->pci_device_fn); break; case AHC_EISA: - size += sprintf(BLS, "at EISA slot %d\n", p->pci_device_fn); + seq_printf(m, "at EISA slot %d\n", p->pci_device_fn); break; default: - size += sprintf(BLS, "at PCI %d/%d/%d\n", p->pci_bus, + seq_printf(m, "at PCI %d/%d/%d\n", p->pci_bus, PCI_SLOT(p->pci_device_fn), PCI_FUNC(p->pci_device_fn)); break; } if( !(p->maddr) ) { - size += sprintf(BLS, " Programmed I/O Base: %lx\n", p->base); + seq_printf(m, " Programmed I/O Base: %lx\n", p->base); } else { - size += sprintf(BLS, " PCI MMAPed I/O Base: 0x%lx\n", p->mbase); + seq_printf(m, " PCI MMAPed I/O Base: 0x%lx\n", p->mbase); } if( (p->chip & (AHC_VL | AHC_EISA)) ) { - size += sprintf(BLS, " BIOS Memory Address: 0x%08x\n", p->bios_address); + seq_printf(m, " BIOS Memory Address: 0x%08x\n", p->bios_address); } - size += sprintf(BLS, " Adapter SEEPROM Config: %s\n", + seq_printf(m, " Adapter SEEPROM Config: %s\n", (p->flags & AHC_SEEPROM_FOUND) ? "SEEPROM found and used." : ((p->flags & AHC_USEDEFAULTS) ? "SEEPROM not found, using defaults." : "SEEPROM not found, using leftover BIOS values.") ); - size += sprintf(BLS, " Adaptec SCSI BIOS: %s\n", + seq_printf(m, " Adaptec SCSI BIOS: %s\n", (p->flags & AHC_BIOS_ENABLED) ? "Enabled" : "Disabled"); - size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); - size += sprintf(BLS, " SCBs: Active %d, Max Active %d,\n", + seq_printf(m, " IRQ: %d\n", HBAptr->irq); + seq_printf(m, " SCBs: Active %d, Max Active %d,\n", p->activescbs, p->max_activescbs); - size += sprintf(BLS, " Allocated %d, HW %d, " + seq_printf(m, " Allocated %d, HW %d, " "Page %d\n", p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); if (p->flags & AHC_EXTERNAL_SRAM) - size += sprintf(BLS, " Using External SCB SRAM\n"); - size += sprintf(BLS, " Interrupts: %ld", p->isr_count); + seq_printf(m, " Using External SCB SRAM\n"); + seq_printf(m, " Interrupts: %ld", p->isr_count); if (p->chip & AHC_EISA) { - size += sprintf(BLS, " %s\n", + seq_printf(m, " %s\n", (p->pause & IRQMS) ? "(Level Sensitive)" : "(Edge Triggered)"); } else { - size += sprintf(BLS, "\n"); + seq_printf(m, "\n"); } - size += sprintf(BLS, " BIOS Control Word: 0x%04x\n", + seq_printf(m, " BIOS Control Word: 0x%04x\n", p->bios_control); - size += sprintf(BLS, " Adapter Control Word: 0x%04x\n", + seq_printf(m, " Adapter Control Word: 0x%04x\n", p->adapter_control); - size += sprintf(BLS, " Extended Translation: %sabled\n", + seq_printf(m, " Extended Translation: %sabled\n", (p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis"); - size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable); + seq_printf(m, "Disconnect Enable Flags: 0x%04x\n", p->discenable); if (p->features & (AHC_ULTRA | AHC_ULTRA2)) { - size += sprintf(BLS, " Ultra Enable Flags: 0x%04x\n", p->ultraenb); + seq_printf(m, " Ultra Enable Flags: 0x%04x\n", p->ultraenb); } - size += sprintf(BLS, "Default Tag Queue Depth: %d\n", aic7xxx_default_queue_depth); - size += sprintf(BLS, " Tagged Queue By Device array for aic7xxx host " + seq_printf(m, "Default Tag Queue Depth: %d\n", aic7xxx_default_queue_depth); + seq_printf(m, " Tagged Queue By Device array for aic7xxx host " "instance %d:\n", p->instance); - size += sprintf(BLS, " {"); + seq_printf(m, " {"); for(i=0; i < (MAX_TARGETS - 1); i++) - size += sprintf(BLS, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]); - size += sprintf(BLS, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]); + seq_printf(m, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]); + seq_printf(m, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]); - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Statistics:\n\n"); + seq_printf(m, "\n"); + seq_printf(m, "Statistics:\n\n"); list_for_each_entry(aic_dev, &p->aic_devs, list) { sdptr = aic_dev->SDptr; tindex = sdptr->channel << 3 | sdptr->id; - size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n", + seq_printf(m, "(scsi%d:%d:%d:%d)\n", p->host_no, sdptr->channel, sdptr->id, sdptr->lun); - size += sprintf(BLS, " Device using %s/%s", + seq_printf(m, " Device using %s/%s", (aic_dev->cur.width == MSG_EXT_WDTR_BUS_16_BIT) ? "Wide" : "Narrow", (aic_dev->cur.offset != 0) ? @@ -279,78 +195,59 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t sync_rate = aic7xxx_find_syncrate(p, &period, 0, &options); if (sync_rate != NULL) { - size += sprintf(BLS, "%s MByte/sec, offset %d\n", + seq_printf(m, "%s MByte/sec, offset %d\n", sync_rate->rate[rate], aic_dev->cur.offset ); } else { - size += sprintf(BLS, "3.3 MByte/sec, offset %d\n", + seq_printf(m, "3.3 MByte/sec, offset %d\n", aic_dev->cur.offset ); } } - size += sprintf(BLS, " Transinfo settings: "); - size += sprintf(BLS, "current(%d/%d/%d/%d), ", + seq_printf(m, " Transinfo settings: "); + seq_printf(m, "current(%d/%d/%d/%d), ", aic_dev->cur.period, aic_dev->cur.offset, aic_dev->cur.width, aic_dev->cur.options); - size += sprintf(BLS, "goal(%d/%d/%d/%d), ", + seq_printf(m, "goal(%d/%d/%d/%d), ", aic_dev->goal.period, aic_dev->goal.offset, aic_dev->goal.width, aic_dev->goal.options); - size += sprintf(BLS, "user(%d/%d/%d/%d)\n", + seq_printf(m, "user(%d/%d/%d/%d)\n", p->user[tindex].period, p->user[tindex].offset, p->user[tindex].width, p->user[tindex].options); if(sdptr->simple_tags) { - size += sprintf(BLS, " Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth); + seq_printf(m, " Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth); } if(aic_dev->barrier_total) - size += sprintf(BLS, " Total transfers %ld:\n (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n", + seq_printf(m, " Total transfers %ld:\n (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n", aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total, aic_dev->barrier_total, aic_dev->ordered_total); else - size += sprintf(BLS, " Total transfers %ld:\n (%ld/%ld reads/writes)\n", + seq_printf(m, " Total transfers %ld:\n (%ld/%ld reads/writes)\n", aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total); - size += sprintf(BLS, "%s\n", HDRB); - size += sprintf(BLS, " Reads:"); + seq_printf(m, "%s\n", HDRB); + seq_printf(m, " Reads:"); for (i = 0; i < ARRAY_SIZE(aic_dev->r_bins); i++) { - size += sprintf(BLS, " %10ld", aic_dev->r_bins[i]); + seq_printf(m, " %10ld", aic_dev->r_bins[i]); } - size += sprintf(BLS, "\n"); - size += sprintf(BLS, " Writes:"); + seq_printf(m, "\n"); + seq_printf(m, " Writes:"); for (i = 0; i < ARRAY_SIZE(aic_dev->w_bins); i++) { - size += sprintf(BLS, " %10ld", aic_dev->w_bins[i]); + seq_printf(m, " %10ld", aic_dev->w_bins[i]); } - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "\n\n"); - } - if (size >= aic7xxx_buffer_size) - { - printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); - } - - if (offset > size - 1) - { - kfree(aic7xxx_buffer); - aic7xxx_buffer = NULL; - aic7xxx_buffer_size = length = 0; - *start = NULL; + seq_printf(m, "\n"); + seq_printf(m, "\n\n"); } - else - { - *start = buffer; - length = min_t(int, length, size - offset); - memcpy(buffer, &aic7xxx_buffer[offset], length); - } - - return (length); + return 0; } /* diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 3e1172adb37..09ba1869d36 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -2836,20 +2836,15 @@ char *acornscsi_info(struct Scsi_Host *host) return string; } -int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset, - int length, int inout) +static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance) { - int pos, begin = 0, devidx; + int devidx; struct scsi_device *scd; AS_Host *host; - char *p = buffer; - - if (inout == 1) - return -EINVAL; host = (AS_Host *)instance->hostdata; - p += sprintf(p, "AcornSCSI driver v%d.%d.%d" + seq_printf(m, "AcornSCSI driver v%d.%d.%d" #ifdef CONFIG_SCSI_ACORNSCSI_SYNC " SYNC" #endif @@ -2864,14 +2859,14 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, #endif "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH); - p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n", + seq_printf(m, "SBIC: WD33C93A Address: %p IRQ : %d\n", host->base + SBIC_REGIDX, host->scsi.irq); #ifdef USE_DMAC - p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n", + seq_printf(m, "DMAC: uPC71071 Address: %p IRQ : %d\n\n", host->base + DMAC_OFFSET, host->scsi.irq); #endif - p += sprintf(p, "Statistics:\n" + seq_printf(m, "Statistics:\n" "Queued commands: %-10u Issued commands: %-10u\n" "Done commands : %-10u Reads : %-10u\n" "Writes : %-10u Others : %-10u\n" @@ -2886,7 +2881,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, for (devidx = 0; devidx < 9; devidx ++) { unsigned int statptr, prev; - p += sprintf(p, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx)); + seq_printf(m, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx)); statptr = host->status_ptr[devidx] - 10; if ((signed int)statptr < 0) @@ -2896,7 +2891,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) { if (host->status[devidx][statptr].when) { - p += sprintf(p, "%c%02X:%02X+%2ld", + seq_printf(m, "%c%02X:%02X+%2ld", host->status[devidx][statptr].irq ? '-' : ' ', host->status[devidx][statptr].ph, host->status[devidx][statptr].ssr, @@ -2907,51 +2902,32 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, } } - p += sprintf(p, "\nAttached devices:\n"); + seq_printf(m, "\nAttached devices:\n"); shost_for_each_device(scd, instance) { - p += sprintf(p, "Device/Lun TaggedQ Sync\n"); - p += sprintf(p, " %d/%d ", scd->id, scd->lun); + seq_printf(m, "Device/Lun TaggedQ Sync\n"); + seq_printf(m, " %d/%d ", scd->id, scd->lun); if (scd->tagged_supported) - p += sprintf(p, "%3sabled(%3d) ", + seq_printf(m, "%3sabled(%3d) ", scd->simple_tags ? "en" : "dis", scd->current_tag); else - p += sprintf(p, "unsupported "); + seq_printf(m, "unsupported "); if (host->device[scd->id].sync_xfer & 15) - p += sprintf(p, "offset %d, %d ns\n", + seq_printf(m, "offset %d, %d ns\n", host->device[scd->id].sync_xfer & 15, acornscsi_getperiod(host->device[scd->id].sync_xfer)); else - p += sprintf(p, "async\n"); + seq_printf(m, "async\n"); - pos = p - buffer; - if (pos + begin < offset) { - begin += pos; - p = buffer; - } - pos = p - buffer; - if (pos + begin > offset + length) { - scsi_device_put(scd); - break; - } } - - pos = p - buffer; - - *start = buffer + (offset - begin); - pos -= offset - begin; - - if (pos > length) - pos = length; - - return pos; + return 0; } static struct scsi_host_template acornscsi_template = { .module = THIS_MODULE, - .proc_info = acornscsi_proc_info, + .show_info = acornscsi_show_info, .name = "AcornSCSI", .info = acornscsi_info, .queuecommand = acornscsi_queuecmd, diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 9274510294a..32d23212de4 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -220,47 +220,21 @@ static const char *arxescsi_info(struct Scsi_Host *host) return string; } -/* - * Function: int arxescsi_proc_info(char *buffer, char **start, off_t offset, - * int length, int host_no, int inout) - * Purpose : Return information about the driver to a user process accessing - * the /proc filesystem. - * Params : buffer - a buffer to write information to - * start - a pointer into this buffer set by this routine to the start - * of the required information. - * offset - offset into information that we have read up to. - * length - length of buffer - * host_no - host number to return information for - * inout - 0 for reading, 1 for writing. - * Returns : length of data written to buffer. - */ static int -arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, - int inout) +arxescsi_show_info(struct seq_file *m, struct Scsi_Host *host) { struct arxescsi_info *info; - char *p = buffer; - int pos; - info = (struct arxescsi_info *)host->hostdata; - if (inout == 1) - return -EINVAL; - - p += sprintf(p, "ARXE 16-bit SCSI driver v%s\n", VERSION); - p += fas216_print_host(&info->info, p); - p += fas216_print_stats(&info->info, p); - p += fas216_print_devices(&info->info, p); - - *start = buffer + offset; - pos = p - buffer - offset; - if (pos > length) - pos = length; - return pos; + seq_printf(m, "ARXE 16-bit SCSI driver v%s\n", VERSION); + fas216_print_host(&info->info, m); + fas216_print_stats(&info->info, m); + fas216_print_devices(&info->info, m); + return 0; } static struct scsi_host_template arxescsi_template = { - .proc_info = arxescsi_proc_info, + .show_info = arxescsi_show_info, .name = "ARXE SCSI card", .info = arxescsi_info, .queuecommand = fas216_noqueue_command, diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index c93938b246d..b679778376c 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -30,7 +30,6 @@ #define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value) #define NCR5380_intr cumanascsi_intr #define NCR5380_queue_command cumanascsi_queue_command -#define NCR5380_proc_info cumanascsi_proc_info #define NCR5380_implementation_fields \ unsigned ctrl; \ diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index e3bae93c3c2..58915f29055 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -337,50 +337,25 @@ cumanascsi_2_set_proc_info(struct Scsi_Host *host, char *buffer, int length) return ret; } -/* Prototype: int cumanascsi_2_proc_info(char *buffer, char **start, off_t offset, - * int length, int host_no, int inout) - * Purpose : Return information about the driver to a user process accessing - * the /proc filesystem. - * Params : buffer - a buffer to write information to - * start - a pointer into this buffer set by this routine to the start - * of the required information. - * offset - offset into information that we have read up to. - * length - length of buffer - * host_no - host number to return information for - * inout - 0 for reading, 1 for writing. - * Returns : length of data written to buffer. - */ -int cumanascsi_2_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int inout) +static int cumanascsi_2_show_info(struct seq_file *m, struct Scsi_Host *host) { struct cumanascsi2_info *info; - char *p = buffer; - int pos; - - if (inout == 1) - return cumanascsi_2_set_proc_info(host, buffer, length); - info = (struct cumanascsi2_info *)host->hostdata; - p += sprintf(p, "Cumana SCSI II driver v%s\n", VERSION); - p += fas216_print_host(&info->info, p); - p += sprintf(p, "Term : o%s\n", + seq_printf(m, "Cumana SCSI II driver v%s\n", VERSION); + fas216_print_host(&info->info, m); + seq_printf(m, "Term : o%s\n", info->terms ? "n" : "ff"); - p += fas216_print_stats(&info->info, p); - p += fas216_print_devices(&info->info, p); - - *start = buffer + offset; - pos = p - buffer - offset; - if (pos > length) - pos = length; - - return pos; + fas216_print_stats(&info->info, m); + fas216_print_devices(&info->info, m); + return 0; } static struct scsi_host_template cumanascsi2_template = { .module = THIS_MODULE, - .proc_info = cumanascsi_2_proc_info, + .show_info = cumanascsi_2_show_info, + .write_info = cumanascsi_2_set_proc_info, .name = "Cumana SCSI II", .info = cumanascsi_2_info, .queuecommand = fas216_queue_command, diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index 8e36908415e..5bf3c0d134b 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -422,45 +422,20 @@ eesoxscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length) return ret; } -/* Prototype: int eesoxscsi_proc_info(char *buffer, char **start, off_t offset, - * int length, int host_no, int inout) - * Purpose : Return information about the driver to a user process accessing - * the /proc filesystem. - * Params : buffer - a buffer to write information to - * start - a pointer into this buffer set by this routine to the start - * of the required information. - * offset - offset into information that we have read up to. - * length - length of buffer - * host_no - host number to return information for - * inout - 0 for reading, 1 for writing. - * Returns : length of data written to buffer. - */ -int eesoxscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int inout) +static int eesoxscsi_show_info(struct seq_file *m, struct Scsi_Host *host) { struct eesoxscsi_info *info; - char *p = buffer; - int pos; - - if (inout == 1) - return eesoxscsi_set_proc_info(host, buffer, length); info = (struct eesoxscsi_info *)host->hostdata; - p += sprintf(p, "EESOX SCSI driver v%s\n", VERSION); - p += fas216_print_host(&info->info, p); - p += sprintf(p, "Term : o%s\n", + seq_printf(m, "EESOX SCSI driver v%s\n", VERSION); + fas216_print_host(&info->info, m); + seq_printf(m, "Term : o%s\n", info->control & EESOX_TERM_ENABLE ? "n" : "ff"); - p += fas216_print_stats(&info->info, p); - p += fas216_print_devices(&info->info, p); - - *start = buffer + offset; - pos = p - buffer - offset; - if (pos > length) - pos = length; - - return pos; + fas216_print_stats(&info->info, m); + fas216_print_devices(&info->info, m); + return 0; } static ssize_t eesoxscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf) @@ -498,7 +473,8 @@ static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, static struct scsi_host_template eesox_template = { .module = THIS_MODULE, - .proc_info = eesoxscsi_proc_info, + .show_info = eesoxscsi_show_info, + .write_info = eesoxscsi_set_proc_info, .name = "EESOX SCSI", .info = eesoxscsi_info, .queuecommand = fas216_queue_command, diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 737554c37d9..b46a6f6c0eb 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2958,9 +2958,9 @@ void fas216_release(struct Scsi_Host *host) queue_free(&info->queues.issue); } -int fas216_print_host(FAS216_Info *info, char *buffer) +void fas216_print_host(FAS216_Info *info, struct seq_file *m) { - return sprintf(buffer, + seq_printf(m, "\n" "Chip : %s\n" " Address: 0x%p\n" @@ -2970,11 +2970,9 @@ int fas216_print_host(FAS216_Info *info, char *buffer) info->scsi.irq, info->scsi.dma); } -int fas216_print_stats(FAS216_Info *info, char *buffer) +void fas216_print_stats(FAS216_Info *info, struct seq_file *m) { - char *p = buffer; - - p += sprintf(p, "\n" + seq_printf(m, "\n" "Command Statistics:\n" " Queued : %u\n" " Issued : %u\n" @@ -2991,38 +2989,33 @@ int fas216_print_stats(FAS216_Info *info, char *buffer) info->stats.writes, info->stats.miscs, info->stats.disconnects, info->stats.aborts, info->stats.bus_resets, info->stats.host_resets); - - return p - buffer; } -int fas216_print_devices(FAS216_Info *info, char *buffer) +void fas216_print_devices(FAS216_Info *info, struct seq_file *m) { struct fas216_device *dev; struct scsi_device *scd; - char *p = buffer; - p += sprintf(p, "Device/Lun TaggedQ Parity Sync\n"); + seq_printf(m, "Device/Lun TaggedQ Parity Sync\n"); shost_for_each_device(scd, info->host) { dev = &info->device[scd->id]; - p += sprintf(p, " %d/%d ", scd->id, scd->lun); + seq_printf(m, " %d/%d ", scd->id, scd->lun); if (scd->tagged_supported) - p += sprintf(p, "%3sabled(%3d) ", + seq_printf(m, "%3sabled(%3d) ", scd->simple_tags ? "en" : "dis", scd->current_tag); else - p += sprintf(p, "unsupported "); + seq_printf(m, "unsupported "); - p += sprintf(p, "%3sabled ", dev->parity_enabled ? "en" : "dis"); + seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis"); if (dev->sof) - p += sprintf(p, "offset %d, %d ns\n", + seq_printf(m, "offset %d, %d ns\n", dev->sof, dev->period * 4); else - p += sprintf(p, "async\n"); + seq_printf(m, "async\n"); } - - return p - buffer; } EXPORT_SYMBOL(fas216_init); diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index df2e1b3ddfe..c57c16ef819 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -358,9 +358,9 @@ extern void fas216_remove (struct Scsi_Host *instance); */ extern void fas216_release (struct Scsi_Host *instance); -extern int fas216_print_host(FAS216_Info *info, char *buffer); -extern int fas216_print_stats(FAS216_Info *info, char *buffer); -extern int fas216_print_devices(FAS216_Info *info, char *buffer); +extern void fas216_print_host(FAS216_Info *info, struct seq_file *m); +extern void fas216_print_stats(FAS216_Info *info, struct seq_file *m); +extern void fas216_print_devices(FAS216_Info *info, struct seq_file *m); /* Function: int fas216_eh_abort(struct scsi_cmnd *SCpnt) * Purpose : abort this command diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index 48facdc1800..4266eef8aca 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -31,7 +31,8 @@ #define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2)) #define NCR5380_intr oakscsi_intr #define NCR5380_queue_command oakscsi_queue_command -#define NCR5380_proc_info oakscsi_proc_info +#define NCR5380_show_info oakscsi_show_info +#define NCR5380_write_info oakscsi_write_info #define NCR5380_implementation_fields \ void __iomem *base @@ -115,7 +116,8 @@ printk("reading %p len %d\n", addr, len); static struct scsi_host_template oakscsi_template = { .module = THIS_MODULE, - .proc_info = oakscsi_proc_info, + .show_info = oakscsi_show_info, + .write_info = oakscsi_write_info, .name = "Oak 16-bit SCSI", .info = oakscsi_info, .queuecommand = oakscsi_queue_command, diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 246600b9355..abc9593615e 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -237,32 +237,20 @@ powertecscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length) * inout - 0 for reading, 1 for writing. * Returns : length of data written to buffer. */ -int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int inout) +static int powertecscsi_show_info(struct seq_file *m, struct Scsi_Host *host) { struct powertec_info *info; - char *p = buffer; - int pos; - - if (inout == 1) - return powertecscsi_set_proc_info(host, buffer, length); info = (struct powertec_info *)host->hostdata; - p += sprintf(p, "PowerTec SCSI driver v%s\n", VERSION); - p += fas216_print_host(&info->info, p); - p += sprintf(p, "Term : o%s\n", + seq_printf(m, "PowerTec SCSI driver v%s\n", VERSION); + fas216_print_host(&info->info, m); + seq_printf(m, "Term : o%s\n", info->term_ctl ? "n" : "ff"); - p += fas216_print_stats(&info->info, p); - p += fas216_print_devices(&info->info, p); - - *start = buffer + offset; - pos = p - buffer - offset; - if (pos > length) - pos = length; - - return pos; + fas216_print_stats(&info->info, m); + fas216_print_devices(&info->info, m); + return 0; } static ssize_t powertecscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf) @@ -291,7 +279,8 @@ static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, static struct scsi_host_template powertecscsi_template = { .module = THIS_MODULE, - .proc_info = powertecscsi_proc_info, + .show_info = powertecscsi_show_info, + .write_info = powertecscsi_set_proc_info, .name = "PowerTec SCSI", .info = powertecscsi_info, .queuecommand = fas216_queue_command, diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 2db79b469d9..0f3cdbc80ba 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -719,119 +719,94 @@ static void __init NCR5380_print_options(struct Scsi_Host *instance) * Inputs : instance, pointer to this instance. */ -static void NCR5380_print_status(struct Scsi_Host *instance) +static void lprint_Scsi_Cmnd(Scsi_Cmnd *cmd) { - char *pr_bfr; - char *start; - int len; - - NCR_PRINT(NDEBUG_ANY); - NCR_PRINT_PHASE(NDEBUG_ANY); - - pr_bfr = (char *)__get_free_page(GFP_ATOMIC); - if (!pr_bfr) { - printk("NCR5380_print_status: no memory for print buffer\n"); - return; - } - len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0); - pr_bfr[len] = 0; - printk("\n%s\n", pr_bfr); - free_page((unsigned long)pr_bfr); + int i, s; + unsigned char *command; + printk("scsi%d: destination target %d, lun %d\n", + H_NO(cmd), cmd->device->id, cmd->device->lun); + printk(KERN_CONT " command = "); + command = cmd->cmnd; + printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]); + for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) + printk(KERN_CONT " %02x", command[i]); + printk("\n"); } - -/******************************************/ -/* - * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED] - * - * *buffer: I/O buffer - * **start: if inout == FALSE pointer into buffer where user read should start - * offset: current offset - * length: length of buffer - * hostno: Scsi_Host host_no - * inout: TRUE - user is writing; FALSE - user is reading - * - * Return the number of bytes read from or written -*/ - -#undef SPRINTF -#define SPRINTF(fmt,args...) \ - do { \ - if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ - pos += sprintf(pos, fmt , ## args); \ - } while(0) -static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length); - -static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, - char **start, off_t offset, int length, int inout) +static void NCR5380_print_status(struct Scsi_Host *instance) { - char *pos = buffer; struct NCR5380_hostdata *hostdata; Scsi_Cmnd *ptr; unsigned long flags; - off_t begin = 0; -#define check_offset() \ - do { \ - if (pos - buffer < offset - begin) { \ - begin += pos - buffer; \ - pos = buffer; \ - } \ - } while (0) + + NCR_PRINT(NDEBUG_ANY); + NCR_PRINT_PHASE(NDEBUG_ANY); hostdata = (struct NCR5380_hostdata *)instance->hostdata; - if (inout) /* Has data been written to the file ? */ - return -ENOSYS; /* Currently this is a no-op */ - SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); - check_offset(); + printk("\nNCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); local_irq_save(flags); - SPRINTF("NCR5380: coroutine is%s running.\n", + printk("NCR5380: coroutine is%s running.\n", main_running ? "" : "n't"); - check_offset(); if (!hostdata->connected) - SPRINTF("scsi%d: no currently connected command\n", HOSTNO); + printk("scsi%d: no currently connected command\n", HOSTNO); else - pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, - pos, buffer, length); - SPRINTF("scsi%d: issue_queue\n", HOSTNO); - check_offset(); - for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); - check_offset(); - } + lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected); + printk("scsi%d: issue_queue\n", HOSTNO); + for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) + lprint_Scsi_Cmnd(ptr); - SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); - check_offset(); + printk("scsi%d: disconnected_queue\n", HOSTNO); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; - ptr = NEXT(ptr)) { - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); - check_offset(); - } + ptr = NEXT(ptr)) + lprint_Scsi_Cmnd(ptr); local_irq_restore(flags); - *start = buffer + (offset - begin); - if (pos - buffer < offset - begin) - return 0; - else if (pos - buffer - (offset - begin) < length) - return pos - buffer - (offset - begin); - return length; + printk("\n"); } -static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length) +static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m) { int i, s; unsigned char *command; - SPRINTF("scsi%d: destination target %d, lun %d\n", + seq_printf(m, "scsi%d: destination target %d, lun %d\n", H_NO(cmd), cmd->device->id, cmd->device->lun); - SPRINTF(" command = "); + seq_printf(m, " command = "); command = cmd->cmnd; - SPRINTF("%2d (0x%02x)", command[0], command[0]); + seq_printf(m, "%2d (0x%02x)", command[0], command[0]); for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) - SPRINTF(" %02x", command[i]); - SPRINTF("\n"); - return pos; + seq_printf(m, " %02x", command[i]); + seq_printf(m, "\n"); } +static int NCR5380_show_info(struct seq_file *m, struct Scsi_Host *instance) +{ + struct NCR5380_hostdata *hostdata; + Scsi_Cmnd *ptr; + unsigned long flags; + + hostdata = (struct NCR5380_hostdata *)instance->hostdata; + + seq_printf(m, "NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); + local_irq_save(flags); + seq_printf(m, "NCR5380: coroutine is%s running.\n", + main_running ? "" : "n't"); + if (!hostdata->connected) + seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); + else + show_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m); + seq_printf(m, "scsi%d: issue_queue\n", HOSTNO); + for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) + show_Scsi_Cmnd(ptr, m); + + seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO); + for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; + ptr = NEXT(ptr)) + show_Scsi_Cmnd(ptr, m); + + local_irq_restore(flags); + return 0; +} /* * Function : void NCR5380_init (struct Scsi_Host *instance) diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index df740cbbaef..a3e6c8a3ff0 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -1100,7 +1100,7 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value) #include "atari_NCR5380.c" static struct scsi_host_template driver_template = { - .proc_info = atari_scsi_proc_info, + .show_info = atari_scsi_show_info, .name = "Atari native SCSI", .detect = atari_scsi_detect, .release = atari_scsi_release, diff --git a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h index bd52df78b20..11c624bb122 100644 --- a/drivers/scsi/atari_scsi.h +++ b/drivers/scsi/atari_scsi.h @@ -47,7 +47,7 @@ #define NCR5380_intr atari_scsi_intr #define NCR5380_queue_command atari_scsi_queue_command #define NCR5380_abort atari_scsi_abort -#define NCR5380_proc_info atari_scsi_proc_info +#define NCR5380_show_info atari_scsi_show_info #define NCR5380_dma_read_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 0) #define NCR5380_dma_write_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 1) #define NCR5380_dma_residual(inst) atari_scsi_dma_residual( inst ) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index cfc73041f10..15a629d8ed0 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -3099,38 +3099,14 @@ static const char *atp870u_info(struct Scsi_Host *notused) return buffer; } -#define BLS buffer + len + size -static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, - char **start, off_t offset, int length, int inout) +static int atp870u_show_info(struct seq_file *m, struct Scsi_Host *HBAptr) { - static u8 buff[512]; - int size = 0; - int len = 0; - off_t begin = 0; - off_t pos = 0; - - if (inout) - return -EINVAL; - if (offset == 0) - memset(buff, 0, sizeof(buff)); - size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n"); - len += size; - pos = begin + len; - size = 0; - - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Adapter Configuration:\n"); - size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port); - size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); - len += size; - pos = begin + len; - - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len > length) { - len = length; /* Ending slop */ - } - return (len); + seq_printf(m, "ACARD AEC-671X Driver Version: 2.6+ac\n"); + seq_printf(m, "\n"); + seq_printf(m, "Adapter Configuration:\n"); + seq_printf(m, " Base IO: %#.4lx\n", HBAptr->io_port); + seq_printf(m, " IRQ: %d\n", HBAptr->irq); + return 0; } @@ -3177,7 +3153,7 @@ static struct scsi_host_template atp870u_template = { .module = THIS_MODULE, .name = "atp870u" /* name */, .proc_name = "atp870u", - .proc_info = atp870u_proc_info, + .show_info = atp870u_show_info, .info = atp870u_info /* info */, .queuecommand = atp870u_queuecommand /* queuecommand */, .eh_abort_handler = atp870u_abort /* abort */, diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index fed486bfd3f..694e13c45df 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -4616,26 +4616,21 @@ static void adapter_uninit(struct AdapterCtlBlk *acb) #undef SPRINTF -#define SPRINTF(args...) pos += sprintf(pos, args) +#define SPRINTF(args...) seq_printf(m,##args) #undef YESNO #define YESNO(YN) \ if (YN) SPRINTF(" Yes ");\ else SPRINTF(" No ") -static int dc395x_proc_info(struct Scsi_Host *host, char *buffer, - char **start, off_t offset, int length, int inout) +static int dc395x_show_info(struct seq_file *m, struct Scsi_Host *host) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; int spd, spd1; - char *pos = buffer; struct DeviceCtlBlk *dcb; unsigned long flags; int dev; - if (inout) /* Has data been written to the file ? */ - return -EPERM; - SPRINTF(DC395X_BANNER " PCI SCSI Host Adapter\n"); SPRINTF(" Driver Version " DC395X_VERSION "\n"); @@ -4735,22 +4730,15 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer, SPRINTF("END\n"); } - *start = buffer + offset; DC395x_UNLOCK_IO(acb->scsi_host, flags); - - if (pos - buffer < offset) - return 0; - else if (pos - buffer - offset < length) - return pos - buffer - offset; - else - return length; + return 0; } static struct scsi_host_template dc395x_driver_template = { .module = THIS_MODULE, .proc_name = DC395X_NAME, - .proc_info = dc395x_proc_info, + .show_info = dc395x_show_info, .name = DC395X_BANNER " " DC395X_VERSION, .queuecommand = dc395x_queue_command, .bios_param = dc395x_bios_param, diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index b6e2700ec1c..19e1b422260 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -553,36 +553,14 @@ static const char *adpt_info(struct Scsi_Host *host) return (char *) (pHba->detail); } -static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int inout) +static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host) { struct adpt_device* d; int id; int chan; - int len = 0; - int begin = 0; - int pos = 0; adpt_hba* pHba; int unit; - *start = buffer; - if (inout == TRUE) { - /* - * The user has done a write and wants us to take the - * data in the buffer and do something with it. - * proc_scsiwrite calls us with inout = 1 - * - * Read data from buffer (writing to us) - NOT SUPPORTED - */ - return -EINVAL; - } - - /* - * inout = 0 means the user has done a read and wants information - * returned, so we write information about the cards into the buffer - * proc_scsiread() calls us with inout = 0 - */ - // Find HBA (host bus adapter) we are looking for mutex_lock(&adpt_configuration_lock); for (pHba = hba_chain; pHba; pHba = pHba->next) { @@ -596,86 +574,30 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of } host = pHba->host; - len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION); - len += sprintf(buffer+len, "%s\n", pHba->detail); - len += sprintf(buffer+len, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n", + seq_printf(m, "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION); + seq_printf(m, "%s\n", pHba->detail); + seq_printf(m, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n", pHba->host->host_no, pHba->name, host->irq); - len += sprintf(buffer+len, "\tpost fifo size = %d\n\treply fifo size = %d\n\tsg table size = %d\n\n", + seq_printf(m, "\tpost fifo size = %d\n\treply fifo size = %d\n\tsg table size = %d\n\n", host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize); - pos = begin + len; - - /* CHECKPOINT */ - if(pos > offset + length) { - goto stop_output; - } - if(pos <= offset) { - /* - * If we haven't even written to where we last left - * off (the last time we were called), reset the - * beginning pointer. - */ - len = 0; - begin = pos; - } - len += sprintf(buffer+len, "Devices:\n"); + seq_printf(m, "Devices:\n"); for(chan = 0; chan < MAX_CHANNEL; chan++) { for(id = 0; id < MAX_ID; id++) { d = pHba->channel[chan].device[id]; - while(d){ - len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor); - len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev); - pos = begin + len; - - - /* CHECKPOINT */ - if(pos > offset + length) { - goto stop_output; - } - if(pos <= offset) { - len = 0; - begin = pos; - } + while(d) { + seq_printf(m,"\t%-24.24s", d->pScsi_dev->vendor); + seq_printf(m," Rev: %-8.8s\n", d->pScsi_dev->rev); unit = d->pI2o_dev->lct_data.tid; - len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n", + seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n", unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun, scsi_device_online(d->pScsi_dev)? "online":"offline"); - pos = begin + len; - - /* CHECKPOINT */ - if(pos > offset + length) { - goto stop_output; - } - if(pos <= offset) { - len = 0; - begin = pos; - } - d = d->next_lun; } } } - - /* - * begin is where we last checked our position with regards to offset - * begin is always less than offset. len is relative to begin. It - * is the number of bytes written past begin - * - */ -stop_output: - /* stop the output and calculate the correct length */ - *(buffer + len) = '\0'; - - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); - if(len > length) { - len = length; - } else if(len < 0){ - len = 0; - **start = '\0'; - } - return len; + return 0; } /* @@ -3639,7 +3561,7 @@ static struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "dpt_i2o", .proc_name = "dpt_i2o", - .proc_info = adpt_proc_info, + .show_info = adpt_show_info, .info = adpt_info, .queuecommand = adpt_queue, .eh_abort_handler = adpt_abort, diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 4b11bb04f5c..d01f0160414 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -216,7 +216,8 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) int sig, count; tpnt->proc_name = "dtc3x80"; - tpnt->proc_info = &dtc_proc_info; + tpnt->show_info = dtc_show_info; + tpnt->write_info = dtc_write_info; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { addr = 0; diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h index cdc621204b6..92d7cfc3f4f 100644 --- a/drivers/scsi/dtc.h +++ b/drivers/scsi/dtc.h @@ -88,7 +88,8 @@ static int dtc_bus_reset(Scsi_Cmnd *); #define NCR5380_queue_command dtc_queue_command #define NCR5380_abort dtc_abort #define NCR5380_bus_reset dtc_bus_reset -#define NCR5380_proc_info dtc_proc_info +#define NCR5380_show_info dtc_show_info +#define NCR5380_write_info dtc_write_info /* 15 12 11 10 1001 1100 0000 0000 */ diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index d5f8362335d..356def44ce5 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -92,58 +92,22 @@ static unsigned long queue_counter; static struct scsi_host_template driver_template; -/* - * eata_proc_info - * inout : decides on the direction of the dataflow and the meaning of the - * variables - * buffer: If inout==FALSE data is being written to it else read from it - * *start: If inout==FALSE start of the valid data in the buffer - * offset: If inout==FALSE offset from the beginning of the imaginary file - * from which we start writing into the buffer - * length: If inout==FALSE max number of bytes to be written into the buffer - * else number of bytes in the buffer - */ -static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, - int length, int rw) +static int eata_pio_show_info(struct seq_file *m, struct Scsi_Host *shost) { - int len = 0; - off_t begin = 0, pos = 0; - - if (rw) - return -ENOSYS; - - len += sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " + seq_printf(m, "EATA (Extended Attachment) PIO driver version: " "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); - len += sprintf(buffer + len, "queued commands: %10ld\n" + seq_printf(m, "queued commands: %10ld\n" "processed interrupts:%10ld\n", queue_counter, int_counter); - len += sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", + seq_printf(m, "\nscsi%-2d: HBA %.10s\n", shost->host_no, SD(shost)->name); - len += sprintf(buffer + len, "Firmware revision: v%s\n", + seq_printf(m, "Firmware revision: v%s\n", SD(shost)->revision); - len += sprintf(buffer + len, "IO: PIO\n"); - len += sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base); - len += sprintf(buffer + len, "Host Bus: %s\n", + seq_printf(m, "IO: PIO\n"); + seq_printf(m, "Base IO : %#.4x\n", (u32) shost->base); + seq_printf(m, "Host Bus: %s\n", (SD(shost)->bustype == 'P')?"PCI ": (SD(shost)->bustype == 'E')?"EISA":"ISA "); - - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - -stop_output: - DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len > length) - len = length; /* Ending slop */ - DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); - - return len; + return 0; } static int eata_pio_release(struct Scsi_Host *sh) @@ -985,7 +949,7 @@ static int eata_pio_detect(struct scsi_host_template *tpnt) static struct scsi_host_template driver_template = { .proc_name = "eata_pio", .name = "EATA (Extended Attachment) PIO driver", - .proc_info = eata_pio_proc_info, + .show_info = eata_pio_show_info, .detect = eata_pio_detect, .release = eata_pio_release, .queuecommand = eata_pio_queue, diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 5041f925c19..5cec6c60ca2 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -745,42 +745,36 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, #include "NCR5380.c" -#define PRINTP(x) len += sprintf(buffer+len, x) +#define PRINTP(x) seq_printf(m, x) #define ANDP , -static int sprint_opcode(char *buffer, int len, int opcode) +static void sprint_opcode(struct seq_file *m, int opcode) { - int start = len; PRINTP("0x%02x " ANDP opcode); - return len - start; } -static int sprint_command(char *buffer, int len, unsigned char *command) +static void sprint_command(struct seq_file *m, unsigned char *command) { - int i, s, start = len; - len += sprint_opcode(buffer, len, command[0]); + int i, s; + sprint_opcode(m, command[0]); for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) PRINTP("%02x " ANDP command[i]); PRINTP("\n"); - return len - start; } /** * sprintf_Scsi_Cmnd - print a scsi command - * @buffer: buffr to print into - * @len: buffer length + * @m: seq_fil to print into * @cmd: SCSI command block * * Print out the target and command data in hex */ -static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd) +static void sprint_Scsi_Cmnd(struct seq_file *m, Scsi_Cmnd * cmd) { - int start = len; PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun); PRINTP(" command = "); - len += sprint_command(buffer, len, cmd->cmnd); - return len - start; + sprint_command(m, cmd->cmnd); } /** @@ -800,9 +794,8 @@ static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd) * Locks: global cli/lock for queue walk */ -static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, char **start, off_t offset, int length, int inout) +static int generic_NCR5380_show_info(struct seq_file *m, struct Scsi_Host *scsi_ptr) { - int len = 0; NCR5380_local_declare(); unsigned long flags; unsigned char status; @@ -853,16 +846,16 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c PRINTP(" T:%d %s " ANDP dev->id ANDP scsi_device_type(dev->type)); for (i = 0; i < 8; i++) if (dev->vendor[i] >= 0x20) - *(buffer + (len++)) = dev->vendor[i]; - *(buffer + (len++)) = ' '; + seq_putc(m, dev->vendor[i]); + seq_putc(m, ' '); for (i = 0; i < 16; i++) if (dev->model[i] >= 0x20) - *(buffer + (len++)) = dev->model[i]; - *(buffer + (len++)) = ' '; + seq_putc(m, dev->model[i]); + seq_putc(m, ' '); for (i = 0; i < 4; i++) if (dev->rev[i] >= 0x20) - *(buffer + (len++)) = dev->rev[i]; - *(buffer + (len++)) = ' '; + seq_putc(m, dev->rev[i]); + seq_putc(m, ' '); PRINTP("\n%10ld kb read in %5ld secs" ANDP br / 1024 ANDP tr); if (tr) @@ -886,32 +879,28 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c if (!hostdata->connected) { PRINTP("No currently connected command\n"); } else { - len += sprint_Scsi_Cmnd(buffer, len, (Scsi_Cmnd *) hostdata->connected); + sprint_Scsi_Cmnd(m, (Scsi_Cmnd *) hostdata->connected); } PRINTP("issue_queue\n"); for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - len += sprint_Scsi_Cmnd(buffer, len, ptr); + sprint_Scsi_Cmnd(m, ptr); PRINTP("disconnected_queue\n"); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) - len += sprint_Scsi_Cmnd(buffer, len, ptr); + sprint_Scsi_Cmnd(m, ptr); - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; spin_unlock_irqrestore(scsi_ptr->host_lock, flags); - return len; + return 0; } #undef PRINTP #undef ANDP static struct scsi_host_template driver_template = { - .proc_info = generic_NCR5380_proc_info, + .show_info = generic_NCR5380_show_info, .name = "Generic NCR5380/NCR53C400 Scsi Driver", .detect = generic_NCR5380_detect, .release = generic_NCR5380_release_resources, diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 59bceac51a4..6d55b4e7e79 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4676,7 +4676,8 @@ static struct scsi_host_template gdth_template = { .eh_bus_reset_handler = gdth_eh_bus_reset, .slave_configure = gdth_slave_configure, .bios_param = gdth_bios_param, - .proc_info = gdth_proc_info, + .show_info = gdth_show_info, + .write_info = gdth_set_info, .eh_timed_out = gdth_timed_out, .proc_name = "gdth", .can_queue = GDTH_MAXCMDS, diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index fbf6f0f4b0d..3fd8b83ffbf 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -1007,6 +1007,7 @@ typedef struct { /* function prototyping */ -int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int); +int gdth_show_info(struct seq_file *, struct Scsi_Host *); +int gdth_set_info(struct Scsi_Host *, char *, int); #endif diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 652754319a4..9fb63268486 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -5,23 +5,9 @@ #include <linux/completion.h> #include <linux/slab.h> -int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, - int inout) +int gdth_set_info(struct Scsi_Host *host, char *buffer, int length) { gdth_ha_str *ha = shost_priv(host); - - TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", - length,(int)offset,inout)); - - if (inout) - return(gdth_set_info(buffer,length,host,ha)); - else - return(gdth_get_info(buffer,start,offset,length,host,ha)); -} - -static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - gdth_ha_str *ha) -{ int ret_val = -EINVAL; TRACE2(("gdth_set_info() ha %d\n",ha->hanum,)); @@ -149,12 +135,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, return(-EINVAL); } -static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host, gdth_ha_str *ha) +int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) { - int size = 0,len = 0; + gdth_ha_str *ha = shost_priv(host); int hlen; - off_t begin = 0,pos = 0; int id, i, j, k, sec, flag; int no_mdrv = 0, drv_no, is_mirr; u32 cnt; @@ -189,8 +173,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* request is i.e. "cat /proc/scsi/gdth/0" */ /* format: %-15s\t%-10s\t%-15s\t%s */ /* driver parameters */ - size = sprintf(buffer+len,"Driver Parameters:\n"); - len += size; pos = begin + len; + seq_printf(m, "Driver Parameters:\n"); if (reserve_list[0] == 0xff) strcpy(hrec, "--"); else { @@ -201,69 +184,50 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, hlen += snprintf(hrec + hlen , 161 - hlen, ",%d", reserve_list[i]); } } - size = sprintf(buffer+len, + seq_printf(m, " reserve_mode: \t%d \treserve_list: \t%s\n", reserve_mode, hrec); - len += size; pos = begin + len; - size = sprintf(buffer+len, + seq_printf(m, " max_ids: \t%-3d \thdr_channel: \t%d\n", max_ids, hdr_channel); - len += size; pos = begin + len; /* controller information */ - size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); - len += size; pos = begin + len; - strcpy(hrec, ha->binfo.type_string); - size = sprintf(buffer+len, + seq_printf(m,"\nDisk Array Controller Information:\n"); + seq_printf(m, " Number: \t%d \tName: \t%s\n", - ha->hanum, hrec); - len += size; pos = begin + len; + ha->hanum, ha->binfo.type_string); + seq_printf(m, + " Driver Ver.: \t%-10s\tFirmware Ver.: \t", + GDTH_VERSION_STR); if (ha->more_proc) - sprintf(hrec, "%d.%02d.%02d-%c%03X", + seq_printf(m, "%d.%02d.%02d-%c%03X\n", (u8)(ha->binfo.upd_fw_ver>>24), (u8)(ha->binfo.upd_fw_ver>>16), (u8)(ha->binfo.upd_fw_ver), ha->bfeat.raid ? 'R':'N', ha->binfo.upd_revision); else - sprintf(hrec, "%d.%02d", (u8)(ha->cpar.version>>8), + seq_printf(m, "%d.%02d\n", (u8)(ha->cpar.version>>8), (u8)(ha->cpar.version)); - - size = sprintf(buffer+len, - " Driver Ver.: \t%-10s\tFirmware Ver.: \t%s\n", - GDTH_VERSION_STR, hrec); - len += size; pos = begin + len; - if (ha->more_proc) { + if (ha->more_proc) /* more information: 1. about controller */ - size = sprintf(buffer+len, + seq_printf(m, " Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n", ha->binfo.ser_no, ha->binfo.memsize / 1024); - len += size; pos = begin + len; - } #ifdef GDTH_DMA_STATISTICS /* controller statistics */ - size = sprintf(buffer+len,"\nController Statistics:\n"); - len += size; pos = begin + len; - size = sprintf(buffer+len, + seq_printf(m,"\nController Statistics:\n"); + seq_printf(m, " 32-bit DMA buffer:\t%lu\t64-bit DMA buffer:\t%lu\n", ha->dma32_cnt, ha->dma64_cnt); - len += size; pos = begin + len; #endif - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - if (ha->more_proc) { /* more information: 2. about physical devices */ - size = sprintf(buffer+len,"\nPhysical Devices:"); - len += size; pos = begin + len; + seq_printf(m, "\nPhysical Devices:"); flag = FALSE; buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); @@ -309,21 +273,19 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, strncpy(hrec+8,pdi->product,16); strncpy(hrec+24,pdi->revision,4); hrec[28] = 0; - size = sprintf(buffer+len, + seq_printf(m, "\n Chn/ID/LUN: \t%c/%02d/%d \tName: \t%s\n", 'A'+i,pdi->target_id,pdi->lun,hrec); - len += size; pos = begin + len; flag = TRUE; pdi->no_ldrive &= 0xffff; if (pdi->no_ldrive == 0xffff) strcpy(hrec,"--"); else sprintf(hrec,"%d",pdi->no_ldrive); - size = sprintf(buffer+len, + seq_printf(m, " Capacity [MB]:\t%-6d \tTo Log. Drive: \t%s\n", pdi->blkcnt/(1024*1024/pdi->blksize), hrec); - len += size; pos = begin + len; } else { pdi->devtype = 0xff; } @@ -333,11 +295,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, for (k = 0; k < pds->count; ++k) { if (pds->list[k].tid == pdi->target_id && pds->list[k].lun == pdi->lun) { - size = sprintf(buffer+len, + seq_printf(m, " Retries: \t%-6d \tReassigns: \t%d\n", pds->list[k].retries, pds->list[k].reassigns); - len += size; pos = begin + len; break; } } @@ -355,32 +316,20 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, pdef->sddc_type = 0x08; if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { - size = sprintf(buffer+len, + seq_printf(m, " Grown Defects:\t%d\n", pdef->sddc_cnt); - len += size; pos = begin + len; } } - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) { - gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - goto stop_output; - } } } gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - if (!flag) { - size = sprintf(buffer+len, "\n --\n"); - len += size; pos = begin + len; - } + if (!flag) + seq_printf(m, "\n --\n"); /* 3. about logical drives */ - size = sprintf(buffer+len,"\nLogical Drives:"); - len += size; pos = begin + len; + seq_printf(m,"\nLogical Drives:"); flag = FALSE; buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); @@ -418,10 +367,9 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, } if (drv_no == i) { - size = sprintf(buffer+len, + seq_printf(m, "\n Number: \t%-2d \tStatus: \t%s\n", drv_no, hrec); - len += size; pos = begin + len; flag = TRUE; no_mdrv = pcdi->cd_ldcnt; if (no_mdrv > 1 || pcdi->ld_slave != -1) { @@ -436,61 +384,37 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, } else { strcpy(hrec, "???"); } - size = sprintf(buffer+len, + seq_printf(m, " Capacity [MB]:\t%-6d \tType: \t%s\n", pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize), hrec); - len += size; pos = begin + len; } else { - size = sprintf(buffer+len, + seq_printf(m, " Slave Number: \t%-2d \tStatus: \t%s\n", drv_no & 0x7fff, hrec); - len += size; pos = begin + len; } drv_no = pcdi->ld_slave; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) { - gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - goto stop_output; - } } while (drv_no != -1); - if (is_mirr) { - size = sprintf(buffer+len, + if (is_mirr) + seq_printf(m, " Missing Drv.: \t%-2d \tInvalid Drv.: \t%d\n", no_mdrv - j - k, k); - len += size; pos = begin + len; - } - + if (!ha->hdr[i].is_arraydrv) strcpy(hrec, "--"); else sprintf(hrec, "%d", ha->hdr[i].master_no); - size = sprintf(buffer+len, + seq_printf(m, " To Array Drv.:\t%s\n", hrec); - len += size; pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) { - gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - goto stop_output; - } } gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - if (!flag) { - size = sprintf(buffer+len, "\n --\n"); - len += size; pos = begin + len; - } + if (!flag) + seq_printf(m, "\n --\n"); /* 4. about array drives */ - size = sprintf(buffer+len,"\nArray Drives:"); - len += size; pos = begin + len; + seq_printf(m,"\nArray Drives:"); flag = FALSE; buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); @@ -525,10 +449,9 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, strcat(hrec, "/expand"); else if (pai->ai_ext_state & 0x1) strcat(hrec, "/patch"); - size = sprintf(buffer+len, + seq_printf(m, "\n Number: \t%-2d \tStatus: \t%s\n", i,hrec); - len += size; pos = begin + len; flag = TRUE; if (pai->ai_type == 0) @@ -539,31 +462,19 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, strcpy(hrec, "RAID-5"); else strcpy(hrec, "RAID-10"); - size = sprintf(buffer+len, + seq_printf(m, " Capacity [MB]:\t%-6d \tType: \t%s\n", pai->ai_size/(1024*1024/pai->ai_secsize), hrec); - len += size; pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) { - gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - goto stop_output; - } } } gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); - if (!flag) { - size = sprintf(buffer+len, "\n --\n"); - len += size; pos = begin + len; - } + if (!flag) + seq_printf(m, "\n --\n"); /* 5. about host drives */ - size = sprintf(buffer+len,"\nHost Drives:"); - len += size; pos = begin + len; + seq_printf(m,"\nHost Drives:"); flag = FALSE; buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr); @@ -605,33 +516,22 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, if (!(ha->hdr[i].present)) continue; - size = sprintf(buffer+len, + seq_printf(m, "\n Number: \t%-2d \tArr/Log. Drive:\t%d\n", i, ha->hdr[i].ldr_no); - len += size; pos = begin + len; flag = TRUE; - size = sprintf(buffer+len, + seq_printf(m, " Capacity [MB]:\t%-6d \tStart Sector: \t%d\n", (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec); - len += size; pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; } - if (!flag) { - size = sprintf(buffer+len, "\n --\n"); - len += size; pos = begin + len; - } + if (!flag) + seq_printf(m, "\n --\n"); } /* controller events */ - size = sprintf(buffer+len,"\nController Events:\n"); - len += size; pos = begin + len; + seq_printf(m,"\nController Events:\n"); for (id = -1;;) { id = gdth_read_event(ha, id, estr); @@ -643,29 +543,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, do_gettimeofday(&tv); sec = (int)(tv.tv_sec - estr->first_stamp); if (sec < 0) sec = 0; - size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n", + seq_printf(m," date- %02d:%02d:%02d\t%s\n", sec/3600, sec%3600/60, sec%60, hrec); - len += size; pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; } if (id == -1) break; } - stop_output: - *start = buffer +(offset-begin); - len -= (offset-begin); - if (len > length) - len = length; - TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n", - len,(int)pos,(int)begin,(int)offset,length,size)); - rc = len; - + rc = 0; free_fail: kfree(gdtcmd); kfree(estr); diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h index dab15f59f2c..aaa61819897 100644 --- a/drivers/scsi/gdth_proc.h +++ b/drivers/scsi/gdth_proc.h @@ -8,11 +8,6 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info); -static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - gdth_ha_str *ha); -static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host, gdth_ha_str *ha); - static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, int length, gdth_ha_str *ha); diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index dbe4cc6b9f8..2203ac28110 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -191,7 +191,8 @@ static int gvp11_bus_reset(struct scsi_cmnd *cmd) static struct scsi_host_template gvp11_scsi_template = { .module = THIS_MODULE, .name = "GVP Series II SCSI", - .proc_info = wd33c93_proc_info, + .show_info = wd33c93_show_info, + .write_info = wd33c93_write_info, .proc_name = "GVP11", .queuecommand = wd33c93_queuecommand, .eh_abort_handler = wd33c93_abort, diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 26cd9d1d757..89a8266560d 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -121,45 +121,26 @@ static inline void imm_pb_release(imm_struct *dev) * testing... * Also gives a method to use a script to obtain optimum timings (TODO) */ -static inline int imm_proc_write(imm_struct *dev, char *buffer, int length) +static int imm_write_info(struct Scsi_Host *host, char *buffer, int length) { - unsigned long x; + imm_struct *dev = imm_dev(host); if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) { - x = simple_strtoul(buffer + 5, NULL, 0); - dev->mode = x; + dev->mode = simple_strtoul(buffer + 5, NULL, 0); return length; } printk("imm /proc: invalid variable\n"); - return (-EINVAL); + return -EINVAL; } -static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, - off_t offset, int length, int inout) +static int imm_show_info(struct seq_file *m, struct Scsi_Host *host) { imm_struct *dev = imm_dev(host); - int len = 0; - - if (inout) - return imm_proc_write(dev, buffer, length); - - len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION); - len += - sprintf(buffer + len, "Parport : %s\n", - dev->dev->port->name); - len += - sprintf(buffer + len, "Mode : %s\n", - IMM_MODE_STRING[dev->mode]); - /* Request for beyond end of buffer */ - if (offset > len) - return 0; - - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; - return len; + seq_printf(m, "Version : %s\n", IMM_VERSION); + seq_printf(m, "Parport : %s\n", dev->dev->port->name); + seq_printf(m, "Mode : %s\n", IMM_MODE_STRING[dev->mode]); + return 0; } #if IMM_DEBUG > 0 @@ -1118,7 +1099,8 @@ static int imm_adjust_queue(struct scsi_device *device) static struct scsi_host_template imm_template = { .module = THIS_MODULE, .proc_name = "imm", - .proc_info = imm_proc_info, + .show_info = imm_show_info, + .write_info = imm_write_info, .name = "Iomega VPI2 (imm) interface", .queuecommand = imm_queuecommand, .eh_abort_handler = imm_abort, diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index deb5b6d8398..bf028218ac3 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -2166,152 +2166,117 @@ static int in2000_biosparam(struct scsi_device *sdev, struct block_device *bdev, } -static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in) +static int in2000_write_info(struct Scsi_Host *instance, char *buf, int len) { #ifdef PROC_INTERFACE char *bp; - char tbuf[128]; - unsigned long flags; struct IN2000_hostdata *hd; - Scsi_Cmnd *cmd; int x, i; - static int stop = 0; hd = (struct IN2000_hostdata *) instance->hostdata; -/* If 'in' is TRUE we need to _read_ the proc file. We accept the following - * keywords (same format as command-line, but only ONE per read): - * debug - * disconnect - * period - * resync - * proc - */ - - if (in) { - buf[len] = '\0'; - bp = buf; - if (!strncmp(bp, "debug:", 6)) { - bp += 6; - hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK; - } else if (!strncmp(bp, "disconnect:", 11)) { - bp += 11; - x = simple_strtoul(bp, NULL, 0); - if (x < DIS_NEVER || x > DIS_ALWAYS) - x = DIS_ADAPTIVE; - hd->disconnect = x; - } else if (!strncmp(bp, "period:", 7)) { - bp += 7; - x = simple_strtoul(bp, NULL, 0); - hd->default_sx_per = sx_table[round_period((unsigned int) x)].period_ns; - } else if (!strncmp(bp, "resync:", 7)) { - bp += 7; - x = simple_strtoul(bp, NULL, 0); - for (i = 0; i < 7; i++) - if (x & (1 << i)) - hd->sync_stat[i] = SS_UNSET; - } else if (!strncmp(bp, "proc:", 5)) { - bp += 5; - hd->proc = simple_strtoul(bp, NULL, 0); - } else if (!strncmp(bp, "level2:", 7)) { - bp += 7; - hd->level2 = simple_strtoul(bp, NULL, 0); - } - return len; + buf[len] = '\0'; + bp = buf; + if (!strncmp(bp, "debug:", 6)) { + bp += 6; + hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK; + } else if (!strncmp(bp, "disconnect:", 11)) { + bp += 11; + x = simple_strtoul(bp, NULL, 0); + if (x < DIS_NEVER || x > DIS_ALWAYS) + x = DIS_ADAPTIVE; + hd->disconnect = x; + } else if (!strncmp(bp, "period:", 7)) { + bp += 7; + x = simple_strtoul(bp, NULL, 0); + hd->default_sx_per = sx_table[round_period((unsigned int) x)].period_ns; + } else if (!strncmp(bp, "resync:", 7)) { + bp += 7; + x = simple_strtoul(bp, NULL, 0); + for (i = 0; i < 7; i++) + if (x & (1 << i)) + hd->sync_stat[i] = SS_UNSET; + } else if (!strncmp(bp, "proc:", 5)) { + bp += 5; + hd->proc = simple_strtoul(bp, NULL, 0); + } else if (!strncmp(bp, "level2:", 7)) { + bp += 7; + hd->level2 = simple_strtoul(bp, NULL, 0); } +#endif + return len; +} + +static int in2000_show_info(struct seq_file *m, struct Scsi_Host *instance) +{ + +#ifdef PROC_INTERFACE + unsigned long flags; + struct IN2000_hostdata *hd; + Scsi_Cmnd *cmd; + int x; + + hd = (struct IN2000_hostdata *) instance->hostdata; spin_lock_irqsave(instance->host_lock, flags); - bp = buf; - *bp = '\0'; - if (hd->proc & PR_VERSION) { - sprintf(tbuf, "\nVersion %s - %s.", IN2000_VERSION, IN2000_DATE); - strcat(bp, tbuf); - } + if (hd->proc & PR_VERSION) + seq_printf(m, "\nVersion %s - %s.", IN2000_VERSION, IN2000_DATE); + if (hd->proc & PR_INFO) { - sprintf(tbuf, "\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s", (hd->dip_switch & 0x7f), instance->irq, hd->io_base, (hd->dip_switch & 0x40) ? "Yes" : "No", (hd->dip_switch & 0x20) ? "Yes" : "No"); - strcat(bp, tbuf); - strcat(bp, "\nsync_xfer[] = "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%02x", hd->sync_xfer[x]); - strcat(bp, tbuf); - } - strcat(bp, "\nsync_stat[] = "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%02x", hd->sync_stat[x]); - strcat(bp, tbuf); - } + seq_printf(m, "\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s", (hd->dip_switch & 0x7f), instance->irq, hd->io_base, (hd->dip_switch & 0x40) ? "Yes" : "No", (hd->dip_switch & 0x20) ? "Yes" : "No"); + seq_printf(m, "\nsync_xfer[] = "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%02x", hd->sync_xfer[x]); + seq_printf(m, "\nsync_stat[] = "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%02x", hd->sync_stat[x]); } #ifdef PROC_STATISTICS if (hd->proc & PR_STATISTICS) { - strcat(bp, "\ncommands issued: "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]); - strcat(bp, tbuf); - } - strcat(bp, "\ndisconnects allowed:"); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]); - strcat(bp, tbuf); - } - strcat(bp, "\ndisconnects done: "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]); - strcat(bp, tbuf); - } - sprintf(tbuf, "\ninterrupts: \t%ld", hd->int_cnt); - strcat(bp, tbuf); + seq_printf(m, "\ncommands issued: "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->cmd_cnt[x]); + seq_printf(m, "\ndisconnects allowed:"); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->disc_allowed_cnt[x]); + seq_printf(m, "\ndisconnects done: "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->disc_done_cnt[x]); + seq_printf(m, "\ninterrupts: \t%ld", hd->int_cnt); } #endif if (hd->proc & PR_CONNECTED) { - strcat(bp, "\nconnected: "); + seq_printf(m, "\nconnected: "); if (hd->connected) { cmd = (Scsi_Cmnd *) hd->connected; - sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); } } if (hd->proc & PR_INPUTQ) { - strcat(bp, "\ninput_Q: "); + seq_printf(m, "\ninput_Q: "); cmd = (Scsi_Cmnd *) hd->input_Q; while (cmd) { - sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); cmd = (Scsi_Cmnd *) cmd->host_scribble; } } if (hd->proc & PR_DISCQ) { - strcat(bp, "\ndisconnected_Q:"); + seq_printf(m, "\ndisconnected_Q:"); cmd = (Scsi_Cmnd *) hd->disconnected_Q; while (cmd) { - sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); cmd = (Scsi_Cmnd *) cmd->host_scribble; } } if (hd->proc & PR_TEST) { ; /* insert your own custom function here */ } - strcat(bp, "\n"); + seq_printf(m, "\n"); spin_unlock_irqrestore(instance->host_lock, flags); - *start = buf; - if (stop) { - stop = 0; - return 0; /* return 0 to signal end-of-file */ - } - if (off > 0x40000) /* ALWAYS stop after 256k bytes have been read */ - stop = 1; - if (hd->proc & PR_STOP) /* stop every other time */ - stop = 1; - return strlen(bp); - -#else /* PROC_INTERFACE */ - - return 0; - #endif /* PROC_INTERFACE */ - + return 0; } MODULE_LICENSE("GPL"); @@ -2319,7 +2284,8 @@ MODULE_LICENSE("GPL"); static struct scsi_host_template driver_template = { .proc_name = "in2000", - .proc_info = in2000_proc_info, + .write_info = in2000_write_info, + .show_info = in2000_show_info, .name = "Always IN2000", .detect = in2000_detect, .release = in2000_release, diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 9aa86a315a0..8d5ea8a1e5a 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -326,10 +326,9 @@ static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data, static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data, unsigned int count); -static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); -static int ips_host_info(ips_ha_t *, char *, off_t, int); -static void copy_mem_info(IPS_INFOSTR *, char *, int); -static int copy_info(IPS_INFOSTR *, char *, ...); +static int ips_write_info(struct Scsi_Host *, char *, int); +static int ips_show_info(struct seq_file *, struct Scsi_Host *); +static int ips_host_info(ips_ha_t *, struct seq_file *); static int ips_abort_init(ips_ha_t * ha, int index); static int ips_init_phase2(int index); @@ -367,7 +366,8 @@ static struct scsi_host_template ips_driver_template = { .eh_abort_handler = ips_eh_abort, .eh_host_reset_handler = ips_eh_reset, .proc_name = "ips", - .proc_info = ips_proc_info, + .show_info = ips_show_info, + .write_info = ips_write_info, .slave_configure = ips_slave_configure, .bios_param = ips_biosparam, .this_id = -1, @@ -1433,25 +1433,12 @@ ips_info(struct Scsi_Host *SH) return (bp); } -/****************************************************************************/ -/* */ -/* Routine Name: ips_proc_info */ -/* */ -/* Routine Description: */ -/* */ -/* The passthru interface for the driver */ -/* */ -/****************************************************************************/ static int -ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int func) +ips_write_info(struct Scsi_Host *host, char *buffer, int length) { int i; - int ret; ips_ha_t *ha = NULL; - METHOD_TRACE("ips_proc_info", 1); - /* Find our host structure */ for (i = 0; i < ips_next_controller; i++) { if (ips_sh[i]) { @@ -1465,18 +1452,29 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, if (!ha) return (-EINVAL); - if (func) { - /* write */ - return (0); - } else { - /* read */ - if (start) - *start = buffer; + return 0; +} - ret = ips_host_info(ha, buffer, offset, length); +static int +ips_show_info(struct seq_file *m, struct Scsi_Host *host) +{ + int i; + ips_ha_t *ha = NULL; - return (ret); + /* Find our host structure */ + for (i = 0; i < ips_next_controller; i++) { + if (ips_sh[i]) { + if (ips_sh[i] == host) { + ha = (ips_ha_t *) ips_sh[i]->hostdata; + break; + } + } } + + if (!ha) + return (-EINVAL); + + return ips_host_info(ha, m); } /*--------------------------------------------------------------------------*/ @@ -2035,183 +2033,113 @@ ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb) /* */ /****************************************************************************/ static int -ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len) +ips_host_info(ips_ha_t *ha, struct seq_file *m) { - IPS_INFOSTR info; - METHOD_TRACE("ips_host_info", 1); - info.buffer = ptr; - info.length = len; - info.offset = offset; - info.pos = 0; - info.localpos = 0; - - copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); + seq_printf(m, "\nIBM ServeRAID General Information:\n\n"); if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && (le16_to_cpu(ha->nvram->adapter_type) != 0)) - copy_info(&info, "\tController Type : %s\n", + seq_printf(m, "\tController Type : %s\n", ips_adapter_name[ha->ad_type - 1]); else - copy_info(&info, + seq_printf(m, "\tController Type : Unknown\n"); if (ha->io_addr) - copy_info(&info, - "\tIO region : 0x%lx (%d bytes)\n", + seq_printf(m, + "\tIO region : 0x%x (%d bytes)\n", ha->io_addr, ha->io_len); if (ha->mem_addr) { - copy_info(&info, - "\tMemory region : 0x%lx (%d bytes)\n", + seq_printf(m, + "\tMemory region : 0x%x (%d bytes)\n", ha->mem_addr, ha->mem_len); - copy_info(&info, + seq_printf(m, "\tShared memory address : 0x%lx\n", - ha->mem_ptr); + (unsigned long)ha->mem_ptr); } - copy_info(&info, "\tIRQ number : %d\n", ha->pcidev->irq); + seq_printf(m, "\tIRQ number : %d\n", ha->pcidev->irq); /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */ /* That keeps everything happy for "text" operations on the proc file. */ if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) { if (ha->nvram->bios_low[3] == 0) { - copy_info(&info, - "\tBIOS Version : %c%c%c%c%c%c%c\n", - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2]); + seq_printf(m, + "\tBIOS Version : %c%c%c%c%c%c%c\n", + ha->nvram->bios_high[0], ha->nvram->bios_high[1], + ha->nvram->bios_high[2], ha->nvram->bios_high[3], + ha->nvram->bios_low[0], ha->nvram->bios_low[1], + ha->nvram->bios_low[2]); } else { - copy_info(&info, - "\tBIOS Version : %c%c%c%c%c%c%c%c\n", - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2], ha->nvram->bios_low[3]); + seq_printf(m, + "\tBIOS Version : %c%c%c%c%c%c%c%c\n", + ha->nvram->bios_high[0], ha->nvram->bios_high[1], + ha->nvram->bios_high[2], ha->nvram->bios_high[3], + ha->nvram->bios_low[0], ha->nvram->bios_low[1], + ha->nvram->bios_low[2], ha->nvram->bios_low[3]); } } if (ha->enq->CodeBlkVersion[7] == 0) { - copy_info(&info, - "\tFirmware Version : %c%c%c%c%c%c%c\n", - ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], - ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], - ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], - ha->enq->CodeBlkVersion[6]); + seq_printf(m, + "\tFirmware Version : %c%c%c%c%c%c%c\n", + ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], + ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], + ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], + ha->enq->CodeBlkVersion[6]); } else { - copy_info(&info, - "\tFirmware Version : %c%c%c%c%c%c%c%c\n", - ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], - ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], - ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], - ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); + seq_printf(m, + "\tFirmware Version : %c%c%c%c%c%c%c%c\n", + ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], + ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], + ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], + ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); } if (ha->enq->BootBlkVersion[7] == 0) { - copy_info(&info, - "\tBoot Block Version : %c%c%c%c%c%c%c\n", - ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], - ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], - ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], - ha->enq->BootBlkVersion[6]); + seq_printf(m, + "\tBoot Block Version : %c%c%c%c%c%c%c\n", + ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], + ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], + ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], + ha->enq->BootBlkVersion[6]); } else { - copy_info(&info, - "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", - ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], - ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], - ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], - ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); + seq_printf(m, + "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", + ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], + ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], + ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], + ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); } - copy_info(&info, "\tDriver Version : %s%s\n", + seq_printf(m, "\tDriver Version : %s%s\n", IPS_VERSION_HIGH, IPS_VERSION_LOW); - copy_info(&info, "\tDriver Build : %d\n", + seq_printf(m, "\tDriver Build : %d\n", IPS_BUILD_IDENT); - copy_info(&info, "\tMax Physical Devices : %d\n", + seq_printf(m, "\tMax Physical Devices : %d\n", ha->enq->ucMaxPhysicalDevices); - copy_info(&info, "\tMax Active Commands : %d\n", + seq_printf(m, "\tMax Active Commands : %d\n", ha->max_cmds); - copy_info(&info, "\tCurrent Queued Commands : %d\n", + seq_printf(m, "\tCurrent Queued Commands : %d\n", ha->scb_waitlist.count); - copy_info(&info, "\tCurrent Active Commands : %d\n", + seq_printf(m, "\tCurrent Active Commands : %d\n", ha->scb_activelist.count - ha->num_ioctl); - copy_info(&info, "\tCurrent Queued PT Commands : %d\n", + seq_printf(m, "\tCurrent Queued PT Commands : %d\n", ha->copp_waitlist.count); - copy_info(&info, "\tCurrent Active PT Commands : %d\n", + seq_printf(m, "\tCurrent Active PT Commands : %d\n", ha->num_ioctl); - copy_info(&info, "\n"); - - return (info.localpos); -} - -/****************************************************************************/ -/* */ -/* Routine Name: copy_mem_info */ -/* */ -/* Routine Description: */ -/* */ -/* Copy data into an IPS_INFOSTR structure */ -/* */ -/****************************************************************************/ -static void -copy_mem_info(IPS_INFOSTR * info, char *data, int len) -{ - METHOD_TRACE("copy_mem_info", 1); - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - data += (info->offset - info->pos); - len -= (info->offset - info->pos); - info->pos += (info->offset - info->pos); - } - - if (info->localpos + len > info->length) - len = info->length - info->localpos; + seq_printf(m, "\n"); - if (len > 0) { - memcpy(info->buffer + info->localpos, data, len); - info->pos += len; - info->localpos += len; - } -} - -/****************************************************************************/ -/* */ -/* Routine Name: copy_info */ -/* */ -/* Routine Description: */ -/* */ -/* printf style wrapper for an info structure */ -/* */ -/****************************************************************************/ -static int -copy_info(IPS_INFOSTR * info, char *fmt, ...) -{ - va_list args; - char buf[128]; - int len; - - METHOD_TRACE("copy_info", 1); - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - - return (len); + return 0; } /****************************************************************************/ diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index f2df0593332..45b9566b928 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -416,7 +416,6 @@ /* * Scsi_Host Template */ - static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); static int ips_slave_configure(struct scsi_device *SDptr); @@ -959,14 +958,6 @@ typedef union { IPS_ENH_SG_LIST *enh_list; } IPS_SG_LIST; -typedef struct _IPS_INFOSTR { - char *buffer; - int length; - int offset; - int pos; - int localpos; -} IPS_INFOSTR; - typedef struct { char *option_name; int *option_flag; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5da29729026..90b8b0515e2 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -10394,36 +10394,6 @@ lpfc_io_resume(struct pci_dev *pdev) return; } -/** - * lpfc_mgmt_open - method called when 'lpfcmgmt' is opened from userspace - * @inode: pointer to the inode representing the lpfcmgmt device - * @filep: pointer to the file representing the open lpfcmgmt device - * - * This routine puts a reference count on the lpfc module whenever the - * character device is opened - **/ -static int -lpfc_mgmt_open(struct inode *inode, struct file *filep) -{ - try_module_get(THIS_MODULE); - return 0; -} - -/** - * lpfc_mgmt_release - method called when 'lpfcmgmt' is closed in userspace - * @inode: pointer to the inode representing the lpfcmgmt device - * @filep: pointer to the file representing the open lpfcmgmt device - * - * This routine removes a reference count from the lpfc module when the - * character device is closed - **/ -static int -lpfc_mgmt_release(struct inode *inode, struct file *filep) -{ - module_put(THIS_MODULE); - return 0; -} - static struct pci_device_id lpfc_id_table[] = { {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER, PCI_ANY_ID, PCI_ANY_ID, }, @@ -10541,8 +10511,7 @@ static struct pci_driver lpfc_driver = { }; static const struct file_operations lpfc_mgmt_fop = { - .open = lpfc_mgmt_open, - .release = lpfc_mgmt_release, + .owner = THIS_MODULE, }; static struct miscdevice lpfc_mgmt_dev = { diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 24828b54773..858075723c8 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -561,7 +561,8 @@ static int macscsi_pwrite (struct Scsi_Host *instance, static struct scsi_host_template driver_template = { .proc_name = "Mac5380", - .proc_info = macscsi_proc_info, + .show_info = macscsi_show_info, + .write_info = macscsi_write_info, .name = "Macintosh NCR5380 SCSI", .detect = macscsi_detect, .release = macscsi_release, diff --git a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h index d26e331c6c1..7dc62fce1c4 100644 --- a/drivers/scsi/mac_scsi.h +++ b/drivers/scsi/mac_scsi.h @@ -72,7 +72,8 @@ #define NCR5380_queue_command macscsi_queue_command #define NCR5380_abort macscsi_abort #define NCR5380_bus_reset macscsi_bus_reset -#define NCR5380_proc_info macscsi_proc_info +#define NCR5380_show_info macscsi_show_info +#define NCR5380_write_info macscsi_write_info #define BOARD_NORMAL 0 #define BOARD_NCR53C400 1 diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 9504ec0ec68..7373255aa1e 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -39,6 +39,7 @@ #include <linux/completion.h> #include <linux/delay.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/reboot.h> #include <linux/module.h> #include <linux/list.h> @@ -2069,385 +2070,201 @@ mega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev) #ifdef CONFIG_PROC_FS /* Following code handles /proc fs */ -#define CREATE_READ_PROC(string, func) create_proc_read_entry(string, \ - S_IRUSR | S_IFREG, \ - controller_proc_dir_entry, \ - func, adapter) - -/** - * mega_create_proc_entry() - * @index - index in soft state array - * @parent - parent node for this /proc entry - * - * Creates /proc entries for our controllers. - */ -static void -mega_create_proc_entry(int index, struct proc_dir_entry *parent) -{ - struct proc_dir_entry *controller_proc_dir_entry = NULL; - u8 string[64] = { 0 }; - adapter_t *adapter = hba_soft_state[index]; - - sprintf(string, "hba%d", adapter->host->host_no); - - controller_proc_dir_entry = - adapter->controller_proc_dir_entry = proc_mkdir(string, parent); - - if(!controller_proc_dir_entry) { - printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n"); - return; - } - adapter->proc_read = CREATE_READ_PROC("config", proc_read_config); - adapter->proc_stat = CREATE_READ_PROC("stat", proc_read_stat); - adapter->proc_mbox = CREATE_READ_PROC("mailbox", proc_read_mbox); -#if MEGA_HAVE_ENH_PROC - adapter->proc_rr = CREATE_READ_PROC("rebuild-rate", proc_rebuild_rate); - adapter->proc_battery = CREATE_READ_PROC("battery-status", - proc_battery); - - /* - * Display each physical drive on its channel - */ - adapter->proc_pdrvstat[0] = CREATE_READ_PROC("diskdrives-ch0", - proc_pdrv_ch0); - adapter->proc_pdrvstat[1] = CREATE_READ_PROC("diskdrives-ch1", - proc_pdrv_ch1); - adapter->proc_pdrvstat[2] = CREATE_READ_PROC("diskdrives-ch2", - proc_pdrv_ch2); - adapter->proc_pdrvstat[3] = CREATE_READ_PROC("diskdrives-ch3", - proc_pdrv_ch3); - - /* - * Display a set of up to 10 logical drive through each of following - * /proc entries - */ - adapter->proc_rdrvstat[0] = CREATE_READ_PROC("raiddrives-0-9", - proc_rdrv_10); - adapter->proc_rdrvstat[1] = CREATE_READ_PROC("raiddrives-10-19", - proc_rdrv_20); - adapter->proc_rdrvstat[2] = CREATE_READ_PROC("raiddrives-20-29", - proc_rdrv_30); - adapter->proc_rdrvstat[3] = CREATE_READ_PROC("raiddrives-30-39", - proc_rdrv_40); -#endif -} - - /** - * proc_read_config() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_config() + * @m - Synthetic file construction data + * @v - File iterator * * Display configuration information about the controller. */ static int -proc_read_config(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_config(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; - int len = 0; - - len += sprintf(page+len, "%s", MEGARAID_VERSION); + adapter_t *adapter = m->private; + seq_puts(m, MEGARAID_VERSION); if(adapter->product_info.product_name[0]) - len += sprintf(page+len, "%s\n", - adapter->product_info.product_name); - - len += sprintf(page+len, "Controller Type: "); + seq_printf(m, "%s\n", adapter->product_info.product_name); - if( adapter->flag & BOARD_MEMMAP ) { - len += sprintf(page+len, - "438/466/467/471/493/518/520/531/532\n"); - } - else { - len += sprintf(page+len, - "418/428/434\n"); - } + seq_puts(m, "Controller Type: "); - if(adapter->flag & BOARD_40LD) { - len += sprintf(page+len, - "Controller Supports 40 Logical Drives\n"); - } + if( adapter->flag & BOARD_MEMMAP ) + seq_puts(m, "438/466/467/471/493/518/520/531/532\n"); + else + seq_puts(m, "418/428/434\n"); - if(adapter->flag & BOARD_64BIT) { - len += sprintf(page+len, - "Controller capable of 64-bit memory addressing\n"); - } - if( adapter->has_64bit_addr ) { - len += sprintf(page+len, - "Controller using 64-bit memory addressing\n"); - } - else { - len += sprintf(page+len, - "Controller is not using 64-bit memory addressing\n"); - } + if(adapter->flag & BOARD_40LD) + seq_puts(m, "Controller Supports 40 Logical Drives\n"); - len += sprintf(page+len, "Base = %08lx, Irq = %d, ", adapter->base, - adapter->host->irq); - - len += sprintf(page+len, "Logical Drives = %d, Channels = %d\n", - adapter->numldrv, adapter->product_info.nchannels); - - len += sprintf(page+len, "Version =%s:%s, DRAM = %dMb\n", - adapter->fw_version, adapter->bios_version, - adapter->product_info.dram_size); - - len += sprintf(page+len, - "Controller Queue Depth = %d, Driver Queue Depth = %d\n", - adapter->product_info.max_commands, adapter->max_cmds); - - len += sprintf(page+len, "support_ext_cdb = %d\n", - adapter->support_ext_cdb); - len += sprintf(page+len, "support_random_del = %d\n", - adapter->support_random_del); - len += sprintf(page+len, "boot_ldrv_enabled = %d\n", - adapter->boot_ldrv_enabled); - len += sprintf(page+len, "boot_ldrv = %d\n", - adapter->boot_ldrv); - len += sprintf(page+len, "boot_pdrv_enabled = %d\n", - adapter->boot_pdrv_enabled); - len += sprintf(page+len, "boot_pdrv_ch = %d\n", - adapter->boot_pdrv_ch); - len += sprintf(page+len, "boot_pdrv_tgt = %d\n", - adapter->boot_pdrv_tgt); - len += sprintf(page+len, "quiescent = %d\n", - atomic_read(&adapter->quiescent)); - len += sprintf(page+len, "has_cluster = %d\n", - adapter->has_cluster); - - len += sprintf(page+len, "\nModule Parameters:\n"); - len += sprintf(page+len, "max_cmd_per_lun = %d\n", - max_cmd_per_lun); - len += sprintf(page+len, "max_sectors_per_io = %d\n", - max_sectors_per_io); - - *eof = 1; - - return len; + if(adapter->flag & BOARD_64BIT) + seq_puts(m, "Controller capable of 64-bit memory addressing\n"); + if( adapter->has_64bit_addr ) + seq_puts(m, "Controller using 64-bit memory addressing\n"); + else + seq_puts(m, "Controller is not using 64-bit memory addressing\n"); + + seq_printf(m, "Base = %08lx, Irq = %d, ", + adapter->base, adapter->host->irq); + + seq_printf(m, "Logical Drives = %d, Channels = %d\n", + adapter->numldrv, adapter->product_info.nchannels); + + seq_printf(m, "Version =%s:%s, DRAM = %dMb\n", + adapter->fw_version, adapter->bios_version, + adapter->product_info.dram_size); + + seq_printf(m, "Controller Queue Depth = %d, Driver Queue Depth = %d\n", + adapter->product_info.max_commands, adapter->max_cmds); + + seq_printf(m, "support_ext_cdb = %d\n", adapter->support_ext_cdb); + seq_printf(m, "support_random_del = %d\n", adapter->support_random_del); + seq_printf(m, "boot_ldrv_enabled = %d\n", adapter->boot_ldrv_enabled); + seq_printf(m, "boot_ldrv = %d\n", adapter->boot_ldrv); + seq_printf(m, "boot_pdrv_enabled = %d\n", adapter->boot_pdrv_enabled); + seq_printf(m, "boot_pdrv_ch = %d\n", adapter->boot_pdrv_ch); + seq_printf(m, "boot_pdrv_tgt = %d\n", adapter->boot_pdrv_tgt); + seq_printf(m, "quiescent = %d\n", + atomic_read(&adapter->quiescent)); + seq_printf(m, "has_cluster = %d\n", adapter->has_cluster); + + seq_puts(m, "\nModule Parameters:\n"); + seq_printf(m, "max_cmd_per_lun = %d\n", max_cmd_per_lun); + seq_printf(m, "max_sectors_per_io = %d\n", max_sectors_per_io); + return 0; } - - /** - * proc_read_stat() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_stat() + * @m - Synthetic file construction data + * @v - File iterator * - * Diaplay statistical information about the I/O activity. + * Display statistical information about the I/O activity. */ static int -proc_read_stat(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_stat(struct seq_file *m, void *v) { - adapter_t *adapter; - int len; + adapter_t *adapter = m->private; +#if MEGA_HAVE_STATS int i; +#endif - i = 0; /* avoid compilation warnings */ - len = 0; - adapter = (adapter_t *)data; - - len = sprintf(page, "Statistical Information for this controller\n"); - len += sprintf(page+len, "pend_cmds = %d\n", - atomic_read(&adapter->pend_cmds)); + seq_puts(m, "Statistical Information for this controller\n"); + seq_printf(m, "pend_cmds = %d\n", atomic_read(&adapter->pend_cmds)); #if MEGA_HAVE_STATS for(i = 0; i < adapter->numldrv; i++) { - len += sprintf(page+len, "Logical Drive %d:\n", i); - - len += sprintf(page+len, - "\tReads Issued = %lu, Writes Issued = %lu\n", - adapter->nreads[i], adapter->nwrites[i]); - - len += sprintf(page+len, - "\tSectors Read = %lu, Sectors Written = %lu\n", - adapter->nreadblocks[i], adapter->nwriteblocks[i]); - - len += sprintf(page+len, - "\tRead errors = %lu, Write errors = %lu\n\n", - adapter->rd_errors[i], adapter->wr_errors[i]); + seq_printf(m, "Logical Drive %d:\n", i); + seq_printf(m, "\tReads Issued = %lu, Writes Issued = %lu\n", + adapter->nreads[i], adapter->nwrites[i]); + seq_printf(m, "\tSectors Read = %lu, Sectors Written = %lu\n", + adapter->nreadblocks[i], adapter->nwriteblocks[i]); + seq_printf(m, "\tRead errors = %lu, Write errors = %lu\n\n", + adapter->rd_errors[i], adapter->wr_errors[i]); } #else - len += sprintf(page+len, - "IO and error counters not compiled in driver.\n"); + seq_puts(m, "IO and error counters not compiled in driver.\n"); #endif - - *eof = 1; - - return len; + return 0; } /** - * proc_read_mbox() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_mbox() + * @m - Synthetic file construction data + * @v - File iterator * * Display mailbox information for the last command issued. This information * is good for debugging. */ static int -proc_read_mbox(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_mbox(struct seq_file *m, void *v) { - - adapter_t *adapter = (adapter_t *)data; + adapter_t *adapter = m->private; volatile mbox_t *mbox = adapter->mbox; - int len = 0; - - len = sprintf(page, "Contents of Mail Box Structure\n"); - len += sprintf(page+len, " Fw Command = 0x%02x\n", - mbox->m_out.cmd); - len += sprintf(page+len, " Cmd Sequence = 0x%02x\n", - mbox->m_out.cmdid); - len += sprintf(page+len, " No of Sectors= %04d\n", - mbox->m_out.numsectors); - len += sprintf(page+len, " LBA = 0x%02x\n", - mbox->m_out.lba); - len += sprintf(page+len, " DTA = 0x%08x\n", - mbox->m_out.xferaddr); - len += sprintf(page+len, " Logical Drive= 0x%02x\n", - mbox->m_out.logdrv); - len += sprintf(page+len, " No of SG Elmt= 0x%02x\n", - mbox->m_out.numsgelements); - len += sprintf(page+len, " Busy = %01x\n", - mbox->m_in.busy); - len += sprintf(page+len, " Status = 0x%02x\n", - mbox->m_in.status); - - *eof = 1; - - return len; + + seq_puts(m, "Contents of Mail Box Structure\n"); + seq_printf(m, " Fw Command = 0x%02x\n", mbox->m_out.cmd); + seq_printf(m, " Cmd Sequence = 0x%02x\n", mbox->m_out.cmdid); + seq_printf(m, " No of Sectors= %04d\n", mbox->m_out.numsectors); + seq_printf(m, " LBA = 0x%02x\n", mbox->m_out.lba); + seq_printf(m, " DTA = 0x%08x\n", mbox->m_out.xferaddr); + seq_printf(m, " Logical Drive= 0x%02x\n", mbox->m_out.logdrv); + seq_printf(m, " No of SG Elmt= 0x%02x\n", mbox->m_out.numsgelements); + seq_printf(m, " Busy = %01x\n", mbox->m_in.busy); + seq_printf(m, " Status = 0x%02x\n", mbox->m_in.status); + return 0; } /** - * proc_rebuild_rate() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_rebuild_rate() + * @m - Synthetic file construction data + * @v - File iterator * * Display current rebuild rate */ static int -proc_rebuild_rate(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_rebuild_rate(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; + adapter_t *adapter = m->private; dma_addr_t dma_handle; caddr_t inquiry; struct pci_dev *pdev; - int len = 0; - if( make_local_pdev(adapter, &pdev) != 0 ) { - *eof = 1; - return len; - } + if( make_local_pdev(adapter, &pdev) != 0 ) + return 0; - if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { - free_local_pdev(pdev); - *eof = 1; - return len; - } + if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) + goto free_pdev; if( mega_adapinq(adapter, dma_handle) != 0 ) { - - len = sprintf(page, "Adapter inquiry failed.\n"); - + seq_puts(m, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - free_local_pdev(pdev); - - *eof = 1; - - return len; + goto free_inquiry; } - if( adapter->flag & BOARD_40LD ) { - len = sprintf(page, "Rebuild Rate: [%d%%]\n", - ((mega_inquiry3 *)inquiry)->rebuild_rate); - } - else { - len = sprintf(page, "Rebuild Rate: [%d%%]\n", + if( adapter->flag & BOARD_40LD ) + seq_printf(m, "Rebuild Rate: [%d%%]\n", + ((mega_inquiry3 *)inquiry)->rebuild_rate); + else + seq_printf(m, "Rebuild Rate: [%d%%]\n", ((mraid_ext_inquiry *) - inquiry)->raid_inq.adapter_info.rebuild_rate); - } - + inquiry)->raid_inq.adapter_info.rebuild_rate); +free_inquiry: mega_free_inquiry(inquiry, dma_handle, pdev); - +free_pdev: free_local_pdev(pdev); - - *eof = 1; - - return len; + return 0; } /** - * proc_battery() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_battery() + * @m - Synthetic file construction data + * @v - File iterator * * Display information about the battery module on the controller. */ static int -proc_battery(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_battery(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; + adapter_t *adapter = m->private; dma_addr_t dma_handle; caddr_t inquiry; struct pci_dev *pdev; - u8 battery_status = 0; - char str[256]; - int len = 0; + u8 battery_status; - if( make_local_pdev(adapter, &pdev) != 0 ) { - *eof = 1; - return len; - } + if( make_local_pdev(adapter, &pdev) != 0 ) + return 0; - if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { - free_local_pdev(pdev); - *eof = 1; - return len; - } + if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) + goto free_pdev; if( mega_adapinq(adapter, dma_handle) != 0 ) { - - len = sprintf(page, "Adapter inquiry failed.\n"); - + seq_printf(m, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - free_local_pdev(pdev); - - *eof = 1; - - return len; + goto free_inquiry; } if( adapter->flag & BOARD_40LD ) { @@ -2461,146 +2278,80 @@ proc_battery(char *page, char **start, off_t offset, int count, int *eof, /* * Decode the battery status */ - sprintf(str, "Battery Status:[%d]", battery_status); + seq_printf(m, "Battery Status:[%d]", battery_status); if(battery_status == MEGA_BATT_CHARGE_DONE) - strcat(str, " Charge Done"); + seq_puts(m, " Charge Done"); if(battery_status & MEGA_BATT_MODULE_MISSING) - strcat(str, " Module Missing"); + seq_puts(m, " Module Missing"); if(battery_status & MEGA_BATT_LOW_VOLTAGE) - strcat(str, " Low Voltage"); + seq_puts(m, " Low Voltage"); if(battery_status & MEGA_BATT_TEMP_HIGH) - strcat(str, " Temperature High"); + seq_puts(m, " Temperature High"); if(battery_status & MEGA_BATT_PACK_MISSING) - strcat(str, " Pack Missing"); + seq_puts(m, " Pack Missing"); if(battery_status & MEGA_BATT_CHARGE_INPROG) - strcat(str, " Charge In-progress"); + seq_puts(m, " Charge In-progress"); if(battery_status & MEGA_BATT_CHARGE_FAIL) - strcat(str, " Charge Fail"); + seq_puts(m, " Charge Fail"); if(battery_status & MEGA_BATT_CYCLES_EXCEEDED) - strcat(str, " Cycles Exceeded"); - - len = sprintf(page, "%s\n", str); + seq_puts(m, " Cycles Exceeded"); + seq_putc(m, '\n'); +free_inquiry: mega_free_inquiry(inquiry, dma_handle, pdev); - +free_pdev: free_local_pdev(pdev); - - *eof = 1; - - return len; -} - - -/** - * proc_pdrv_ch0() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state - * - * Display information about the physical drives on physical channel 0. - */ -static int -proc_pdrv_ch0(char *page, char **start, off_t offset, int count, int *eof, - void *data) -{ - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_pdrv(adapter, page, 0)); -} - - -/** - * proc_pdrv_ch1() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state - * - * Display information about the physical drives on physical channel 1. - */ -static int -proc_pdrv_ch1(char *page, char **start, off_t offset, int count, int *eof, - void *data) -{ - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_pdrv(adapter, page, 1)); + return 0; } -/** - * proc_pdrv_ch2() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state - * - * Display information about the physical drives on physical channel 2. +/* + * Display scsi inquiry */ -static int -proc_pdrv_ch2(char *page, char **start, off_t offset, int count, int *eof, - void *data) +static void +mega_print_inquiry(struct seq_file *m, char *scsi_inq) { - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_pdrv(adapter, page, 2)); -} + int i; + seq_puts(m, " Vendor: "); + seq_write(m, scsi_inq + 8, 8); + seq_puts(m, " Model: "); + seq_write(m, scsi_inq + 16, 16); + seq_puts(m, " Rev: "); + seq_write(m, scsi_inq + 32, 4); + seq_putc(m, '\n'); -/** - * proc_pdrv_ch3() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state - * - * Display information about the physical drives on physical channel 3. - */ -static int -proc_pdrv_ch3(char *page, char **start, off_t offset, int count, int *eof, - void *data) -{ - adapter_t *adapter = (adapter_t *)data; + i = scsi_inq[0] & 0x1f; + seq_printf(m, " Type: %s ", scsi_device_type(i)); - *eof = 1; + seq_printf(m, " ANSI SCSI revision: %02x", + scsi_inq[2] & 0x07); - return (proc_pdrv(adapter, page, 3)); + if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 ) + seq_puts(m, " CCS\n"); + else + seq_putc(m, '\n'); } - /** - * proc_pdrv() + * proc_show_pdrv() + * @m - Synthetic file construction data * @page - buffer to write the data in * @adapter - pointer to our soft state * * Display information about the physical drives. */ static int -proc_pdrv(adapter_t *adapter, char *page, int channel) +proc_show_pdrv(struct seq_file *m, adapter_t *adapter, int channel) { dma_addr_t dma_handle; char *scsi_inq; @@ -2611,32 +2362,24 @@ proc_pdrv(adapter_t *adapter, char *page, int channel) u8 state; int tgt; int max_channels; - int len = 0; - char str[80]; int i; - if( make_local_pdev(adapter, &pdev) != 0 ) { - return len; - } + if( make_local_pdev(adapter, &pdev) != 0 ) + return 0; - if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { + if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) goto free_pdev; - } if( mega_adapinq(adapter, dma_handle) != 0 ) { - len = sprintf(page, "Adapter inquiry failed.\n"); - + seq_puts(m, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); - goto free_inquiry; } scsi_inq = pci_alloc_consistent(pdev, 256, &scsi_inq_dma_handle); - if( scsi_inq == NULL ) { - len = sprintf(page, "memory not available for scsi inq.\n"); - + seq_puts(m, "memory not available for scsi inq.\n"); goto free_inquiry; } @@ -2659,39 +2402,31 @@ proc_pdrv(adapter_t *adapter, char *page, int channel) i = channel*16 + tgt; state = *(pdrv_state + i); - switch( state & 0x0F ) { - case PDRV_ONLINE: - sprintf(str, - "Channel:%2d Id:%2d State: Online", - channel, tgt); + seq_printf(m, "Channel:%2d Id:%2d State: Online", + channel, tgt); break; case PDRV_FAILED: - sprintf(str, - "Channel:%2d Id:%2d State: Failed", - channel, tgt); + seq_printf(m, "Channel:%2d Id:%2d State: Failed", + channel, tgt); break; case PDRV_RBLD: - sprintf(str, - "Channel:%2d Id:%2d State: Rebuild", - channel, tgt); + seq_printf(m, "Channel:%2d Id:%2d State: Rebuild", + channel, tgt); break; case PDRV_HOTSPARE: - sprintf(str, - "Channel:%2d Id:%2d State: Hot spare", - channel, tgt); + seq_printf(m, "Channel:%2d Id:%2d State: Hot spare", + channel, tgt); break; default: - sprintf(str, - "Channel:%2d Id:%2d State: Un-configured", - channel, tgt); + seq_printf(m, "Channel:%2d Id:%2d State: Un-configured", + channel, tgt); break; - } /* @@ -2710,11 +2445,8 @@ proc_pdrv(adapter_t *adapter, char *page, int channel) * Check for overflow. We print less than 240 * characters for inquiry */ - if( (len + 240) >= PAGE_SIZE ) break; - - len += sprintf(page+len, "%s.\n", str); - - len += mega_print_inquiry(page+len, scsi_inq); + seq_puts(m, ".\n"); + mega_print_inquiry(m, scsi_inq); } free_pci: @@ -2723,150 +2455,68 @@ free_inquiry: mega_free_inquiry(inquiry, dma_handle, pdev); free_pdev: free_local_pdev(pdev); - - return len; -} - - -/* - * Display scsi inquiry - */ -static int -mega_print_inquiry(char *page, char *scsi_inq) -{ - int len = 0; - int i; - - len = sprintf(page, " Vendor: "); - for( i = 8; i < 16; i++ ) { - len += sprintf(page+len, "%c", scsi_inq[i]); - } - - len += sprintf(page+len, " Model: "); - - for( i = 16; i < 32; i++ ) { - len += sprintf(page+len, "%c", scsi_inq[i]); - } - - len += sprintf(page+len, " Rev: "); - - for( i = 32; i < 36; i++ ) { - len += sprintf(page+len, "%c", scsi_inq[i]); - } - - len += sprintf(page+len, "\n"); - - i = scsi_inq[0] & 0x1f; - - len += sprintf(page+len, " Type: %s ", scsi_device_type(i)); - - len += sprintf(page+len, - " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07); - - if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 ) - len += sprintf(page+len, " CCS\n"); - else - len += sprintf(page+len, "\n"); - - return len; + return 0; } - /** - * proc_rdrv_10() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_pdrv_ch0() + * @m - Synthetic file construction data + * @v - File iterator * - * Display real time information about the logical drives 0 through 9. + * Display information about the physical drives on physical channel 0. */ static int -proc_rdrv_10(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_pdrv_ch0(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_rdrv(adapter, page, 0, 9)); + return proc_show_pdrv(m, m->private, 0); } /** - * proc_rdrv_20() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_pdrv_ch1() + * @m - Synthetic file construction data + * @v - File iterator * - * Display real time information about the logical drives 0 through 9. + * Display information about the physical drives on physical channel 1. */ static int -proc_rdrv_20(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_pdrv_ch1(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_rdrv(adapter, page, 10, 19)); + return proc_show_pdrv(m, m->private, 1); } /** - * proc_rdrv_30() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_pdrv_ch2() + * @m - Synthetic file construction data + * @v - File iterator * - * Display real time information about the logical drives 0 through 9. + * Display information about the physical drives on physical channel 2. */ static int -proc_rdrv_30(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_pdrv_ch2(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_rdrv(adapter, page, 20, 29)); + return proc_show_pdrv(m, m->private, 2); } /** - * proc_rdrv_40() - * @page - buffer to write the data in - * @start - where the actual data has been written in page - * @offset - same meaning as the read system call - * @count - same meaning as the read system call - * @eof - set if no more data needs to be returned - * @data - pointer to our soft state + * proc_show_pdrv_ch3() + * @m - Synthetic file construction data + * @v - File iterator * - * Display real time information about the logical drives 0 through 9. + * Display information about the physical drives on physical channel 3. */ static int -proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof, - void *data) +proc_show_pdrv_ch3(struct seq_file *m, void *v) { - adapter_t *adapter = (adapter_t *)data; - - *eof = 1; - - return (proc_rdrv(adapter, page, 30, 39)); + return proc_show_pdrv(m, m->private, 3); } /** - * proc_rdrv() - * @page - buffer to write the data in + * proc_show_rdrv() + * @m - Synthetic file construction data * @adapter - pointer to our soft state * @start - starting logical drive to display * @end - ending logical drive to display @@ -2875,7 +2525,7 @@ proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof, * /proc/scsi/scsi interface */ static int -proc_rdrv(adapter_t *adapter, char *page, int start, int end ) +proc_show_rdrv(struct seq_file *m, adapter_t *adapter, int start, int end ) { dma_addr_t dma_handle; logdrv_param *lparam; @@ -2887,29 +2537,18 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) u8 *rdrv_state; int num_ldrv; u32 array_sz; - int len = 0; int i; - if( make_local_pdev(adapter, &pdev) != 0 ) { - return len; - } + if( make_local_pdev(adapter, &pdev) != 0 ) + return 0; - if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { - free_local_pdev(pdev); - return len; - } + if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) + goto free_pdev; if( mega_adapinq(adapter, dma_handle) != 0 ) { - - len = sprintf(page, "Adapter inquiry failed.\n"); - + seq_puts(m, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - free_local_pdev(pdev); - - return len; + goto free_inquiry; } memset(&mc, 0, sizeof(megacmd_t)); @@ -2935,13 +2574,8 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) &disk_array_dma_handle); if( disk_array == NULL ) { - len = sprintf(page, "memory not available.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - free_local_pdev(pdev); - - return len; + seq_puts(m, "memory not available.\n"); + goto free_inquiry; } mc.xferaddr = (u32)disk_array_dma_handle; @@ -2951,17 +2585,8 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) mc.opcode = OP_DCMD_READ_CONFIG; if( mega_internal_command(adapter, &mc, NULL) ) { - - len = sprintf(page, "40LD read config failed.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - pci_free_consistent(pdev, array_sz, disk_array, - disk_array_dma_handle); - - free_local_pdev(pdev); - - return len; + seq_puts(m, "40LD read config failed.\n"); + goto free_pci; } } @@ -2969,24 +2594,10 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) mc.cmd = NEW_READ_CONFIG_8LD; if( mega_internal_command(adapter, &mc, NULL) ) { - mc.cmd = READ_CONFIG_8LD; - - if( mega_internal_command(adapter, &mc, - NULL) ){ - - len = sprintf(page, - "8LD read config failed.\n"); - - mega_free_inquiry(inquiry, dma_handle, pdev); - - pci_free_consistent(pdev, array_sz, - disk_array, - disk_array_dma_handle); - - free_local_pdev(pdev); - - return len; + if( mega_internal_command(adapter, &mc, NULL) ) { + seq_puts(m, "8LD read config failed.\n"); + goto free_pci; } } } @@ -3006,29 +2617,23 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) * Check for overflow. We print less than 240 characters for * information about each logical drive. */ - if( (len + 240) >= PAGE_SIZE ) break; - - len += sprintf(page+len, "Logical drive:%2d:, ", i); + seq_printf(m, "Logical drive:%2d:, ", i); switch( rdrv_state[i] & 0x0F ) { case RDRV_OFFLINE: - len += sprintf(page+len, "state: offline"); + seq_puts(m, "state: offline"); break; - case RDRV_DEGRADED: - len += sprintf(page+len, "state: degraded"); + seq_puts(m, "state: degraded"); break; - case RDRV_OPTIMAL: - len += sprintf(page+len, "state: optimal"); + seq_puts(m, "state: optimal"); break; - case RDRV_DELETED: - len += sprintf(page+len, "state: deleted"); + seq_puts(m, "state: deleted"); break; - default: - len += sprintf(page+len, "state: unknown"); + seq_puts(m, "state: unknown"); break; } @@ -3036,84 +2641,203 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) * Check if check consistency or initialization is going on * for this logical drive. */ - if( (rdrv_state[i] & 0xF0) == 0x20 ) { - len += sprintf(page+len, - ", check-consistency in progress"); - } - else if( (rdrv_state[i] & 0xF0) == 0x10 ) { - len += sprintf(page+len, - ", initialization in progress"); - } + if( (rdrv_state[i] & 0xF0) == 0x20 ) + seq_puts(m, ", check-consistency in progress"); + else if( (rdrv_state[i] & 0xF0) == 0x10 ) + seq_puts(m, ", initialization in progress"); - len += sprintf(page+len, "\n"); - - len += sprintf(page+len, "Span depth:%3d, ", - lparam->span_depth); - - len += sprintf(page+len, "RAID level:%3d, ", - lparam->level); - - len += sprintf(page+len, "Stripe size:%3d, ", - lparam->stripe_sz ? lparam->stripe_sz/2: 128); - - len += sprintf(page+len, "Row size:%3d\n", - lparam->row_size); + seq_putc(m, '\n'); + seq_printf(m, "Span depth:%3d, ", lparam->span_depth); + seq_printf(m, "RAID level:%3d, ", lparam->level); + seq_printf(m, "Stripe size:%3d, ", + lparam->stripe_sz ? lparam->stripe_sz/2: 128); + seq_printf(m, "Row size:%3d\n", lparam->row_size); - len += sprintf(page+len, "Read Policy: "); - + seq_puts(m, "Read Policy: "); switch(lparam->read_ahead) { - case NO_READ_AHEAD: - len += sprintf(page+len, "No read ahead, "); + seq_puts(m, "No read ahead, "); break; - case READ_AHEAD: - len += sprintf(page+len, "Read ahead, "); + seq_puts(m, "Read ahead, "); break; - case ADAP_READ_AHEAD: - len += sprintf(page+len, "Adaptive, "); + seq_puts(m, "Adaptive, "); break; } - len += sprintf(page+len, "Write Policy: "); - + seq_puts(m, "Write Policy: "); switch(lparam->write_mode) { - case WRMODE_WRITE_THRU: - len += sprintf(page+len, "Write thru, "); + seq_puts(m, "Write thru, "); break; - case WRMODE_WRITE_BACK: - len += sprintf(page+len, "Write back, "); + seq_puts(m, "Write back, "); break; } - len += sprintf(page+len, "Cache Policy: "); - + seq_puts(m, "Cache Policy: "); switch(lparam->direct_io) { - case CACHED_IO: - len += sprintf(page+len, "Cached IO\n\n"); + seq_puts(m, "Cached IO\n\n"); break; - case DIRECT_IO: - len += sprintf(page+len, "Direct IO\n\n"); + seq_puts(m, "Direct IO\n\n"); break; } } - mega_free_inquiry(inquiry, dma_handle, pdev); - +free_pci: pci_free_consistent(pdev, array_sz, disk_array, disk_array_dma_handle); - +free_inquiry: + mega_free_inquiry(inquiry, dma_handle, pdev); +free_pdev: free_local_pdev(pdev); + return 0; +} + +/** + * proc_show_rdrv_10() + * @m - Synthetic file construction data + * @v - File iterator + * + * Display real time information about the logical drives 0 through 9. + */ +static int +proc_show_rdrv_10(struct seq_file *m, void *v) +{ + return proc_show_rdrv(m, m->private, 0, 9); +} + + +/** + * proc_show_rdrv_20() + * @m - Synthetic file construction data + * @v - File iterator + * + * Display real time information about the logical drives 0 through 9. + */ +static int +proc_show_rdrv_20(struct seq_file *m, void *v) +{ + return proc_show_rdrv(m, m->private, 10, 19); +} + + +/** + * proc_show_rdrv_30() + * @m - Synthetic file construction data + * @v - File iterator + * + * Display real time information about the logical drives 0 through 9. + */ +static int +proc_show_rdrv_30(struct seq_file *m, void *v) +{ + return proc_show_rdrv(m, m->private, 20, 29); +} + + +/** + * proc_show_rdrv_40() + * @m - Synthetic file construction data + * @v - File iterator + * + * Display real time information about the logical drives 0 through 9. + */ +static int +proc_show_rdrv_40(struct seq_file *m, void *v) +{ + return proc_show_rdrv(m, m->private, 30, 39); +} + + +/* + * seq_file wrappers for procfile show routines. + */ +static int mega_proc_open(struct inode *inode, struct file *file) +{ + adapter_t *adapter = proc_get_parent_data(inode); + int (*show)(struct seq_file *, void *) = PDE_DATA(inode); + + return single_open(file, show, adapter); +} + +static const struct file_operations mega_proc_fops = { + .open = mega_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * Table of proc files we need to create. + */ +struct mega_proc_file { + const char *name; + unsigned short ptr_offset; + int (*show) (struct seq_file *m, void *v); +}; + +static const struct mega_proc_file mega_proc_files[] = { + { "config", offsetof(adapter_t, proc_read), proc_show_config }, + { "stat", offsetof(adapter_t, proc_stat), proc_show_stat }, + { "mailbox", offsetof(adapter_t, proc_mbox), proc_show_mbox }, +#if MEGA_HAVE_ENH_PROC + { "rebuild-rate", offsetof(adapter_t, proc_rr), proc_show_rebuild_rate }, + { "battery-status", offsetof(adapter_t, proc_battery), proc_show_battery }, + { "diskdrives-ch0", offsetof(adapter_t, proc_pdrvstat[0]), proc_show_pdrv_ch0 }, + { "diskdrives-ch1", offsetof(adapter_t, proc_pdrvstat[1]), proc_show_pdrv_ch1 }, + { "diskdrives-ch2", offsetof(adapter_t, proc_pdrvstat[2]), proc_show_pdrv_ch2 }, + { "diskdrives-ch3", offsetof(adapter_t, proc_pdrvstat[3]), proc_show_pdrv_ch3 }, + { "raiddrives-0-9", offsetof(adapter_t, proc_rdrvstat[0]), proc_show_rdrv_10 }, + { "raiddrives-10-19", offsetof(adapter_t, proc_rdrvstat[1]), proc_show_rdrv_20 }, + { "raiddrives-20-29", offsetof(adapter_t, proc_rdrvstat[2]), proc_show_rdrv_30 }, + { "raiddrives-30-39", offsetof(adapter_t, proc_rdrvstat[3]), proc_show_rdrv_40 }, +#endif + { NULL } +}; - return len; +/** + * mega_create_proc_entry() + * @index - index in soft state array + * @parent - parent node for this /proc entry + * + * Creates /proc entries for our controllers. + */ +static void +mega_create_proc_entry(int index, struct proc_dir_entry *parent) +{ + const struct mega_proc_file *f; + adapter_t *adapter = hba_soft_state[index]; + struct proc_dir_entry *dir, *de, **ppde; + u8 string[16]; + + sprintf(string, "hba%d", adapter->host->host_no); + + dir = adapter->controller_proc_dir_entry = + proc_mkdir_data(string, 0, parent, adapter); + if(!dir) { + printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n"); + return; + } + + for (f = mega_proc_files; f->name; f++) { + de = proc_create_data(f->name, S_IRUSR, dir, &mega_proc_fops, + f->show); + if (!de) { + printk(KERN_WARNING "\nmegaraid: proc_create failed\n"); + return; + } + + ppde = (void *)adapter + f->ptr_offset; + *ppde = de; + } } + #else static inline void mega_create_proc_entry(int index, struct proc_dir_entry *parent) { diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 4fb2adf6b80..4d0ce4e78df 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -987,24 +987,7 @@ static int mega_init_scb (adapter_t *); static int mega_is_bios_enabled (adapter_t *); #ifdef CONFIG_PROC_FS -static int mega_print_inquiry(char *, char *); static void mega_create_proc_entry(int, struct proc_dir_entry *); -static int proc_read_config(char *, char **, off_t, int, int *, void *); -static int proc_read_stat(char *, char **, off_t, int, int *, void *); -static int proc_read_mbox(char *, char **, off_t, int, int *, void *); -static int proc_rebuild_rate(char *, char **, off_t, int, int *, void *); -static int proc_battery(char *, char **, off_t, int, int *, void *); -static int proc_pdrv_ch0(char *, char **, off_t, int, int *, void *); -static int proc_pdrv_ch1(char *, char **, off_t, int, int *, void *); -static int proc_pdrv_ch2(char *, char **, off_t, int, int *, void *); -static int proc_pdrv_ch3(char *, char **, off_t, int, int *, void *); -static int proc_pdrv(adapter_t *, char *, int); -static int proc_rdrv_10(char *, char **, off_t, int, int *, void *); -static int proc_rdrv_20(char *, char **, off_t, int, int *, void *); -static int proc_rdrv_30(char *, char **, off_t, int, int *, void *); -static int proc_rdrv_40(char *, char **, off_t, int, int *, void *); -static int proc_rdrv(adapter_t *, char *, int, int); - static int mega_adapinq(adapter_t *, dma_addr_t); static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t); #endif diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 08685c4cf23..eec052c2670 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -505,19 +505,6 @@ _ctl_fasync(int fd, struct file *filep, int mode) } /** - * _ctl_release - - * @inode - - * @filep - - * - * Called when application releases the fasyn callback handler. - */ -static int -_ctl_release(struct inode *inode, struct file *filep) -{ - return fasync_helper(-1, filep, 0, &async_queue); -} - -/** * _ctl_poll - * @file - * @wait - @@ -3027,7 +3014,6 @@ struct device_attribute *mpt2sas_dev_attrs[] = { static const struct file_operations ctl_fops = { .owner = THIS_MODULE, .unlocked_ioctl = _ctl_ioctl, - .release = _ctl_release, .poll = _ctl_poll, .fasync = _ctl_fasync, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 054d5231c97..0b402b6f2d2 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -503,19 +503,6 @@ _ctl_fasync(int fd, struct file *filep, int mode) } /** - * _ctl_release - - * @inode - - * @filep - - * - * Called when application releases the fasyn callback handler. - */ -static int -_ctl_release(struct inode *inode, struct file *filep) -{ - return fasync_helper(-1, filep, 0, &async_queue); -} - -/** * _ctl_poll - * @file - * @wait - @@ -3233,7 +3220,6 @@ struct device_attribute *mpt3sas_dev_attrs[] = { static const struct file_operations ctl_fops = { .owner = THIS_MODULE, .unlocked_ioctl = _ctl_ioctl, - .release = _ctl_release, .poll = _ctl_poll, .fasync = _ctl_fasync, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index c29d0dbb966..e7f6661a886 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c @@ -76,7 +76,8 @@ int mvme147_detect(struct scsi_host_template *tpnt) called++; tpnt->proc_name = "MVME147"; - tpnt->proc_info = &wd33c93_proc_info; + tpnt->show_info = wd33c93_show_info, + tpnt->write_info = wd33c93_write_info, instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); if (!instance) diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 1cc0c1c69c8..1e3879dcbdc 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -192,7 +192,7 @@ static int __init init_nsp32 (void); static void __exit exit_nsp32 (void); /* struct struct scsi_host_template */ -static int nsp32_proc_info (struct Scsi_Host *, char *, char **, off_t, int, int); +static int nsp32_show_info (struct seq_file *, struct Scsi_Host *); static int nsp32_detect (struct pci_dev *pdev); static int nsp32_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); @@ -268,7 +268,7 @@ static void nsp32_dmessage(const char *, int, int, char *, ...); static struct scsi_host_template nsp32_template = { .proc_name = "nsp32", .name = "Workbit NinjaSCSI-32Bi/UDE", - .proc_info = nsp32_proc_info, + .show_info = nsp32_show_info, .info = nsp32_info, .queuecommand = nsp32_queuecommand, .can_queue = 1, @@ -1442,19 +1442,10 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id) } #undef SPRINTF -#define SPRINTF(args...) \ - do { \ - if(length > (pos - buffer)) { \ - pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \ - nsp32_dbg(NSP32_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ - } \ - } while(0) - -static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start, - off_t offset, int length, int inout) +#define SPRINTF(args...) seq_printf(m, ##args) + +static int nsp32_show_info(struct seq_file *m, struct Scsi_Host *host) { - char *pos = buffer; - int thislength; unsigned long flags; nsp32_hw_data *data; int hostno; @@ -1463,11 +1454,6 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start, int id, speed; long model; - /* Write is not supported, just return. */ - if (inout == TRUE) { - return -EINVAL; - } - hostno = host->host_no; data = (nsp32_hw_data *)host->hostdata; base = host->io_port; @@ -1527,20 +1513,7 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start, } SPRINTF("\n"); } - - - thislength = pos - (buffer + offset); - - if(thislength < 0) { - *start = NULL; - return 0; - } - - - thislength = min(thislength, length); - *start = buffer + offset; - - return thislength; + return 0; } #undef SPRINTF diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 2f72c9807b1..62f1a603176 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -388,7 +388,8 @@ int __init pas16_detect(struct scsi_host_template * tpnt) int count; tpnt->proc_name = "pas16"; - tpnt->proc_info = &pas16_proc_info; + tpnt->show_info = pas16_show_info; + tpnt->write_info = pas16_write_info; if (pas16_addr != 0) { overrides[0].io_port = pas16_addr; diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index a04281cace2..3721342835e 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h @@ -163,7 +163,8 @@ static int pas16_bus_reset(Scsi_Cmnd *); #define NCR5380_queue_command pas16_queue_command #define NCR5380_abort pas16_abort #define NCR5380_bus_reset pas16_bus_reset -#define NCR5380_proc_info pas16_proc_info +#define NCR5380_show_info pas16_show_info +#define NCR5380_write_info pas16_write_info /* 15 14 12 10 7 5 3 1101 0100 1010 1000 */ diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index b61a753eb89..987fbb1b244 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -76,7 +76,7 @@ MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 static struct scsi_host_template nsp_driver_template = { .proc_name = "nsp_cs", - .proc_info = nsp_proc_info, + .show_info = nsp_show_info, .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", .info = nsp_info, .queuecommand = nsp_queuecommand, @@ -1365,33 +1365,19 @@ static const char *nsp_info(struct Scsi_Host *shpnt) } #undef SPRINTF -#define SPRINTF(args...) \ - do { \ - if(length > (pos - buffer)) { \ - pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \ - nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ - } \ - } while(0) - -static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start, - off_t offset, int length, int inout) +#define SPRINTF(args...) seq_printf(m, ##args) + +static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host) { int id; - char *pos = buffer; - int thislength; int speed; unsigned long flags; nsp_hw_data *data; int hostno; - if (inout) { - return -EINVAL; - } - hostno = host->host_no; data = (nsp_hw_data *)host->hostdata; - SPRINTF("NinjaSCSI status\n\n"); SPRINTF("Driver version: $Revision: 1.23 $\n"); SPRINTF("SCSI host No.: %d\n", hostno); @@ -1458,19 +1444,7 @@ static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start, } SPRINTF("\n"); } - - thislength = pos - (buffer + offset); - - if(thislength < 0) { - *start = NULL; - return 0; - } - - - thislength = min(thislength, length); - *start = buffer + offset; - - return thislength; + return 0; } #undef SPRINTF diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 7fc9a9d0a44..afd64f0adc4 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -292,13 +292,8 @@ static int nsp_cs_config (struct pcmcia_device *link); /* Linux SCSI subsystem specific functions */ static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); static const char *nsp_info (struct Scsi_Host *shpnt); -static int nsp_proc_info ( - struct Scsi_Host *host, - char *buffer, - char **start, - off_t offset, - int length, - int inout); +static int nsp_show_info (struct seq_file *m, + struct Scsi_Host *host); static int nsp_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *SCpnt); /* Error handler */ diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index b46f5e90683..8e1b7377506 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3599,19 +3599,6 @@ static int pmcraid_chr_open(struct inode *inode, struct file *filep) } /** - * pmcraid_release - char node "release" entry point - */ -static int pmcraid_chr_release(struct inode *inode, struct file *filep) -{ - struct pmcraid_instance *pinstance = filep->private_data; - - filep->private_data = NULL; - fasync_helper(-1, filep, 0, &pinstance->aen_queue); - - return 0; -} - -/** * pmcraid_fasync - Async notifier registration from applications * * This function adds the calling process to a driver global queue. When an @@ -4167,7 +4154,6 @@ static long pmcraid_chr_ioctl( static const struct file_operations pmcraid_fops = { .owner = THIS_MODULE, .open = pmcraid_chr_open, - .release = pmcraid_chr_release, .fasync = pmcraid_chr_fasync, .unlocked_ioctl = pmcraid_chr_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index d164c963936..1db8b26063b 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -118,8 +118,9 @@ static inline void ppa_pb_release(ppa_struct *dev) * Also gives a method to use a script to obtain optimum timings (TODO) */ -static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length) +static inline int ppa_write_info(struct Scsi_Host *host, char *buffer, int length) { + ppa_struct *dev = ppa_dev(host); unsigned long x; if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) { @@ -137,35 +138,17 @@ static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length) return -EINVAL; } -static int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) +static int ppa_show_info(struct seq_file *m, struct Scsi_Host *host) { - int len = 0; ppa_struct *dev = ppa_dev(host); - if (inout) - return ppa_proc_write(dev, buffer, length); - - len += sprintf(buffer + len, "Version : %s\n", PPA_VERSION); - len += - sprintf(buffer + len, "Parport : %s\n", - dev->dev->port->name); - len += - sprintf(buffer + len, "Mode : %s\n", - PPA_MODE_STRING[dev->mode]); + seq_printf(m, "Version : %s\n", PPA_VERSION); + seq_printf(m, "Parport : %s\n", dev->dev->port->name); + seq_printf(m, "Mode : %s\n", PPA_MODE_STRING[dev->mode]); #if PPA_DEBUG > 0 - len += - sprintf(buffer + len, "recon_tmo : %lu\n", dev->recon_tmo); + seq_printf(m, "recon_tmo : %lu\n", dev->recon_tmo); #endif - - /* Request for beyond end of buffer */ - if (offset > length) - return 0; - - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; - return len; + return 0; } static int device_check(ppa_struct *dev); @@ -981,7 +964,8 @@ static int ppa_adjust_queue(struct scsi_device *device) static struct scsi_host_template ppa_template = { .module = THIS_MODULE, .proc_name = "ppa", - .proc_info = ppa_proc_info, + .show_info = ppa_show_info, + .write_info = ppa_write_info, .name = "Iomega VPI0 (ppa) interface", .queuecommand = ppa_queuecommand, .eh_abort_handler = ppa_abort, diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a083715843b..5307bf86d5e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5539,7 +5539,7 @@ static struct pci_driver qla2xxx_pci_driver = { .err_handler = &qla2xxx_err_handler, }; -static struct file_operations apidev_fops = { +static const struct file_operations apidev_fops = { .owner = THIS_MODULE, .llseek = noop_llseek, }; diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5cda11c07c6..5add6f4e792 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -2823,31 +2823,27 @@ static const char * scsi_debug_info(struct Scsi_Host * shp) /* scsi_debug_proc_info * Used if the driver currently has no own support for /proc/scsi */ -static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int inout) +static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int length) { - int len, pos, begin; - int orig_length; + char arr[16]; + int opts; + int minLen = length > 15 ? 15 : length; - orig_length = length; - - if (inout == 1) { - char arr[16]; - int minLen = length > 15 ? 15 : length; + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) + return -EACCES; + memcpy(arr, buffer, minLen); + arr[minLen] = '\0'; + if (1 != sscanf(arr, "%d", &opts)) + return -EINVAL; + scsi_debug_opts = opts; + if (scsi_debug_every_nth != 0) + scsi_debug_cmnd_count = 0; + return length; +} - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) - return -EACCES; - memcpy(arr, buffer, minLen); - arr[minLen] = '\0'; - if (1 != sscanf(arr, "%d", &pos)) - return -EINVAL; - scsi_debug_opts = pos; - if (scsi_debug_every_nth != 0) - scsi_debug_cmnd_count = 0; - return length; - } - begin = 0; - pos = len = sprintf(buffer, "scsi_debug adapter driver, version " +static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) +{ + seq_printf(m, "scsi_debug adapter driver, version " "%s [%s]\n" "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, " "every_nth=%d(curr:%d)\n" @@ -2862,15 +2858,7 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads, sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets, num_host_resets, dix_reads, dix_writes, dif_errors); - if (pos < offset) { - len = 0; - begin = pos; - } - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); - if (len > length) - len = length; - return len; + return 0; } static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf) @@ -3957,7 +3945,8 @@ write: static DEF_SCSI_QCMD(scsi_debug_queuecommand) static struct scsi_host_template sdebug_driver_template = { - .proc_info = scsi_debug_proc_info, + .show_info = scsi_debug_show_info, + .write_info = scsi_debug_write_info, .proc_name = sdebug_proc_name, .name = "SCSI DEBUG", .info = scsi_debug_info, diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index ad747dc337d..db66357211e 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -45,58 +45,50 @@ static struct proc_dir_entry *proc_scsi; /* Protect sht->present and sht->proc_dir */ static DEFINE_MUTEX(global_host_template_mutex); -/** - * proc_scsi_read - handle read from /proc by calling host's proc_info() command - * @buffer: passed to proc_info - * @start: passed to proc_info - * @offset: passed to proc_info - * @length: passed to proc_info - * @eof: returns whether length read was less than requested - * @data: pointer to a &struct Scsi_Host - */ - -static int proc_scsi_read(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) -{ - struct Scsi_Host *shost = data; - int n; - - n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0); - *eof = (n < length); - - return n; -} - -/** - * proc_scsi_write_proc - Handle write to /proc by calling host's proc_info() - * @file: not used - * @buf: source of data to write. - * @count: number of bytes (at most PROC_BLOCK_SIZE) to write. - * @data: pointer to &struct Scsi_Host - */ -static int proc_scsi_write_proc(struct file *file, const char __user *buf, - unsigned long count, void *data) +static ssize_t proc_scsi_host_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { - struct Scsi_Host *shost = data; + struct Scsi_Host *shost = PDE_DATA(file_inode(file)); ssize_t ret = -ENOMEM; char *page; - char *start; if (count > PROC_BLOCK_SIZE) return -EOVERFLOW; + if (!shost->hostt->write_info) + return -EINVAL; + page = (char *)__get_free_page(GFP_KERNEL); if (page) { ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; - ret = shost->hostt->proc_info(shost, page, &start, 0, count, 1); + ret = shost->hostt->write_info(shost, page, count); } out: free_page((unsigned long)page); return ret; } +static int proc_scsi_show(struct seq_file *m, void *v) +{ + struct Scsi_Host *shost = m->private; + return shost->hostt->show_info(m, shost); +} + +static int proc_scsi_host_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, proc_scsi_show, PDE_DATA(inode), + 4 * PAGE_SIZE); +} + +static const struct file_operations proc_scsi_fops = { + .open = proc_scsi_host_open, + .read = seq_read, + .llseek = seq_lseek, + .write = proc_scsi_host_write +}; + /** * scsi_proc_hostdir_add - Create directory in /proc for a scsi host * @sht: owner of this directory @@ -106,7 +98,7 @@ out: void scsi_proc_hostdir_add(struct scsi_host_template *sht) { - if (!sht->proc_info) + if (!sht->show_info) return; mutex_lock(&global_host_template_mutex); @@ -125,7 +117,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht) */ void scsi_proc_hostdir_rm(struct scsi_host_template *sht) { - if (!sht->proc_info) + if (!sht->show_info) return; mutex_lock(&global_host_template_mutex); @@ -151,16 +143,12 @@ void scsi_proc_host_add(struct Scsi_Host *shost) return; sprintf(name,"%d", shost->host_no); - p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, - sht->proc_dir, proc_scsi_read, shost); - if (!p) { + p = proc_create_data(name, S_IRUGO | S_IWUSR, + sht->proc_dir, &proc_scsi_fops, shost); + if (!p) printk(KERN_ERR "%s: Failed to register host %d in" "%s\n", __func__, shost->host_no, sht->proc_name); - return; - } - - p->write_proc = proc_scsi_write_proc; } /** diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 599568299fb..bac55f7f69f 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1171,112 +1171,36 @@ printk("sym_user_command: data=%ld\n", uc->data); #endif /* SYM_LINUX_USER_COMMAND_SUPPORT */ -#ifdef SYM_LINUX_USER_INFO_SUPPORT -/* - * Informations through the proc file system. - */ -struct info_str { - char *buffer; - int length; - int offset; - int pos; -}; - -static void copy_mem_info(struct info_str *info, char *data, int len) -{ - if (info->pos + len > info->length) - len = info->length - info->pos; - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - if (info->pos < info->offset) { - data += (info->offset - info->pos); - len -= (info->offset - info->pos); - } - - if (len > 0) { - memcpy(info->buffer + info->pos, data, len); - info->pos += len; - } -} - -static int copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[81]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - return len; -} - /* * Copy formatted information into the input buffer. */ -static int sym_host_info(struct Scsi_Host *shost, char *ptr, off_t offset, int len) +static int sym_show_info(struct seq_file *m, struct Scsi_Host *shost) { +#ifdef SYM_LINUX_USER_INFO_SUPPORT struct sym_data *sym_data = shost_priv(shost); struct pci_dev *pdev = sym_data->pdev; struct sym_hcb *np = sym_data->ncb; - struct info_str info; - - info.buffer = ptr; - info.length = len; - info.offset = offset; - info.pos = 0; - copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " - "revision id 0x%x\n", np->s.chip_name, - pdev->device, pdev->revision); - copy_info(&info, "At PCI address %s, IRQ %u\n", + seq_printf(m, "Chip " NAME53C "%s, device id 0x%x, " + "revision id 0x%x\n", np->s.chip_name, + pdev->device, pdev->revision); + seq_printf(m, "At PCI address %s, IRQ %u\n", pci_name(pdev), pdev->irq); - copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", - (int) (np->minsync_dt ? np->minsync_dt : np->minsync), - np->maxwide ? "Wide" : "Narrow", - np->minsync_dt ? ", DT capable" : ""); + seq_printf(m, "Min. period factor %d, %s SCSI BUS%s\n", + (int) (np->minsync_dt ? np->minsync_dt : np->minsync), + np->maxwide ? "Wide" : "Narrow", + np->minsync_dt ? ", DT capable" : ""); - copy_info(&info, "Max. started commands %d, " - "max. commands per LUN %d\n", - SYM_CONF_MAX_START, SYM_CONF_MAX_TAG); + seq_printf(m, "Max. started commands %d, " + "max. commands per LUN %d\n", + SYM_CONF_MAX_START, SYM_CONF_MAX_TAG); - return info.pos > info.offset? info.pos - info.offset : 0; -} -#endif /* SYM_LINUX_USER_INFO_SUPPORT */ - -/* - * Entry point of the scsi proc fs of the driver. - * - func = 0 means read (returns adapter infos) - * - func = 1 means write (not yet merget from sym53c8xx) - */ -static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer, - char **start, off_t offset, int length, int func) -{ - int retv; - - if (func) { -#ifdef SYM_LINUX_USER_COMMAND_SUPPORT - retv = sym_user_command(shost, buffer, length); -#else - retv = -EINVAL; -#endif - } else { - if (start) - *start = buffer; -#ifdef SYM_LINUX_USER_INFO_SUPPORT - retv = sym_host_info(shost, buffer, offset, length); + return 0; #else - retv = -EINVAL; -#endif - } - - return retv; + return -EINVAL; +#endif /* SYM_LINUX_USER_INFO_SUPPORT */ } + #endif /* SYM_LINUX_PROC_INFO_SUPPORT */ /* @@ -1742,7 +1666,10 @@ static struct scsi_host_template sym2_template = { .use_clustering = ENABLE_CLUSTERING, .max_sectors = 0xFFFF, #ifdef SYM_LINUX_PROC_INFO_SUPPORT - .proc_info = sym53c8xx_proc_info, + .show_info = sym_show_info, +#ifdef SYM_LINUX_USER_COMMAND_SUPPORT + .write_info = sym_user_command, +#endif .proc_name = NAME53C8XX, #endif }; diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index d672d97fb84..f1e4b4148c7 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -201,7 +201,8 @@ int __init t128_detect(struct scsi_host_template * tpnt){ int sig, count; tpnt->proc_name = "t128"; - tpnt->proc_info = &t128_proc_info; + tpnt->show_info = t128_show_info; + tpnt->write_info = t128_write_info; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { base = 0; diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index ada1115079c..1df82c28e56 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h @@ -140,7 +140,8 @@ static int t128_bus_reset(struct scsi_cmnd *); #define NCR5380_queue_command t128_queue_command #define NCR5380_abort t128_abort #define NCR5380_bus_reset t128_bus_reset -#define NCR5380_proc_info t128_proc_info +#define NCR5380_show_info t128_show_info +#define NCR5380_write_info t128_write_info /* 15 14 12 10 7 5 3 1101 0100 1010 1000 */ diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index c0ee4ea28a1..41883a87931 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -2054,22 +2054,16 @@ wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs, printk(" Version %s - %s\n", WD33C93_VERSION, WD33C93_DATE); } -int -wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in) +int wd33c93_write_info(struct Scsi_Host *instance, char *buf, int len) { - #ifdef PROC_INTERFACE - char *bp; - char tbuf[128]; struct WD33C93_hostdata *hd; - struct scsi_cmnd *cmd; int x; - static int stop = 0; hd = (struct WD33C93_hostdata *) instance->hostdata; -/* If 'in' is TRUE we need to _read_ the proc file. We accept the following +/* We accept the following * keywords (same format as command-line, but arguments are not optional): * debug * disconnect @@ -2083,145 +2077,124 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off * nosync */ - if (in) { - buf[len] = '\0'; - for (bp = buf; *bp; ) { - while (',' == *bp || ' ' == *bp) - ++bp; - if (!strncmp(bp, "debug:", 6)) { - hd->args = simple_strtoul(bp+6, &bp, 0) & DB_MASK; - } else if (!strncmp(bp, "disconnect:", 11)) { - x = simple_strtoul(bp+11, &bp, 0); - if (x < DIS_NEVER || x > DIS_ALWAYS) - x = DIS_ADAPTIVE; - hd->disconnect = x; - } else if (!strncmp(bp, "period:", 7)) { + buf[len] = '\0'; + for (bp = buf; *bp; ) { + while (',' == *bp || ' ' == *bp) + ++bp; + if (!strncmp(bp, "debug:", 6)) { + hd->args = simple_strtoul(bp+6, &bp, 0) & DB_MASK; + } else if (!strncmp(bp, "disconnect:", 11)) { + x = simple_strtoul(bp+11, &bp, 0); + if (x < DIS_NEVER || x > DIS_ALWAYS) + x = DIS_ADAPTIVE; + hd->disconnect = x; + } else if (!strncmp(bp, "period:", 7)) { + x = simple_strtoul(bp+7, &bp, 0); + hd->default_sx_per = + hd->sx_table[round_period((unsigned int) x, + hd->sx_table)].period_ns; + } else if (!strncmp(bp, "resync:", 7)) { + set_resync(hd, (int)simple_strtoul(bp+7, &bp, 0)); + } else if (!strncmp(bp, "proc:", 5)) { + hd->proc = simple_strtoul(bp+5, &bp, 0); + } else if (!strncmp(bp, "nodma:", 6)) { + hd->no_dma = simple_strtoul(bp+6, &bp, 0); + } else if (!strncmp(bp, "level2:", 7)) { + hd->level2 = simple_strtoul(bp+7, &bp, 0); + } else if (!strncmp(bp, "burst:", 6)) { + hd->dma_mode = + simple_strtol(bp+6, &bp, 0) ? CTRL_BURST:CTRL_DMA; + } else if (!strncmp(bp, "fast:", 5)) { + x = !!simple_strtol(bp+5, &bp, 0); + if (x != hd->fast) + set_resync(hd, 0xff); + hd->fast = x; + } else if (!strncmp(bp, "nosync:", 7)) { x = simple_strtoul(bp+7, &bp, 0); - hd->default_sx_per = - hd->sx_table[round_period((unsigned int) x, - hd->sx_table)].period_ns; - } else if (!strncmp(bp, "resync:", 7)) { - set_resync(hd, (int)simple_strtoul(bp+7, &bp, 0)); - } else if (!strncmp(bp, "proc:", 5)) { - hd->proc = simple_strtoul(bp+5, &bp, 0); - } else if (!strncmp(bp, "nodma:", 6)) { - hd->no_dma = simple_strtoul(bp+6, &bp, 0); - } else if (!strncmp(bp, "level2:", 7)) { - hd->level2 = simple_strtoul(bp+7, &bp, 0); - } else if (!strncmp(bp, "burst:", 6)) { - hd->dma_mode = - simple_strtol(bp+6, &bp, 0) ? CTRL_BURST:CTRL_DMA; - } else if (!strncmp(bp, "fast:", 5)) { - x = !!simple_strtol(bp+5, &bp, 0); - if (x != hd->fast) - set_resync(hd, 0xff); - hd->fast = x; - } else if (!strncmp(bp, "nosync:", 7)) { - x = simple_strtoul(bp+7, &bp, 0); - set_resync(hd, x ^ hd->no_sync); - hd->no_sync = x; - } else { - break; /* unknown keyword,syntax-error,... */ - } + set_resync(hd, x ^ hd->no_sync); + hd->no_sync = x; + } else { + break; /* unknown keyword,syntax-error,... */ } - return len; } + return len; +#else + return 0; +#endif +} + +int +wd33c93_show_info(struct seq_file *m, struct Scsi_Host *instance) +{ +#ifdef PROC_INTERFACE + struct WD33C93_hostdata *hd; + struct scsi_cmnd *cmd; + int x; + + hd = (struct WD33C93_hostdata *) instance->hostdata; spin_lock_irq(&hd->lock); - bp = buf; - *bp = '\0'; - if (hd->proc & PR_VERSION) { - sprintf(tbuf, "\nVersion %s - %s.", + if (hd->proc & PR_VERSION) + seq_printf(m, "\nVersion %s - %s.", WD33C93_VERSION, WD33C93_DATE); - strcat(bp, tbuf); - } + if (hd->proc & PR_INFO) { - sprintf(tbuf, "\nclock_freq=%02x no_sync=%02x no_dma=%d" + seq_printf(m, "\nclock_freq=%02x no_sync=%02x no_dma=%d" " dma_mode=%02x fast=%d", hd->clock_freq, hd->no_sync, hd->no_dma, hd->dma_mode, hd->fast); - strcat(bp, tbuf); - strcat(bp, "\nsync_xfer[] = "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%02x", hd->sync_xfer[x]); - strcat(bp, tbuf); - } - strcat(bp, "\nsync_stat[] = "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%02x", hd->sync_stat[x]); - strcat(bp, tbuf); - } + seq_printf(m, "\nsync_xfer[] = "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%02x", hd->sync_xfer[x]); + seq_printf(m, "\nsync_stat[] = "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%02x", hd->sync_stat[x]); } #ifdef PROC_STATISTICS if (hd->proc & PR_STATISTICS) { - strcat(bp, "\ncommands issued: "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]); - strcat(bp, tbuf); - } - strcat(bp, "\ndisconnects allowed:"); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]); - strcat(bp, tbuf); - } - strcat(bp, "\ndisconnects done: "); - for (x = 0; x < 7; x++) { - sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]); - strcat(bp, tbuf); - } - sprintf(tbuf, + seq_printf(m, "\ncommands issued: "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->cmd_cnt[x]); + seq_printf(m, "\ndisconnects allowed:"); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->disc_allowed_cnt[x]); + seq_printf(m, "\ndisconnects done: "); + for (x = 0; x < 7; x++) + seq_printf(m, "\t%ld", hd->disc_done_cnt[x]); + seq_printf(m, "\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO", hd->int_cnt, hd->dma_cnt, hd->pio_cnt); - strcat(bp, tbuf); } #endif if (hd->proc & PR_CONNECTED) { - strcat(bp, "\nconnected: "); + seq_printf(m, "\nconnected: "); if (hd->connected) { cmd = (struct scsi_cmnd *) hd->connected; - sprintf(tbuf, " %d:%d(%02x)", + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); } } if (hd->proc & PR_INPUTQ) { - strcat(bp, "\ninput_Q: "); + seq_printf(m, "\ninput_Q: "); cmd = (struct scsi_cmnd *) hd->input_Q; while (cmd) { - sprintf(tbuf, " %d:%d(%02x)", + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); cmd = (struct scsi_cmnd *) cmd->host_scribble; } } if (hd->proc & PR_DISCQ) { - strcat(bp, "\ndisconnected_Q:"); + seq_printf(m, "\ndisconnected_Q:"); cmd = (struct scsi_cmnd *) hd->disconnected_Q; while (cmd) { - sprintf(tbuf, " %d:%d(%02x)", + seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]); - strcat(bp, tbuf); cmd = (struct scsi_cmnd *) cmd->host_scribble; } } - strcat(bp, "\n"); + seq_printf(m, "\n"); spin_unlock_irq(&hd->lock); - *start = buf; - if (stop) { - stop = 0; - return 0; - } - if (off > 0x40000) /* ALWAYS stop after 256k bytes have been read */ - stop = 1; - if (hd->proc & PR_STOP) /* stop every other time */ - stop = 1; - return strlen(bp); - -#else /* PROC_INTERFACE */ - - return 0; - #endif /* PROC_INTERFACE */ - + return 0; } EXPORT_SYMBOL(wd33c93_host_reset); @@ -2229,4 +2202,5 @@ EXPORT_SYMBOL(wd33c93_init); EXPORT_SYMBOL(wd33c93_abort); EXPORT_SYMBOL(wd33c93_queuecommand); EXPORT_SYMBOL(wd33c93_intr); -EXPORT_SYMBOL(wd33c93_proc_info); +EXPORT_SYMBOL(wd33c93_show_info); +EXPORT_SYMBOL(wd33c93_write_info); diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h index 3b463d7304d..08abe508e9a 100644 --- a/drivers/scsi/wd33c93.h +++ b/drivers/scsi/wd33c93.h @@ -345,7 +345,8 @@ void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs, int wd33c93_abort (struct scsi_cmnd *cmd); int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd); void wd33c93_intr (struct Scsi_Host *instance); -int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); +int wd33c93_show_info(struct seq_file *, struct Scsi_Host *); +int wd33c93_write_info(struct Scsi_Host *, char *, int); int wd33c93_host_reset (struct scsi_cmnd *); #endif /* WD33C93_H */ diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index d89a5dfd3ad..f9a6e4b0aff 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -1296,9 +1296,9 @@ static void wd7000_revision(Adapter * host) #undef SPRINTF -#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } +#define SPRINTF(args...) { seq_printf(m, ## args); } -static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host) +static int wd7000_set_info(struct Scsi_Host *host, char *buffer, int length) { dprintk("Buffer = <%.*s>, length = %d\n", length, buffer, length); @@ -1310,22 +1310,15 @@ static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host) } -static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) +static int wd7000_show_info(struct seq_file *m, struct Scsi_Host *host) { Adapter *adapter = (Adapter *)host->hostdata; unsigned long flags; - char *pos = buffer; #ifdef WD7000_DEBUG Mailbox *ogmbs, *icmbs; short count; #endif - /* - * Has data been written to the file ? - */ - if (inout) - return (wd7000_set_info(buffer, length, host)); - spin_lock_irqsave(host->host_lock, flags); SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", host->host_no, adapter->rev1, adapter->rev2); SPRINTF(" IO base: 0x%x\n", adapter->iobase); @@ -1368,17 +1361,7 @@ static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, spin_unlock_irqrestore(host->host_lock, flags); - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return (0); - else if ((pos - buffer - offset) < length) - return (pos - buffer - offset); - else - return (length); + return 0; } @@ -1413,7 +1396,8 @@ static __init int wd7000_detect(struct scsi_host_template *tpnt) for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1); tpnt->proc_name = "wd7000"; - tpnt->proc_info = &wd7000_proc_info; + tpnt->show_info = &wd7000_show_info; + tpnt->write_info = wd7000_set_info; /* * Set up SCB free list, which is shared by all adapters @@ -1658,7 +1642,8 @@ MODULE_LICENSE("GPL"); static struct scsi_host_template driver_template = { .proc_name = "wd7000", - .proc_info = wd7000_proc_info, + .show_info = wd7000_show_info, + .write_info = wd7000_set_info, .name = "Western Digital WD-7000", .detect = wd7000_detect, .release = wd7000_release, diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 362c214bcc0..db790f9fc9d 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -31,17 +31,15 @@ #include "comedidev.h" #include "comedi_internal.h" #include <linux/proc_fs.h> -#include <linux/string.h> +#include <linux/seq_file.h> -static int comedi_read(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +static int comedi_read(struct seq_file *m, void *v) { int i; int devices_q = 0; - int l = 0; struct comedi_driver *driv; - l += sprintf(buf + l, + seq_printf(m, "comedi version " COMEDI_RELEASE "\n" "format string: %s\n", "\"%2d: %-20s %-20s %4d\", i, " @@ -49,42 +47,51 @@ static int comedi_read(char *buf, char **start, off_t offset, int len, for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { struct comedi_device *dev = comedi_dev_from_minor(i); - if (!dev) continue; if (dev->attached) { devices_q = 1; - l += sprintf(buf + l, "%2d: %-20s %-20s %4d\n", - i, - dev->driver->driver_name, - dev->board_name, dev->n_subdevices); + seq_printf(m, "%2d: %-20s %-20s %4d\n", + i, dev->driver->driver_name, + dev->board_name, dev->n_subdevices); } } if (!devices_q) - l += sprintf(buf + l, "no devices\n"); + seq_puts(m, "no devices\n"); for (driv = comedi_drivers; driv; driv = driv->next) { - l += sprintf(buf + l, "%s:\n", driv->driver_name); - for (i = 0; i < driv->num_names; i++) { - l += sprintf(buf + l, " %s\n", - *(char **)((char *)driv->board_name + - i * driv->offset)); - } + seq_printf(m, "%s:\n", driv->driver_name); + for (i = 0; i < driv->num_names; i++) + seq_printf(m, " %s\n", + *(char **)((char *)driv->board_name + + i * driv->offset)); + if (!driv->num_names) - l += sprintf(buf + l, " %s\n", driv->driver_name); + seq_printf(m, " %s\n", driv->driver_name); } - return l; + return 0; } -void comedi_proc_init(void) +/* + * seq_file wrappers for procfile show routines. + */ +static int comedi_proc_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *comedi_proc; + return single_open(file, comedi_read, NULL); +} + +static const struct file_operations comedi_proc_fops = { + .open = comedi_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - comedi_proc = create_proc_entry("comedi", S_IFREG | S_IRUGO, NULL); - if (comedi_proc) - comedi_proc->read_proc = comedi_read; +void comedi_proc_init(void) +{ + proc_create("comedi", 0644, NULL, &comedi_proc_fops); } void comedi_proc_cleanup(void) diff --git a/drivers/staging/csr/csr_wifi_hip_udi.c b/drivers/staging/csr/csr_wifi_hip_udi.c index a65b822db69..a6b006b0e98 100644 --- a/drivers/staging/csr/csr_wifi_hip_udi.c +++ b/drivers/staging/csr/csr_wifi_hip_udi.c @@ -24,10 +24,50 @@ * * --------------------------------------------------------------------------- */ +#include <linux/seq_file.h> #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_card.h" +static void unifi_print_unsafe_sdio_status(card_t *card, struct seq_file *m) +{ +#ifdef CSR_UNSAFE_SDIO_ACCESS + s32 iostate; + CsrResult r; + static const char *const states[] = { + "AWAKE", "DROWSY", "TORPID" + }; +#define SHARED_READ_RETRY_LIMIT 10 + u8 b; + + seq_printf(m, "Host State: %s\n", states[card->host_state]); + + r = unifi_check_io_status(card, &iostate); + if (iostate == 1) { + seq_puts(m, remaining, "I/O Check: F1 disabled\n"); + } else { + if (iostate == 1) { + seq_puts(m, "I/O Check: pending interrupt\n"); + + seq_printf(m, "BH reason interrupt = %d\n", card->bh_reason_unifi); + seq_printf(m, "BH reason host = %d\n", card->bh_reason_host); + + for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) { + r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b); + if (r == CSR_RESULT_SUCCESS && !(b & 0x80)) { + seq_printf(m, "fhsr: %u (driver thinks is %u)\n", + b, card->from_host_signals_r); + break; + } + } + + iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); + seq_printf(m, "thsw: %u (driver thinks is %u)\n", + iostate, card->to_host_signals_w); + } +#endif +} + /* * --------------------------------------------------------------------------- * unifi_print_status @@ -41,228 +81,93 @@ * None. * --------------------------------------------------------------------------- */ -s32 unifi_print_status(card_t *card, char *str, s32 *remain) +s32 unifi_print_status(card_t *card, struct seq_file *m) { - char *p = str; - sdio_config_data_t *cfg; - u16 i, n; - s32 remaining = *remain; - s32 written; -#ifdef CSR_UNSAFE_SDIO_ACCESS - s32 iostate; - CsrResult r; - static const char *const states[] = { - "AWAKE", "DROWSY", "TORPID" - }; - #define SHARED_READ_RETRY_LIMIT 10 - u8 b; -#endif - - if (remaining <= 0) - { - return 0; - } - - i = n = 0; - written = scnprintf(p, remaining, "Chip ID %u\n", - (u16)card->chip_id); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "Chip Version %04X\n", - card->chip_version); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "HIP v%u.%u\n", - (card->config_data.version >> 8) & 0xFF, - card->config_data.version & 0xFF); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "Build %u: %s\n", - card->build_id, card->build_id_string); - UNIFI_SNPRINTF_RET(p, remaining, written); - - cfg = &card->config_data; - - written = scnprintf(p, remaining, "sdio ctrl offset %u\n", - cfg->sdio_ctrl_offset); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "fromhost sigbuf handle %u\n", - cfg->fromhost_sigbuf_handle); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "tohost_sigbuf_handle %u\n", - cfg->tohost_sigbuf_handle); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "num_fromhost_sig_frags %u\n", - cfg->num_fromhost_sig_frags); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "num_tohost_sig_frags %u\n", - cfg->num_tohost_sig_frags); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "num_fromhost_data_slots %u\n", - cfg->num_fromhost_data_slots); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "num_tohost_data_slots %u\n", - cfg->num_tohost_data_slots); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "data_slot_size %u\n", - cfg->data_slot_size); - UNIFI_SNPRINTF_RET(p, remaining, written); - - /* Added by protocol version 0x0001 */ - written = scnprintf(p, remaining, "overlay_size %u\n", - (u16)cfg->overlay_size); - UNIFI_SNPRINTF_RET(p, remaining, written); - - /* Added by protocol version 0x0300 */ - written = scnprintf(p, remaining, "data_slot_round %u\n", - cfg->data_slot_round); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "sig_frag_size %u\n", - cfg->sig_frag_size); - UNIFI_SNPRINTF_RET(p, remaining, written); - - /* Added by protocol version 0x0300 */ - written = scnprintf(p, remaining, "tohost_sig_pad %u\n", - cfg->tohost_signal_padding); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, "\nInternal state:\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n", - card->last_phy_panic_code, card->last_phy_panic_arg); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n", - card->last_mac_panic_code, card->last_mac_panic_arg); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, "fhsr: %u\n", - (u16)card->from_host_signals_r); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "fhsw: %u\n", - (u16)card->from_host_signals_w); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "thsr: %u\n", - (u16)card->to_host_signals_r); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "thsw: %u\n", - (u16)card->to_host_signals_w); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, - "fh buffer contains: %d signals, %td bytes\n", - card->fh_buffer.count, - card->fh_buffer.ptr - card->fh_buffer.buf); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, "paused: "); - UNIFI_SNPRINTF_RET(p, remaining, written); - for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++) - { - written = scnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0"); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - written = scnprintf(p, remaining, "\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, - "fh command q: %u waiting, %u free of %u:\n", - CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue), - CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue), - UNIFI_SOFT_COMMAND_Q_LENGTH); - UNIFI_SNPRINTF_RET(p, remaining, written); - for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) - { - written = scnprintf(p, remaining, - "fh traffic q[%u]: %u waiting, %u free of %u:\n", - i, - CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]), - CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]), - UNIFI_SOFT_TRAFFIC_Q_LENGTH); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - - written = scnprintf(p, remaining, "fh data slots free: %u\n", - card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0); - UNIFI_SNPRINTF_RET(p, remaining, written); - - - written = scnprintf(p, remaining, "From host data slots:"); - UNIFI_SNPRINTF_RET(p, remaining, written); - n = card->config_data.num_fromhost_data_slots; - for (i = 0; i < n && card->from_host_data; i++) - { - written = scnprintf(p, remaining, " %u", - (u16)card->from_host_data[i].bd.data_length); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - written = scnprintf(p, remaining, "\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - - written = scnprintf(p, remaining, "To host data slots:"); - UNIFI_SNPRINTF_RET(p, remaining, written); - n = card->config_data.num_tohost_data_slots; - for (i = 0; i < n && card->to_host_data; i++) - { - written = scnprintf(p, remaining, " %u", - (u16)card->to_host_data[i].data_length); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - - written = scnprintf(p, remaining, "\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - -#ifdef CSR_UNSAFE_SDIO_ACCESS - written = scnprintf(p, remaining, "Host State: %s\n", states[card->host_state]); - UNIFI_SNPRINTF_RET(p, remaining, written); - - r = unifi_check_io_status(card, &iostate); - if (iostate == 1) - { - written = scnprintf(p, remaining, "I/O Check: F1 disabled\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - else - { - if (iostate == 1) - { - written = scnprintf(p, remaining, "I/O Check: pending interrupt\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - } - - written = scnprintf(p, remaining, "BH reason interrupt = %d\n", - card->bh_reason_unifi); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "BH reason host = %d\n", - card->bh_reason_host); - UNIFI_SNPRINTF_RET(p, remaining, written); - - for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) - { - r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b); - if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80))) - { - written = scnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n", - b, card->from_host_signals_r); - UNIFI_SNPRINTF_RET(p, remaining, written); - break; - } - } - iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); - written = scnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n", - iostate, card->to_host_signals_w); - UNIFI_SNPRINTF_RET(p, remaining, written); - } -#endif - - written = scnprintf(p, remaining, "\nStats:\n"); - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "Total SDIO bytes: R=%u W=%u\n", - card->sdio_bytes_read, card->sdio_bytes_written); - - UNIFI_SNPRINTF_RET(p, remaining, written); - written = scnprintf(p, remaining, "Interrupts generated on card: %u\n", - card->unifi_interrupt_seq); - UNIFI_SNPRINTF_RET(p, remaining, written); - - *remain = remaining; - return (p - str); -} /* unifi_print_status() */ - - + sdio_config_data_t *cfg; + u16 i, n; + + i = n = 0; + seq_printf(m, "Chip ID %u\n", card->chip_id); + seq_printf(m, "Chip Version %04X\n", card->chip_version); + seq_printf(m, "HIP v%u.%u\n", + (card->config_data.version >> 8) & 0xFF, + card->config_data.version & 0xFF); + seq_printf(m, "Build %u: %s\n", card->build_id, card->build_id_string); + + cfg = &card->config_data; + + seq_printf(m, "sdio ctrl offset %u\n", cfg->sdio_ctrl_offset); + seq_printf(m, "fromhost sigbuf handle %u\n", cfg->fromhost_sigbuf_handle); + seq_printf(m, "tohost_sigbuf_handle %u\n", cfg->tohost_sigbuf_handle); + seq_printf(m, "num_fromhost_sig_frags %u\n", cfg->num_fromhost_sig_frags); + seq_printf(m, "num_tohost_sig_frags %u\n", cfg->num_tohost_sig_frags); + seq_printf(m, "num_fromhost_data_slots %u\n", cfg->num_fromhost_data_slots); + seq_printf(m, "num_tohost_data_slots %u\n", cfg->num_tohost_data_slots); + seq_printf(m, "data_slot_size %u\n", cfg->data_slot_size); + + /* Added by protocol version 0x0001 */ + seq_printf(m, "overlay_size %u\n", cfg->overlay_size); + + /* Added by protocol version 0x0300 */ + seq_printf(m, "data_slot_round %u\n", cfg->data_slot_round); + seq_printf(m, "sig_frag_size %u\n", cfg->sig_frag_size); + + /* Added by protocol version 0x0300 */ + seq_printf(m, "tohost_sig_pad %u\n", cfg->tohost_signal_padding); + + seq_puts(m, "\nInternal state:\n"); + + seq_printf(m, "Last PHY PANIC: %04x:%04x\n", + card->last_phy_panic_code, card->last_phy_panic_arg); + seq_printf(m, "Last MAC PANIC: %04x:%04x\n", + card->last_mac_panic_code, card->last_mac_panic_arg); + + seq_printf(m, "fhsr: %hu\n", (u16)card->from_host_signals_r); + seq_printf(m, "fhsw: %hu\n", (u16)card->from_host_signals_w); + seq_printf(m, "thsr: %hu\n", (u16)card->to_host_signals_r); + seq_printf(m, "thsw: %hu\n", (u16)card->to_host_signals_w); + seq_printf(m, "fh buffer contains: %d signals, %td bytes\n", + card->fh_buffer.count, + card->fh_buffer.ptr - card->fh_buffer.buf); + + seq_puts(m, "paused: "); + for (i = 0; i < ARRAY_SIZE(card->tx_q_paused_flag); i++) + seq_printf(m, card->tx_q_paused_flag[i] ? "1" : "0"); + seq_putc(m, '\n'); + + seq_printf(m, "fh command q: %u waiting, %u free of %u:\n", + CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue), + CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue), + UNIFI_SOFT_COMMAND_Q_LENGTH); + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + seq_printf(m, "fh traffic q[%u]: %u waiting, %u free of %u:\n", + i, + CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]), + CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]), + UNIFI_SOFT_TRAFFIC_Q_LENGTH); + + seq_printf(m, "fh data slots free: %u\n", + card->from_host_data ? CardGetFreeFromHostDataSlots(card) : 0); + + seq_puts(m, "From host data slots:"); + n = card->config_data.num_fromhost_data_slots; + for (i = 0; i < n && card->from_host_data; i++) + seq_printf(m, " %hu", (u16)card->from_host_data[i].bd.data_length); + seq_putc(m, '\n'); + + seq_puts(m, "To host data slots:"); + n = card->config_data.num_tohost_data_slots; + for (i = 0; i < n && card->to_host_data; i++) + seq_printf(m, " %hu", (u16)card->to_host_data[i].data_length); + seq_putc(m, '\n'); + + unifi_print_unsafe_sdio_status(card, m); + + seq_puts(m, "\nStats:\n"); + seq_printf(m, "Total SDIO bytes: R=%u W=%u\n", + card->sdio_bytes_read, card->sdio_bytes_written); + + seq_printf(m, "Interrupts generated on card: %u\n", card->unifi_interrupt_seq); + return 0; +} diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h index 9d85cfd5761..4126e85bfe9 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h @@ -47,21 +47,6 @@ CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn); * This is used in the linux /proc interface and might be useful * in other systems. */ -s32 unifi_print_status(card_t *card, char *str, s32 *remain); - -#define UNIFI_SNPRINTF_RET(buf_p, remain, written) \ - do { \ - if (written >= remain) { \ - if (remain >= 2) { \ - buf_p[remain - 2] = '\n'; \ - buf_p[remain - 1] = 0; \ - } \ - buf_p += remain; \ - remain = 0; \ - } else if (written > 0) { \ - buf_p += written; \ - remain -= written; \ - } \ - } while (0) +s32 unifi_print_status(card_t *card, struct seq_file *m); #endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */ diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 5520d6539f7..bdc25236ab0 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -1941,7 +1941,7 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) * **************************************************************************** */ -static struct file_operations unifi_fops = { +static const struct file_operations unifi_fops = { .owner = THIS_MODULE, .open = unifi_open, .release = unifi_release, @@ -2041,7 +2041,7 @@ void uf_destroy_device_nodes(unifi_priv_t *priv) * ---------------------------------------------------------------- */ static int -uf_create_debug_device(struct file_operations *fops) +uf_create_debug_device(const struct file_operations *fops) { int ret; diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index af9c28f073b..f9b5c22c00b 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -31,6 +31,7 @@ * --------------------------------------------------------------------------- */ #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_unifiversion.h" @@ -76,9 +77,28 @@ DEFINE_SEMAPHORE(Unifi_instance_mutex); */ DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq); +#ifdef CONFIG_PROC_FS +/* + * seq_file wrappers for procfile show routines. + */ +static int uf_proc_show(struct seq_file *m, void *v); + +#define UNIFI_DEBUG_TXT_BUFFER (8 * 1024) + +static int uf_proc_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, uf_proc_show, PDE_DATA(inode), + UNIFI_DEBUG_TXT_BUFFER); +} + +static const struct file_operations uf_proc_fops = { + .open = uf_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -static int uf_read_proc(char *page, char **start, off_t offset, int count, - int *eof, void *data); +#endif /* CONFIG_PROC_FS */ #ifdef CSR_WIFI_RX_PATH_SPLIT @@ -327,8 +347,8 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) * The following complex casting is in place in order to eliminate 64-bit compilation warning * "cast to/from pointer from/to integer of different size" */ - if (!create_proc_read_entry(priv->proc_entry_name, 0, 0, - uf_read_proc, (void *)(long)priv->instance)) + if (!proc_create_data(priv->proc_entry_name, 0, NULL, + &uf_proc_fops, (void *)(long)priv->instance)) { unifi_error(priv, "unifi: can't create /proc/driver/unifi\n"); } @@ -827,7 +847,7 @@ uf_put_instance(int inst) /* * --------------------------------------------------------------------------- - * uf_read_proc + * uf_proc_show * * Read method for driver node in /proc/driver/unifi0 * @@ -844,107 +864,54 @@ uf_put_instance(int inst) * --------------------------------------------------------------------------- */ #ifdef CONFIG_PROC_FS -static int -uf_read_proc(char *page, char **start, off_t offset, int count, - int *eof, void *data) +static int uf_proc_show(struct seq_file *m, void *v) { -#define UNIFI_DEBUG_TXT_BUFFER 8*1024 - unifi_priv_t *priv; - int actual_amount_to_copy; - char *p, *orig_p; - s32 remain = UNIFI_DEBUG_TXT_BUFFER; - s32 written; - int i; - - /* - * The following complex casting is in place in order to eliminate 64-bit compilation warning - * "cast to/from pointer from/to integer of different size" - */ - priv = uf_find_instance((int)(long)data); - if (!priv) { - return 0; - } - - p = kmalloc( UNIFI_DEBUG_TXT_BUFFER, GFP_KERNEL ); - - orig_p = p; - - written = scnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n", - CSR_WIFI_VERSION, __DATE__, __TIME__); - UNIFI_SNPRINTF_RET(p, remain, written); + unifi_priv_t *priv; + int i; + + /* + * The following complex casting is in place in order to eliminate + * 64-bit compilation warning "cast to/from pointer from/to integer of + * different size" + */ + priv = uf_find_instance((long)m->private); + if (!priv) + return 0; + + seq_printf(m, "UniFi SDIO Driver: %s %s %s\n", + CSR_WIFI_VERSION, __DATE__, __TIME__); #ifdef CSR_SME_USERSPACE - written = scnprintf(p, remain, "SME: CSR userspace "); - UNIFI_SNPRINTF_RET(p, remain, written); + seq_puts(m, "SME: CSR userspace "); #ifdef CSR_SUPPORT_WEXT - written = scnprintf(p, remain, "with WEXT support\n"); + seq_puts(m, "with WEXT support\n"); #else - written = scnprintf(p, remain, "\n"); + seq_putc(m, '\n'); #endif /* CSR_SUPPORT_WEXT */ - UNIFI_SNPRINTF_RET(p, remain, written); #endif /* CSR_SME_USERSPACE */ #ifdef CSR_NATIVE_LINUX - written = scnprintf(p, remain, "SME: native\n"); - UNIFI_SNPRINTF_RET(p, remain, written); + seq_puts(m, "SME: native\n"); #endif #ifdef CSR_SUPPORT_SME - written = scnprintf(p, remain, - "Firmware (ROM) build:%u, Patch:%u\n", - priv->card_info.fw_build, - priv->sme_versions.firmwarePatch); - UNIFI_SNPRINTF_RET(p, remain, written); + seq_printf(m, "Firmware (ROM) build:%u, Patch:%u\n", + priv->card_info.fw_build, + priv->sme_versions.firmwarePatch); #endif - p += unifi_print_status(priv->card, p, &remain); - - written = scnprintf(p, remain, "Last dbg str: %s\n", - priv->last_debug_string); - UNIFI_SNPRINTF_RET(p, remain, written); - - written = scnprintf(p, remain, "Last dbg16:"); - UNIFI_SNPRINTF_RET(p, remain, written); - for (i = 0; i < 8; i++) { - written = scnprintf(p, remain, " %04X", - priv->last_debug_word16[i]); - UNIFI_SNPRINTF_RET(p, remain, written); - } - written = scnprintf(p, remain, "\n"); - UNIFI_SNPRINTF_RET(p, remain, written); - written = scnprintf(p, remain, " "); - UNIFI_SNPRINTF_RET(p, remain, written); - for (; i < 16; i++) { - written = scnprintf(p, remain, " %04X", - priv->last_debug_word16[i]); - UNIFI_SNPRINTF_RET(p, remain, written); - } - written = scnprintf(p, remain, "\n"); - UNIFI_SNPRINTF_RET(p, remain, written); - *start = page; - - written = UNIFI_DEBUG_TXT_BUFFER - remain; - - if( offset >= written ) - { - *eof = 1; - kfree( orig_p ); - return(0); - } - - if( offset + count > written ) - { - actual_amount_to_copy = written - offset; - *eof = 1; - } - else - { - actual_amount_to_copy = count; - } - memcpy( page, &(orig_p[offset]), actual_amount_to_copy ); + unifi_print_status(priv->card, m); - kfree( orig_p ); + seq_printf(m, "Last dbg str: %s\n", priv->last_debug_string); - return( actual_amount_to_copy ); -} /* uf_read_proc() */ + seq_puts(m, "Last dbg16:"); + for (i = 0; i < 8; i++) + seq_printf(m, " %04X", priv->last_debug_word16[i]); + seq_putc(m, '\n'); + seq_puts(m, " "); + for (; i < 16; i++) + seq_printf(m, " %04X", priv->last_debug_word16[i]); + seq_putc(m, '\n'); + return 0; +} #endif diff --git a/drivers/staging/cxt1e1/Makefile b/drivers/staging/cxt1e1/Makefile index e99b8231182..b9ccb765025 100644 --- a/drivers/staging/cxt1e1/Makefile +++ b/drivers/staging/cxt1e1/Makefile @@ -12,8 +12,9 @@ cxt1e1-y := \ linux.o \ functions.o \ hwprobe.o \ - sbeproc.o \ pmc93x6_eeprom.o \ sbecrc.o \ comet_tables.o \ sbeid.o + +cxt1e1-$(CONFIG_PROC_FS) += sbeproc.o diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c index f42531c3d8d..49f10f0b7d2 100644 --- a/drivers/staging/cxt1e1/sbeproc.c +++ b/drivers/staging/cxt1e1/sbeproc.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/sched.h> #include <asm/uaccess.h> #include "pmcc4_sysdep.h" @@ -26,332 +27,193 @@ #include "pmcc4_private.h" #include "sbeproc.h" -/* forwards */ -void sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *); +extern void sbecom_get_brdinfo(ci_t *, struct sbe_brd_info *, u_int8_t *); extern struct s_hdw_info hdw_info[MAX_BOARDS]; -#ifdef CONFIG_PROC_FS - -/********************************************************************/ -/* procfs stuff */ -/********************************************************************/ - - -void -sbecom_proc_brd_cleanup (ci_t * ci) +void sbecom_proc_brd_cleanup(ci_t *ci) { - if (ci->dir_dev) - { - char dir[7 + SBE_IFACETMPL_SIZE + 1]; - snprintf(dir, sizeof(dir), "driver/%s", ci->devname); - remove_proc_entry("info", ci->dir_dev); - remove_proc_entry(dir, NULL); - ci->dir_dev = NULL; - } + if (ci->dir_dev) { + char dir[7 + SBE_IFACETMPL_SIZE + 1]; + snprintf(dir, sizeof(dir), "driver/%s", ci->devname); + remove_proc_entry("info", ci->dir_dev); + remove_proc_entry(dir, NULL); + ci->dir_dev = NULL; + } } - -static int -sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, - int length, int *eof, void *priv) +static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip) { - ci_t *ci = (ci_t *) priv; - int len = 0; - char *spd; - struct sbe_brd_info *bip; - - if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info)))) - { - return -ENOMEM; - } -#if 0 - /** RLD DEBUG **/ - pr_info(">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n", - (int) offset, (int) length); -#endif - - { - hdw_info_t *hi = &hdw_info[ci->brdno]; - - u_int8_t *bsn = 0; - - switch (hi->promfmt) - { - case PROM_FORMAT_TYPE1: - bsn = (u_int8_t *) hi->mfg_info.pft1.Serial; - break; - case PROM_FORMAT_TYPE2: - bsn = (u_int8_t *) hi->mfg_info.pft2.Serial; - break; - } - - sbecom_get_brdinfo (ci, bip, bsn); - } - -#if 0 - /** RLD DEBUG **/ - pr_info(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n", - (char *) &bip->first_iname, (char *) &bip->first_iname, - (char *) &bip->last_iname, (char *) &bip->last_iname); -#endif - len += sprintf (buffer + len, "Board Type: "); - switch (bip->brd_id) - { - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3): - len += sprintf (buffer + len, "wanPMC-C1T3"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): - len += sprintf (buffer + len, "wanPTMC-256T3 <E1>"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): - len += sprintf (buffer + len, "wanPTMC-256T3 <T1>"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1): - len += sprintf (buffer + len, "wanPTMC-C24TE1"); - break; - - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): - len += sprintf (buffer + len, "wanPMC-C4T1E1"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): - len += sprintf (buffer + len, "wanPMC-C2T1E1"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): - len += sprintf (buffer + len, "wanPMC-C1T1E1"); - break; - - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): - len += sprintf (buffer + len, "wanPCI-C4T1E1"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): - len += sprintf (buffer + len, "wanPCI-C2T1E1"); - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): - len += sprintf (buffer + len, "wanPCI-C1T1E1"); - break; - - default: - len += sprintf (buffer + len, "unknown"); - break; - } - len += sprintf (buffer + len, " [%08X]\n", bip->brd_id); + hdw_info_t *hi = &hdw_info[ci->brdno]; + u_int8_t *bsn = 0; + + switch (hi->promfmt) + { + case PROM_FORMAT_TYPE1: + bsn = (u_int8_t *) hi->mfg_info.pft1.Serial; + break; + case PROM_FORMAT_TYPE2: + bsn = (u_int8_t *) hi->mfg_info.pft2.Serial; + break; + } + + sbecom_get_brdinfo (ci, bip, bsn); + + pr_devel(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n", + bip->first_iname, bip->first_iname, + bip->last_iname, bip->last_iname); +} - len += sprintf (buffer + len, "Board Number: %d\n", bip->brdno); - len += sprintf (buffer + len, "Hardware ID: 0x%02X\n", ci->hdw_bid); - len += sprintf (buffer + len, "Board SN: %06X\n", bip->brd_sn); - len += sprintf(buffer + len, "Board MAC: %pMF\n", - bip->brd_mac_addr); - len += sprintf (buffer + len, "Ports: %d\n", ci->max_port); - len += sprintf (buffer + len, "Channels: %d\n", bip->brd_chan_cnt); +/* + * Describe the driver state through /proc + */ +static int sbecom_proc_get_sbe_info(struct seq_file *m, void *v) +{ + ci_t *ci = m->private; + char *spd; + struct sbe_brd_info *bip; + + if (!(bip = OS_kmalloc(sizeof(struct sbe_brd_info)))) + return -ENOMEM; + + pr_devel(">> sbecom_proc_get_sbe_info: entered\n"); + + sbecom_proc_get_brdinfo(ci, bip); + + seq_puts(m, "Board Type: "); + switch (bip->brd_id) { + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3): + seq_puts(m, "wanPMC-C1T3"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + seq_puts(m, "wanPTMC-256T3 <E1>"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + seq_puts(m, "wanPTMC-256T3 <T1>"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1): + seq_puts(m, "wanPTMC-C24TE1"); + break; + + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + seq_puts(m, "wanPMC-C4T1E1"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + seq_puts(m, "wanPMC-C2T1E1"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + seq_puts(m, "wanPMC-C1T1E1"); + break; + + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + seq_puts(m, "wanPCI-C4T1E1"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + seq_puts(m, "wanPCI-C2T1E1"); + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + seq_puts(m, "wanPCI-C1T1E1"); + break; + + default: + seq_puts(m, "unknown"); + break; + } + + seq_printf(m, " [%08X]\n", bip->brd_id); + + seq_printf(m, "Board Number: %d\n", bip->brdno); + seq_printf(m, "Hardware ID: 0x%02X\n", ci->hdw_bid); + seq_printf(m, "Board SN: %06X\n", bip->brd_sn); + seq_printf(m, "Board MAC: %pMF\n", bip->brd_mac_addr); + seq_printf(m, "Ports: %d\n", ci->max_port); + seq_printf(m, "Channels: %d\n", bip->brd_chan_cnt); #if 1 - len += sprintf (buffer + len, "Interface: %s -> %s\n", - (char *) &bip->first_iname, (char *) &bip->last_iname); + seq_printf(m, "Interface: %s -> %s\n", + bip->first_iname, bip->last_iname); #else - len += sprintf (buffer + len, "Interface: <not available> 1st %p lst %p\n", - (char *) &bip->first_iname, (char *) &bip->last_iname); + seq_printf(m, "Interface: <not available> 1st %p lst %p\n", + bip->first_iname, bip->last_iname); #endif - switch (bip->brd_pci_speed) - { - case BINFO_PCI_SPEED_33: - spd = "33Mhz"; - break; - case BINFO_PCI_SPEED_66: - spd = "66Mhz"; - break; - default: - spd = "<not available>"; - break; - } - len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd); - len += sprintf (buffer + len, "Release: %s\n", ci->release); + switch (bip->brd_pci_speed) { + case BINFO_PCI_SPEED_33: + spd = "33Mhz"; + break; + case BINFO_PCI_SPEED_66: + spd = "66Mhz"; + break; + default: + spd = "<not available>"; + break; + } + seq_printf(m, "PCI Bus Speed: %s\n", spd); + seq_printf(m, "Release: %s\n", ci->release); #ifdef SBE_PMCC4_ENABLE - { - extern int cxt1e1_max_mru; -#if 0 - extern int max_chans_used; - extern int cxt1e1_max_mtu; -#endif - extern int max_rxdesc_used, max_txdesc_used; - - len += sprintf (buffer + len, "\ncxt1e1_max_mru: %d\n", cxt1e1_max_mru); + { + extern int cxt1e1_max_mru; #if 0 - len += sprintf (buffer + len, "\nmax_chans_used: %d\n", max_chans_used); - len += sprintf (buffer + len, "cxt1e1_max_mtu: %d\n", cxt1e1_max_mtu); -#endif - len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used); - len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used); - } -#endif - - OS_kfree (bip); /* cleanup */ - - /*** - * How to be a proc read function - * ------------------------------ - * Prototype: - * int f(char *buffer, char **start, off_t offset, - * int count, int *peof, void *dat) - * - * Assume that the buffer is "count" bytes in size. - * - * If you know you have supplied all the data you - * have, set *peof. - * - * You have three ways to return data: - * 0) Leave *start = NULL. (This is the default.) - * Put the data of the requested offset at that - * offset within the buffer. Return the number (n) - * of bytes there are from the beginning of the - * buffer up to the last byte of data. If the - * number of supplied bytes (= n - offset) is - * greater than zero and you didn't signal eof - * and the reader is prepared to take more data - * you will be called again with the requested - * offset advanced by the number of bytes - * absorbed. This interface is useful for files - * no larger than the buffer. - * 1) Set *start = an unsigned long value less than - * the buffer address but greater than zero. - * Put the data of the requested offset at the - * beginning of the buffer. Return the number of - * bytes of data placed there. If this number is - * greater than zero and you didn't signal eof - * and the reader is prepared to take more data - * you will be called again with the requested - * offset advanced by *start. This interface is - * useful when you have a large file consisting - * of a series of blocks which you want to count - * and return as wholes. - * (Hack by Paul.Russell@rustcorp.com.au) - * 2) Set *start = an address within the buffer. - * Put the data of the requested offset at *start. - * Return the number of bytes of data placed there. - * If this number is greater than zero and you - * didn't signal eof and the reader is prepared to - * take more data you will be called again with the - * requested offset advanced by the number of bytes - * absorbed. - */ - -#if 1 - /* #4 - interpretation of above = set EOF, return len */ - *eof = 1; + extern int max_chans_used; + extern int cxt1e1_max_mtu; #endif + extern int max_rxdesc_used, max_txdesc_used; + seq_printf(m, "\ncxt1e1_max_mru: %d\n", cxt1e1_max_mru); #if 0 - /* - * #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with - * this plagarized code which results in this routine being called TWICE. - * The second call returns ZERO, resulting in hidden failure, but at - * least only a single message set is being displayed. - */ - if (len <= offset + length) - *eof = 1; - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; - if (len < 0) - len = 0; -#endif - -#if 0 /* #2 from net/tokenring/olympic.c + - * lanstreamer.c */ - { - off_t begin = 0; - int size = 0; - off_t pos = 0; - - size = len; - pos = begin + size; - if (pos < offset) - { - len = 0; - begin = pos; - } - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len > length) - len = length; /* Ending slop */ - } + seq_printf(m, "\nmax_chans_used: %d\n", max_chans_used); + seq_printf(m, "cxt1e1_max_mtu: %d\n", cxt1e1_max_mtu); #endif - -#if 0 /* #3 from - * char/ftape/lowlevel/ftape-proc.c */ - len = strlen (buffer); - *start = NULL; - if (offset + length >= len) - *eof = 1; - else - *eof = 0; -#endif - -#if 0 - pr_info(">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */ + seq_printf(m, "max_rxdesc_used: %d\n", max_rxdesc_used); + seq_printf(m, "max_txdesc_used: %d\n", max_txdesc_used); + } #endif -/*** - using NONE: returns = 314.314.314. - using #1 : returns = 314, 0. - using #2 : returns = 314, 0, 0. - using #3 : returns = 314, 314. - using #4 : returns = 314, 314. -***/ + kfree(bip); - return len; + pr_devel(">> proc_fs: finished\n"); + return 0; } -/* initialize the /proc subsystem for the specific SBE driver */ - -int __init -sbecom_proc_brd_init (ci_t * ci) +/* + * seq_file wrappers for procfile show routines. + */ +static int sbecom_proc_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *e; - char dir[7 + SBE_IFACETMPL_SIZE + 1]; - - /* create a directory in the root procfs */ - snprintf(dir, sizeof(dir), "driver/%s", ci->devname); - ci->dir_dev = proc_mkdir(dir, NULL); - if (!ci->dir_dev) - { - pr_err("Unable to create directory /proc/driver/%s\n", ci->devname); - goto fail; - } - e = create_proc_read_entry ("info", S_IFREG | S_IRUGO, - ci->dir_dev, sbecom_proc_get_sbe_info, ci); - if (!e) - { - pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname); - goto fail; - } - return 0; - -fail: - sbecom_proc_brd_cleanup (ci); - return 1; + return single_open(file, sbecom_proc_get_sbe_info, PDE_DATA(inode)); } -#else /*** ! CONFIG_PROC_FS ***/ +static const struct file_operations sbecom_proc_fops = { + .open = sbecom_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -/* stubbed off dummy routines */ - -void -sbecom_proc_brd_cleanup (ci_t * ci) -{ -} - -int __init -sbecom_proc_brd_init (ci_t * ci) +/* + * Initialize the /proc subsystem for the specific SBE driver + */ +int __init sbecom_proc_brd_init(ci_t *ci) { - return 0; -} - -#endif /*** CONFIG_PROC_FS ***/ + char dir[7 + SBE_IFACETMPL_SIZE + 1]; + snprintf(dir, sizeof(dir), "driver/%s", ci->devname); + ci->dir_dev = proc_mkdir(dir, NULL); + if (!ci->dir_dev) { + pr_err("Unable to create directory /proc/driver/%s\n", ci->devname); + goto fail; + } + + if (!proc_create_data("info", S_IFREG | S_IRUGO, ci->dir_dev, + &sbecom_proc_fops, ci)) { + pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname); + goto fail; + } + return 0; -/*** End-of-File ***/ +fail: + sbecom_proc_brd_cleanup(ci); + return 1; +} diff --git a/drivers/staging/cxt1e1/sbeproc.h b/drivers/staging/cxt1e1/sbeproc.h index e82be6afd1e..e5c072cf195 100644 --- a/drivers/staging/cxt1e1/sbeproc.h +++ b/drivers/staging/cxt1e1/sbeproc.h @@ -23,10 +23,20 @@ #ifdef CONFIG_PROC_FS -#ifdef __KERNEL__ void sbecom_proc_brd_cleanup (ci_t *); int __init sbecom_proc_brd_init (ci_t *); -#endif /*** __KERNEL__ ***/ +#else + +static inline void sbecom_proc_brd_cleanup(ci_t * ci) +{ +} + +static inline int __init sbecom_proc_brd_init(ci_t * ci) +{ + return 0; +} + #endif /*** CONFIG_PROC_FS ***/ + #endif /*** _INC_SBEPROC_H_ ***/ diff --git a/drivers/staging/dgrp/dgrp_common.c b/drivers/staging/dgrp/dgrp_common.c index 3553998b72b..9a9b45624ba 100644 --- a/drivers/staging/dgrp/dgrp_common.c +++ b/drivers/staging/dgrp/dgrp_common.c @@ -167,34 +167,3 @@ void dgrp_carrier(struct ch_struct *ch) ch->ch_flag &= ~CH_PHYS_CD; } - -/** - * dgrp_chk_perm() -- check permissions for net device - * @inode: pointer to inode structure for the net communication device - * @op: operation to be tested - * - * The file permissions and ownerships are tested to determine whether - * the operation "op" is permitted on the file pointed to by the inode. - * Returns 0 if the operation is permitted, -EACCESS otherwise - */ -int dgrp_chk_perm(int mode, int op) -{ - if (!uid_eq(GLOBAL_ROOT_UID, current_euid())) - mode >>= 6; - else if (in_egroup_p(GLOBAL_ROOT_GID)) - mode >>= 3; - - if ((mode & op & 0007) == op) - return 0; - - if (capable(CAP_SYS_ADMIN)) - return 0; - - return -EACCES; -} - -/* dgrp_chk_perm wrapper for permission call in struct inode_operations */ -int dgrp_inode_permission(struct inode *inode, int op) -{ - return dgrp_chk_perm(inode->i_mode, op); -} diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h index 2832b8e26c4..23aba6c4d22 100644 --- a/drivers/staging/dgrp/dgrp_common.h +++ b/drivers/staging/dgrp/dgrp_common.h @@ -49,20 +49,20 @@ extern struct dgrp_poll_data dgrp_poll_data; extern void dgrp_poll_handler(unsigned long arg); /* from dgrp_mon_ops.c */ -extern void dgrp_register_mon_hook(struct proc_dir_entry *de); +extern const struct file_operations dgrp_mon_ops; /* from dgrp_tty.c */ extern int dgrp_tty_init(struct nd_struct *nd); extern void dgrp_tty_uninit(struct nd_struct *nd); /* from dgrp_ports_ops.c */ -extern void dgrp_register_ports_hook(struct proc_dir_entry *de); +extern const struct file_operations dgrp_ports_ops; /* from dgrp_net_ops.c */ -extern void dgrp_register_net_hook(struct proc_dir_entry *de); +extern const struct file_operations dgrp_net_ops; /* from dgrp_dpa_ops.c */ -extern void dgrp_register_dpa_hook(struct proc_dir_entry *de); +extern const struct file_operations dgrp_dpa_ops; extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int); /* from dgrp_sysfs.c */ @@ -76,61 +76,6 @@ extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c); extern void dgrp_remove_tty_sysfs(struct device *c); /* from dgrp_specproc.c */ -/* - * The list of DGRP entries with r/w capabilities. These - * magic numbers are used for identification purposes. - */ -enum { - DGRP_CONFIG = 1, /* Configure portservers */ - DGRP_NETDIR = 2, /* Directory for "net" devices */ - DGRP_MONDIR = 3, /* Directory for "mon" devices */ - DGRP_PORTSDIR = 4, /* Directory for "ports" devices */ - DGRP_INFO = 5, /* Get info. about the running module */ - DGRP_NODEINFO = 6, /* Get info. about the configured nodes */ - DGRP_DPADIR = 7, /* Directory for the "dpa" devices */ -}; - -/* - * Directions for proc handlers - */ -enum { - INBOUND = 1, /* Data being written to kernel */ - OUTBOUND = 2, /* Data being read from the kernel */ -}; - -/** - * dgrp_proc_entry: structure for dgrp proc dirs - * @id: ID number associated with this particular entry. Should be - * unique across all of DGRP. - * @name: text name associated with the /proc entry - * @mode: file access permisssions for the /proc entry - * @child: pointer to table describing a subdirectory for this entry - * @de: pointer to directory entry for this object once registered. Used - * to grab the handle of the object for unregistration - * @excl_sem: semaphore to provide exclusive to struct - * @excl_cnt: counter of current accesses - * - * Each entry in a DGRP proc directory is described with a - * dgrp_proc_entry structure. A collection of these - * entries (in an array) represents the members associated - * with a particular /proc directory, and is referred to - * as a table. All tables are terminated by an entry with - * zeros for every member. - */ -struct dgrp_proc_entry { - int id; /* Integer identifier */ - const char *name; /* ASCII identifier */ - mode_t mode; /* File access permissions */ - struct dgrp_proc_entry *child; /* Child pointer */ - - /* file ops to use, pass NULL to use default */ - struct file_operations *proc_file_ops; - - struct proc_dir_entry *de; /* proc entry pointer */ - struct semaphore excl_sem; /* Protects exclusive access var */ - int excl_cnt; /* Counts number of curr accesses */ -}; - extern void dgrp_unregister_proc(void); extern void dgrp_register_proc(void); @@ -144,8 +89,6 @@ extern void dgrp_register_proc(void); *-----------------------------------------------------------------------*/ void dgrp_carrier(struct ch_struct *ch); -extern int dgrp_inode_permission(struct inode *inode, int op); -extern int dgrp_chk_perm(int mode, int op); /* diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c index ca10a3362e2..114799cddd8 100644 --- a/drivers/staging/dgrp/dgrp_dpa_ops.c +++ b/drivers/staging/dgrp/dgrp_dpa_ops.c @@ -40,6 +40,7 @@ #include <linux/cred.h> #include <linux/sched.h> #include <linux/ratelimit.h> +#include <linux/slab.h> #include <asm/unaligned.h> #include "dgrp_common.h" @@ -52,7 +53,7 @@ static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *); -static const struct file_operations dpa_ops = { +const struct file_operations dgrp_dpa_ops = { .owner = THIS_MODULE, .read = dgrp_dpa_read, .poll = dgrp_dpa_select, @@ -61,12 +62,6 @@ static const struct file_operations dpa_ops = { .release = dgrp_dpa_release, }; -static struct inode_operations dpa_inode_ops = { - .permission = dgrp_inode_permission -}; - - - struct digi_node { uint nd_state; /* Node state: 1 = up, 0 = down. */ uint nd_chan_count; /* Number of channels found */ @@ -111,17 +106,6 @@ struct digi_debug { #define DIGI_SETDEBUG (('d'<<8) | 247) /* set debug info */ -void dgrp_register_dpa_hook(struct proc_dir_entry *de) -{ - struct nd_struct *node = de->data; - - de->proc_iops = &dpa_inode_ops; - rcu_assign_pointer(de->proc_fops, &dpa_ops); - - node->nd_dpa_de = de; - spin_lock_init(&node->nd_dpa_lock); -} - /* * dgrp_dpa_open -- open the DPA device for a particular PortServer */ @@ -130,8 +114,6 @@ static int dgrp_dpa_open(struct inode *inode, struct file *file) struct nd_struct *nd; int rtn = 0; - struct proc_dir_entry *de; - rtn = try_module_get(THIS_MODULE); if (!rtn) return -ENXIO; @@ -154,12 +136,7 @@ static int dgrp_dpa_open(struct inode *inode, struct file *file) /* * Get the node pointer, and fail if it doesn't exist. */ - de = PDE(inode); - if (!de) { - rtn = -ENXIO; - goto done; - } - nd = (struct nd_struct *)de->data; + nd = PDE_DATA(inode); if (!nd) { rtn = -ENXIO; goto done; diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c index b484fccb494..d18be4180e3 100644 --- a/drivers/staging/dgrp/dgrp_mon_ops.c +++ b/drivers/staging/dgrp/dgrp_mon_ops.c @@ -37,6 +37,7 @@ #include <linux/tty.h> #include <linux/sched.h> #include <asm/unaligned.h> +#include <linux/slab.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> @@ -49,7 +50,7 @@ static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *); static long dgrp_mon_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static const struct file_operations mon_ops = { +const struct file_operations dgrp_mon_ops = { .owner = THIS_MODULE, .read = dgrp_mon_read, .unlocked_ioctl = dgrp_mon_ioctl, @@ -57,20 +58,6 @@ static const struct file_operations mon_ops = { .release = dgrp_mon_release, }; -static struct inode_operations mon_inode_ops = { - .permission = dgrp_inode_permission -}; - -void dgrp_register_mon_hook(struct proc_dir_entry *de) -{ - struct nd_struct *node = de->data; - - de->proc_iops = &mon_inode_ops; - rcu_assign_pointer(de->proc_fops, &mon_ops); - node->nd_mon_de = de; - sema_init(&node->nd_mon_semaphore, 1); -} - /** * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer * @inode: struct inode * @@ -81,7 +68,6 @@ void dgrp_register_mon_hook(struct proc_dir_entry *de) static int dgrp_mon_open(struct inode *inode, struct file *file) { struct nd_struct *nd; - struct proc_dir_entry *de; struct timeval tv; uint32_t time; u8 *buf; @@ -109,13 +95,7 @@ static int dgrp_mon_open(struct inode *inode, struct file *file) /* * Get the node pointer, and fail if it doesn't exist. */ - de = PDE(inode); - if (!de) { - rtn = -ENXIO; - goto done; - } - - nd = (struct nd_struct *)de->data; + nd = PDE_DATA(inode); if (!nd) { rtn = -ENXIO; goto done; diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 64f48ffb9d4..5b7833f593f 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -35,7 +35,7 @@ #include <linux/module.h> #include <linux/proc_fs.h> -#include <linux/types.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/device.h> #include <linux/tty.h> @@ -72,7 +72,7 @@ static long dgrp_net_ioctl(struct file *file, unsigned int cmd, static unsigned int dgrp_net_select(struct file *file, struct poll_table_struct *table); -static const struct file_operations net_ops = { +const struct file_operations dgrp_net_ops = { .owner = THIS_MODULE, .read = dgrp_net_read, .write = dgrp_net_write, @@ -82,23 +82,6 @@ static const struct file_operations net_ops = { .release = dgrp_net_release, }; -static struct inode_operations net_inode_ops = { - .permission = dgrp_inode_permission -}; - -void dgrp_register_net_hook(struct proc_dir_entry *de) -{ - struct nd_struct *node = de->data; - - de->proc_iops = &net_inode_ops; - rcu_assign_pointer(de->proc_fops, &net_ops); - node->nd_net_de = de; - sema_init(&node->nd_net_semaphore, 1); - node->nd_state = NS_CLOSED; - dgrp_create_node_class_sysfs_files(node); -} - - /** * dgrp_dump() -- prints memory for debugging purposes. * @mem: Memory location which should be printed to the console @@ -801,7 +784,6 @@ out_err: static int dgrp_net_open(struct inode *inode, struct file *file) { struct nd_struct *nd; - struct proc_dir_entry *de; ulong lock_flags; int rtn; @@ -825,13 +807,7 @@ static int dgrp_net_open(struct inode *inode, struct file *file) /* * Get the node pointer, and fail if it doesn't exist. */ - de = PDE(inode); - if (!de) { - rtn = -ENXIO; - goto done; - } - - nd = (struct nd_struct *) de->data; + nd = PDE_DATA(inode); if (!nd) { rtn = -ENXIO; goto done; diff --git a/drivers/staging/dgrp/dgrp_ports_ops.c b/drivers/staging/dgrp/dgrp_ports_ops.c index f93dc1f262f..4ce030815f2 100644 --- a/drivers/staging/dgrp/dgrp_ports_ops.c +++ b/drivers/staging/dgrp/dgrp_ports_ops.c @@ -47,7 +47,7 @@ /* File operation declarations */ static int dgrp_ports_open(struct inode *, struct file *); -static const struct file_operations ports_ops = { +const struct file_operations dgrp_ports_ops = { .owner = THIS_MODULE, .open = dgrp_ports_open, .read = seq_read, @@ -55,20 +55,6 @@ static const struct file_operations ports_ops = { .release = seq_release }; -static struct inode_operations ports_inode_ops = { - .permission = dgrp_inode_permission -}; - - -void dgrp_register_ports_hook(struct proc_dir_entry *de) -{ - struct nd_struct *node = de->data; - - de->proc_iops = &ports_inode_ops; - rcu_assign_pointer(de->proc_fops, &ports_ops); - node->nd_ports_de = de; -} - static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos) { if (*pos == 0) @@ -163,7 +149,7 @@ static int dgrp_ports_open(struct inode *inode, struct file *file) rtn = seq_open(file, &ports_seq_ops); if (!rtn) { seq = file->private_data; - seq->private = PDE(inode)->data; + seq->private = PDE_DATA(inode); } return rtn; diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index d66712c8aa9..205d80ef445 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -37,6 +37,7 @@ #include <linux/sched.h> #include <linux/cred.h> #include <linux/proc_fs.h> +#include <linux/slab.h> #include <linux/ctype.h> #include <linux/seq_file.h> #include <linux/uaccess.h> @@ -44,43 +45,17 @@ #include "dgrp_common.h" -static struct dgrp_proc_entry dgrp_table[]; static struct proc_dir_entry *dgrp_proc_dir_entry; static int dgrp_add_id(long id); static int dgrp_remove_nd(struct nd_struct *nd); -static void unregister_dgrp_device(struct proc_dir_entry *de); -static void register_dgrp_device(struct nd_struct *node, +static struct proc_dir_entry *add_proc_file(struct nd_struct *node, struct proc_dir_entry *root, - void (*register_hook)(struct proc_dir_entry *de)); + const struct file_operations *fops); /* File operation declarations */ -static int dgrp_gen_proc_open(struct inode *, struct file *); -static int dgrp_gen_proc_close(struct inode *, struct file *); static int parse_write_config(char *); - -static const struct file_operations dgrp_proc_file_ops = { - .owner = THIS_MODULE, - .open = dgrp_gen_proc_open, - .release = dgrp_gen_proc_close, -}; - -static struct inode_operations proc_inode_ops = { - .permission = dgrp_inode_permission -}; - - -static void register_proc_table(struct dgrp_proc_entry *, - struct proc_dir_entry *); -static void unregister_proc_table(struct dgrp_proc_entry *, - struct proc_dir_entry *); - -static struct dgrp_proc_entry dgrp_net_table[]; -static struct dgrp_proc_entry dgrp_mon_table[]; -static struct dgrp_proc_entry dgrp_ports_table[]; -static struct dgrp_proc_entry dgrp_dpa_table[]; - static ssize_t dgrp_config_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos); @@ -89,7 +64,7 @@ static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file); static int dgrp_info_proc_open(struct inode *inode, struct file *file); static int dgrp_config_proc_open(struct inode *inode, struct file *file); -static struct file_operations config_proc_file_ops = { +static const struct file_operations config_proc_file_ops = { .owner = THIS_MODULE, .open = dgrp_config_proc_open, .read = seq_read, @@ -98,7 +73,7 @@ static struct file_operations config_proc_file_ops = { .write = dgrp_config_proc_write, }; -static struct file_operations info_proc_file_ops = { +static const struct file_operations info_proc_file_ops = { .owner = THIS_MODULE, .open = dgrp_info_proc_open, .read = seq_read, @@ -106,7 +81,7 @@ static struct file_operations info_proc_file_ops = { .release = single_release, }; -static struct file_operations nodeinfo_proc_file_ops = { +static const struct file_operations nodeinfo_proc_file_ops = { .owner = THIS_MODULE, .open = dgrp_nodeinfo_proc_open, .read = seq_read, @@ -114,71 +89,25 @@ static struct file_operations nodeinfo_proc_file_ops = { .release = seq_release, }; -static struct dgrp_proc_entry dgrp_table[] = { - { - .id = DGRP_CONFIG, - .name = "config", - .mode = 0644, - .proc_file_ops = &config_proc_file_ops, - }, - { - .id = DGRP_INFO, - .name = "info", - .mode = 0644, - .proc_file_ops = &info_proc_file_ops, - }, - { - .id = DGRP_NODEINFO, - .name = "nodeinfo", - .mode = 0644, - .proc_file_ops = &nodeinfo_proc_file_ops, - }, - { - .id = DGRP_NETDIR, - .name = "net", - .mode = 0500, - .child = dgrp_net_table - }, - { - .id = DGRP_MONDIR, - .name = "mon", - .mode = 0500, - .child = dgrp_mon_table - }, - { - .id = DGRP_PORTSDIR, - .name = "ports", - .mode = 0500, - .child = dgrp_ports_table - }, - { - .id = DGRP_DPADIR, - .name = "dpa", - .mode = 0500, - .child = dgrp_dpa_table - } -}; - static struct proc_dir_entry *net_entry_pointer; static struct proc_dir_entry *mon_entry_pointer; static struct proc_dir_entry *dpa_entry_pointer; static struct proc_dir_entry *ports_entry_pointer; -static struct dgrp_proc_entry dgrp_net_table[] = { - {0} -}; - -static struct dgrp_proc_entry dgrp_mon_table[] = { - {0} -}; - -static struct dgrp_proc_entry dgrp_ports_table[] = { - {0} -}; - -static struct dgrp_proc_entry dgrp_dpa_table[] = { - {0} -}; +static void remove_files(struct nd_struct *nd) +{ + char buf[3]; + ID_TO_CHAR(nd->nd_ID, buf); + dgrp_remove_node_class_sysfs_files(nd); + if (nd->nd_net_de) + remove_proc_entry(buf, net_entry_pointer); + if (nd->nd_mon_de) + remove_proc_entry(buf, mon_entry_pointer); + if (nd->nd_dpa_de) + remove_proc_entry(buf, dpa_entry_pointer); + if (nd->nd_ports_de) + remove_proc_entry(buf, ports_entry_pointer); +} void dgrp_unregister_proc(void) { @@ -188,12 +117,19 @@ void dgrp_unregister_proc(void) ports_entry_pointer = NULL; if (dgrp_proc_dir_entry) { - unregister_proc_table(dgrp_table, dgrp_proc_dir_entry); - remove_proc_entry(dgrp_proc_dir_entry->name, - dgrp_proc_dir_entry->parent); + struct nd_struct *nd; + list_for_each_entry(nd, &nd_struct_list, list) + remove_files(nd); + remove_proc_entry("dgrp/config", NULL); + remove_proc_entry("dgrp/info", NULL); + remove_proc_entry("dgrp/nodeinfo", NULL); + remove_proc_entry("dgrp/net", NULL); + remove_proc_entry("dgrp/mon", NULL); + remove_proc_entry("dgrp/dpa", NULL); + remove_proc_entry("dgrp/ports", NULL); + remove_proc_entry("dgrp", NULL); dgrp_proc_dir_entry = NULL; } - } void dgrp_register_proc(void) @@ -201,211 +137,16 @@ void dgrp_register_proc(void) /* * Register /proc/dgrp */ - dgrp_proc_dir_entry = proc_create("dgrp", S_IFDIR, NULL, - &dgrp_proc_file_ops); - register_proc_table(dgrp_table, dgrp_proc_dir_entry); -} - -/* - * /proc/sys support - */ -static int dgrp_proc_match(int len, const char *name, struct proc_dir_entry *de) -{ - if (!de || !de->low_ino) - return 0; - if (de->namelen != len) - return 0; - return !memcmp(name, de->name, len); -} - - -/* - * Scan the entries in table and add them all to /proc at the position - * referred to by "root" - */ -static void register_proc_table(struct dgrp_proc_entry *table, - struct proc_dir_entry *root) -{ - struct proc_dir_entry *de; - int len; - mode_t mode; - - if (table == NULL) + dgrp_proc_dir_entry = proc_mkdir("dgrp", NULL); + if (!dgrp_proc_dir_entry) return; - if (root == NULL) - return; - - for (; table->id; table++) { - /* Can't do anything without a proc name. */ - if (!table->name) - continue; - - /* Maybe we can't do anything with it... */ - if (!table->proc_file_ops && - !table->child) { - pr_warn("dgrp: Can't register %s\n", - table->name); - continue; - } - - len = strlen(table->name); - mode = table->mode; - - de = NULL; - if (!table->child) - mode |= S_IFREG; - else { - mode |= S_IFDIR; - for (de = root->subdir; de; de = de->next) { - if (dgrp_proc_match(len, table->name, de)) - break; - } - /* If the subdir exists already, de is non-NULL */ - } - - if (!de) { - de = create_proc_entry(table->name, mode, root); - if (!de) - continue; - de->data = (void *) table; - if (!table->child) { - de->proc_iops = &proc_inode_ops; - if (table->proc_file_ops) - rcu_assign_pointer(de->proc_fops, - table->proc_file_ops); - else - rcu_assign_pointer(de->proc_fops, - &dgrp_proc_file_ops); - } - } - table->de = de; - if (de->mode & S_IFDIR) - register_proc_table(table->child, de); - - if (table->id == DGRP_NETDIR) - net_entry_pointer = de; - - if (table->id == DGRP_MONDIR) - mon_entry_pointer = de; - - if (table->id == DGRP_DPADIR) - dpa_entry_pointer = de; - - if (table->id == DGRP_PORTSDIR) - ports_entry_pointer = de; - } -} - -/* - * Unregister a /proc sysctl table and any subdirectories. - */ -static void unregister_proc_table(struct dgrp_proc_entry *table, - struct proc_dir_entry *root) -{ - struct proc_dir_entry *de; - struct nd_struct *tmp; - - if (table == NULL) - return; - - list_for_each_entry(tmp, &nd_struct_list, list) { - if ((table == dgrp_net_table) && (tmp->nd_net_de)) { - unregister_dgrp_device(tmp->nd_net_de); - dgrp_remove_node_class_sysfs_files(tmp); - } - - if ((table == dgrp_mon_table) && (tmp->nd_mon_de)) - unregister_dgrp_device(tmp->nd_mon_de); - - if ((table == dgrp_dpa_table) && (tmp->nd_dpa_de)) - unregister_dgrp_device(tmp->nd_dpa_de); - - if ((table == dgrp_ports_table) && (tmp->nd_ports_de)) - unregister_dgrp_device(tmp->nd_ports_de); - } - - for (; table->id; table++) { - de = table->de; - - if (!de) - continue; - if (de->mode & S_IFDIR) { - if (!table->child) { - pr_alert("dgrp: malformed sysctl tree on free\n"); - continue; - } - unregister_proc_table(table->child, de); - - /* Don't unregister directories which still have entries */ - if (de->subdir) - continue; - } - - /* Don't unregister proc entries that are still being used.. */ - if ((atomic_read(&de->count)) != 1) { - pr_alert("proc entry %s in use, not removing\n", - de->name); - continue; - } - - remove_proc_entry(de->name, de->parent); - table->de = NULL; - } -} - -static int dgrp_gen_proc_open(struct inode *inode, struct file *file) -{ - struct proc_dir_entry *de; - struct dgrp_proc_entry *entry; - int ret = 0; - - de = (struct proc_dir_entry *) PDE(file_inode(file)); - if (!de || !de->data) { - ret = -ENXIO; - goto done; - } - - entry = (struct dgrp_proc_entry *) de->data; - if (!entry) { - ret = -ENXIO; - goto done; - } - - down(&entry->excl_sem); - - if (entry->excl_cnt) - ret = -EBUSY; - else - entry->excl_cnt++; - - up(&entry->excl_sem); - -done: - return ret; -} - -static int dgrp_gen_proc_close(struct inode *inode, struct file *file) -{ - struct proc_dir_entry *de; - struct dgrp_proc_entry *entry; - - de = (struct proc_dir_entry *) PDE(file_inode(file)); - if (!de || !de->data) - goto done; - - entry = (struct dgrp_proc_entry *) de->data; - if (!entry) - goto done; - - down(&entry->excl_sem); - - if (entry->excl_cnt) - entry->excl_cnt = 0; - - up(&entry->excl_sem); - -done: - return 0; + proc_create("dgrp/config", 0644, NULL, &config_proc_file_ops); + proc_create("dgrp/info", 0644, NULL, &info_proc_file_ops); + proc_create("dgrp/nodeinfo", 0644, NULL, &nodeinfo_proc_file_ops); + net_entry_pointer = proc_mkdir_mode("dgrp/net", 0500, NULL); + mon_entry_pointer = proc_mkdir_mode("dgrp/mon", 0500, NULL); + dpa_entry_pointer = proc_mkdir_mode("dgrp/dpa", 0500, NULL); + ports_entry_pointer = proc_mkdir_mode("dgrp/ports", 0500, NULL); } static void *dgrp_config_proc_start(struct seq_file *m, loff_t *pos) @@ -736,6 +477,10 @@ static int dgrp_add_id(long id) init_waitqueue_head(&nd->nd_tx_waitq); init_waitqueue_head(&nd->nd_mon_wqueue); init_waitqueue_head(&nd->nd_dpa_wqueue); + sema_init(&nd->nd_mon_semaphore, 1); + sema_init(&nd->nd_net_semaphore, 1); + spin_lock_init(&nd->nd_dpa_lock); + nd->nd_state = NS_CLOSED; for (i = 0; i < SEQ_MAX; i++) init_waitqueue_head(&nd->nd_seq_wque[i]); @@ -750,12 +495,12 @@ static int dgrp_add_id(long id) if (ret) goto error_out; - register_dgrp_device(nd, net_entry_pointer, dgrp_register_net_hook); - register_dgrp_device(nd, mon_entry_pointer, dgrp_register_mon_hook); - register_dgrp_device(nd, dpa_entry_pointer, dgrp_register_dpa_hook); - register_dgrp_device(nd, ports_entry_pointer, - dgrp_register_ports_hook); - + dgrp_create_node_class_sysfs_files(nd); + nd->nd_net_de = add_proc_file(nd, net_entry_pointer, &dgrp_net_ops); + nd->nd_mon_de = add_proc_file(nd, mon_entry_pointer, &dgrp_mon_ops); + nd->nd_dpa_de = add_proc_file(nd, dpa_entry_pointer, &dgrp_dpa_ops); + nd->nd_ports_de = add_proc_file(nd, ports_entry_pointer, + &dgrp_ports_ops); return 0; /* FIXME this guy should free the tty driver stored in nd and destroy @@ -774,16 +519,7 @@ static int dgrp_remove_nd(struct nd_struct *nd) if (nd->nd_tty_ref_cnt) return -EBUSY; - if (nd->nd_net_de) { - unregister_dgrp_device(nd->nd_net_de); - dgrp_remove_node_class_sysfs_files(nd); - } - - unregister_dgrp_device(nd->nd_mon_de); - - unregister_dgrp_device(nd->nd_ports_de); - - unregister_dgrp_device(nd->nd_dpa_de); + remove_files(nd); dgrp_tty_uninit(nd); @@ -795,38 +531,11 @@ static int dgrp_remove_nd(struct nd_struct *nd) return 0; } -static void register_dgrp_device(struct nd_struct *node, +static struct proc_dir_entry *add_proc_file(struct nd_struct *node, struct proc_dir_entry *root, - void (*register_hook)(struct proc_dir_entry *de)) + const struct file_operations *fops) { char buf[3]; - struct proc_dir_entry *de; - ID_TO_CHAR(node->nd_ID, buf); - - de = create_proc_entry(buf, 0600 | S_IFREG, root); - if (!de) - return; - - de->data = (void *) node; - - if (register_hook) - register_hook(de); - -} - -static void unregister_dgrp_device(struct proc_dir_entry *de) -{ - if (!de) - return; - - /* Don't unregister proc entries that are still being used.. */ - if ((atomic_read(&de->count)) != 1) { - pr_alert("%s - proc entry %s in use. Not removing.\n", - __func__, de->name); - return; - } - - remove_proc_entry(de->name, de->parent); - de = NULL; + return proc_create_data(buf, 0600, root, fops, node); } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index 5337b415d45..21b369e0150 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c @@ -19,6 +19,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/string.h> #include <linux/vmalloc.h> #include <linux/netdevice.h> @@ -29,70 +30,55 @@ #define FT1000_PROC "ft1000" #define MAX_FILE_LEN 255 -#define PUTM_TO_PAGE(len, page, args...) \ - len += snprintf(page+len, PAGE_SIZE - len, args) - -#define PUTX_TO_PAGE(len, page, message, size, var) \ - len += snprintf(page+len, PAGE_SIZE - len, message); \ +#define seq_putx(m, message, size, var) \ + seq_printf(m, message); \ for(i = 0; i < (size - 1); i++) { \ - len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \ + seq_printf(m, "%02x:", var[i]); \ } \ - len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i]) + seq_printf(m, "%02x\n", var[i]) -#define PUTD_TO_PAGE(len, page, message, size, var) \ - len += snprintf(page+len, PAGE_SIZE - len, message); \ +#define seq_putd(m, message, size, var) \ + seq_printf(m, message); \ for(i = 0; i < (size - 1); i++) { \ - len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \ + seq_printf(m, "%d.", var[i]); \ } \ - len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i]) + seq_printf(m, "%d\n", var[i]) -static int ft1000ReadProc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int ft1000ReadProc(struct seq_file *m, void *v) { - struct net_device *dev; - int len; - int i; - struct ft1000_info *info; - char *status[] = { + static const char *status[] = { "Idle (Disconnect)", "Searching", "Active (Connected)", "Waiting for L2", "Sleep", "No Coverage", "", "" }; - char *signal[] = { "", "*", "**", "***", "****" }; + static const char *signal[] = { "", "*", "**", "***", "****" }; + + struct net_device *dev = m->private; + struct ft1000_info *info = netdev_priv(dev); + int i; int strength; int quality; struct timeval tv; time_t delta; - dev = (struct net_device *)data; - info = netdev_priv(dev); - - if (off > 0) { - *eof = 1; - return 0; - } - - /* Wrap-around */ - if (info->AsicID == ELECTRABUZZ_ID) { if (info->ProgConStat != 0xFF) { info->LedStat = ft1000_read_dpram(dev, FT1000_DSP_LED); info->ConStat = - ft1000_read_dpram(dev, - FT1000_DSP_CON_STATE); + ft1000_read_dpram(dev, FT1000_DSP_CON_STATE); } else { info->ConStat = 0xf; } } else { if (info->ProgConStat != 0xFF) { info->LedStat = - ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_DSP_LED, - FT1000_MAG_DSP_LED_INDX)); + ntohs(ft1000_read_dpram_mag_16( + dev, FT1000_MAG_DSP_LED, + FT1000_MAG_DSP_LED_INDX)); info->ConStat = - ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_DSP_CON_STATE, - FT1000_MAG_DSP_CON_STATE_INDX)); + ntohs(ft1000_read_dpram_mag_16( + dev, FT1000_MAG_DSP_CON_STATE, + FT1000_MAG_DSP_CON_STATE_INDX)); } else { info->ConStat = 0xf; } @@ -135,36 +121,46 @@ static int ft1000ReadProc(char *page, char **start, off_t off, } do_gettimeofday(&tv); - delta = (tv.tv_sec - info->ConTm); - len = 0; - PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n", + delta = tv.tv_sec - info->ConTm; + seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n", ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); - PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta); - PUTM_TO_PAGE(len, page, "Asic ID: %s\n", - (info->AsicID) == + seq_printf(m, "Connection Time[s]: %ld\n", delta); + seq_printf(m, "Asic ID: %s\n", + info->AsicID == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); - PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku); - PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64); - PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer); - PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ, - info->HwSerNum); - PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ, - info->RfCalVer); - PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ, - info->RfCalDate); - PUTM_TO_PAGE(len, page, "Media State: %s\n", + seq_putx(m, "SKU: ", SKUSZ, info->Sku); + seq_putx(m, "EUI64: ", EUISZ, info->eui64); + seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer); + seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum); + seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer); + seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate); + seq_printf(m, "Media State: %s\n", (info->mediastate) ? "link" : "no link"); - PUTM_TO_PAGE(len, page, "Connection Status: %s\n", - status[((info->ConStat) & 0x7)]); - PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets); - PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets); - PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes); - PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes); - PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]); - PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]); - return len; + seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]); + seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets); + seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets); + seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes); + seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes); + seq_printf(m, "Signal Strength: %s\n", signal[strength]); + seq_printf(m, "Signal Quality: %s\n", signal[quality]); + return 0; +} + +/* + * seq_file wrappers for procfile show routines. + */ +static int ft1000_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ft1000ReadProc, PDE_DATA(inode)); } +static const struct file_operations ft1000_proc_fops = { + .open = ft1000_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr) { @@ -176,8 +172,8 @@ static int ft1000NotifyProc(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_CHANGENAME: remove_proc_entry(info->netdevname, info->ft1000_proc_dir); - create_proc_read_entry(dev->name, 0644, info->ft1000_proc_dir, - ft1000ReadProc, dev); + proc_create_data(dev->name, 0644, info->ft1000_proc_dir, + &ft1000_proc_fops, dev); snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name); break; } @@ -195,8 +191,10 @@ void ft1000InitProc(struct net_device *dev) info = netdev_priv(dev); info->ft1000_proc_dir = proc_mkdir(FT1000_PROC, init_net.proc_net); - create_proc_read_entry(dev->name, 0644, info->ft1000_proc_dir, - ft1000ReadProc, dev); + + proc_create_data(dev->name, 0644, info->ft1000_proc_dir, + &ft1000_proc_fops, dev); + snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name); register_netdevice_notifier(&ft1000_netdev_notifier); } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 297389e8c60..3251d2e073b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -55,7 +55,7 @@ int numofmsgbuf = 0; // // Table of entry-point routines for char device // -static struct file_operations ft1000fops = +static const struct file_operations ft1000fops = { .unlocked_ioctl = ft1000_ioctl, .poll = ft1000_poll_dev, diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index b99640637fe..d8294d6c956 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/netdevice.h> @@ -30,22 +31,17 @@ #define FT1000_PROC_DIR "ft1000" -#define PUTM_TO_PAGE(len,page,args...) \ - len += snprintf(page+len, PAGE_SIZE - len, args) +#define seq_putx(m, message, size, var) \ + seq_printf(m, message); \ + for(i = 0; i < (size - 1); i++) \ + seq_printf(m, "%02x:", var[i]); \ + seq_printf(m, "%02x\n", var[i]) -#define PUTX_TO_PAGE(len,page,message,size,var) \ - len += snprintf(page+len, PAGE_SIZE - len, message); \ - for (i = 0; i < (size - 1); i++) {\ - len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \ - } \ - len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i]) - -#define PUTD_TO_PAGE(len,page,message,size,var) \ - len += snprintf(page+len, PAGE_SIZE - len, message); \ - for (i = 0; i < (size - 1); i++) {\ - len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \ - } \ - len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i]) +#define seq_putd(m, message, size, var) \ + seq_printf(m, message); \ + for(i = 0; i < (size - 1); i++) \ + seq_printf(m, "%d.", var[i]); \ + seq_printf(m, "%d\n", var[i]) #define FTNET_PROC init_net.proc_net @@ -55,19 +51,9 @@ int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u8 highlow); -static int -ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int ft1000ReadProc(struct seq_file *m, void *v) { - struct net_device *dev; - int len; - int i; - unsigned short ledStat; - unsigned short conStat; - - struct ft1000_info *info; - - char *status[] = { + static const char *status[] = { "Idle (Disconnect)", "Searching", "Active (Connected)", @@ -77,22 +63,18 @@ ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof, "", "", }; + static const char *signal[] = { "", "*", "**", "***", "****" }; - char *signal[] = { "", "*", "**", "***", "****" }; + struct net_device *dev = m->private; + struct ft1000_info *info = netdev_priv(dev); + int i; + unsigned short ledStat; + unsigned short conStat; int strength; int quality; struct timeval tv; time_t delta; - dev = (struct net_device *) data; - info = netdev_priv(dev); - - if (off > 0) { - *eof = 1; - return 0; - } - - if (info->ProgConStat != 0xFF) { ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); @@ -144,36 +126,43 @@ ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof, quality = 0; } - len = 0; - PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n", + seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n", ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); - PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta); - PUTM_TO_PAGE(len, page, "Asic ID: %s\n", - (info->AsicID) == - ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); - PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku); - PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64); - PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer); - PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ, - info->HwSerNum); - PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ, - info->RfCalVer); - PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ, - info->RfCalDate); - PUTM_TO_PAGE(len, page, "Media State: %s\n", - (info->mediastate) ? "link" : "no link"); - PUTM_TO_PAGE(len, page, "Connection Status: %s\n", - status[((info->ConStat) & 0x7)]); - PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets); - PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets); - PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes); - PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes); - PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]); - PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]); - - return len; + seq_printf(m, "Connection Time[s]: %ld\n", delta); + seq_printf(m, "Asic ID: %s\n", + (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); + seq_putx(m, "SKU: ", SKUSZ, info->Sku); + seq_putx(m, "EUI64: ", EUISZ, info->eui64); + seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer); + seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum); + seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer); + seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate); + seq_printf(m, "Media State: %s\n", (info->mediastate) ? "link" : "no link"); + seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]); + seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets); + seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets); + seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes); + seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes); + seq_printf(m, "Signal Strength: %s\n", signal[strength]); + seq_printf(m, "Signal Quality: %s\n", signal[quality]); + return 0; +} + +/* + * seq_file wrappers for procfile show routines. + */ +static int ft1000_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ft1000ReadProc, PDE_DATA(inode)); } +static const struct file_operations ft1000_proc_fops = { + .open = ft1000_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr) { @@ -186,9 +175,9 @@ ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr) switch (event) { case NETDEV_CHANGENAME: remove_proc_entry(info->netdevname, info->ft1000_proc_dir); - ft1000_proc_file = create_proc_read_entry(dev->name, 0644, - info->ft1000_proc_dir, - ft1000ReadProc, dev); + ft1000_proc_file = + proc_create_data(dev->name, 0644, info->ft1000_proc_dir, + &ft1000_proc_fops, dev); snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name); break; } @@ -217,10 +206,10 @@ int ft1000_init_proc(struct net_device *dev) } ft1000_proc_file = - create_proc_read_entry(dev->name, 0644, - info->ft1000_proc_dir, ft1000ReadProc, dev); + proc_create_data(dev->name, 0644, info->ft1000_proc_dir, + &ft1000_proc_fops, dev); - if (ft1000_proc_file == NULL) { + if (!ft1000_proc_file) { printk(KERN_WARNING "Unable to create /proc entry.\n"); goto fail_entry; } diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c index 083b20e6253..48e1005349d 100644 --- a/drivers/staging/keucr/scsiglue.c +++ b/drivers/staging/keucr/scsiglue.c @@ -229,26 +229,18 @@ void usb_stor_report_bus_reset(struct us_data *us) /* we use this macro to help us write into the buffer */ #undef SPRINTF -#define SPRINTF(args...) \ - do { \ - if (pos < buffer+length) \ - pos += sprintf(pos, ## args); \ - } while (0) +#define SPRINTF(args...) seq_printf(m, ##args) -/* - * proc_info() - */ -static int proc_info(struct Scsi_Host *host, char *buffer, char **start, - off_t offset, int length, int inout) +static int write_info(struct Scsi_Host *host, char *buffer, int length) +{ + return length; +} + +static int show_info(struct seq_file *m, struct Scsi_Host *host) { struct us_data *us = host_to_us(host); - char *pos = buffer; const char *string; - /* pr_info("scsiglue --- proc_info\n"); */ - if (inout) - return length; - /* print the controller name */ SPRINTF(" Host scsi%d: usb-storage\n", host->host_no); @@ -278,29 +270,17 @@ static int proc_info(struct Scsi_Host *host, char *buffer, char **start, SPRINTF(" Transport: %s\n", us->transport_name); /* show the device flags */ - if (pos < buffer + length) { - pos += sprintf(pos, " Quirks:"); + SPRINTF(" Quirks:"); #define US_FLAG(name, value) \ do { \ if (us->fflags & value) \ - pos += sprintf(pos, " " #name); \ + SPRINTF(" " #name); \ } while (0); US_DO_ALL_FLAGS #undef US_FLAG - - *(pos++) = '\n'; - } - - /* Calculate start of next buffer, and return value. */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return 0; - else if ((pos - buffer - offset) < length) - return pos - buffer - offset; - else - return length; + seq_putc(m, '\n'); + return 0; } /*********************************************************************** @@ -351,7 +331,8 @@ struct scsi_host_template usb_stor_host_template = { /* basic userland interface stuff */ .name = "eucr-storage", .proc_name = "eucr-storage", - .proc_info = proc_info, + .write_info = write_info, + .show_info = show_info, .info = host_info, /* command interface -- queued only */ diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index 70ea4145b4c..edacc800164 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -372,7 +372,6 @@ typedef struct r8180_priv struct Stats stats; struct _link_detect_t link_detect; //YJ,add,080828 struct iw_statistics wstats; - struct proc_dir_entry *dir_dev; /*RX stuff*/ u32 *rxring; diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index d10d75e8a33..f7c1d9905ec 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -36,6 +36,8 @@ #include <linux/syscalls.h> #include <linux/eeprom_93cx6.h> #include <linux/interrupt.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include "r8180_hw.h" #include "r8180.h" @@ -204,51 +206,35 @@ void rtl8180_start_tx_beacon(struct net_device *dev); static struct proc_dir_entry *rtl8180_proc; -static int proc_get_registers(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_registers(struct seq_file *m, void *v) { - struct net_device *dev = data; - int len = 0; - int i, n; - int max = 0xff; + struct net_device *dev = m->private; + int i, n, max = 0xff; /* This dump the current register page */ for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); + seq_printf(m, "\nD: %2x > ", n); for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, "%2x ", - read_nic_byte(dev, n)); + seq_printf(m, "%2x ", read_nic_byte(dev, n)); } - len += snprintf(page + len, count - len, "\n"); - - *eof = 1; - return len; + seq_putc(m, '\n'); + return 0; } int get_curr_tx_free_desc(struct net_device *dev, int priority); -static int proc_get_stats_hw(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_hw(struct seq_file *m, void *v) { - int len = 0; - - *eof = 1; - return len; + return 0; } -static int proc_get_stats_rx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_rx(struct seq_file *m, void *v) { - struct net_device *dev = data; + struct net_device *dev = m->private; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - int len = 0; - - len += snprintf(page + len, count - len, + seq_printf(m, "RX OK: %lu\n" "RX Retry: %lu\n" "RX CRC Error(0-500): %lu\n" @@ -263,22 +249,17 @@ static int proc_get_stats_rx(char *page, char **start, priv->stats.rxicverr ); - *eof = 1; - return len; + return 0; } -static int proc_get_stats_tx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_tx(struct seq_file *m, void *v) { - struct net_device *dev = data; + struct net_device *dev = m->private; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - int len = 0; unsigned long totalOK; totalOK = priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint; - len += snprintf(page + len, count - len, + seq_printf(m, "TX OK: %lu\n" "TX Error: %lu\n" "TX Retry: %lu\n" @@ -291,8 +272,7 @@ static int proc_get_stats_tx(char *page, char **start, priv->stats.txbeaconerr ); - *eof = 1; - return len; + return 0; } void rtl8180_proc_module_init(void) @@ -308,59 +288,61 @@ void rtl8180_proc_module_remove(void) void rtl8180_proc_remove_one(struct net_device *dev) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - if (priv->dir_dev) { - remove_proc_entry("stats-hw", priv->dir_dev); - remove_proc_entry("stats-tx", priv->dir_dev); - remove_proc_entry("stats-rx", priv->dir_dev); - remove_proc_entry("registers", priv->dir_dev); - priv->dir_dev = NULL; - } + remove_proc_subtree(dev->name, rtl8180_proc); } -void rtl8180_proc_init_one(struct net_device *dev) +/* + * seq_file wrappers for procfile show routines. + */ +static int rtl8180_proc_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *e; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct net_device *dev = proc_get_parent_data(inode); + int (*show)(struct seq_file *, void *) = PDE_DATA(inode); - priv->dir_dev = rtl8180_proc; - if (!priv->dir_dev) { - DMESGE("Unable to initialize /proc/net/r8180/%s\n", - dev->name); - return; - } + return single_open(file, show, dev); +} - e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_hw, dev); - if (!e) { - DMESGE("Unable to initialize " - "/proc/net/r8180/%s/stats-hw\n", - dev->name); - } +static const struct file_operations rtl8180_proc_fops = { + .open = rtl8180_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_rx, dev); - if (!e) { - DMESGE("Unable to initialize " - "/proc/net/r8180/%s/stats-rx\n", - dev->name); - } +/* + * Table of proc files we need to create. + */ +struct rtl8180_proc_file { + char name[12]; + int (*show)(struct seq_file *, void *); +}; +static const struct rtl8180_proc_file rtl8180_proc_files[] = { + { "stats-hw", &proc_get_stats_hw }, + { "stats-rx", &proc_get_stats_rx }, + { "stats-tx", &proc_get_stats_tx }, + { "registers", &proc_get_registers }, + { "" } +}; + +void rtl8180_proc_init_one(struct net_device *dev) +{ + const struct rtl8180_proc_file *f; + struct proc_dir_entry *dir; - e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_tx, dev); - if (!e) { - DMESGE("Unable to initialize " - "/proc/net/r8180/%s/stats-tx\n", - dev->name); + dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev); + if (!dir) { + DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name); + return; } - e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers, dev); - if (!e) { - DMESGE("Unable to initialize " - "/proc/net/r8180/%s/registers\n", - dev->name); + for (f = rtl8180_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8180_proc_fops, f->show)) { + DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n", + dev->name, f->name); + return; + } } } diff --git a/drivers/staging/rtl8192e/rtl8192e/Makefile b/drivers/staging/rtl8192e/rtl8192e/Makefile index 313a92ec683..a2c4fb4ba1a 100644 --- a/drivers/staging/rtl8192e/rtl8192e/Makefile +++ b/drivers/staging/rtl8192e/rtl8192e/Makefile @@ -7,7 +7,6 @@ r8192e_pci-objs := \ r8190P_rtl8256.o \ rtl_cam.o \ rtl_core.o \ - rtl_debug.o \ rtl_dm.o \ rtl_eeprom.o \ rtl_ethtool.o \ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 4ebf99b3097..2b6c61c5d3d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -2966,8 +2966,6 @@ static int rtl8192_pci_probe(struct pci_dev *pdev, goto err_free_irq; RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name); - rtl8192_proc_init_one(dev); - if (priv->polling_timer_on == 0) check_rfctrl_gpio_timer((unsigned long)dev); @@ -3003,7 +3001,6 @@ static void rtl8192_pci_disconnect(struct pci_dev *pdev) del_timer_sync(&priv->gpio_polling_timer); cancel_delayed_work(&priv->gpio_change_rf_wq); priv->polling_timer_on = 0; - rtl8192_proc_remove_one(dev); rtl8192_down(dev, true); deinit_hal_dm(dev); if (priv->pFirmware) { @@ -3093,7 +3090,6 @@ static int __init rtl8192_pci_module_init(void) printk(KERN_INFO "\nLinux kernel driver for RTL8192E WLAN cards\n"); printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan Driver\n"); - rtl8192_proc_module_init(); if (0 != pci_register_driver(&rtl8192_pci_driver)) { DMESG("No device found"); /*pci_unregister_driver (&rtl8192_pci_driver);*/ @@ -3107,7 +3103,6 @@ static void __exit rtl8192_pci_module_exit(void) pci_unregister_driver(&rtl8192_pci_driver); RT_TRACE(COMP_DOWN, "Exiting"); - rtl8192_proc_module_remove(); } void check_rfctrl_gpio_timer(unsigned long data) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 320d5fc026b..87d4d349c89 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -1085,10 +1085,4 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, enum wireless_mode WirelessMode, struct channel_access_setting *ChnlAccessSetting); -/* proc stuff from rtl_debug.c */ -void rtl8192_proc_init_one(struct net_device *dev); -void rtl8192_proc_remove_one(struct net_device *dev); -void rtl8192_proc_module_init(void); -void rtl8192_proc_module_remove(void); - #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c b/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c deleted file mode 100644 index c19b14cd6f7..00000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c +++ /dev/null @@ -1,1029 +0,0 @@ -/****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae <wlanfae@realtek.com> -******************************************************************************/ -#include "rtl_core.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ -#include "r8192E_cmdpkt.h" - -/**************************************************************************** - -----------------------------PROCFS STUFF------------------------- -*****************************************************************************/ -/*This part is related to PROC, which will record some statistics. */ -static struct proc_dir_entry *rtl8192_proc; - -static int proc_get_stats_ap(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - struct rtllib_network *target; - int len = 0; - - list_for_each_entry(target, &ieee->network_list, list) { - - len += snprintf(page + len, count - len, - "%s ", target->ssid); - - if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0) - len += snprintf(page + len, count - len, - "WPA\n"); - else - len += snprintf(page + len, count - len, - "non_WPA\n"); - - } - - *eof = 1; - return len; -} - -static int proc_get_registers_0(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x000; - - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0>>8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; n++, i++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_1(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x100; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0>>8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_2(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x200; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0 >> 8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C " - "0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_3(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x300; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0>>8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_4(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x400; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0>>8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_5(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x500; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0 >> 8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_6(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x600; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0>>8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " - "0C 0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_7(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x700; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n ", - (page0 >> 8)); - len += snprintf(page + len, count - len, - "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C " - "0D 0E 0F"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, - "\nD: %2x > ", n); - for (i = 0; i < 16 && n <= max; i++, n++) - len += snprintf(page + len, count - len, - "%2.2x ", read_nic_byte(dev, - (page0 | n))); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_8(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x800; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0 >> 8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; - -} -static int proc_get_registers_9(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0x900; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0>>8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_registers_a(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0xa00; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0>>8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_registers_b(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0xb00; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0 >> 8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_registers_c(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0xc00; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0>>8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_registers_d(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0xd00; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0>>8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_registers_e(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n, page0; - - int max = 0xff; - page0 = 0xe00; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page %x##################\n", - (page0>>8)); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_QueryBBReg(dev, - (page0 | n), bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_reg_rf_a(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n; - - int max = 0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### RF-A ##################\n "); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_phy_QueryRFReg(dev, - (enum rf90_radio_path)RF90_PATH_A, n, - bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_reg_rf_b(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n; - - int max = 0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### RF-B ##################\n "); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_phy_QueryRFReg(dev, - (enum rf90_radio_path)RF90_PATH_B, n, - bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_reg_rf_c(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n; - - int max = 0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### RF-C ##################\n"); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_phy_QueryRFReg(dev, - (enum rf90_radio_path)RF90_PATH_C, n, - bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_reg_rf_d(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - - int len = 0; - int i, n; - - int max = 0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### RF-D ##################\n "); - for (n = 0; n <= max;) { - len += snprintf(page + len, count - len, "\nD: %2x > ", n); - for (i = 0; i < 4 && n <= max; n += 4, i++) - len += snprintf(page + len, count - len, - "%8.8x ", rtl8192_phy_QueryRFReg(dev, - (enum rf90_radio_path)RF90_PATH_D, n, - bMaskDWord)); - } - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_cam_register_1(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - u32 target_command = 0; - u32 target_content = 0; - u8 entry_i = 0; - u32 ulStatus; - int len = 0; - int i = 100, j = 0; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### SECURITY CAM (0-10) ######" - "############\n "); - for (j = 0; j < 11; j++) { - len += snprintf(page + len, count - len, "\nD: %2x > ", j); - for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { - target_command = entry_i+CAM_CONTENT_COUNT*j; - target_command = target_command | BIT31; - - while ((i--) >= 0) { - ulStatus = read_nic_dword(dev, RWCAM); - if (ulStatus & BIT31) - continue; - else - break; - } - write_nic_dword(dev, RWCAM, target_command); - target_content = read_nic_dword(dev, RCAMO); - len += snprintf(page + len, count - len, "%8.8x ", - target_content); - } - } - - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_cam_register_2(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - u32 target_command = 0; - u32 target_content = 0; - u8 entry_i = 0; - u32 ulStatus; - int len = 0; - int i = 100, j = 0; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### SECURITY CAM (11-21) " - "##################\n "); - for (j = 11; j < 22; j++) { - len += snprintf(page + len, count - len, "\nD: %2x > ", j); - for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { - target_command = entry_i + CAM_CONTENT_COUNT * j; - target_command = target_command | BIT31; - - while ((i--) >= 0) { - ulStatus = read_nic_dword(dev, RWCAM); - if (ulStatus & BIT31) - continue; - else - break; - } - write_nic_dword(dev, RWCAM, target_command); - target_content = read_nic_dword(dev, RCAMO); - len += snprintf(page + len, count - len, "%8.8x ", - target_content); - } - } - - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} - -static int proc_get_cam_register_3(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - u32 target_command = 0; - u32 target_content = 0; - u8 entry_i = 0; - u32 ulStatus; - int len = 0; - int i = 100, j = 0; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n#################### SECURITY CAM (22-31) ######" - "############\n "); - for (j = 22; j < TOTAL_CAM_ENTRY; j++) { - len += snprintf(page + len, count - len, "\nD: %2x > ", j); - for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { - target_command = entry_i + CAM_CONTENT_COUNT * j; - target_command = target_command | BIT31; - - while ((i--) >= 0) { - ulStatus = read_nic_dword(dev, RWCAM); - if (ulStatus & BIT31) - continue; - else - break; - } - write_nic_dword(dev, RWCAM, target_command); - target_content = read_nic_dword(dev, RCAMO); - len += snprintf(page + len, count - len, "%8.8x ", - target_content); - } - } - - len += snprintf(page + len, count - len, "\n"); - *eof = 1; - return len; -} -static int proc_get_stats_tx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - int len = 0; - - len += snprintf(page + len, count - len, - "TX VI priority ok int: %lu\n" - "TX VO priority ok int: %lu\n" - "TX BE priority ok int: %lu\n" - "TX BK priority ok int: %lu\n" - "TX MANAGE priority ok int: %lu\n" - "TX BEACON priority ok int: %lu\n" - "TX BEACON priority error int: %lu\n" - "TX CMDPKT priority ok int: %lu\n" - "TX queue stopped?: %d\n" - "TX fifo overflow: %lu\n" - "TX total data packets %lu\n" - "TX total data bytes :%lu\n", - priv->stats.txviokint, - priv->stats.txvookint, - priv->stats.txbeokint, - priv->stats.txbkokint, - priv->stats.txmanageokint, - priv->stats.txbeaconokint, - priv->stats.txbeaconerr, - priv->stats.txcmdpktokint, - netif_queue_stopped(dev), - priv->stats.txoverflow, - priv->rtllib->stats.tx_packets, - priv->rtllib->stats.tx_bytes - - - ); - - *eof = 1; - return len; -} - - - -static int proc_get_stats_rx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - int len = 0; - - len += snprintf(page + len, count - len, - "RX packets: %lu\n" - "RX data crc err: %lu\n" - "RX mgmt crc err: %lu\n" - "RX desc err: %lu\n" - "RX rx overflow error: %lu\n", - priv->stats.rxint, - priv->stats.rxdatacrcerr, - priv->stats.rxmgmtcrcerr, - priv->stats.rxrdu, - priv->stats.rxoverflow); - - *eof = 1; - return len; -} - -void rtl8192_proc_module_init(void) -{ - RT_TRACE(COMP_INIT, "Initializing proc filesystem"); - rtl8192_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); -} - - -void rtl8192_proc_module_remove(void) -{ - remove_proc_entry(DRV_NAME, init_net.proc_net); -} - - -void rtl8192_proc_remove_one(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - printk(KERN_INFO "dev name %s\n", dev->name); - - if (priv->dir_dev) { - remove_proc_entry("stats-tx", priv->dir_dev); - remove_proc_entry("stats-rx", priv->dir_dev); - remove_proc_entry("stats-ap", priv->dir_dev); - remove_proc_entry("registers-0", priv->dir_dev); - remove_proc_entry("registers-1", priv->dir_dev); - remove_proc_entry("registers-2", priv->dir_dev); - remove_proc_entry("registers-3", priv->dir_dev); - remove_proc_entry("registers-4", priv->dir_dev); - remove_proc_entry("registers-5", priv->dir_dev); - remove_proc_entry("registers-6", priv->dir_dev); - remove_proc_entry("registers-7", priv->dir_dev); - remove_proc_entry("registers-8", priv->dir_dev); - remove_proc_entry("registers-9", priv->dir_dev); - remove_proc_entry("registers-a", priv->dir_dev); - remove_proc_entry("registers-b", priv->dir_dev); - remove_proc_entry("registers-c", priv->dir_dev); - remove_proc_entry("registers-d", priv->dir_dev); - remove_proc_entry("registers-e", priv->dir_dev); - remove_proc_entry("RF-A", priv->dir_dev); - remove_proc_entry("RF-B", priv->dir_dev); - remove_proc_entry("RF-C", priv->dir_dev); - remove_proc_entry("RF-D", priv->dir_dev); - remove_proc_entry("SEC-CAM-1", priv->dir_dev); - remove_proc_entry("SEC-CAM-2", priv->dir_dev); - remove_proc_entry("SEC-CAM-3", priv->dir_dev); - remove_proc_entry("wlan0", rtl8192_proc); - priv->dir_dev = NULL; - } -} - - -void rtl8192_proc_init_one(struct net_device *dev) -{ - struct proc_dir_entry *e; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - priv->dir_dev = create_proc_entry(dev->name, - S_IFDIR | S_IRUGO | S_IXUGO, - rtl8192_proc); - if (!priv->dir_dev) { - RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192" - "/%s\n", dev->name); - return; - } - e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_rx, dev); - - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-rx\n", - dev->name); - - e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_tx, dev); - - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-tx\n", - dev->name); - - e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_ap, dev); - - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-ap\n", - dev->name); - - e = create_proc_read_entry("registers-0", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_0, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-0\n", - dev->name); - e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_1, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-1\n", - dev->name); - e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_2, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-2\n", - dev->name); - e = create_proc_read_entry("registers-3", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_3, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-3\n", - dev->name); - e = create_proc_read_entry("registers-4", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_4, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-4\n", - dev->name); - e = create_proc_read_entry("registers-5", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_5, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-5\n", - dev->name); - e = create_proc_read_entry("registers-6", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_6, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-6\n", - dev->name); - e = create_proc_read_entry("registers-7", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_7, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-7\n", - dev->name); - e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_8, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-8\n", - dev->name); - e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_9, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-9\n", - dev->name); - e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_a, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-a\n", - dev->name); - e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_b, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-b\n", - dev->name); - e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_c, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-c\n", - dev->name); - e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_d, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-d\n", - dev->name); - e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers_e, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers-e\n", - dev->name); - e = create_proc_read_entry("RF-A", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_reg_rf_a, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/RF-A\n", - dev->name); - e = create_proc_read_entry("RF-B", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_reg_rf_b, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/RF-B\n", - dev->name); - e = create_proc_read_entry("RF-C", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_reg_rf_c, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/RF-C\n", - dev->name); - e = create_proc_read_entry("RF-D", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_reg_rf_d, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/RF-D\n", - dev->name); - e = create_proc_read_entry("SEC-CAM-1", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_cam_register_1, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/SEC-CAM-1\n", - dev->name); - e = create_proc_read_entry("SEC-CAM-2", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_cam_register_2, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/SEC-CAM-2\n", - dev->name); - e = create_proc_read_entry("SEC-CAM-3", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_cam_register_3, dev); - if (!e) - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/SEC-CAM-3\n", - dev->name); -} diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index 4217b88e6fc..e51cb49ce10 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -412,19 +412,18 @@ static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv) } -static char *rtllib_ccmp_print_stats(char *p, void *priv) +static void rtllib_ccmp_print_stats(struct seq_file *m, void *priv) { struct rtllib_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%pM rx_pn=%pM " - "format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - ccmp->tx_pn, ccmp->rx_pn, - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; + seq_printf(m, + "key[%d] alg=CCMP key_set=%d " + "tx_pn=%pM rx_pn=%pM " + "format_errors=%d replays=%d decrypt_errors=%d\n", + ccmp->key_idx, ccmp->key_set, + ccmp->tx_pn, ccmp->rx_pn, + ccmp->dot11RSNAStatsCCMPFormatErrors, + ccmp->dot11RSNAStatsCCMPReplays, + ccmp->dot11RSNAStatsCCMPDecryptErrors); } static struct lib80211_crypto_ops rtllib_crypt_ccmp = { diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 800925053fb..5cfd73baf1c 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -708,30 +708,30 @@ static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv) } -static char *rtllib_tkip_print_stats(char *p, void *priv) +static void rtllib_tkip_print_stats(struct seq_file *m, void *priv) { struct rtllib_tkip_data *tkip = priv; - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; + seq_printf(m, + "key[%d] alg=TKIP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "replays=%d icv_errors=%d local_mic_failures=%d\n", + tkip->key_idx, tkip->key_set, + (tkip->tx_iv32 >> 24) & 0xff, + (tkip->tx_iv32 >> 16) & 0xff, + (tkip->tx_iv32 >> 8) & 0xff, + tkip->tx_iv32 & 0xff, + (tkip->tx_iv16 >> 8) & 0xff, + tkip->tx_iv16 & 0xff, + (tkip->rx_iv32 >> 24) & 0xff, + (tkip->rx_iv32 >> 16) & 0xff, + (tkip->rx_iv32 >> 8) & 0xff, + tkip->rx_iv32 & 0xff, + (tkip->rx_iv16 >> 8) & 0xff, + tkip->rx_iv16 & 0xff, + tkip->dot11RSNAStatsTKIPReplays, + tkip->dot11RSNAStatsTKIPICVErrors, + tkip->dot11RSNAStatsTKIPLocalMICFailures); } static struct lib80211_crypto_ops rtllib_crypt_tkip = { diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c index 8cdf38913a3..c4df6e01ef7 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c @@ -247,12 +247,10 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) } -static char *prism2_wep_print_stats(char *p, void *priv) +static void prism2_wep_print_stats(struct seq_file *m, void *priv) { struct prism2_wep_data *wep = priv; - p += sprintf(p, "key[%d] alg=WEP len=%d\n", - wep->key_idx, wep->key_len); - return p; + seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len); } static struct lib80211_crypto_ops rtllib_crypt_wep = { diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index f9dae958a5d..84ea721d5d8 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -208,61 +208,51 @@ static int debug = \ ; static struct proc_dir_entry *rtllib_proc; -static int show_debug_level(char *page, char **start, off_t offset, - int count, int *eof, void *data) +static int show_debug_level(struct seq_file *m, void *v) { - return snprintf(page, count, "0x%08X\n", rtllib_debug_level); + return seq_printf(m, "0x%08X\n", rtllib_debug_level); } -static int store_debug_level(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t write_debug_level(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { - char buf[] = "0x00000000"; - unsigned long len = min((unsigned long)sizeof(buf) - 1, count); - char *p = (char *)buf; unsigned long val; + int err = kstrtoul_from_user(buffer, count, 0, &val); + if (err) + return err; + rtllib_debug_level = val; + return count; +} - if (copy_from_user(buf, buffer, len)) - return count; - buf[len] = 0; - if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { - p++; - if (p[0] == 'x' || p[0] == 'X') - p++; - val = simple_strtoul(p, &p, 16); - } else - val = simple_strtoul(p, &p, 10); - if (p == buf) - printk(KERN_INFO DRV_NAME - ": %s is not in hex or decimal form.\n", buf); - else - rtllib_debug_level = val; - - return strnlen(buf, count); +static int open_debug_level(struct inode *inode, struct file *file) +{ + return single_open(file, show_debug_level, NULL); } +static const struct file_operations fops = { + .open = open_debug_level, + .read = seq_read, + .llseek = seq_lseek, + .write = write_debug_level +}; + int __init rtllib_init(void) { struct proc_dir_entry *e; rtllib_debug_level = debug; - rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); + rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net); if (rtllib_proc == NULL) { RTLLIB_ERROR("Unable to create " DRV_NAME " proc directory\n"); return -EIO; } - e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, - rtllib_proc); + e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops); if (!e) { remove_proc_entry(DRV_NAME, init_net.proc_net); rtllib_proc = NULL; return -EIO; } - e->read_proc = show_debug_level; - e->write_proc = store_debug_level; - e->data = NULL; - return 0; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 76c56e5aed7..e0870c05a5e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -243,39 +243,34 @@ static int debug = \ ; struct proc_dir_entry *ieee80211_proc; -static int show_debug_level(char *page, char **start, off_t offset, - int count, int *eof, void *data) +static int show_debug_level(struct seq_file *m, void *v) { - return snprintf(page, count, "0x%08X\n", ieee80211_debug_level); + return seq_printf(m, "0x%08X\n", ieee80211_debug_level); } -static int store_debug_level(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t write_debug_level(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { - char buf[] = "0x00000000"; - unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count); - char *p = (char *)buf; unsigned long val; + int err = kstrtoul_from_user(buffer, count, 0, &val); + if (err) + return err; + ieee80211_debug_level = val; + return count; +} - if (copy_from_user(buf, buffer, len)) - return count; - buf[len] = 0; - if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { - p++; - if (p[0] == 'x' || p[0] == 'X') - p++; - val = simple_strtoul(p, &p, 16); - } else - val = simple_strtoul(p, &p, 10); - if (p == buf) - printk(KERN_INFO DRV_NAME - ": %s is not in hex or decimal form.\n", buf); - else - ieee80211_debug_level = val; - - return strnlen(buf, count); +static int open_debug_level(struct inode *inode, struct file *file) +{ + return single_open(file, show_debug_level, NULL); } +static const struct file_operations fops = { + .open = open_debug_level, + .read = seq_read, + .llseek = seq_lseek, + .write = write_debug_level +}; + int __init ieee80211_debug_init(void) { struct proc_dir_entry *e; @@ -288,17 +283,13 @@ int __init ieee80211_debug_init(void) " proc directory\n"); return -EIO; } - e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, - ieee80211_proc); + e = proc_create("debug_level", S_IRUGO | S_IWUSR, + ieee80211_proc, &fops); if (!e) { remove_proc_entry(DRV_NAME, init_net.proc_net); ieee80211_proc = NULL; return -EIO; } - e->read_proc = show_debug_level; - e->write_proc = store_debug_level; - e->data = NULL; - return 0; } diff --git a/drivers/staging/rtl8192u/ieee80211/proc.c b/drivers/staging/rtl8192u/ieee80211/proc.c index 6eda928e409..c426dfdd9fd 100644 --- a/drivers/staging/rtl8192u/ieee80211/proc.c +++ b/drivers/staging/rtl8192u/ieee80211/proc.c @@ -99,7 +99,7 @@ static int crypto_info_open(struct inode *inode, struct file *file) return seq_open(file, &crypto_seq_ops); } -static struct file_operations proc_crypto_ops = { +static const struct file_operations proc_crypto_ops = { .open = crypto_info_open, .read = seq_read, .llseek = seq_lseek, @@ -108,9 +108,5 @@ static struct file_operations proc_crypto_ops = { void __init crypto_init_proc(void) { - struct proc_dir_entry *proc; - - proc = create_proc_entry("crypto", 0, NULL); - if (proc) - proc->proc_fops = &proc_crypto_ops; + proc_create("crypto", 0, NULL, &proc_crypto_ops); } diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index e538e026b51..bedeb330ad4 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -946,7 +946,6 @@ typedef struct r8192_priv { /*stats*/ struct Stats stats; struct iw_statistics wstats; - struct proc_dir_entry *dir_dev; /*RX stuff*/ // u32 *rxring; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index f7de2f6d49a..14592339755 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -71,6 +71,8 @@ double __extendsfdf2(float a) {return a;} //#include "r8192xU_phyreg.h" #include <linux/usb.h> #include <linux/slab.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> // FIXME: check if 2.6.7 is ok #ifdef CONFIG_RTL8192_PM @@ -472,103 +474,73 @@ void watch_dog_timer_callback(unsigned long data); static struct proc_dir_entry *rtl8192_proc; -static int proc_get_stats_ap(char *page, char **start, off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_ap(struct seq_file *m, void *v) { - struct net_device *dev = data; + struct net_device *dev = m->private; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; struct ieee80211_network *target; - int len = 0; - list_for_each_entry(target, &ieee->network_list, list) { - - len += snprintf(page + len, count - len, "%s ", target->ssid); - + const char *wpa = "non_WPA"; if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0) - len += snprintf(page + len, count - len, "WPA\n"); - else - len += snprintf(page + len, count - len, "non_WPA\n"); + wpa = "WPA"; + + seq_printf(m, "%s %s\n", target->ssid, wpa); } - *eof = 1; - return len; + return 0; } -static int proc_get_registers(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_registers(struct seq_file *m, void *v) { - struct net_device *dev = data; -// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct net_device *dev = m->private; + int i,n, max = 0xff; - int len = 0; - int i,n; - - int max=0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page 0##################\n "); + seq_puts(m, "\n####################page 0##################\n "); for (n=0;n<=max;) { //printk( "\nD: %2x> ", n); - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); + seq_printf(m, "\nD: %2x > ",n); for (i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,0x000|n)); + seq_printf(m, "%2x ",read_nic_byte(dev,0x000|n)); // printk("%2x ",read_nic_byte(dev,n)); } - len += snprintf(page + len, count - len, - "\n####################page 1##################\n "); + + seq_puts(m, "\n####################page 1##################\n "); for (n=0;n<=max;) { //printk( "\nD: %2x> ", n); - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); + seq_printf(m, "\nD: %2x > ",n); for (i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,0x100|n)); + seq_printf(m, "%2x ",read_nic_byte(dev,0x100|n)); // printk("%2x ",read_nic_byte(dev,n)); } - len += snprintf(page + len, count - len, - "\n####################page 3##################\n "); + + seq_puts(m, "\n####################page 3##################\n "); for (n=0;n<=max;) { //printk( "\nD: %2x> ", n); - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); + seq_printf(m, "\nD: %2x > ",n); for(i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,0x300|n)); + seq_printf(m, "%2x ",read_nic_byte(dev,0x300|n)); // printk("%2x ",read_nic_byte(dev,n)); } - len += snprintf(page + len, count - len,"\n"); - *eof = 1; - return len; + seq_putc(m, '\n'); + return 0; } - - - - -static int proc_get_stats_tx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_tx(struct seq_file *m, void *v) { - struct net_device *dev = data; + struct net_device *dev = m->private; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - int len = 0; - - len += snprintf(page + len, count - len, + seq_printf(m, "TX VI priority ok int: %lu\n" "TX VI priority error int: %lu\n" "TX VO priority ok int: %lu\n" @@ -629,22 +601,15 @@ static int proc_get_stats_tx(char *page, char **start, // priv->stats.txbeaconerr ); - *eof = 1; - return len; + return 0; } - - -static int proc_get_stats_rx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) +static int proc_get_stats_rx(struct seq_file *m, void *v) { - struct net_device *dev = data; + struct net_device *dev = m->private; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - int len = 0; - - len += snprintf(page + len, count - len, + seq_printf(m, "RX packets: %lu\n" "RX urb status error: %lu\n" "RX invalid urb error: %lu\n", @@ -652,9 +617,9 @@ static int proc_get_stats_rx(char *page, char **start, priv->stats.rxstaterr, priv->stats.rxurberr); - *eof = 1; - return len; + return 0; } + void rtl8192_proc_module_init(void) { RT_TRACE(COMP_INIT, "Initializing proc filesystem"); @@ -667,74 +632,70 @@ void rtl8192_proc_module_remove(void) remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net); } - -void rtl8192_proc_remove_one(struct net_device *dev) +/* + * seq_file wrappers for procfile show routines. + */ +static int rtl8192_proc_open(struct inode *inode, struct file *file) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct net_device *dev = proc_get_parent_data(inode); + int (*show)(struct seq_file *, void *) = PDE_DATA(inode); - - if (priv->dir_dev) { - // remove_proc_entry("stats-hw", priv->dir_dev); - remove_proc_entry("stats-tx", priv->dir_dev); - remove_proc_entry("stats-rx", priv->dir_dev); - // remove_proc_entry("stats-ieee", priv->dir_dev); - remove_proc_entry("stats-ap", priv->dir_dev); - remove_proc_entry("registers", priv->dir_dev); - // remove_proc_entry("cck-registers",priv->dir_dev); - // remove_proc_entry("ofdm-registers",priv->dir_dev); - //remove_proc_entry(dev->name, rtl8192_proc); - remove_proc_entry("wlan0", rtl8192_proc); - priv->dir_dev = NULL; - } + return single_open(file, show, dev); } +static const struct file_operations rtl8192_proc_fops = { + .open = rtl8192_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -void rtl8192_proc_init_one(struct net_device *dev) -{ - struct proc_dir_entry *e; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc); - if (!priv->dir_dev) { - RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", - dev->name); - return; - } - e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_rx, dev); - - if (!e) { - RT_TRACE(COMP_ERR,"Unable to initialize " - "/proc/net/rtl8192/%s/stats-rx\n", - dev->name); - } - +/* + * Table of proc files we need to create. + */ +struct rtl8192_proc_file { + char name[12]; + int (*show)(struct seq_file *, void *); +}; - e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_tx, dev); +static const struct rtl8192_proc_file rtl8192_proc_files[] = { + { "stats-rx", &proc_get_stats_rx }, + { "stats-tx", &proc_get_stats_tx }, + { "stats-ap", &proc_get_stats_ap }, + { "registers", &proc_get_registers }, + { "" } +}; - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-tx\n", - dev->name); - } +void rtl8192_proc_init_one(struct net_device *dev) +{ + const struct rtl8192_proc_file *f; + struct proc_dir_entry *dir; - e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_ap, dev); + if (rtl8192_proc) { + dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev); + if (!dir) { + RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", + dev->name); + return; + } - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-ap\n", - dev->name); + for (f = rtl8192_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8192_proc_fops, f->show)) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/%s\n", + dev->name, f->name); + return; + } + } } +} - e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers, dev); - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers\n", - dev->name); - } +void rtl8192_proc_remove_one(struct net_device *dev) +{ + remove_proc_subtree(dev->name, rtl8192_proc); } + /**************************************************************************** -----------------------------MISC STUFF------------------------- *****************************************************************************/ diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index b58f1dfe006..61087054640 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -1968,18 +1968,16 @@ int slave_configure(struct scsi_device *sdev) /* we use this macro to help us write into the buffer */ #undef SPRINTF -#define SPRINTF(args...) \ - do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) +#define SPRINTF(args...) seq_printf(m, ##args) -int proc_info(struct Scsi_Host *host, char *buffer, - char **start, off_t offset, int length, int inout) +static int write_info(struct Scsi_Host *host, char *buffer, int length) { - char *pos = buffer; - /* if someone is sending us data, just throw it away */ - if (inout) - return length; + return length; +} +static int show_info(struct seq_file *m, struct Scsi_Host *host) +{ /* print the controller name */ SPRINTF(" Host scsi%d: %s\n", host->host_no, RTS51X_NAME); @@ -1988,18 +1986,7 @@ int proc_info(struct Scsi_Host *host, char *buffer, SPRINTF(" Product: RTS51xx USB Card Reader\n"); SPRINTF(" Version: %s\n", DRIVER_VERSION); SPRINTF(" Build: %s\n", __TIME__); - - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return 0; - else if ((pos - buffer - offset) < length) - return pos - buffer - offset; - else - return length; + return 0; } /* queue a command */ @@ -2100,7 +2087,8 @@ struct scsi_host_template rts51x_host_template = { /* basic userland interface stuff */ .name = RTS51X_NAME, .proc_name = RTS51X_NAME, - .proc_info = proc_info, + .show_info = show_info, + .write_info = write_info, .info = rts5139_info, /* command interface -- queued only */ diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 3a5213611d2..1a0d7056618 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -147,8 +147,6 @@ struct scsi_cmnd; int slave_alloc(struct scsi_device *sdev); int slave_configure(struct scsi_device *sdev); -int proc_info(struct Scsi_Host *host, char *buffer, - char **start, off_t offset, int length, int inout); int queuecommand(struct Scsi_Host *, struct scsi_cmnd *); int command_abort(struct scsi_cmnd *srb); int bus_reset(struct scsi_cmnd *srb); diff --git a/drivers/staging/silicom/Makefile b/drivers/staging/silicom/Makefile index 80e6d12d156..ca8359481c4 100644 --- a/drivers/staging/silicom/Makefile +++ b/drivers/staging/silicom/Makefile @@ -4,6 +4,3 @@ obj-$(CONFIG_BPCTL) += bpctl_mod.o obj-$(CONFIG_SBYPASS) += bypasslib/ - - -bpctl_mod-objs := bp_mod.o bp_proc.o diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c deleted file mode 100644 index a01ca97b766..00000000000 --- a/drivers/staging/silicom/bp_proc.c +++ /dev/null @@ -1,1327 +0,0 @@ -/******************************************************************************/ -/* */ -/* Copyright (c) 2004-2006 Silicom, Ltd */ -/* All rights reserved. */ -/* */ -/* 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, located in the file LICENSE. */ -/* */ -/* */ -/******************************************************************************/ - -#if defined(CONFIG_SMP) && !defined(__SMP__) -#define __SMP__ -#endif - -#include <linux/proc_fs.h> -#include <linux/netdevice.h> -#include <asm/uaccess.h> -/* #include <linux/smp_lock.h> */ -#include "bp_mod.h" - -#define BP_PROC_DIR "bypass" -/* #define BYPASS_SUPPORT "bypass" */ - -#ifdef BYPASS_SUPPORT - -#define GPIO6_SET_ENTRY_SD "gpio6_set" -#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" - -#define GPIO7_SET_ENTRY_SD "gpio7_set" -#define GPIO7_CLEAR_ENTRY_SD "gpio7_clear" - -#define PULSE_SET_ENTRY_SD "pulse_set" -#define ZERO_SET_ENTRY_SD "zero_set" -#define PULSE_GET1_ENTRY_SD "pulse_get1" -#define PULSE_GET2_ENTRY_SD "pulse_get2" - -#define CMND_ON_ENTRY_SD "cmnd_on" -#define CMND_OFF_ENTRY_SD "cmnd_off" -#define RESET_CONT_ENTRY_SD "reset_cont" - - /*COMMANDS*/ -#define BYPASS_INFO_ENTRY_SD "bypass_info" -#define BYPASS_SLAVE_ENTRY_SD "bypass_slave" -#define BYPASS_CAPS_ENTRY_SD "bypass_caps" -#define WD_SET_CAPS_ENTRY_SD "wd_set_caps" -#define BYPASS_ENTRY_SD "bypass" -#define BYPASS_CHANGE_ENTRY_SD "bypass_change" -#define BYPASS_WD_ENTRY_SD "bypass_wd" -#define WD_EXPIRE_TIME_ENTRY_SD "wd_expire_time" -#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd" -#define DIS_BYPASS_ENTRY_SD "dis_bypass" -#define BYPASS_PWUP_ENTRY_SD "bypass_pwup" -#define BYPASS_PWOFF_ENTRY_SD "bypass_pwoff" -#define STD_NIC_ENTRY_SD "std_nic" -#define STD_NIC_ENTRY_SD "std_nic" -#define TAP_ENTRY_SD "tap" -#define TAP_CHANGE_ENTRY_SD "tap_change" -#define DIS_TAP_ENTRY_SD "dis_tap" -#define TAP_PWUP_ENTRY_SD "tap_pwup" -#define TWO_PORT_LINK_ENTRY_SD "two_port_link" -#define WD_EXP_MODE_ENTRY_SD "wd_exp_mode" -#define WD_AUTORESET_ENTRY_SD "wd_autoreset" -#define TPL_ENTRY_SD "tpl" -#define WAIT_AT_PWUP_ENTRY_SD "wait_at_pwup" -#define HW_RESET_ENTRY_SD "hw_reset" -#define DISC_ENTRY_SD "disc" -#define DISC_CHANGE_ENTRY_SD "disc_change" -#define DIS_DISC_ENTRY_SD "dis_disc" -#define DISC_PWUP_ENTRY_SD "disc_pwup" - -static struct proc_dir_entry *bp_procfs_dir; - -static struct proc_dir_entry *proc_getdir(char *name, - struct proc_dir_entry *proc_dir) -{ - struct proc_dir_entry *pde = proc_dir; - for (pde = pde->subdir; pde; pde = pde->next) { - if (pde->namelen && (strcmp(name, pde->name) == 0)) { - /* directory exists */ - break; - } - } - if (pde == (struct proc_dir_entry *)0) { - /* create the directory */ - pde = create_proc_entry(name, S_IFDIR, proc_dir); - if (pde == (struct proc_dir_entry *)0) - return pde; - } - return pde; -} - -int -bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, - char *proc_name, - write_proc_t *write_proc, - read_proc_t *read_proc, - struct proc_dir_entry *parent_pfs, void *data) -{ - strcpy(pfs_unit_curr->proc_name, proc_name); - pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, - S_IFREG | S_IRUSR | - S_IWUSR | S_IRGRP | - S_IROTH, parent_pfs); - if (pfs_unit_curr->proc_entry == 0) - return -1; - - pfs_unit_curr->proc_entry->read_proc = read_proc; - pfs_unit_curr->proc_entry->write_proc = write_proc; - pfs_unit_curr->proc_entry->data = data; - - return 0; - -} - -int -get_bypass_info_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - int len = 0; - - len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->bp_name); - len += - sprintf(page + len, "Firmware version\t0x%x\n", - pbp_device_block->bp_fw_ver); - - *eof = 1; - return len; -} - -int -get_bypass_slave_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - struct pci_dev *pci_slave_dev = pbp_device_block->bp_slave; - struct net_device *net_slave_dev; - int len = 0; - - if (is_bypass_fn(pbp_device_block)) { - net_slave_dev = pci_get_drvdata(pci_slave_dev); - if (net_slave_dev) - len = sprintf(page, "%s\n", net_slave_dev->name); - else - len = sprintf(page, "fail\n"); - } else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -get_bypass_caps_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_caps_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "-1\n"); - else - len = sprintf(page, "0x%x\n", ret); - *eof = 1; - return len; - -} - -int -get_wd_set_caps_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_set_caps_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "-1\n"); - else - len = sprintf(page, "0x%x\n", ret); - *eof = 1; - return len; -} - -int -set_bypass_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_fn(pbp_device_block, bypass_param); - - return count; -} - -int -set_tap_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_tap_fn(pbp_device_block, tap_param); - - return count; -} - -int -set_disc_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_disc_fn(pbp_device_block, tap_param); - - return count; -} - -int -get_bypass_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -int -get_tap_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -int -get_disc_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_disc_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -int -get_bypass_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_change_fn(pbp_device_block); - if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -get_tap_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_change_fn(pbp_device_block); - if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -get_disc_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_disc_change_fn(pbp_device_block); - if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -set_bypass_wd_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - unsigned int timeout = 0; - char *timeout_ptr = kbuf; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - timeout_ptr = kbuf; - timeout = atoi(&timeout_ptr); - - set_bypass_wd_fn(pbp_device_block, timeout); - - return count; -} - -int -get_bypass_wd_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0, timeout = 0; - - ret = get_bypass_wd_fn(pbp_device_block, &timeout); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (timeout == -1) - len = sprintf(page, "unknown\n"); - else if (timeout == 0) - len = sprintf(page, "disable\n"); - else - len = sprintf(page, "%d\n", timeout); - - *eof = 1; - return len; -} - -int -get_wd_expire_time_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0, timeout = 0; - - ret = get_wd_expire_time_fn(pbp_device_block, &timeout); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (timeout == -1) - len = sprintf(page, "expire\n"); - else if (timeout == 0) - len = sprintf(page, "disable\n"); - - else - len = sprintf(page, "%d\n", timeout); - *eof = 1; - return len; -} - -int -get_tpl_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tpl_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -#ifdef PMC_FIX_FLAG -int -get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bp_wait_at_pwup_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -int -get_hw_reset_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bp_hw_reset_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; -} - -#endif /*PMC_WAIT_FLAG */ - -int -reset_bypass_wd_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = reset_bypass_wd_timer_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "disable\n"); - else if (ret == 1) - len = sprintf(page, "success\n"); - - *eof = 1; - return len; -} - -int -set_dis_bypass_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_dis_bypass_fn(pbp_device_block, bypass_param); - - return count; -} - -int -set_dis_tap_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_dis_tap_fn(pbp_device_block, tap_param); - - return count; -} - -int -set_dis_disc_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_dis_disc_fn(pbp_device_block, tap_param); - - return count; -} - -int -get_dis_bypass_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_bypass_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_dis_tap_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_tap_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_dis_disc_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_disc_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -set_bypass_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_pwup_fn(pbp_device_block, bypass_param); - - return count; -} - -int -set_bypass_pwoff_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_pwoff_fn(pbp_device_block, bypass_param); - - return count; -} - -int -set_tap_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_tap_pwup_fn(pbp_device_block, tap_param); - - return count; -} - -int -set_disc_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_disc_pwup_fn(pbp_device_block, tap_param); - - return count; -} - -int -get_bypass_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_pwup_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_pwoff_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_tap_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_pwup_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_disc_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_disc_pwup_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -set_std_nic_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_std_nic_fn(pbp_device_block, bypass_param); - - return count; -} - -int -get_std_nic_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_std_nic_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_exp_mode_fn(pbp_device_block); - if (ret == 1) - len = sprintf(page, "tap\n"); - else if (ret == 0) - len = sprintf(page, "bypass\n"); - else if (ret == 2) - len = sprintf(page, "disc\n"); - - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -set_wd_exp_mode_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "tap") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "bypass") == 0) - bypass_param = 0; - else if (strcmp(kbuf, "disc") == 0) - bypass_param = 2; - - set_wd_exp_mode_fn(pbp_device_block, bypass_param); - - return count; -} - -int -get_wd_autoreset_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_autoreset_fn(pbp_device_block); - if (ret >= 0) - len = sprintf(page, "%d\n", ret); - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -int -set_wd_autoreset_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - u32 timeout = 0; - char *timeout_ptr = kbuf; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - timeout_ptr = kbuf; - timeout = atoi(&timeout_ptr); - - set_wd_autoreset_fn(pbp_device_block, timeout); - - return count; -} - -int -set_tpl_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_tpl_fn(pbp_device_block, tpl_param); - - return count; -} - -#ifdef PMC_FIX_FLAG -int -set_wait_at_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param); - - return count; -} - -int -set_hw_reset_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) - return -1; - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_bp_hw_reset_fn(pbp_device_block, tpl_param); - - return count; -} - -#endif /*PMC_FIX_FLAG */ - -int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) -{ - struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); - static struct proc_dir_entry *procfs_dir; - int ret = 0; - - sprintf(current_pfs->dir_name, "bypass_%s", dev->name); - - if (!bp_procfs_dir) - return -1; - - /* create device proc dir */ - procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir); - if (procfs_dir == 0) { - printk(KERN_DEBUG "Could not create procfs directory %s\n", - current_pfs->dir_name); - return -1; - } - current_pfs->bypass_entry = procfs_dir; - - if (bypass_proc_create_entry(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL, /* write */ - get_bypass_info_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (pbp_device_block->bp_caps & SW_CTL_CAP) { - - /* Create set param proc's */ - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL, /* write */ - get_bypass_slave_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL, /* write */ - get_bypass_caps_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL, /* write */ - get_wd_set_caps_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs, /* write */ - get_bypass_wd_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL, /* write */ - get_wd_expire_time_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL, /* write */ - reset_bypass_wd_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs, /* write */ - get_std_nic_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (pbp_device_block->bp_caps & BP_CAP) { - if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs, /* write */ - get_bypass_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs, /* write */ - get_dis_bypass_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */ - get_bypass_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs, /* write */ - get_bypass_pwoff_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL, /* write */ - get_bypass_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - } - - if (pbp_device_block->bp_caps & TAP_CAP) { - - if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */ - get_tap_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs, /* write */ - get_dis_tap_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs, /* write */ - get_tap_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL, /* write */ - get_tap_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - } - if (pbp_device_block->bp_caps & DISC_CAP) { - - if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs, /* write */ - get_disc_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; -#if 1 - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs, /* write */ - get_dis_disc_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; -#endif - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs, /* write */ - get_disc_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */ - get_disc_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - } - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */ - get_wd_exp_mode_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs, /* write */ - get_wd_autoreset_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */ - get_tpl_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; -#ifdef PMC_FIX_FLAG - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs, /* write */ - get_wait_at_pwup_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs, /* write */ - get_hw_reset_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - -#endif - - } - if (ret < 0) - printk(KERN_DEBUG "Create proc entry failed\n"); - - return ret; -} - -int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block) -{ - - struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; - struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr = - NULL; - char name[256]; - - for (pde = pde->subdir; pde;) { - strcpy(name, pde->name); - pde_curr = pde; - pde = pde->next; - remove_proc_entry(name, current_pfs->bypass_entry); - } - if (!pde) - remove_proc_entry(current_pfs->dir_name, bp_procfs_dir); - - return 0; -} - -#endif /* BYPASS_SUPPORT */ diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bpctl_mod.c index 45a22272320..b7e570ccb75 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bpctl_mod.c @@ -35,7 +35,6 @@ #define BP_MOD_DESCR "Silicom Bypass-SD Control driver" #define BP_SYNC_FLAG 1 -static int Device_Open = 0; static int major_num = 0; MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il"); @@ -60,35 +59,9 @@ typedef enum { bp_none, } bp_media_type; -struct pfs_unit_sd { - struct proc_dir_entry *proc_entry; - char proc_name[32]; -}; - struct bypass_pfs_sd { char dir_name[32]; struct proc_dir_entry *bypass_entry; - struct pfs_unit_sd bypass_info; - struct pfs_unit_sd bypass_slave; - struct pfs_unit_sd bypass_caps; - struct pfs_unit_sd wd_set_caps; - struct pfs_unit_sd bypass; - struct pfs_unit_sd bypass_change; - struct pfs_unit_sd bypass_wd; - struct pfs_unit_sd wd_expire_time; - struct pfs_unit_sd reset_bypass_wd; - struct pfs_unit_sd dis_bypass; - struct pfs_unit_sd bypass_pwup; - struct pfs_unit_sd bypass_pwoff; - struct pfs_unit_sd std_nic; - struct pfs_unit_sd tap; - struct pfs_unit_sd dis_tap; - struct pfs_unit_sd tap_pwup; - struct pfs_unit_sd tap_change; - struct pfs_unit_sd wd_exp_mode; - struct pfs_unit_sd wd_autoreset; - struct pfs_unit_sd tpl; - }; typedef struct _bpctl_dev { @@ -315,27 +288,6 @@ static struct notifier_block bp_notifier_block = { .notifier_call = bp_device_event, }; -static int device_open(struct inode *inode, struct file *file) -{ -#ifdef DEBUG - printk("device_open(%p)\n", file); -#endif - Device_Open++; -/* -* Initialize the message -*/ - return SUCCESS; -} - -static int device_release(struct inode *inode, struct file *file) -{ -#ifdef DEBUG - printk("device_release(%p,%p)\n", inode, file); -#endif - Device_Open--; - return SUCCESS; -} - int is_bypass_fn(bpctl_dev_t *pbpctl_dev); int wdt_time_left(bpctl_dev_t *pbpctl_dev); @@ -1728,62 +1680,33 @@ int gpio6_clear_fn(bpctl_dev_t *pbpctl_dev) } #endif /*BYPASS_DEBUG */ -static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) +static bpctl_dev_t *lookup_port(bpctl_dev_t *dev) { - int idx_dev = 0; - - if (pbpctl_dev == NULL) - return NULL; - - if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) { - for (idx_dev = 0; - ((bpctl_dev_arr[idx_dev].pdev != NULL) - && (idx_dev < device_num)); idx_dev++) { - if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) - && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) - && ((bpctl_dev_arr[idx_dev].func == 1) - && (pbpctl_dev->func == 0))) { - - return &(bpctl_dev_arr[idx_dev]); - } - if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && - (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && - ((bpctl_dev_arr[idx_dev].func == 3) - && (pbpctl_dev->func == 2))) { + bpctl_dev_t *p; + int n; + for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) { + if (p->bus == dev->bus + && p->slot == dev->slot + && p->func == (dev->func ^ 1)) + return p; + } + return NULL; +} - return &(bpctl_dev_arr[idx_dev]); - } - } +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) +{ + if (pbpctl_dev) { + if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2) + return lookup_port(pbpctl_dev); } return NULL; } static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) { - int idx_dev = 0; - - if (pbpctl_dev == NULL) - return NULL; - - if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) { - for (idx_dev = 0; - ((bpctl_dev_arr[idx_dev].pdev != NULL) - && (idx_dev < device_num)); idx_dev++) { - if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) - && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) - && ((bpctl_dev_arr[idx_dev].func == 0) - && (pbpctl_dev->func == 1))) { - - return &(bpctl_dev_arr[idx_dev]); - } - if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && - (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && - ((bpctl_dev_arr[idx_dev].func == 2) - && (pbpctl_dev->func == 3))) { - - return &(bpctl_dev_arr[idx_dev]); - } - } + if (pbpctl_dev) { + if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3) + return lookup_port(pbpctl_dev); } return NULL; } @@ -5858,11 +5781,9 @@ static long device_ioctl(struct file *file, /* see include/linux/fs.h */ return ret; } -struct file_operations Fops = { +static const struct file_operations Fops = { .owner = THIS_MODULE, .unlocked_ioctl = device_ioctl, - .open = device_open, - .release = device_release, /* a.k.a. close */ }; #ifndef PCI_DEVICE @@ -6686,6 +6607,118 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0,} }; +static void find_fw(bpctl_dev_t *dev) +{ + unsigned long mmio_start, mmio_len; + struct pci_dev *pdev1 = dev->pdev; + + if ((OLD_IF_SERIES(dev->subdevice)) || + (INTEL_IF_SERIES(dev->subdevice))) + dev->bp_fw_ver = 0xff; + else + dev->bp_fw_ver = bypass_fw_ver(dev); + + if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) { + int cnt = 100; + while (cnt--) { + iounmap((void *)dev->mem_map); + mmio_start = pci_resource_start(pdev1, 0); + mmio_len = pci_resource_len(pdev1, 0); + + dev->mem_map = (unsigned long) + ioremap(mmio_start, mmio_len); + + dev->bp_fw_ver = bypass_fw_ver(dev); + if (dev-> bp_fw_ver == 0xa8) + break; + } + } + /* dev->bp_fw_ver=0xa8; */ + printk("firmware version: 0x%x\n", dev->bp_fw_ver); +} + +static int init_one(bpctl_dev_t *dev, bpmod_info_t *info, struct pci_dev *pdev1) +{ + unsigned long mmio_start, mmio_len; + + dev->pdev = pdev1; + mmio_start = pci_resource_start(pdev1, 0); + mmio_len = pci_resource_len(pdev1, 0); + + dev->desc = dev_desc[info->index].name; + dev->name = info->bp_name; + dev->device = info->device; + dev->vendor = info->vendor; + dev->subdevice = info->subdevice; + dev->subvendor = info->subvendor; + dev->func = PCI_FUNC(pdev1->devfn); + dev->slot = PCI_SLOT(pdev1->devfn); + dev->bus = pdev1->bus->number; + dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len); +#ifdef BP_SYNC_FLAG + spin_lock_init(&dev->bypass_wr_lock); +#endif + if (BP10G9_IF_SERIES(dev->subdevice)) + dev->bp_10g9 = 1; + if (BP10G_IF_SERIES(dev->subdevice)) + dev->bp_10g = 1; + if (PEG540_IF_SERIES(dev->subdevice)) + dev->bp_540 = 1; + if (PEGF5_IF_SERIES(dev->subdevice)) + dev->bp_fiber5 = 1; + if (PEG80_IF_SERIES(dev->subdevice)) + dev->bp_i80 = 1; + if (PEGF80_IF_SERIES(dev->subdevice)) + dev->bp_i80 = 1; + if ((dev->subdevice & 0xa00) == 0xa00) + dev->bp_i80 = 1; + if (BP10GB_IF_SERIES(dev->subdevice)) { + if (dev->ifindex == 0) { + unregister_chrdev(major_num, DEVICE_NAME); + printk("Please load network driver for %s adapter!\n", + dev->name); + return -1; + } + + if (dev->ndev && !(dev->ndev->flags & IFF_UP)) { + unregister_chrdev(major_num, DEVICE_NAME); + printk("Please bring up network interfaces for %s adapter!\n", + dev->name); + return -1; + } + dev->bp_10gb = 1; + } + + if (!dev->bp_10g9) { + if (is_bypass_fn(dev)) { + printk(KERN_INFO "%s found, ", + dev->name); + find_fw(dev); + } + dev->wdt_status = WDT_STATUS_UNKNOWN; + dev->reset_time = 0; + atomic_set(&dev->wdt_busy, 0); + dev->bp_status_un = 1; + + bypass_caps_init(dev); + + init_bypass_wd_auto(dev); + init_bypass_tpl_auto(dev); + if (NOKIA_SERIES(dev->subdevice)) + reset_cont(dev); + } +#ifdef BP_SELF_TEST + if ((dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL))) { + memset(dev->bp_tx_data, 0xff, 6); + memset(dev->bp_tx_data + 6, 0x0, 1); + memset(dev->bp_tx_data + 7, 0xaa, 5); + *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST); + } else + printk("bp_ctl: Memory allocation error!\n"); +#endif + return 0; +} + /* * Initialize the module - Register the character device */ @@ -6694,7 +6727,7 @@ static int __init bypass_init_module(void) { int ret_val, idx, idx_dev = 0; struct pci_dev *pdev1 = NULL; - unsigned long mmio_start, mmio_len; + bpctl_dev_t *dev; printk(BP_MOD_DESCR " v" BP_MOD_VER "\n"); ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops); @@ -6729,181 +6762,16 @@ static int __init bypass_init_module(void) memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t))); pdev1 = NULL; + dev = bpctl_dev_arr; for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, tx_ctl_pci_tbl[idx].device, tx_ctl_pci_tbl[idx].subvendor, tx_ctl_pci_tbl[idx].subdevice, pdev1))) { - bpctl_dev_arr[idx_dev].pdev = pdev1; - - mmio_start = pci_resource_start(pdev1, 0); - mmio_len = pci_resource_len(pdev1, 0); - - bpctl_dev_arr[idx_dev].desc = - dev_desc[tx_ctl_pci_tbl[idx].index].name; - bpctl_dev_arr[idx_dev].name = - tx_ctl_pci_tbl[idx].bp_name; - bpctl_dev_arr[idx_dev].device = - tx_ctl_pci_tbl[idx].device; - bpctl_dev_arr[idx_dev].vendor = - tx_ctl_pci_tbl[idx].vendor; - bpctl_dev_arr[idx_dev].subdevice = - tx_ctl_pci_tbl[idx].subdevice; - bpctl_dev_arr[idx_dev].subvendor = - tx_ctl_pci_tbl[idx].subvendor; - /* bpctl_dev_arr[idx_dev].pdev=pdev1; */ - bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn); - bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn); - bpctl_dev_arr[idx_dev].bus = pdev1->bus->number; - bpctl_dev_arr[idx_dev].mem_map = - (unsigned long)ioremap(mmio_start, mmio_len); -#ifdef BP_SYNC_FLAG - spin_lock_init(&bpctl_dev_arr[idx_dev].bypass_wr_lock); -#endif - if (BP10G9_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - bpctl_dev_arr[idx_dev].bp_10g9 = 1; - if (BP10G_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - bpctl_dev_arr[idx_dev].bp_10g = 1; - if (PEG540_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) { - - bpctl_dev_arr[idx_dev].bp_540 = 1; - } - if (PEGF5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - bpctl_dev_arr[idx_dev].bp_fiber5 = 1; - if (PEG80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - bpctl_dev_arr[idx_dev].bp_i80 = 1; - if (PEGF80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - bpctl_dev_arr[idx_dev].bp_i80 = 1; - if ((bpctl_dev_arr[idx_dev].subdevice & 0xa00) == 0xa00) - bpctl_dev_arr[idx_dev].bp_i80 = 1; - if (BP10GB_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) { - if (bpctl_dev_arr[idx_dev].ifindex == 0) { - unregister_chrdev(major_num, - DEVICE_NAME); - printk - ("Please load network driver for %s adapter!\n", - bpctl_dev_arr[idx_dev].name); - return -1; - } - - if (bpctl_dev_arr[idx_dev].ndev) { - if (! - (bpctl_dev_arr[idx_dev].ndev-> - flags & IFF_UP)) { - if (! - (bpctl_dev_arr[idx_dev]. - ndev->flags & IFF_UP)) { - unregister_chrdev - (major_num, - DEVICE_NAME); - printk - ("Please bring up network interfaces for %s adapter!\n", - bpctl_dev_arr - [idx_dev].name); - return -1; - } - - } - } - bpctl_dev_arr[idx_dev].bp_10gb = 1; - } - - if (!bpctl_dev_arr[idx_dev].bp_10g9) { - - if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { - printk(KERN_INFO "%s found, ", - bpctl_dev_arr[idx_dev].name); - if ((OLD_IF_SERIES - (bpctl_dev_arr[idx_dev].subdevice)) - || - (INTEL_IF_SERIES - (bpctl_dev_arr[idx_dev]. - subdevice))) - bpctl_dev_arr[idx_dev]. - bp_fw_ver = 0xff; - else - bpctl_dev_arr[idx_dev]. - bp_fw_ver = - bypass_fw_ver(&bpctl_dev_arr - [idx_dev]); - if ((bpctl_dev_arr[idx_dev].bp_10gb == - 1) - && (bpctl_dev_arr[idx_dev]. - bp_fw_ver == 0xff)) { - int cnt = 100; - while (cnt--) { - iounmap((void - *) - (bpctl_dev_arr - [idx_dev]. - mem_map)); - mmio_start = - pci_resource_start - (pdev1, 0); - mmio_len = - pci_resource_len - (pdev1, 0); - - bpctl_dev_arr[idx_dev]. - mem_map = - (unsigned long) - ioremap(mmio_start, - mmio_len); - - bpctl_dev_arr[idx_dev]. - bp_fw_ver = - bypass_fw_ver - (&bpctl_dev_arr - [idx_dev]); - if (bpctl_dev_arr - [idx_dev]. - bp_fw_ver == 0xa8) - break; - - } - } - /* bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; */ - printk("firmware version: 0x%x\n", - bpctl_dev_arr[idx_dev]. - bp_fw_ver); - } - bpctl_dev_arr[idx_dev].wdt_status = - WDT_STATUS_UNKNOWN; - bpctl_dev_arr[idx_dev].reset_time = 0; - atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0); - bpctl_dev_arr[idx_dev].bp_status_un = 1; - - bypass_caps_init(&bpctl_dev_arr[idx_dev]); - - init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); - init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); - if (NOKIA_SERIES - (bpctl_dev_arr[idx_dev].subdevice)) - reset_cont(&bpctl_dev_arr[idx_dev]); - } -#ifdef BP_SELF_TEST - if ((bpctl_dev_arr[idx_dev].bp_tx_data = - kmalloc(BPTEST_DATA_LEN, GFP_KERNEL))) { - - memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0x0, - BPTEST_DATA_LEN); - - memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0xff, - 6); - memset(bpctl_dev_arr[idx_dev].bp_tx_data + 6, - 0x0, 1); - memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7, - 0xaa, 5); - - *(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data + - 12) = htons(ETH_P_BPTEST); - - } else - printk("bp_ctl: Memory allocation error!\n"); -#endif - idx_dev++; - + if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0) + return -1; + dev++; } } if_scan_init(); @@ -6913,33 +6781,27 @@ static int __init bypass_init_module(void) { bpctl_dev_t *pbpctl_dev_c = NULL; - for (idx_dev = 0; - ((bpctl_dev_arr[idx_dev].pdev != NULL) - && (idx_dev < device_num)); idx_dev++) { - if (bpctl_dev_arr[idx_dev].bp_10g9) { - pbpctl_dev_c = - get_status_port_fn(&bpctl_dev_arr[idx_dev]); - if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { + for (idx_dev = 0, dev = bpctl_dev_arr; + idx_dev < device_num && dev->pdev; + idx_dev++, dev++) { + if (dev->bp_10g9) { + pbpctl_dev_c = get_status_port_fn(dev); + if (is_bypass_fn(dev)) { printk(KERN_INFO "%s found, ", - bpctl_dev_arr[idx_dev].name); - bpctl_dev_arr[idx_dev].bp_fw_ver = - bypass_fw_ver(&bpctl_dev_arr - [idx_dev]); + dev->name); + dev->bp_fw_ver = bypass_fw_ver(dev); printk("firmware version: 0x%x\n", - bpctl_dev_arr[idx_dev]. - bp_fw_ver); - + dev->bp_fw_ver); } - bpctl_dev_arr[idx_dev].wdt_status = - WDT_STATUS_UNKNOWN; - bpctl_dev_arr[idx_dev].reset_time = 0; - atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0); - bpctl_dev_arr[idx_dev].bp_status_un = 1; + dev->wdt_status = WDT_STATUS_UNKNOWN; + dev->reset_time = 0; + atomic_set(&dev->wdt_busy, 0); + dev->bp_status_un = 1; - bypass_caps_init(&bpctl_dev_arr[idx_dev]); + bypass_caps_init(dev); - init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); - init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + init_bypass_wd_auto(dev); + init_bypass_tpl_auto(dev); } @@ -7336,78 +7198,11 @@ EXPORT_SYMBOL_NOVERS(bp_if_scan_sd); #define BP_PROC_DIR "bypass" -#define GPIO6_SET_ENTRY_SD "gpio6_set" -#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" - -#define GPIO7_SET_ENTRY_SD "gpio7_set" -#define GPIO7_CLEAR_ENTRY_SD "gpio7_clear" - -#define PULSE_SET_ENTRY_SD "pulse_set" -#define ZERO_SET_ENTRY_SD "zero_set" -#define PULSE_GET1_ENTRY_SD "pulse_get1" -#define PULSE_GET2_ENTRY_SD "pulse_get2" - -#define CMND_ON_ENTRY_SD "cmnd_on" -#define CMND_OFF_ENTRY_SD "cmnd_off" -#define RESET_CONT_ENTRY_SD "reset_cont" - - /*COMMANDS*/ -#define BYPASS_INFO_ENTRY_SD "bypass_info" -#define BYPASS_SLAVE_ENTRY_SD "bypass_slave" -#define BYPASS_CAPS_ENTRY_SD "bypass_caps" -#define WD_SET_CAPS_ENTRY_SD "wd_set_caps" -#define BYPASS_ENTRY_SD "bypass" -#define BYPASS_CHANGE_ENTRY_SD "bypass_change" -#define BYPASS_WD_ENTRY_SD "bypass_wd" -#define WD_EXPIRE_TIME_ENTRY_SD "wd_expire_time" -#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd" -#define DIS_BYPASS_ENTRY_SD "dis_bypass" -#define BYPASS_PWUP_ENTRY_SD "bypass_pwup" -#define BYPASS_PWOFF_ENTRY_SD "bypass_pwoff" -#define STD_NIC_ENTRY_SD "std_nic" -#define STD_NIC_ENTRY_SD "std_nic" -#define TAP_ENTRY_SD "tap" -#define TAP_CHANGE_ENTRY_SD "tap_change" -#define DIS_TAP_ENTRY_SD "dis_tap" -#define TAP_PWUP_ENTRY_SD "tap_pwup" -#define TWO_PORT_LINK_ENTRY_SD "two_port_link" -#define WD_EXP_MODE_ENTRY_SD "wd_exp_mode" -#define WD_AUTORESET_ENTRY_SD "wd_autoreset" -#define TPL_ENTRY_SD "tpl" -#define WAIT_AT_PWUP_ENTRY_SD "wait_at_pwup" -#define HW_RESET_ENTRY_SD "hw_reset" -#define DISC_ENTRY_SD "disc" -#define DISC_CHANGE_ENTRY_SD "disc_change" -#define DIS_DISC_ENTRY_SD "dis_disc" -#define DISC_PWUP_ENTRY_SD "disc_pwup" static struct proc_dir_entry *bp_procfs_dir; -static struct proc_dir_entry *proc_getdir(char *name, - struct proc_dir_entry *proc_dir) -{ - struct proc_dir_entry *pde = proc_dir; - - for (pde = pde->subdir; pde; pde = pde->next) { - if (pde->namelen && (strcmp(name, pde->name) == 0)) { - /* directory exists */ - break; - } - } - if (pde == (struct proc_dir_entry *)0) { - /* create the directory */ - pde = proc_mkdir(name, proc_dir); - if (pde == (struct proc_dir_entry *)0) { - - return pde; - } - } - - return pde; -} - int bp_proc_create(void) { - bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net); + bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net); if (bp_procfs_dir == (struct proc_dir_entry *)0) { printk(KERN_DEBUG "Could not create procfs nicinfo directory %s\n", @@ -7417,144 +7212,99 @@ int bp_proc_create(void) return 0; } -int -bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr, - char *proc_name, - write_proc_t *write_proc, - read_proc_t *read_proc, - struct proc_dir_entry *parent_pfs, void *data) +static int procfs_add(char *proc_name, const struct file_operations *fops, + bpctl_dev_t *dev) { - strcpy(pfs_unit_curr->proc_name, proc_name); - pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, - S_IFREG | S_IRUSR | - S_IWUSR | S_IRGRP | - S_IROTH, parent_pfs); - if (pfs_unit_curr->proc_entry == NULL) + struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set; + if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev)) return -1; - - pfs_unit_curr->proc_entry->read_proc = read_proc; - pfs_unit_curr->proc_entry->write_proc = write_proc; - pfs_unit_curr->proc_entry->data = data; - return 0; - } -int -get_bypass_info_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - int len = 0; - - len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name); - len += - sprintf(page + len, "Firmware version\t0x%x\n", - pbp_device_block->bp_fw_ver); +#define RO_FOPS(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, show_##name, PDE_DATA(inode));\ +} \ +static const struct file_operations name##_ops = { \ + .open = name##_open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +}; - *eof = 1; - return len; -} +#define RW_FOPS(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, show_##name, PDE_DATA(inode));\ +} \ +static const struct file_operations name##_ops = { \ + .open = name##_open, \ + .read = seq_read, \ + .write = name##_write, \ + .llseek = seq_lseek, \ + .release = single_release, \ +}; -int -get_bypass_slave_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_bypass_info(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + bpctl_dev_t *dev = m->private; - int len = 0; - bpctl_dev_t *pbp_device_block_slave = NULL; - int idx_dev = 0; - struct net_device *net_slave_dev = NULL; - - if ((pbp_device_block->func == 0) || (pbp_device_block->func == 2)) { - for (idx_dev = 0; - ((bpctl_dev_arr[idx_dev].pdev != NULL) - && (idx_dev < device_num)); idx_dev++) { - if ((bpctl_dev_arr[idx_dev].bus == - pbp_device_block->bus) - && (bpctl_dev_arr[idx_dev].slot == - pbp_device_block->slot)) { - if ((pbp_device_block->func == 0) - && (bpctl_dev_arr[idx_dev].func == 1)) { - pbp_device_block_slave = - &bpctl_dev_arr[idx_dev]; - break; - } - if ((pbp_device_block->func == 2) && - (bpctl_dev_arr[idx_dev].func == 3)) { - pbp_device_block_slave = - &bpctl_dev_arr[idx_dev]; - break; - } - } - } - } else - pbp_device_block_slave = pbp_device_block; - if (!pbp_device_block_slave) { - len = sprintf(page, "fail\n"); - *eof = 1; - return len; - } - net_slave_dev = pbp_device_block_slave->ndev; - if (net_slave_dev) - len = sprintf(page, "%s\n", net_slave_dev->name); - - *eof = 1; - return len; + seq_printf(m, "Name\t\t\t%s\n", dev->name); + seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver); + return 0; } +RO_FOPS(bypass_info) -int -get_bypass_caps_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_bypass_slave(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; + bpctl_dev_t *dev = m->private; + bpctl_dev_t *slave = get_status_port_fn(dev); + if (!slave) + slave = dev; + if (!slave) + seq_printf(m, "fail\n"); + else if (slave->ndev) + seq_printf(m, "%s\n", slave->ndev->name); + return 0; +} +RO_FOPS(bypass_slave) - ret = get_bypass_caps_fn(pbp_device_block); +static int show_bypass_caps(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_caps_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "-1\n"); + seq_printf(m, "-1\n"); else - len = sprintf(page, "0x%x\n", ret); - *eof = 1; - return len; - + seq_printf(m, "0x%x\n", ret); + return 0; } +RO_FOPS(bypass_caps) -int -get_wd_set_caps_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_wd_set_caps(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_set_caps_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_wd_set_caps_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "-1\n"); + seq_printf(m, "-1\n"); else - len = sprintf(page, "0x%x\n", ret); - *eof = 1; - return len; + seq_printf(m, "0x%x\n", ret); + return 0; } +RO_FOPS(wd_set_caps) -int -set_bypass_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static int user_on_off(const void __user *buffer, size_t count) { char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; + int length = 0; if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -7562,806 +7312,467 @@ set_bypass_pfs(struct file *file, const char *buffer, kbuf[--length] = '\0'; if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_fn(pbp_device_block, bypass_param); - - return count; + return 1; + if (strcmp(kbuf, "off") == 0) + return 0; + return 0; } -int -set_tap_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t bypass_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) return -1; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_tap_fn(pbp_device_block, tap_param); - + set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -set_disc_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static int show_bypass(struct seq_file *m, void *v) { + bpctl_dev_t *dev = m->private; + int ret = get_bypass_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(bypass) - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) { +static ssize_t tap_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_disc_fn(pbp_device_block, tap_param); + set_tap_fn(PDE_DATA(file_inode(file)), tap_param); return count; } - -int -get_bypass_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_tap(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_tap_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; + seq_printf(m, "off\n"); + return 0; } +RW_FOPS(tap) -int -get_tap_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t disc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 1) - len = sprintf(page, "on\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -1; - *eof = 1; - return len; + set_disc_fn(PDE_DATA(file_inode(file)), tap_param); + return count; } - -int -get_disc_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_disc(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_disc_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_disc_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; + seq_printf(m, "off\n"); + return 0; } +RW_FOPS(disc) -int -get_bypass_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_bypass_change(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_change_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_bypass_change_fn(dev); if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; + seq_printf(m, "fail\n"); + return 0; } +RO_FOPS(bypass_change) -int -get_tap_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_tap_change(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_change_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_tap_change_fn(dev); if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; + seq_printf(m, "fail\n"); + return 0; } +RO_FOPS(tap_change) -int -get_disc_change_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_disc_change(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_disc_change_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_disc_change_fn(dev); if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; -} - -#define isdigit(c) (c >= '0' && c <= '9') -__inline static int atoi(char **s) -{ - int i = 0; - while (isdigit(**s)) - i = i * 10 + *((*s)++) - '0'; - return i; + seq_printf(m, "fail\n"); + return 0; } +RO_FOPS(disc_change) -int -set_bypass_wd_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t bypass_wd_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); int timeout; - int ret; - - ret = kstrtoint_from_user(buffer, count, 10, &timeout); + int ret = kstrtoint_from_user(buffer, count, 10, &timeout); if (ret) return ret; - set_bypass_wd_fn(pbp_device_block, timeout); - + set_bypass_wd_fn(dev, timeout); return count; } - -int -get_bypass_wd_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_bypass_wd(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + bpctl_dev_t *dev = m->private; + int ret = 0, timeout = 0; - int len = 0, ret = 0, timeout = 0; - - ret = get_bypass_wd_fn(pbp_device_block, &timeout); + ret = get_bypass_wd_fn(dev, &timeout); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (timeout == -1) - len = sprintf(page, "unknown\n"); + seq_printf(m, "unknown\n"); else if (timeout == 0) - len = sprintf(page, "disable\n"); + seq_printf(m, "disable\n"); else - len = sprintf(page, "%d\n", timeout); - - *eof = 1; - return len; + seq_printf(m, "%d\n", timeout); + return 0; } +RW_FOPS(bypass_wd) -int -get_wd_expire_time_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_wd_expire_time(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0, timeout = 0; - - ret = get_wd_expire_time_fn(pbp_device_block, &timeout); + bpctl_dev_t *dev = m->private; + int ret = 0, timeout = 0; + ret = get_wd_expire_time_fn(dev, &timeout); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (timeout == -1) - len = sprintf(page, "expire\n"); + seq_printf(m, "expire\n"); else if (timeout == 0) - len = sprintf(page, "disable\n"); - + seq_printf(m, "disable\n"); else - len = sprintf(page, "%d\n", timeout); - *eof = 1; - return len; + seq_printf(m, "%d\n", timeout); + return 0; } +RO_FOPS(wd_expire_time) -int -get_tpl_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t tpl_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; - ret = get_tpl_fn(pbp_device_block); + set_tpl_fn(dev, tpl_param); + return count; +} +static int show_tpl(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_tpl_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; + seq_printf(m, "off\n"); + return 0; } +RW_FOPS(tpl) #ifdef PMC_FIX_FLAG -int -get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; - ret = get_bp_wait_at_pwup_fn(pbp_device_block); + set_bp_wait_at_pwup_fn(dev, tpl_param); + return count; +} +static int show_wait_at_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bp_wait_at_pwup_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; + seq_printf(m, "off\n"); + return 0; } +RW_FOPS(wait_at_pwup) -int -get_hw_reset_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t hw_reset_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; - ret = get_bp_hw_reset_fn(pbp_device_block); + set_bp_hw_reset_fn(dev, tpl_param); + return count; +} +static int show_hw_reset(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bp_hw_reset_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 1) - len = sprintf(page, "on\n"); + seq_printf(m, "on\n"); else if (ret == 0) - len = sprintf(page, "off\n"); - - *eof = 1; - return len; + seq_printf(m, "off\n"); + return 0; } +RW_FOPS(hw_reset) #endif /*PMC_WAIT_FLAG */ -int -reset_bypass_wd_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_reset_bypass_wd(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = reset_bypass_wd_timer_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = reset_bypass_wd_timer_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "disable\n"); + seq_printf(m, "disable\n"); else if (ret == 1) - len = sprintf(page, "success\n"); - - *eof = 1; - return len; + seq_printf(m, "success\n"); + return 0; } +RO_FOPS(reset_bypass_wd) -int -set_dis_bypass_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t dis_bypass_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count >= sizeof(kbuf)) + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) return -EINVAL; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_dis_bypass_fn(pbp_device_block, bypass_param); - + set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -set_dis_tap_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static int show_dis_bypass(struct seq_file *m, void *v) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count >= sizeof(kbuf)) - return -EINVAL; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_dis_tap_fn(pbp_device_block, tap_param); - - return count; + bpctl_dev_t *dev = m->private; + int ret = get_dis_bypass_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(dis_bypass) -int -set_dis_disc_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t dis_tap_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count >= sizeof(kbuf)) + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) return -EINVAL; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_dis_disc_fn(pbp_device_block, tap_param); - + set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param); return count; } - -int -get_dis_bypass_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_dis_tap(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_bypass_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_dis_tap_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(dis_tap) -int -get_dis_tap_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t dis_disc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_tap_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; - *eof = 1; - return len; + set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param); + return count; } - -int -get_dis_disc_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_dis_disc(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_dis_disc_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_dis_disc_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -set_bypass_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count >= sizeof(kbuf)) - return -EINVAL; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_pwup_fn(pbp_device_block, bypass_param); - - return count; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(dis_disc) -int -set_bypass_pwoff_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count >= sizeof(kbuf)) + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) return -EINVAL; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_bypass_pwoff_fn(pbp_device_block, bypass_param); - + set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -set_tap_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static int show_bypass_pwup(struct seq_file *m, void *v) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count >= sizeof(kbuf)) - return -EINVAL; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_tap_pwup_fn(pbp_device_block, tap_param); - - return count; + bpctl_dev_t *dev = m->private; + int ret = get_bypass_pwup_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(bypass_pwup) -int -set_disc_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tap_param = 0, length = 0; - - if (count >= sizeof(kbuf)) + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) return -EINVAL; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tap_param = 1; - else if (strcmp(kbuf, "off") == 0) - tap_param = 0; - - set_disc_pwup_fn(pbp_device_block, tap_param); - + set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -get_bypass_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_bypass_pwoff(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_pwup_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_bypass_pwoff_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(bypass_pwoff) -int -get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t tap_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_bypass_pwoff_fn(pbp_device_block); - if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); - else if (ret == 0) - len = sprintf(page, "off\n"); - else - len = sprintf(page, "on\n"); + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; - *eof = 1; - return len; + set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param); + return count; } - -int -get_tap_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_tap_pwup(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_tap_pwup_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_tap_pwup_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(tap_pwup) -int -get_disc_pwup_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static ssize_t disc_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; - ret = get_disc_pwup_fn(pbp_device_block); + set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_disc_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_disc_pwup_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(disc_pwup) -int -set_std_nic_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t std_nic_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int bypass_param = 0, length = 0; - - if (count >= sizeof(kbuf)) + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) return -EINVAL; - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - bypass_param = 1; - else if (strcmp(kbuf, "off") == 0) - bypass_param = 0; - - set_std_nic_fn(pbp_device_block, bypass_param); - + set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -get_std_nic_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_std_nic(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_std_nic_fn(pbp_device_block); + bpctl_dev_t *dev = m->private; + int ret = get_std_nic_fn(dev); if (ret == BP_NOT_CAP) - len = sprintf(page, "fail\n"); + seq_printf(m, "fail\n"); else if (ret == 0) - len = sprintf(page, "off\n"); + seq_printf(m, "off\n"); else - len = sprintf(page, "on\n"); - - *eof = 1; - return len; -} - -int -get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_exp_mode_fn(pbp_device_block); - if (ret == 1) - len = sprintf(page, "tap\n"); - else if (ret == 0) - len = sprintf(page, "bypass\n"); - else if (ret == 2) - len = sprintf(page, "disc\n"); - - else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; + seq_printf(m, "on\n"); + return 0; } +RW_FOPS(std_nic) -int -set_wd_exp_mode_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - int bypass_param = 0, length = 0; if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -8375,143 +7786,47 @@ set_wd_exp_mode_pfs(struct file *file, const char *buffer, else if (strcmp(kbuf, "disc") == 0) bypass_param = 2; - set_wd_exp_mode_fn(pbp_device_block, bypass_param); + set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param); return count; } - -int -get_wd_autoreset_pfs(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int show_wd_exp_mode(struct seq_file *m, void *v) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int len = 0, ret = 0; - - ret = get_wd_autoreset_fn(pbp_device_block); - if (ret >= 0) - len = sprintf(page, "%d\n", ret); + bpctl_dev_t *dev = m->private; + int ret = get_wd_exp_mode_fn(dev); + if (ret == 1) + seq_printf(m, "tap\n"); + else if (ret == 0) + seq_printf(m, "bypass\n"); + else if (ret == 2) + seq_printf(m, "disc\n"); else - len = sprintf(page, "fail\n"); - - *eof = 1; - return len; + seq_printf(m, "fail\n"); + return 0; } +RW_FOPS(wd_exp_mode) -int -set_wd_autoreset_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; int timeout; - int ret; - - ret = kstrtoint_from_user(buffer, count, 10, &timeout); + int ret = kstrtoint_from_user(buffer, count, 10, &timeout); if (ret) return ret; - set_wd_autoreset_fn(pbp_device_block, timeout); - - return count; -} - -int -set_tpl_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_tpl_fn(pbp_device_block, tpl_param); - + set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout); return count; } - -#ifdef PMC_FIX_FLAG -int -set_wait_at_pwup_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param); - - return count; -} - -int -set_hw_reset_pfs(struct file *file, const char *buffer, - unsigned long count, void *data) +static int show_wd_autoreset(struct seq_file *m, void *v) { - - char kbuf[256]; - bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - - int tpl_param = 0, length = 0; - - if (count > (sizeof(kbuf) - 1)) - return -1; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - kbuf[count] = '\0'; - length = strlen(kbuf); - if (kbuf[length - 1] == '\n') - kbuf[--length] = '\0'; - - if (strcmp(kbuf, "on") == 0) - tpl_param = 1; - else if (strcmp(kbuf, "off") == 0) - tpl_param = 0; - - set_bp_hw_reset_fn(pbp_device_block, tpl_param); - - return count; + bpctl_dev_t *dev = m->private; + int ret = get_wd_autoreset_fn(dev); + if (ret >= 0) + seq_printf(m, "%d\n", ret); + else + seq_printf(m, "fail\n"); + return 0; } - -#endif /*PMC_FIX_FLAG */ +RW_FOPS(wd_autoreset) int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) { @@ -8528,168 +7843,54 @@ int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) return -1; /* create device proc dir */ - procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir); - if (procfs_dir == 0) { + procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir); + if (!procfs_dir) { printk(KERN_DEBUG "Could not create procfs directory %s\n", current_pfs->dir_name); return -1; } current_pfs->bypass_entry = procfs_dir; - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL, /* write */ - get_bypass_info_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - +#define ENTRY(x) ret |= procfs_add(#x, &x##_ops, pbp_device_block) + ENTRY(bypass_info); if (pbp_device_block->bp_caps & SW_CTL_CAP) { - /* Create set param proc's */ - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL, /* write */ - get_bypass_slave_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL, /* write */ - get_bypass_caps_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL, /* write */ - get_wd_set_caps_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs, /* write */ - get_bypass_wd_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL, /* write */ - get_wd_expire_time_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL, /* write */ - reset_bypass_wd_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs, /* write */ - get_std_nic_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - + ENTRY(bypass_slave); + ENTRY(bypass_caps); + ENTRY(wd_set_caps); + ENTRY(bypass_wd); + ENTRY(wd_expire_time); + ENTRY(reset_bypass_wd); + ENTRY(std_nic); if (pbp_device_block->bp_caps & BP_CAP) { - if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs, /* write */ - get_bypass_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs, /* write */ - get_dis_bypass_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */ - get_bypass_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs, /* write */ - get_bypass_pwoff_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL, /* write */ - get_bypass_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; + ENTRY(bypass); + ENTRY(dis_bypass); + ENTRY(bypass_pwup); + ENTRY(bypass_pwoff); + ENTRY(bypass_change); } - if (pbp_device_block->bp_caps & TAP_CAP) { - - if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */ - get_tap_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs, /* write */ - get_dis_tap_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs, /* write */ - get_tap_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL, /* write */ - get_tap_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; + ENTRY(tap); + ENTRY(dis_tap); + ENTRY(tap_pwup); + ENTRY(tap_change); } if (pbp_device_block->bp_caps & DISC_CAP) { - - if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs, /* write */ - get_disc_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; -#if 1 - - if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs, /* write */ - get_dis_disc_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; -#endif - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs, /* write */ - get_disc_pwup_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */ - get_disc_change_pfs, /* read */ - procfs_dir, - pbp_device_block)) - ret = -1; + ENTRY(disc); + ENTRY(dis_disc); + ENTRY(disc_pwup); + ENTRY(disc_change); } - if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */ - get_wd_exp_mode_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - - if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs, /* write */ - get_wd_autoreset_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */ - get_tpl_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; + ENTRY(wd_exp_mode); + ENTRY(wd_autoreset); + ENTRY(tpl); #ifdef PMC_FIX_FLAG - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs, /* write */ - get_wait_at_pwup_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs, /* write */ - get_hw_reset_pfs, /* read */ - procfs_dir, pbp_device_block)) - ret = -1; - + ENTRY(wait_at_pwup); + ENTRY(hw_reset); #endif - } +#undef ENTRY if (ret < 0) printk(KERN_DEBUG "Create proc entry failed\n"); @@ -8700,21 +7901,7 @@ int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; - struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr = - NULL; - char name[256]; - - if (!pde) - return 0; - for (pde = pde->subdir; pde;) { - strcpy(name, pde->name); - pde_curr = pde; - pde = pde->next; - remove_proc_entry(name, current_pfs->bypass_entry); - } - if (!pde) - remove_proc_entry(current_pfs->dir_name, bp_procfs_dir); + remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir); current_pfs->bypass_entry = NULL; - return 0; } diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index be4f6c2ca3f..08b250f01da 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -60,6 +60,7 @@ */ #undef __NO_VERSION__ +#include <linux/file.h> #include "device.h" #include "card.h" #include "channel.h" @@ -2737,83 +2738,50 @@ static int Config_FileGetParameter(unsigned char *string, return true; } -int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter) { - unsigned char *config_path = CONFIG_PATH; - unsigned char *buffer = NULL; +int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter) +{ + unsigned char *buffer = kmalloc(1024, GFP_KERNEL); unsigned char tmpbuffer[20]; - struct file *filp = NULL; - mm_segment_t old_fs = get_fs(); - //int oldfsuid=0,oldfsgid=0; - int result = 0; - - set_fs(KERNEL_DS); - - /* Can't do this anymore, so we rely on correct filesystem permissions: - //Make sure a caller can read or write power as root - oldfsuid=current->cred->fsuid; - oldfsgid=current->cred->fsgid; - current->cred->fsuid = 0; - current->cred->fsgid = 0; - */ - - //open file - filp = filp_open(config_path, O_RDWR, 0); - if (IS_ERR(filp)) { - printk("Config_FileOperation:open file fail?\n"); - result = -1; - goto error2; - } + struct file *file; + int result=0; - if (!(filp->f_op) || !(filp->f_op->read) || !(filp->f_op->write)) { - printk("file %s cann't readable or writable?\n", config_path); - result = -1; - goto error1; - } - - buffer = kmalloc(1024, GFP_KERNEL); - if (buffer == NULL) { + if (!buffer) { printk("allocate mem for file fail?\n"); - result = -1; - goto error1; + return -1; + } + file = filp_open(CONFIG_PATH, O_RDONLY, 0); + if (IS_ERR(file)) { + kfree(buffer); + printk("Config_FileOperation:open file fail?\n"); + return -1; } - if (filp->f_op->read(filp, buffer, 1024, &filp->f_pos) < 0) { + if (kernel_read(file, 0, buffer, 1024) < 0) { printk("read file error?\n"); result = -1; goto error1; } - if (Config_FileGetParameter("ZONETYPE", tmpbuffer, buffer) != true) { + if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) { printk("get parameter error?\n"); result = -1; goto error1; } - if (memcmp(tmpbuffer, "USA", 3) == 0) { + if (memcmp(tmpbuffer,"USA",3)==0) { result = ZoneType_USA; - } else if (memcmp(tmpbuffer, "JAPAN", 5) == 0) { + } else if(memcmp(tmpbuffer,"JAPAN",5)==0) { result = ZoneType_Japan; - } else if (memcmp(tmpbuffer, "EUROPE", 5) == 0) { + } else if(memcmp(tmpbuffer,"EUROPE",5)==0) { result = ZoneType_Europe; } else { result = -1; - printk("Unknown Zonetype[%s]?\n", tmpbuffer); + printk("Unknown Zonetype[%s]?\n",tmpbuffer); } error1: kfree(buffer); - - if (filp_close(filp, NULL)) - printk("Config_FileOperation:close file fail\n"); - -error2: - set_fs(old_fs); - - /* - current->cred->fsuid=oldfsuid; - current->cred->fsgid=oldfsgid; - */ - + fput(file); return result; } diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 2161af83eaa..3a3fdc58b6d 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -46,6 +46,7 @@ */ #undef __NO_VERSION__ +#include <linux/file.h> #include "device.h" #include "card.h" #include "baseband.h" @@ -1273,53 +1274,29 @@ static int Config_FileGetParameter(unsigned char *string, /* if read fails, return NULL, or return data pointer */ static unsigned char *Config_FileOperation(struct vnt_private *pDevice) { - unsigned char *config_path = CONFIG_PATH; - unsigned char *buffer = NULL; - struct file *filp=NULL; - mm_segment_t old_fs = get_fs(); + unsigned char *buffer = kmalloc(1024, GFP_KERNEL); + struct file *file; - int result = 0; - - set_fs (KERNEL_DS); - - /* open file */ - filp = filp_open(config_path, O_RDWR, 0); - if (IS_ERR(filp)) { - printk("Config_FileOperation file Not exist\n"); - result=-1; - goto error2; - } - - if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) { - printk("file %s is not read or writeable?\n",config_path); - result = -1; - goto error1; - } - - buffer = kmalloc(1024, GFP_KERNEL); - if(buffer==NULL) { - printk("allocate mem for file fail?\n"); - result = -1; - goto error1; - } - - if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) { - printk("read file error?\n"); - result = -1; - } + if (!buffer) { + printk("allocate mem for file fail?\n"); + return NULL; + } -error1: - if(filp_close(filp,NULL)) - printk("Config_FileOperation:close file fail\n"); + file = filp_open(CONFIG_PATH, O_RDONLY, 0); + if (IS_ERR(file)) { + kfree(buffer); + printk("Config_FileOperation file Not exist\n"); + return NULL; + } -error2: - set_fs (old_fs); + if (kernel_read(file, 0, buffer, 1024) < 0) { + printk("read file error?\n"); + kfree(buffer); + buffer = NULL; + } -if(result!=0) { - kfree(buffer); - buffer=NULL; -} - return buffer; + fput(file); + return buffer; } /* return --->-1:fail; >=0:successful */ diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index f5f120a6246..c4264e8c877 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -73,6 +73,7 @@ #include <linux/module.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/types.h> #include <linux/kernel.h> // #include <linux/sched.h> @@ -144,10 +145,23 @@ void wl_isr_handler( unsigned long p ); #if 0 //SCULL_USE_PROC /* don't waste space if unused */ -//int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused); -int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data ); +static int scull_read_procmem(struct seq_file *m, void *v); static int write_int(struct file *file, const char *buffer, unsigned long count, void *data); -static void proc_write(const char *name, write_proc_t *w, void *data); + +/* + * seq_file wrappers for procfile show routines. + */ +static int scull_read_procmem_open(struct inode *inode, struct file *file) +{ + return single_open(file, scull_read_procmem, PDE_DATA(inode)); +} + +static const struct file_operations scull_read_procmem_fops = { + .open = scull_read_procmem_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; #endif /* SCULL_USE_PROC */ @@ -908,9 +922,8 @@ int wl_insert( struct net_device *dev ) } #if 0 //SCULL_USE_PROC /* don't waste space if unused */ - create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev ); + proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev ); proc_mkdir("driver/wlags49", 0); - proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type); #endif /* SCULL_USE_PROC */ DBG_LEAVE( DbgInfo ); @@ -2097,7 +2110,7 @@ static void __exit wl_module_exit( void ) wl_adapter_cleanup_module( ); #if 0 //SCULL_USE_PROC /* don't waste space if unused */ - remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry + remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data #endif DBG_LEAVE( DbgInfo ); @@ -3531,229 +3544,215 @@ void wl_wds_netdev_deregister( struct wl_private *lp ) /* * The proc filesystem: function to read and entry */ -int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ); -int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) { +static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n) +{ + int i, len; -int i, len; + seq_printf(m, "%-20.20s: ", s); + len = 22; - len = sprintf(buf, "%s", s ); - while ( len < 20 ) len += sprintf(buf+len, " " ); - len += sprintf(buf+len,": " ); - for ( i = 0; i < n; i++ ) { - if ( len % 80 > 75 ) { - len += sprintf(buf+len,"\n" ); - } - len += sprintf(buf+len,"%04X ", p[i] ); + for (i = 0; i < n; i++) { + if (len % 80 > 75) + seq_putc(m, '\n'); + seq_printf(m, "%04X ", p[i]); } - len += sprintf(buf+len,"\n" ); - return len; -} // printf_hcf_16 + seq_putc(m, '\n'); +} -int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ); -int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) { +static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n) +{ + int i, len; -int i, len; + seq_printf(m, "%-20.20s: ", s); + len = 22; - len = sprintf(buf, "%s", s ); - while ( len < 20 ) len += sprintf(buf+len, " " ); - len += sprintf(buf+len,": " ); - for ( i = 0; i <= n; i++ ) { - if ( len % 80 > 77 ) { - len += sprintf(buf+len,"\n" ); - } - len += sprintf(buf+len,"%02X ", p[i] ); + for (i = 0; i <= n; i++) { + if (len % 80 > 77) + seq_putc(m, '\n'); + seq_printf(m, "%02X ", p[i]); } - len += sprintf(buf+len,"\n" ); - return len; -} // printf_hcf8 + seq_putc(m, '\n'); +} -int printf_strct( char *s, char *buf, hcf_16* p ); -int printf_strct( char *s, char *buf, hcf_16* p ) { +static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p) +{ + int i, len; -int i, len; + seq_printf(m, "%-20.20s: ", s); + len = 22; - len = sprintf(buf, "%s", s ); - while ( len < 20 ) len += sprintf(buf+len, " " ); - len += sprintf(buf+len,": " ); for ( i = 0; i <= *p; i++ ) { - if ( len % 80 > 75 ) { - len += sprintf(buf+len,"\n" ); - } - len += sprintf(buf+len,"%04X ", p[i] ); + if (len % 80 > 75) + seq_putc(m, '\n'); + seq_printf(m,"%04X ", p[i]); } - len += sprintf(buf+len,"\n" ); - return len; -} // printf_strct + seq_putc(m, '\n'); +} -int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data ) +int scull_read_procmem(struct seq_file *m, void *v) { - struct wl_private *lp = NULL; + struct wl_private *lp = m->private; IFBP ifbp; CFG_HERMES_TALLIES_STRCT *p; - #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */ - - len=0; - - lp = ((struct net_device *)data)->priv; if (lp == NULL) { - len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" ); + seq_puts(m, "No wl_private in scull_read_procmem\n" ); } else if ( lp->wlags49_type == 0 ){ - ifbp = &lp->hcfCtx; - len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic ); - len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase ); - len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat ); - len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat ); - len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni ); - len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt ); - len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt ); - len += printf_hcf_16( "IFB_FWIdentity", &buf[len], - &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 ); + ifbp = &lp->hcfCtx; + seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic ); + seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase ); + seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat ); + seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat ); + seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni ); + seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt ); + seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt ); + printf_hcf_16(m, "IFB_FWIdentity", + &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 ); } else if ( lp->wlags49_type == 1 ) { - len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); -/****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */ + seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); +/****** seq_printf(m, "slock: %d\n", lp->slock ); */ //x struct tq_struct "task: 0x%04X\n", lp->task ); //x struct net_device_stats "stats: 0x%04X\n", lp->stats ); #ifdef WIRELESS_EXT //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats ); -//x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number ); +//x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number ); //x u_char spy_address[IW_MAX_SPY][ETH_ALEN]; //x struct iw_quality spy_stat[IW_MAX_SPY]; #endif // WIRELESS_EXT - len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx ); - len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on - len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag ); + seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx ); + seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on + seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag ); #if DBG - len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag ); + seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag ); #endif // DBG - len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered ); + seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered ); //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo ); - len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo ); + printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo ); //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity ); - len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity ); + printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity ); //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity ); - len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity ); + printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity ); //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity ); - len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity ); - len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup ); + printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity ); + printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup ); //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity ); - len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity ); + printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity ); //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord ); - len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes ); - len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */ - /* Elements used for async notification from hardware */ + seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes ); + seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */ + /* Elements used for async notification from hardware */ //x RID_LOG_STRCT RidList[10]; //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord ); //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp ); //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat ); //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat ); //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD]; - len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc]) - len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0) + seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc]) + seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0) //x hcf_16 TxRateControl[2]; - len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n", - lp->TxRateControl[0], lp->TxRateControl[1] ); - len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1) - len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347) - len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0) - len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0) - len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0) - len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1) - len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100) + seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n", + lp->TxRateControl[0], lp->TxRateControl[1] ); + seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1) + seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347) + seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0) + seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0) + seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0) + seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1) + seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100) //x hcf_8 MACAddress[ETH_ALEN]; - len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN ); + printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN ); //x char NetworkName[HCF_MAX_NAME_LEN+1]; - len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName ); + seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName ); //x char StationName[HCF_MAX_NAME_LEN+1]; - len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0) + seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0) //x char Key1[MAX_KEY_LEN+1]; - len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN ); + printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN ); //x char Key2[MAX_KEY_LEN+1]; //x char Key3[MAX_KEY_LEN+1]; //x char Key4[MAX_KEY_LEN+1]; - len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1) + seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1) //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys ); //x u_char mailbox[MB_SIZE]; //x char szEncryption[MAX_ENC_LEN]; - len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable ); - len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable ); - len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow ); - len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration ); + seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable ); + seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable ); + seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow ); + seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration ); //x hcf_16 MulticastRate[2]; - len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific? - len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode ); - len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP]) - len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite ); - len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing ); - len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution ); - len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel ); -// len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit ); -// len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit ); + seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific? + seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode ); + seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP]) + seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite ); + seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing ); + seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution ); + seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel ); +// seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit ); +// seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit ); //x hcf_16 srsc[2]; //x hcf_16 brsc[2]; - len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl ); + seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl ); //x //hcf_16 probeDataRates[2]; - len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval ); - len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence ); + seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval ); + seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence ); //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF ); //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES]; //x struct list_head "txFree: 0x%04X\n", lp->txFree ); //x struct list_head txQ[WVLAN_MAX_TX_QUEUES]; - len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on ); - len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count ); + seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on ); + seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count ); //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx ); //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx ); //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState ); //x ScanResult "scan_results: 0x%04X\n", lp->scan_results ); //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results ); - len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps ); - len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma ); + seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps ); + seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma ); //x DMA_STRCT "dma: 0x%04X\n", lp->dma ); #ifdef USE_RTS - len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS ); + seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS ); #endif // USE_RTS #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP //;?should we restore this to allow smaller memory footprint //;?I guess not. This should be brought under Debug mode only - len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1) - len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering ); - len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0) - len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1) - len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay ); - len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type ); + seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1) + seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering ); + seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0) + seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1) + seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay ); + seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type ); #ifdef USE_WDS //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS]; #endif // USE_WDS #endif // HCF_AP } else if ( lp->wlags49_type == 2 ){ - len += sprintf(buf+len,"tallies to be added\n" ); + seq_printf(m, "tallies to be added\n" ); //Hermes Tallies (IFB substructure) { - p = &lp->hcfCtx.IFB_NIC_Tallies; - len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames ); - len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames ); - len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments ); - len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets ); - len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets ); - len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions ); - len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames ); - len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames ); - len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded ); - len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards ); - len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames ); - len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames ); - len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments ); - len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets ); - len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets ); - len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors ); - len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer ); - len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA ); - len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable ); - len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments ); - len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments ); - len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError ); - len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded ); + p = &lp->hcfCtx.IFB_NIC_Tallies; + seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames ); + seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames ); + seq_printf(m, "TxFragments: %08lX\n", p->TxFragments ); + seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets ); + seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets ); + seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions ); + seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames ); + seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames ); + seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded ); + seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards ); + seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames ); + seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames ); + seq_printf(m, "RxFragments: %08lX\n", p->RxFragments ); + seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets ); + seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets ); + seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors ); + seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer ); + seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA ); + seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable ); + seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments ); + seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments ); + seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError ); + seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded ); #if (HCF_EXT) & HCF_EXT_TALLIES_FW - //to be added ;? + //to be added ;? #endif // HCF_EXT_TALLIES_FW } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this #if DBG @@ -3761,27 +3760,19 @@ int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, #endif // DBG lp->wlags49_type = 0; //default to IFB again ;? } else { - len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type ); - len += sprintf(buf+len,"0x0000 - IFB\n" ); - len += sprintf(buf+len,"0x0001 - wl_private\n" ); - len += sprintf(buf+len,"0x0002 - Tallies\n" ); - len += sprintf(buf+len,"0x8xxx - Change debufflag\n" ); - len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" ); - len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" ); - len += sprintf(buf+len,"TX 0200\nDS 0400\n" ); - } - return len; + seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type ); + seq_puts(m, + "0x0000 - IFB\n" + "0x0001 - wl_private\n" + "0x0002 - Tallies\n" + "0x8xxx - Change debufflag\n" + "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" + "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" + "TX 0200\nDS 0400\n"); + } + return 0; } // scull_read_procmem -static void proc_write(const char *name, write_proc_t *w, void *data) -{ - struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL); - if (entry) { - entry->write_proc = w; - entry->data = data; - } -} // proc_write - static int write_int(struct file *file, const char *buffer, unsigned long count, void *data) { static char proc_number[11]; diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 2d444b1ccd3..7c908141cc8 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -79,11 +79,10 @@ static void tcm_loop_release_cmd(struct se_cmd *se_cmd) kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); } -static int tcm_loop_proc_info(struct Scsi_Host *host, char *buffer, - char **start, off_t offset, - int length, int inout) +static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host) { - return sprintf(buffer, "tcm_loop_proc_info()\n"); + seq_printf(m, "tcm_loop_proc_info()\n"); + return 0; } static int tcm_loop_driver_probe(struct device *); @@ -336,7 +335,7 @@ static int tcm_loop_slave_configure(struct scsi_device *sd) } static struct scsi_host_template tcm_loop_driver_template = { - .proc_info = tcm_loop_proc_info, + .show_info = tcm_loop_show_info, .proc_name = "tcm_loopback", .name = "TCM_Loopback", .queuecommand = tcm_loop_queuecommand, diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 8fbb6d22cdc..f87dbfd3277 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1711,7 +1711,7 @@ static int uart_proc_show(struct seq_file *m, void *v) static int uart_proc_open(struct inode *inode, struct file *file) { - return single_open(file, uart_proc_show, PDE(inode)->data); + return single_open(file, uart_proc_show, PDE_DATA(inode)); } static const struct file_operations uart_proc_fops = { diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index a690d64217f..073b938f913 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -221,7 +221,7 @@ static int proc_udc_show(struct seq_file *s, void *unused) static int proc_udc_open(struct inode *inode, struct file *file) { - return single_open(file, proc_udc_show, PDE(inode)->data); + return single_open(file, proc_udc_show, PDE_DATA(inode)); } static const struct file_operations proc_ops = { diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index c377ff84bf2..f394f295d63 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -727,7 +727,6 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) } static const struct file_operations ffs_ep0_operations = { - .owner = THIS_MODULE, .llseek = no_llseek, .open = ffs_ep0_open, @@ -947,7 +946,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, } static const struct file_operations ffs_epfile_operations = { - .owner = THIS_MODULE, .llseek = no_llseek, .open = ffs_epfile_open, diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 7c2a101d19a..2d8c1cfea69 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2010,47 +2010,37 @@ static int fsl_udc_stop(struct usb_gadget *g, static const char proc_filename[] = "driver/fsl_usb2_udc"; -static int fsl_proc_read(char *page, char **start, off_t off, int count, - int *eof, void *_dev) +static int fsl_proc_read(struct seq_file *m, void *v) { - char *buf = page; - char *next = buf; - unsigned size = count; unsigned long flags; - int t, i; + int i; u32 tmp_reg; struct fsl_ep *ep = NULL; struct fsl_req *req; struct fsl_udc *udc = udc_controller; - if (off != 0) - return 0; spin_lock_irqsave(&udc->lock, flags); /* ------basic driver information ---- */ - t = scnprintf(next, size, + seq_printf(m, DRIVER_DESC "\n" "%s version: %s\n" "Gadget driver: %s\n\n", driver_name, DRIVER_VERSION, udc->driver ? udc->driver->driver.name : "(none)"); - size -= t; - next += t; /* ------ DR Registers ----- */ tmp_reg = fsl_readl(&dr_regs->usbcmd); - t = scnprintf(next, size, + seq_printf(m, "USBCMD reg:\n" "SetupTW: %d\n" "Run/Stop: %s\n\n", (tmp_reg & USB_CMD_SUTW) ? 1 : 0, (tmp_reg & USB_CMD_RUN_STOP) ? "Run" : "Stop"); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->usbsts); - t = scnprintf(next, size, + seq_printf(m, "USB Status Reg:\n" "Dr Suspend: %d Reset Received: %d System Error: %s " "USB Error Interrupt: %s\n\n", @@ -2058,11 +2048,9 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, (tmp_reg & USB_STS_RESET) ? 1 : 0, (tmp_reg & USB_STS_SYS_ERR) ? "Err" : "Normal", (tmp_reg & USB_STS_ERR) ? "Err detected" : "No err"); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->usbintr); - t = scnprintf(next, size, + seq_printf(m, "USB Interrupt Enable Reg:\n" "Sleep Enable: %d SOF Received Enable: %d " "Reset Enable: %d\n" @@ -2076,33 +2064,25 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, (tmp_reg & USB_INTR_PTC_DETECT_EN) ? 1 : 0, (tmp_reg & USB_INTR_ERR_INT_EN) ? 1 : 0, (tmp_reg & USB_INTR_INT_EN) ? 1 : 0); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->frindex); - t = scnprintf(next, size, + seq_printf(m, "USB Frame Index Reg: Frame Number is 0x%x\n\n", (tmp_reg & USB_FRINDEX_MASKS)); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->deviceaddr); - t = scnprintf(next, size, + seq_printf(m, "USB Device Address Reg: Device Addr is 0x%x\n\n", (tmp_reg & USB_DEVICE_ADDRESS_MASK)); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->endpointlistaddr); - t = scnprintf(next, size, + seq_printf(m, "USB Endpoint List Address Reg: " "Device Addr is 0x%x\n\n", (tmp_reg & USB_EP_LIST_ADDRESS_MASK)); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->portsc1); - t = scnprintf(next, size, + seq_printf(m, "USB Port Status&Control Reg:\n" "Port Transceiver Type : %s Port Speed: %s\n" "PHY Low Power Suspend: %s Port Reset: %s " @@ -2111,7 +2091,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, "Port Enable/Disable Change: %s\n" "Port Enabled/Disabled: %s " "Current Connect Status: %s\n\n", ( { - char *s; + const char *s; switch (tmp_reg & PORTSCX_PTS_FSLS) { case PORTSCX_PTS_UTMI: s = "UTMI"; break; @@ -2137,13 +2117,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, "Not correct", (tmp_reg & PORTSCX_CURRENT_CONNECT_STATUS) ? "Attached" : "Not-Att"); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->usbmode); - t = scnprintf(next, size, + seq_printf(m, "USB Mode Reg: Controller Mode is: %s\n\n", ( { - char *s; + const char *s; switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) { case USB_MODE_CTRL_MODE_IDLE: s = "Idle"; break; @@ -2156,103 +2134,87 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, } s; } )); - size -= t; - next += t; tmp_reg = fsl_readl(&dr_regs->endptsetupstat); - t = scnprintf(next, size, + seq_printf(m, "Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n", (tmp_reg & EP_SETUP_STATUS_MASK)); - size -= t; - next += t; for (i = 0; i < udc->max_ep / 2; i++) { tmp_reg = fsl_readl(&dr_regs->endptctrl[i]); - t = scnprintf(next, size, "EP Ctrl Reg [0x%x]: = [0x%x]\n", - i, tmp_reg); - size -= t; - next += t; + seq_printf(m, "EP Ctrl Reg [0x%x]: = [0x%x]\n", i, tmp_reg); } tmp_reg = fsl_readl(&dr_regs->endpointprime); - t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg); - size -= t; - next += t; + seq_printf(m, "EP Prime Reg = [0x%x]\n\n", tmp_reg); #ifndef CONFIG_ARCH_MXC if (udc->pdata->have_sysif_regs) { tmp_reg = usb_sys_regs->snoop1; - t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); - size -= t; - next += t; + seq_printf(m, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); tmp_reg = usb_sys_regs->control; - t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n", - tmp_reg); - size -= t; - next += t; + seq_printf(m, "General Control Reg : = [0x%x]\n\n", tmp_reg); } #endif /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ ep = &udc->eps[0]; - t = scnprintf(next, size, "For %s Maxpkt is 0x%x index is 0x%x\n", + seq_printf(m, "For %s Maxpkt is 0x%x index is 0x%x\n", ep->ep.name, ep_maxpacket(ep), ep_index(ep)); - size -= t; - next += t; if (list_empty(&ep->queue)) { - t = scnprintf(next, size, "its req queue is empty\n\n"); - size -= t; - next += t; + seq_puts(m, "its req queue is empty\n\n"); } else { list_for_each_entry(req, &ep->queue, queue) { - t = scnprintf(next, size, + seq_printf(m, "req %p actual 0x%x length 0x%x buf %p\n", &req->req, req->req.actual, req->req.length, req->req.buf); - size -= t; - next += t; } } /* other gadget->eplist ep */ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { if (ep->ep.desc) { - t = scnprintf(next, size, + seq_printf(m, "\nFor %s Maxpkt is 0x%x " "index is 0x%x\n", ep->ep.name, ep_maxpacket(ep), ep_index(ep)); - size -= t; - next += t; if (list_empty(&ep->queue)) { - t = scnprintf(next, size, - "its req queue is empty\n\n"); - size -= t; - next += t; + seq_puts(m, "its req queue is empty\n\n"); } else { list_for_each_entry(req, &ep->queue, queue) { - t = scnprintf(next, size, + seq_printf(m, "req %p actual 0x%x length " "0x%x buf %p\n", &req->req, req->req.actual, req->req.length, req->req.buf); - size -= t; - next += t; - } /* end for each_entry of ep req */ - } /* end for else */ - } /* end for if(ep->queue) */ - } /* end (ep->desc) */ + } /* end for each_entry of ep req */ + } /* end for else */ + } /* end for if(ep->queue) */ + } /* end (ep->desc) */ spin_unlock_irqrestore(&udc->lock, flags); + return 0; +} - *eof = 1; - return count - size; +/* + * seq_file wrappers for procfile show routines. + */ +static int fsl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, fsl_proc_read, NULL); } -#define create_proc_file() create_proc_read_entry(proc_filename, \ - 0, NULL, fsl_proc_read, NULL) +static const struct file_operations fsl_proc_fops = { + .open = fsl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#define create_proc_file() proc_create(proc_filename, 0, NULL, &fsl_proc_fops) #define remove_proc_file() remove_proc_entry(proc_filename, NULL) #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 991aba390d9..480eeb7cfd9 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -35,6 +35,7 @@ #include <linux/list.h> #include <linux/interrupt.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/device.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -1005,7 +1006,7 @@ static const struct usb_gadget_ops goku_ops = { /*-------------------------------------------------------------------------*/ -static inline char *dmastr(void) +static inline const char *dmastr(void) { if (use_dma == 0) return "(dma disabled)"; @@ -1022,13 +1023,10 @@ static const char proc_node_name [] = "driver/udc"; #define FOURBITS "%s%s%s%s" #define EIGHTBITS FOURBITS FOURBITS -static void -dump_intmask(const char *label, u32 mask, char **next, unsigned *size) +static void dump_intmask(struct seq_file *m, const char *label, u32 mask) { - int t; - /* int_status is the same format ... */ - t = scnprintf(*next, *size, + seq_printf(m, "%s %05X =" FOURBITS EIGHTBITS EIGHTBITS "\n", label, mask, (mask & INT_PWRDETECT) ? " power" : "", @@ -1055,33 +1053,23 @@ dump_intmask(const char *label, u32 mask, char **next, unsigned *size) (mask & INT_ENDPOINT0) ? " ep0" : "", (mask & INT_USBRESET) ? " reset" : "", (mask & INT_SUSPEND) ? " suspend" : ""); - *size -= t; - *next += t; } -static int -udc_proc_read(char *buffer, char **start, off_t off, int count, - int *eof, void *_dev) +static int udc_proc_read(struct seq_file *m, void *v) { - char *buf = buffer; - struct goku_udc *dev = _dev; + struct goku_udc *dev = m->private; struct goku_udc_regs __iomem *regs = dev->regs; - char *next = buf; - unsigned size = count; unsigned long flags; - int i, t, is_usb_connected; + int i, is_usb_connected; u32 tmp; - if (off != 0) - return 0; - local_irq_save(flags); /* basic device status */ tmp = readl(®s->power_detect); is_usb_connected = tmp & PW_DETECT; - t = scnprintf(next, size, + seq_printf(m, "%s - %s\n" "%s version: %s %s\n" "Gadget driver: %s\n" @@ -1093,7 +1081,7 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, is_usb_connected ? ((tmp & PW_PULLUP) ? "full speed" : "powered") : "disconnected", - ({char *state; + ({const char *state; switch(dev->ep0state){ case EP0_DISCONNECT: state = "ep0_disconnect"; break; case EP0_IDLE: state = "ep0_idle"; break; @@ -1105,27 +1093,24 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, default: state = "ep0_?"; break; } state; }) ); - size -= t; - next += t; - dump_intmask("int_status", readl(®s->int_status), &next, &size); - dump_intmask("int_enable", readl(®s->int_enable), &next, &size); + dump_intmask(m, "int_status", readl(®s->int_status)); + dump_intmask(m, "int_enable", readl(®s->int_enable)); if (!is_usb_connected || !dev->driver || (tmp & PW_PULLUP) == 0) goto done; /* registers for (active) device and ep0 */ - t = scnprintf(next, size, "\nirqs %lu\ndataset %02x " + if (seq_printf(m, "\nirqs %lu\ndataset %02x " "single.bcs %02x.%02x state %x addr %u\n", dev->irqs, readl(®s->DataSet), readl(®s->EPxSingle), readl(®s->EPxBCS), readl(®s->UsbState), - readl(®s->address)); - size -= t; - next += t; + readl(®s->address)) < 0) + goto done; tmp = readl(®s->dma_master); - t = scnprintf(next, size, + if (seq_printf(m, "dma %03X =" EIGHTBITS "%s %s\n", tmp, (tmp & MST_EOPB_DIS) ? " eopb-" : "", (tmp & MST_EOPB_ENA) ? " eopb+" : "", @@ -1140,9 +1125,8 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, (tmp & MST_WR_ENA) ? " OUT" : "", (tmp & MST_CONNECTION) ? "ep1in/ep2out" - : "ep1out/ep2in"); - size -= t; - next += t; + : "ep1out/ep2in") < 0) + goto done; /* dump endpoint queues */ for (i = 0; i < 4; i++) { @@ -1153,7 +1137,7 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, continue; tmp = readl(ep->reg_status); - t = scnprintf(next, size, + if (seq_printf(m, "%s %s max %u %s, irqs %lu, " "status %02x (%s) " FOURBITS "\n", ep->ep.name, @@ -1186,18 +1170,12 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "", (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "", (tmp & EPxSTATUS_STAGE_ERROR) ? " ep0stat" : "" - ); - if (t <= 0 || t > size) + ) < 0) goto done; - size -= t; - next += t; if (list_empty(&ep->queue)) { - t = scnprintf(next, size, "\t(nothing queued)\n"); - if (t <= 0 || t > size) + if (seq_puts(m, "\t(nothing queued)\n") < 0) goto done; - size -= t; - next += t; continue; } list_for_each_entry(req, &ep->queue, queue) { @@ -1211,23 +1189,34 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, } else tmp = req->req.actual; - t = scnprintf(next, size, + if (seq_printf(m, "\treq %p len %u/%u buf %p\n", &req->req, tmp, req->req.length, - req->req.buf); - if (t <= 0 || t > size) + req->req.buf) < 0) goto done; - size -= t; - next += t; } } done: local_irq_restore(flags); - *eof = 1; - return count - size; + return 0; +} + +/* + * seq_file wrappers for procfile show routines. + */ +static int udc_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, udc_proc_read, PDE_DATA(file_inode(file))); } +static const struct file_operations udc_proc_fops = { + .open = udc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ /*-------------------------------------------------------------------------*/ @@ -1796,7 +1785,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef CONFIG_USB_GADGET_DEBUG_FILES - create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); + proc_create_data(proc_node_name, 0, NULL, &udc_proc_fops, dev); #endif retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index e2b2e9cf254..dda0dc4a556 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -887,7 +887,6 @@ ep_open (struct inode *inode, struct file *fd) /* used before endpoint configuration */ static const struct file_operations ep_config_operations = { - .owner = THIS_MODULE, .llseek = no_llseek, .open = ep_open, @@ -1940,7 +1939,6 @@ dev_open (struct inode *inode, struct file *fd) } static const struct file_operations dev_init_operations = { - .owner = THIS_MODULE, .llseek = no_llseek, .open = dev_open, diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index b943d8cdfbf..67128be1e1b 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -565,7 +565,7 @@ static int proc_udc_show(struct seq_file *s, void *unused) static int proc_udc_open(struct inode *inode, struct file *file) { - return single_open(file, proc_udc_show, PDE(inode)->data); + return single_open(file, proc_udc_show, PDE_DATA(inode)); } static const struct file_operations proc_ops = { diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index d9297eebbf7..1e4cfb05f70 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1065,7 +1065,7 @@ static int rndis_proc_show(struct seq_file *m, void *v) static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - rndis_params *p = PDE(file_inode(file))->data; + rndis_params *p = PDE_DATA(file_inode(file)); u32 speed = 0; int i, fl_speed = 0; @@ -1109,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, static int rndis_proc_open(struct inode *inode, struct file *file) { - return single_open(file, rndis_proc_show, PDE(inode)->data); + return single_open(file, rndis_proc_show, PDE_DATA(inode)); } static const struct file_operations rndis_proc_fops = { diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 974480c516f..b04e8ece4d3 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2175,7 +2175,7 @@ static int proc_isp1362_show(struct seq_file *s, void *unused) static int proc_isp1362_open(struct inode *inode, struct file *file) { - return single_open(file, proc_isp1362_show, PDE(inode)->data); + return single_open(file, proc_isp1362_show, PDE_DATA(inode)); } static const struct file_operations proc_ops = { @@ -2192,14 +2192,11 @@ static void create_debug_file(struct isp1362_hcd *isp1362_hcd) { struct proc_dir_entry *pde; - pde = create_proc_entry(proc_filename, 0, NULL); + pde = proc_create_data(proc_filename, 0, NULL, &proc_ops, isp1362_hcd); if (pde == NULL) { pr_warning("%s: Failed to create debug file '%s'\n", __func__, proc_filename); return; } - - pde->proc_fops = &proc_ops; - pde->data = isp1362_hcd; isp1362_hcd->pde = pde; } diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 15ed7e8d887..ad4483efb6d 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1494,7 +1494,7 @@ static int proc_sl811h_show(struct seq_file *s, void *unused) static int proc_sl811h_open(struct inode *inode, struct file *file) { - return single_open(file, proc_sl811h_show, PDE(inode)->data); + return single_open(file, proc_sl811h_show, PDE_DATA(inode)); } static const struct file_operations proc_ops = { diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 42ad2e6d86c..b6ab515bfc6 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -407,8 +407,6 @@ static int yurex_release(struct inode *inode, struct file *file) if (dev == NULL) return -ENODEV; - yurex_fasync(-1, file, 0); - /* decrement the count on our device */ kref_put(&dev->kref, yurex_delete); return 0; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 4faa982807f..92b05d95ec5 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -437,22 +437,21 @@ void usb_stor_report_bus_reset(struct us_data *us) * /proc/scsi/ functions ***********************************************************************/ +static int write_info(struct Scsi_Host *host, char *buffer, int length) +{ + /* if someone is sending us data, just throw it away */ + return length; +} + /* we use this macro to help us write into the buffer */ #undef SPRINTF -#define SPRINTF(args...) \ - do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) +#define SPRINTF(args...) seq_printf(m, ## args) -static int proc_info (struct Scsi_Host *host, char *buffer, - char **start, off_t offset, int length, int inout) +static int show_info (struct seq_file *m, struct Scsi_Host *host) { struct us_data *us = host_to_us(host); - char *pos = buffer; const char *string; - /* if someone is sending us data, just throw it away */ - if (inout) - return length; - /* print the controller name */ SPRINTF(" Host scsi%d: usb-storage\n", host->host_no); @@ -482,28 +481,14 @@ static int proc_info (struct Scsi_Host *host, char *buffer, SPRINTF(" Transport: %s\n", us->transport_name); /* show the device flags */ - if (pos < buffer + length) { - pos += sprintf(pos, " Quirks:"); + SPRINTF(" Quirks:"); #define US_FLAG(name, value) \ - if (us->fflags & value) pos += sprintf(pos, " " #name); + if (us->fflags & value) seq_printf(m, " " #name); US_DO_ALL_FLAGS #undef US_FLAG - - *(pos++) = '\n'; - } - - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return (0); - else if ((pos - buffer - offset) < length) - return (pos - buffer - offset); - else - return (length); + seq_putc(m, '\n'); + return 0; } /*********************************************************************** @@ -548,7 +533,8 @@ struct scsi_host_template usb_stor_host_template = { /* basic userland interface stuff */ .name = "usb-storage", .proc_name = "usb-storage", - .proc_info = proc_info, + .show_info = show_info, + .write_info = write_info, .info = host_info, /* command interface -- queued only */ diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c index 8d411a3c996..a54f7f7d763 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/bfin_adv7393fb.c @@ -333,29 +333,23 @@ static int proc_output(char *buf) return p - buf; } -static int -adv7393_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static ssize_t +adv7393_read_proc(struct file *file, char __user *buf, + size_t size, loff_t *ppos) { - int len; - - len = proc_output(page); - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; + static const char message[] = "Usage:\n" + "echo 0x[REG][Value] > adv7393\n" + "example: echo 0x1234 >adv7393\n" + "writes 0x34 into Register 0x12\n"; + return simple_read_from_buffer(buf, size, ppos, message, + sizeof(message)); } -static int +static ssize_t adv7393_write_proc(struct file *file, const char __user * buffer, - size_t count, void *data) + size_t count, loff_t *ppos) { - struct adv7393fb_device *fbdev = data; + struct adv7393fb_device *fbdev = PDE_DATA(file_inode(file)); unsigned int val; int ret; @@ -368,6 +362,12 @@ adv7393_write_proc(struct file *file, const char __user * buffer, return count; } +static const struct file_operations fops = { + .read = adv7393_read_proc, + .write = adv7393_write_proc, + .llseek = default_llseek, +}; + static int bfin_adv7393_fb_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -506,17 +506,12 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client, fbdev->info.node, fbdev->info.fix.id); dev_info(&client->dev, "fb memory address : 0x%p\n", fbdev->fb_mem); - entry = create_proc_entry("driver/adv7393", 0, NULL); + entry = proc_create_data("driver/adv7393", 0, NULL, &fops, fbdev); if (!entry) { dev_err(&client->dev, "unable to create /proc entry\n"); ret = -EFAULT; goto free_fb; } - - entry->read_proc = adv7393_read_proc; - entry->write_proc = adv7393_write_proc; - entry->data = fbdev; - return 0; free_fb: diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c index 6c984eacc7e..97563c55af6 100644 --- a/drivers/video/pxa3xx-gcu.c +++ b/drivers/video/pxa3xx-gcu.c @@ -101,7 +101,6 @@ struct pxa3xx_gcu_priv { dma_addr_t shared_phys; struct resource *resource_mem; struct miscdevice misc_dev; - struct file_operations misc_fops; wait_queue_head_t wait_idle; wait_queue_head_t wait_free; spinlock_t spinlock; @@ -369,15 +368,20 @@ pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv) /* Misc device layer */ +static inline struct pxa3xx_gcu_priv *file_dev(struct file *file) +{ + struct miscdevice *dev = file->private_data; + return container_of(dev, struct pxa3xx_gcu_priv, misc_dev); +} + static ssize_t -pxa3xx_gcu_misc_write(struct file *filp, const char *buff, +pxa3xx_gcu_misc_write(struct file *file, const char *buff, size_t count, loff_t *offp) { int ret; unsigned long flags; struct pxa3xx_gcu_batch *buffer; - struct pxa3xx_gcu_priv *priv = - container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); + struct pxa3xx_gcu_priv *priv = file_dev(file); int words = count / 4; @@ -450,11 +454,10 @@ pxa3xx_gcu_misc_write(struct file *filp, const char *buff, static long -pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; - struct pxa3xx_gcu_priv *priv = - container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); + struct pxa3xx_gcu_priv *priv = file_dev(file); switch (cmd) { case PXA3XX_GCU_IOCTL_RESET: @@ -471,11 +474,10 @@ pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } static int -pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma) +pxa3xx_gcu_misc_mmap(struct file *file, struct vm_area_struct *vma) { unsigned int size = vma->vm_end - vma->vm_start; - struct pxa3xx_gcu_priv *priv = - container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); + struct pxa3xx_gcu_priv *priv = file_dev(file); switch (vma->vm_pgoff) { case 0: @@ -574,6 +576,13 @@ free_buffers(struct platform_device *dev, priv->free = NULL; } +static const struct file_operations misc_fops = { + .owner = THIS_MODULE, + .write = pxa3xx_gcu_misc_write, + .unlocked_ioctl = pxa3xx_gcu_misc_ioctl, + .mmap = pxa3xx_gcu_misc_mmap +}; + static int pxa3xx_gcu_probe(struct platform_device *dev) { int i, ret, irq; @@ -601,14 +610,9 @@ static int pxa3xx_gcu_probe(struct platform_device *dev) * container_of(). This isn't really necessary as we have a fixed minor * number anyway, but this is to avoid statics. */ - priv->misc_fops.owner = THIS_MODULE; - priv->misc_fops.write = pxa3xx_gcu_misc_write; - priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl; - priv->misc_fops.mmap = pxa3xx_gcu_misc_mmap; - priv->misc_dev.minor = MISCDEV_MINOR, priv->misc_dev.name = DRV_NAME, - priv->misc_dev.fops = &priv->misc_fops, + priv->misc_dev.fops = &misc_fops, /* register misc device */ ret = misc_register(&priv->misc_dev); diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c index 73b33837e12..1c15ee7456b 100644 --- a/drivers/zorro/proc.c +++ b/drivers/zorro/proc.c @@ -47,9 +47,7 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) static ssize_t proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct inode *ino = file_inode(file); - struct proc_dir_entry *dp = PDE(ino); - struct zorro_dev *z = dp->data; + struct zorro_dev *z = PDE_DATA(file_inode(file)); struct ConfigDev cd; loff_t pos = *ppos; @@ -141,7 +139,7 @@ static int __init zorro_proc_attach_device(unsigned int slot) &zorro_autocon[slot]); if (!entry) return -ENOMEM; - entry->size = sizeof(struct zorro_dev); + proc_set_size(entry, sizeof(struct zorro_dev)); return 0; } diff --git a/fs/Makefile b/fs/Makefile index f0db9c941a5..4fe6df3ec28 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -7,7 +7,7 @@ obj-y := open.o read_write.o file_table.o super.o \ char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ - ioctl.o readdir.o select.o fifo.o dcache.o inode.o \ + ioctl.o readdir.o select.o dcache.o inode.o \ attr.o bad_inode.o file.o filesystems.o namespace.o \ seq_file.o xattr.o libfs.o fs-writeback.o \ pnode.o splice.o sync.o utimes.o \ diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 096b23f821a..526e4bbbde5 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -190,7 +190,7 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file) return ret; m = file->private_data; - m->private = PDE(inode)->data; + m->private = PDE_DATA(inode); return 0; } @@ -448,7 +448,7 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file) struct seq_file *m; int ret; - cell = PDE(inode)->data; + cell = PDE_DATA(inode); if (!cell) return -ENOENT; @@ -554,7 +554,7 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file) struct seq_file *m; int ret; - cell = PDE(inode)->data; + cell = PDE_DATA(inode); if (!cell) return -ENOENT; @@ -659,7 +659,7 @@ static int afs_proc_cell_servers_open(struct inode *inode, struct file *file) struct seq_file *m; int ret; - cell = PDE(inode)->data; + cell = PDE_DATA(inode); if (!cell) return -ENOENT; @@ -1324,6 +1324,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb) if (iocb->ki_pos < 0) return -EINVAL; + if (opcode == IOCB_CMD_PWRITEV) + file_start_write(file); do { ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg], iocb->ki_nr_segs - iocb->ki_cur_seg, @@ -1336,6 +1338,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb) } while (ret > 0 && iocb->ki_left > 0 && (opcode == IOCB_CMD_PWRITEV || (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)))); + if (opcode == IOCB_CMD_PWRITEV) + file_end_write(file); /* This means we must have transferred all that we could */ /* No need to retry anymore */ diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 02fe378fc50..bce87694f7b 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -286,15 +286,12 @@ static int load_aout_binary(struct linux_binprm * bprm) return error; } - error = bprm->file->f_op->read(bprm->file, - (char __user *)text_addr, - ex.a_text+ex.a_data, &pos); + error = read_code(bprm->file, text_addr, pos, + ex.a_text+ex.a_data); if ((signed long)error < 0) { send_sig(SIGKILL, current, 0); return error; } - - flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); } else { if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) @@ -310,14 +307,9 @@ static int load_aout_binary(struct linux_binprm * bprm) } if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { - loff_t pos = fd_offset; vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); - bprm->file->f_op->read(bprm->file, - (char __user *)N_TXTADDR(ex), - ex.a_text+ex.a_data, &pos); - flush_icache_range((unsigned long) N_TXTADDR(ex), - (unsigned long) N_TXTADDR(ex) + - ex.a_text+ex.a_data); + read_code(bprm->file, N_TXTADDR(ex), fd_offset, + ex.a_text + ex.a_data); goto beyond_if; } @@ -396,8 +388,6 @@ static int load_aout_library(struct file *file) start_addr = ex.a_entry & 0xfffff000; if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { - loff_t pos = N_TXTOFF(ex); - if (printk_ratelimit()) { printk(KERN_WARNING @@ -406,11 +396,8 @@ static int load_aout_library(struct file *file) } vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); - file->f_op->read(file, (char __user *)start_addr, - ex.a_text + ex.a_data, &pos); - flush_icache_range((unsigned long) start_addr, - (unsigned long) start_addr + ex.a_text + ex.a_data); - + read_code(file, start_addr, N_TXTOFF(ex), + ex.a_text + ex.a_data); retval = 0; goto out; } diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index c1cc06aed60..9dac212fc6f 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -926,7 +926,6 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( struct elf32_fdpic_loadseg *seg; struct elf32_phdr *phdr; unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags; - loff_t fpos; int loop, ret; load_addr = params->load_addr; @@ -964,14 +963,12 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( if (params->phdrs[loop].p_type != PT_LOAD) continue; - fpos = phdr->p_offset; - seg->addr = maddr + (phdr->p_vaddr - base); seg->p_vaddr = phdr->p_vaddr; seg->p_memsz = phdr->p_memsz; - ret = file->f_op->read(file, (void *) seg->addr, - phdr->p_filesz, &fpos); + ret = read_code(file, seg->addr, phdr->p_offset, + phdr->p_filesz); if (ret < 0) return ret; diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 2036d21baae..d50bbe59da1 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -207,11 +207,12 @@ static int decompress_exec( /* Read in first chunk of data and parse gzip header. */ fpos = offset; - ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); + ret = kernel_read(bprm->file, offset, buf, LBUFSIZE); strm.next_in = buf; strm.avail_in = ret; strm.total_in = 0; + fpos += ret; retval = -ENOEXEC; @@ -277,7 +278,7 @@ static int decompress_exec( } while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { - ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); + ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE); if (ret <= 0) break; len -= ret; @@ -285,6 +286,7 @@ static int decompress_exec( strm.next_in = buf; strm.avail_in = ret; strm.total_in = 0; + fpos += ret; } if (ret < 0) { @@ -428,6 +430,7 @@ static int load_flat_file(struct linux_binprm * bprm, unsigned long textpos = 0, datapos = 0, result; unsigned long realdatastart = 0; unsigned long text_len, data_len, bss_len, stack_len, flags; + unsigned long full_data; unsigned long len, memp = 0; unsigned long memp_size, extra, rlim; unsigned long *reloc = 0, *rp; @@ -451,6 +454,7 @@ static int load_flat_file(struct linux_binprm * bprm, relocs = ntohl(hdr->reloc_count); flags = ntohl(hdr->flags); rev = ntohl(hdr->rev); + full_data = data_len + relocs * sizeof(unsigned long); if (strncmp(hdr->magic, "bFLT", 4)) { /* @@ -577,12 +581,12 @@ static int load_flat_file(struct linux_binprm * bprm, #ifdef CONFIG_BINFMT_ZFLAT if (flags & FLAT_FLAG_GZDATA) { result = decompress_exec(bprm, fpos, (char *) datapos, - data_len + (relocs * sizeof(unsigned long)), 0); + full_data, 0); } else #endif { - result = bprm->file->f_op->read(bprm->file, (char *) datapos, - data_len + (relocs * sizeof(unsigned long)), &fpos); + result = read_code(bprm->file, datapos, fpos, + full_data); } if (IS_ERR_VALUE(result)) { printk("Unable to read data+bss, errno %d\n", (int)-result); @@ -627,30 +631,25 @@ static int load_flat_file(struct linux_binprm * bprm, if (flags & FLAT_FLAG_GZIP) { result = decompress_exec(bprm, sizeof (struct flat_hdr), (((char *) textpos) + sizeof (struct flat_hdr)), - (text_len + data_len + (relocs * sizeof(unsigned long)) + (text_len + full_data - sizeof (struct flat_hdr)), 0); memmove((void *) datapos, (void *) realdatastart, - data_len + (relocs * sizeof(unsigned long))); + full_data); } else if (flags & FLAT_FLAG_GZDATA) { - fpos = 0; - result = bprm->file->f_op->read(bprm->file, - (char *) textpos, text_len, &fpos); + result = read_code(bprm->file, textpos, 0, text_len); if (!IS_ERR_VALUE(result)) result = decompress_exec(bprm, text_len, (char *) datapos, - data_len + (relocs * sizeof(unsigned long)), 0); + full_data, 0); } else #endif { - fpos = 0; - result = bprm->file->f_op->read(bprm->file, - (char *) textpos, text_len, &fpos); - if (!IS_ERR_VALUE(result)) { - fpos = ntohl(hdr->data_start); - result = bprm->file->f_op->read(bprm->file, (char *) datapos, - data_len + (relocs * sizeof(unsigned long)), &fpos); - } + result = read_code(bprm->file, textpos, 0, text_len); + if (!IS_ERR_VALUE(result)) + result = read_code(bprm->file, datapos, + ntohl(hdr->data_start), + full_data); } if (IS_ERR_VALUE(result)) { printk("Unable to read code+data+bss, errno %d\n",(int)-result); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ade03e6f7bd..bb8b7a0e28a 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1514,8 +1514,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, size_t count, ocount; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); - sb_start_write(inode->i_sb); - mutex_lock(&inode->i_mutex); err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); @@ -1617,7 +1615,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, if (sync) atomic_dec(&BTRFS_I(inode)->sync_writers); out: - sb_end_write(inode->i_sb); current->backing_dev_info = NULL; return num_written ? num_written : err; } diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 48099225970..317f9ee9c99 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -962,12 +962,14 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) } data = kmap(page); + file_start_write(file); old_fs = get_fs(); set_fs(KERNEL_DS); ret = file->f_op->write( file, (const void __user *) data, len, &pos); set_fs(old_fs); kunmap(page); + file_end_write(file); if (ret != len) ret = -EIO; } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 7a0dd99e450..2d4a231dd70 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2520,8 +2520,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, BUG_ON(iocb->ki_pos != pos); - sb_start_write(inode->i_sb); - /* * We need to hold the sem to be sure nobody modifies lock list * with a brlock that prevents writing. @@ -2545,7 +2543,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, } up_read(&cinode->lock_sem); - sb_end_write(inode->i_sb); return rc; } diff --git a/fs/coda/file.c b/fs/coda/file.c index fa4c100bdc7..380b798f844 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -79,6 +79,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo return -EINVAL; host_inode = file_inode(host_file); + file_start_write(host_file); mutex_lock(&coda_inode->i_mutex); ret = host_file->f_op->write(host_file, buf, count, ppos); @@ -87,6 +88,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9; coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC; mutex_unlock(&coda_inode->i_mutex); + file_end_write(host_file); return ret; } diff --git a/fs/compat.c b/fs/compat.c index 5f83ffa4211..d0560c93973 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1068,190 +1068,6 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, } #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ -static ssize_t compat_do_readv_writev(int type, struct file *file, - const struct compat_iovec __user *uvector, - unsigned long nr_segs, loff_t *pos) -{ - compat_ssize_t tot_len; - struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov = iovstack; - ssize_t ret; - io_fn_t fn; - iov_fn_t fnv; - - ret = -EINVAL; - if (!file->f_op) - goto out; - - ret = compat_rw_copy_check_uvector(type, uvector, nr_segs, - UIO_FASTIOV, iovstack, &iov); - if (ret <= 0) - goto out; - - tot_len = ret; - ret = rw_verify_area(type, file, pos, tot_len); - if (ret < 0) - goto out; - - fnv = NULL; - if (type == READ) { - fn = file->f_op->read; - fnv = file->f_op->aio_read; - } else { - fn = (io_fn_t)file->f_op->write; - fnv = file->f_op->aio_write; - } - - if (fnv) - ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, - pos, fnv); - else - ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); - -out: - if (iov != iovstack) - kfree(iov); - if ((ret + (type == READ)) > 0) { - if (type == READ) - fsnotify_access(file); - else - fsnotify_modify(file); - } - return ret; -} - -static size_t compat_readv(struct file *file, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t *pos) -{ - ssize_t ret = -EBADF; - - if (!(file->f_mode & FMODE_READ)) - goto out; - - ret = -EINVAL; - if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) - goto out; - - ret = compat_do_readv_writev(READ, file, vec, vlen, pos); - -out: - if (ret > 0) - add_rchar(current, ret); - inc_syscr(current); - return ret; -} - -asmlinkage ssize_t -compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen) -{ - struct fd f = fdget(fd); - ssize_t ret; - loff_t pos; - - if (!f.file) - return -EBADF; - pos = f.file->f_pos; - ret = compat_readv(f.file, vec, vlen, &pos); - f.file->f_pos = pos; - fdput(f); - return ret; -} - -asmlinkage ssize_t -compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos) -{ - struct fd f; - ssize_t ret; - - if (pos < 0) - return -EINVAL; - f = fdget(fd); - if (!f.file) - return -EBADF; - ret = -ESPIPE; - if (f.file->f_mode & FMODE_PREAD) - ret = compat_readv(f.file, vec, vlen, &pos); - fdput(f); - return ret; -} - -asmlinkage ssize_t -compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, u32 pos_low, u32 pos_high) -{ - loff_t pos = ((loff_t)pos_high << 32) | pos_low; - return compat_sys_preadv64(fd, vec, vlen, pos); -} - -static size_t compat_writev(struct file *file, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t *pos) -{ - ssize_t ret = -EBADF; - - if (!(file->f_mode & FMODE_WRITE)) - goto out; - - ret = -EINVAL; - if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) - goto out; - - ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); - -out: - if (ret > 0) - add_wchar(current, ret); - inc_syscw(current); - return ret; -} - -asmlinkage ssize_t -compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen) -{ - struct fd f = fdget(fd); - ssize_t ret; - loff_t pos; - - if (!f.file) - return -EBADF; - pos = f.file->f_pos; - ret = compat_writev(f.file, vec, vlen, &pos); - f.file->f_pos = pos; - fdput(f); - return ret; -} - -asmlinkage ssize_t -compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos) -{ - struct fd f; - ssize_t ret; - - if (pos < 0) - return -EINVAL; - f = fdget(fd); - if (!f.file) - return -EBADF; - ret = -ESPIPE; - if (f.file->f_mode & FMODE_PWRITE) - ret = compat_writev(f.file, vec, vlen, &pos); - fdput(f); - return ret; -} - -asmlinkage ssize_t -compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, u32 pos_low, u32 pos_high) -{ - loff_t pos = ((loff_t)pos_high << 32) | pos_low; - return compat_sys_pwritev64(fd, vec, vlen, pos); -} - /* * Exactly like fs/open.c:sys_open(), except that it doesn't set the * O_LARGEFILE flag. diff --git a/fs/coredump.c b/fs/coredump.c index ec306cc9a28..a9abe313e8d 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -432,9 +432,7 @@ static bool dump_interrupted(void) static void wait_for_dump_helpers(struct file *file) { - struct pipe_inode_info *pipe; - - pipe = file_inode(file)->i_pipe; + struct pipe_inode_info *pipe = file->private_data; pipe_lock(pipe); pipe->readers++; @@ -656,7 +654,9 @@ void do_coredump(siginfo_t *siginfo) goto close_fail; if (displaced) put_files_struct(displaced); + file_start_write(cprm.file); core_dumped = !dump_interrupted() && binfmt->core_dump(&cprm); + file_end_write(cprm.file); if (ispipe && core_pipe_limit) wait_for_dump_helpers(cprm.file); diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index ede07fc7309..bfb53156431 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -9,6 +9,7 @@ #include <linux/efi.h> #include <linux/fs.h> +#include <linux/slab.h> #include "internal.h" diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c index 640e289d522..7e787fb9029 100644 --- a/fs/efivarfs/inode.c +++ b/fs/efivarfs/inode.c @@ -10,6 +10,7 @@ #include <linux/efi.h> #include <linux/fs.h> #include <linux/ctype.h> +#include <linux/slab.h> #include "internal.h" diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 525a2a1ac16..141aee31884 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -13,6 +13,8 @@ #include <linux/module.h> #include <linux/pagemap.h> #include <linux/ucs2_string.h> +#include <linux/slab.h> +#include <linux/magic.h> #include "internal.h" diff --git a/fs/exec.c b/fs/exec.c index 963f510a25a..64301958557 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -802,6 +802,15 @@ int kernel_read(struct file *file, loff_t offset, EXPORT_SYMBOL(kernel_read); +ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len) +{ + ssize_t res = file->f_op->read(file, (void __user *)addr, len, &pos); + if (res > 0) + flush_icache_range(addr, addr + len); + return res; +} +EXPORT_SYMBOL(read_code); + static int exec_mmap(struct mm_struct *mm) { struct task_struct *tsk; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a11ea4d6164..b1ed9e07434 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2260,7 +2260,7 @@ static const struct seq_operations ext4_mb_seq_groups_ops = { static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file) { - struct super_block *sb = PDE(inode)->data; + struct super_block *sb = PDE_DATA(inode); int rc; rc = seq_open(file, &ext4_mb_seq_groups_ops); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index dbc7c090c13..24a146bde74 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1806,7 +1806,7 @@ static int options_seq_show(struct seq_file *seq, void *offset) static int options_open_fs(struct inode *inode, struct file *file) { - return single_open(file, options_seq_show, PDE(inode)->data); + return single_open(file, options_seq_show, PDE_DATA(inode)); } static const struct file_operations ext4_seq_options_fops = { diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 137af4255da..44abc2f286e 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -299,7 +299,7 @@ int f2fs_acl_chmod(struct inode *inode) struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct posix_acl *acl; int error; - mode_t mode = get_inode_mode(inode); + umode_t mode = get_inode_mode(inode); if (!test_opt(sbi, POSIX_ACL)) return 0; diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index a1f38443ece..1be948768e2 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -60,7 +60,7 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) { - mode_t mode = inode->i_mode; + umode_t mode = inode->i_mode; de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 958a46da19a..db626282d42 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -590,7 +590,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int oldflags; - ret = mnt_want_write(filp->f_path.mnt); + ret = mnt_want_write_file(filp); if (ret) return ret; @@ -627,7 +627,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); out: - mnt_drop_write(filp->f_path.mnt); + mnt_drop_write_file(filp); return ret; } default: diff --git a/fs/fifo.c b/fs/fifo.c deleted file mode 100644 index cf6f4345ceb..00000000000 --- a/fs/fifo.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * linux/fs/fifo.c - * - * written by Paul H. Hargrove - * - * Fixes: - * 10-06-1999, AV: fixed OOM handling in fifo_open(), moved - * initialization there, switched to external - * allocation of pipe_inode_info. - */ - -#include <linux/mm.h> -#include <linux/fs.h> -#include <linux/sched.h> -#include <linux/pipe_fs_i.h> - -static int wait_for_partner(struct inode* inode, unsigned int *cnt) -{ - int cur = *cnt; - - while (cur == *cnt) { - pipe_wait(inode->i_pipe); - if (signal_pending(current)) - break; - } - return cur == *cnt ? -ERESTARTSYS : 0; -} - -static void wake_up_partner(struct inode* inode) -{ - wake_up_interruptible(&inode->i_pipe->wait); -} - -static int fifo_open(struct inode *inode, struct file *filp) -{ - struct pipe_inode_info *pipe; - int ret; - - mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; - if (!pipe) { - ret = -ENOMEM; - pipe = alloc_pipe_info(inode); - if (!pipe) - goto err_nocleanup; - inode->i_pipe = pipe; - } - filp->f_version = 0; - - /* We can only do regular read/write on fifos */ - filp->f_mode &= (FMODE_READ | FMODE_WRITE); - - switch (filp->f_mode) { - case FMODE_READ: - /* - * O_RDONLY - * POSIX.1 says that O_NONBLOCK means return with the FIFO - * opened, even when there is no process writing the FIFO. - */ - filp->f_op = &read_pipefifo_fops; - pipe->r_counter++; - if (pipe->readers++ == 0) - wake_up_partner(inode); - - if (!pipe->writers) { - if ((filp->f_flags & O_NONBLOCK)) { - /* suppress POLLHUP until we have - * seen a writer */ - filp->f_version = pipe->w_counter; - } else { - if (wait_for_partner(inode, &pipe->w_counter)) - goto err_rd; - } - } - break; - - case FMODE_WRITE: - /* - * O_WRONLY - * POSIX.1 says that O_NONBLOCK means return -1 with - * errno=ENXIO when there is no process reading the FIFO. - */ - ret = -ENXIO; - if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) - goto err; - - filp->f_op = &write_pipefifo_fops; - pipe->w_counter++; - if (!pipe->writers++) - wake_up_partner(inode); - - if (!pipe->readers) { - if (wait_for_partner(inode, &pipe->r_counter)) - goto err_wr; - } - break; - - case FMODE_READ | FMODE_WRITE: - /* - * O_RDWR - * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. - * This implementation will NEVER block on a O_RDWR open, since - * the process can at least talk to itself. - */ - filp->f_op = &rdwr_pipefifo_fops; - - pipe->readers++; - pipe->writers++; - pipe->r_counter++; - pipe->w_counter++; - if (pipe->readers == 1 || pipe->writers == 1) - wake_up_partner(inode); - break; - - default: - ret = -EINVAL; - goto err; - } - - /* Ok! */ - mutex_unlock(&inode->i_mutex); - return 0; - -err_rd: - if (!--pipe->readers) - wake_up_interruptible(&pipe->wait); - ret = -ERESTARTSYS; - goto err; - -err_wr: - if (!--pipe->writers) - wake_up_interruptible(&pipe->wait); - ret = -ERESTARTSYS; - goto err; - -err: - if (!pipe->readers && !pipe->writers) - free_pipe_info(inode); - -err_nocleanup: - mutex_unlock(&inode->i_mutex); - return ret; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the access mode of the file... - */ -const struct file_operations def_fifo_fops = { - .open = fifo_open, /* will set read_ or write_pipefifo_fops */ - .llseek = noop_llseek, -}; diff --git a/fs/file.c b/fs/file.c index 3906d9577a1..4a78f981557 100644 --- a/fs/file.c +++ b/fs/file.c @@ -23,24 +23,10 @@ #include <linux/rcupdate.h> #include <linux/workqueue.h> -struct fdtable_defer { - spinlock_t lock; - struct work_struct wq; - struct fdtable *next; -}; - int sysctl_nr_open __read_mostly = 1024*1024; int sysctl_nr_open_min = BITS_PER_LONG; int sysctl_nr_open_max = 1024 * 1024; /* raised later */ -/* - * We use this list to defer free fdtables that have vmalloced - * sets/arrays. By keeping a per-cpu list, we avoid having to embed - * the work_struct in fdtable itself which avoids a 64 byte (i386) increase in - * this per-task structure. - */ -static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); - static void *alloc_fdmem(size_t size) { /* @@ -67,46 +53,9 @@ static void __free_fdtable(struct fdtable *fdt) kfree(fdt); } -static void free_fdtable_work(struct work_struct *work) -{ - struct fdtable_defer *f = - container_of(work, struct fdtable_defer, wq); - struct fdtable *fdt; - - spin_lock_bh(&f->lock); - fdt = f->next; - f->next = NULL; - spin_unlock_bh(&f->lock); - while(fdt) { - struct fdtable *next = fdt->next; - - __free_fdtable(fdt); - fdt = next; - } -} - static void free_fdtable_rcu(struct rcu_head *rcu) { - struct fdtable *fdt = container_of(rcu, struct fdtable, rcu); - struct fdtable_defer *fddef; - - BUG_ON(!fdt); - BUG_ON(fdt->max_fds <= NR_OPEN_DEFAULT); - - if (!is_vmalloc_addr(fdt->fd) && !is_vmalloc_addr(fdt->open_fds)) { - kfree(fdt->fd); - kfree(fdt->open_fds); - kfree(fdt); - } else { - fddef = &get_cpu_var(fdtable_defer_list); - spin_lock(&fddef->lock); - fdt->next = fddef->next; - fddef->next = fdt; - /* vmallocs are handled from the workqueue context */ - schedule_work(&fddef->wq); - spin_unlock(&fddef->lock); - put_cpu_var(fdtable_defer_list); - } + __free_fdtable(container_of(rcu, struct fdtable, rcu)); } /* @@ -174,7 +123,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr) fdt->open_fds = data; data += nr / BITS_PER_BYTE; fdt->close_on_exec = data; - fdt->next = NULL; return fdt; @@ -221,7 +169,7 @@ static int expand_fdtable(struct files_struct *files, int nr) /* Continue as planned */ copy_fdtable(new_fdt, cur_fdt); rcu_assign_pointer(files->fdt, new_fdt); - if (cur_fdt->max_fds > NR_OPEN_DEFAULT) + if (cur_fdt != &files->fdtab) call_rcu(&cur_fdt->rcu, free_fdtable_rcu); } else { /* Somebody else expanded, so undo our attempt */ @@ -316,7 +264,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) new_fdt->close_on_exec = newf->close_on_exec_init; new_fdt->open_fds = newf->open_fds_init; new_fdt->fd = &newf->fd_array[0]; - new_fdt->next = NULL; spin_lock(&oldf->file_lock); old_fdt = files_fdtable(oldf); @@ -490,19 +437,8 @@ void exit_files(struct task_struct *tsk) } } -static void fdtable_defer_list_init(int cpu) -{ - struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); - spin_lock_init(&fddef->lock); - INIT_WORK(&fddef->wq, free_fdtable_work); - fddef->next = NULL; -} - void __init files_defer_init(void) { - int i; - for_each_possible_cpu(i) - fdtable_defer_list_init(i); sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG; } diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 11dfa0c3fb4..9bfd1a3214e 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1319,7 +1319,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, page_nr++; ret += buf->len; - if (pipe->inode) + if (pipe->files) do_wakeup = 1; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 34b80ba95ba..d15c6f21c17 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -971,7 +971,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, return err; count = ocount; - sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); /* We can write back this queue in page reclaim */ @@ -1030,7 +1029,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, out: current->backing_dev_info = NULL; mutex_unlock(&inode->i_mutex); - sb_end_write(inode->i_sb); return written ? written : err; } diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 9f9dbeceeee..3027f4dbbab 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -131,6 +131,24 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping, return ret; } +static int hpfs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *pagep, void *fsdata) +{ + struct inode *inode = mapping->host; + int err; + err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); + if (err < len) + hpfs_write_failed(mapping, pos + len); + if (!(err < 0)) { + /* make sure we write it on close, if not earlier */ + hpfs_lock(inode->i_sb); + hpfs_i(inode)->i_dirty = 1; + hpfs_unlock(inode->i_sb); + } + return err; +} + static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping,block,hpfs_get_block); @@ -140,30 +158,16 @@ const struct address_space_operations hpfs_aops = { .readpage = hpfs_readpage, .writepage = hpfs_writepage, .write_begin = hpfs_write_begin, - .write_end = generic_write_end, + .write_end = hpfs_write_end, .bmap = _hpfs_bmap }; -static ssize_t hpfs_file_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - ssize_t retval; - - retval = do_sync_write(file, buf, count, ppos); - if (retval > 0) { - hpfs_lock(file->f_path.dentry->d_sb); - hpfs_i(file_inode(file))->i_dirty = 1; - hpfs_unlock(file->f_path.dentry->d_sb); - } - return retval; -} - const struct file_operations hpfs_file_ops = { .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, - .write = hpfs_file_write, + .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .release = hpfs_file_release, diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 126d3c2e2de..cd3e38972c8 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c @@ -436,7 +436,6 @@ static int hppfs_open(struct inode *inode, struct file *file) path.mnt = inode->i_sb->s_fs_info; path.dentry = HPPFS_I(inode)->proc_dentry; - /* XXX This isn't closed anywhere */ data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred); err = PTR_ERR(data->proc_file); if (IS_ERR(data->proc_file)) @@ -523,12 +522,23 @@ static loff_t hppfs_llseek(struct file *file, loff_t off, int where) return default_llseek(file, off, where); } +static int hppfs_release(struct inode *inode, struct file *file) +{ + struct hppfs_private *data = file->private_data; + struct file *proc_file = data->proc_file; + if (proc_file) + fput(proc_file); + kfree(data); + return 0; +} + static const struct file_operations hppfs_file_fops = { .owner = NULL, .llseek = hppfs_llseek, .read = hppfs_read, .write = hppfs_write, .open = hppfs_open, + .release = hppfs_release, }; struct hppfs_dirent { @@ -570,18 +580,12 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) return err; } -static int hppfs_fsync(struct file *file, loff_t start, loff_t end, - int datasync) -{ - return filemap_write_and_wait_range(file->f_mapping, start, end); -} - static const struct file_operations hppfs_dir_fops = { .owner = NULL, .readdir = hppfs_readdir, .open = hppfs_dir_open, - .fsync = hppfs_fsync, .llseek = default_llseek, + .release = hppfs_release, }; static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf) diff --git a/fs/inode.c b/fs/inode.c index a898b3d43cc..00d5fc3b86e 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1803,7 +1803,7 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) inode->i_fop = &def_blk_fops; inode->i_rdev = rdev; } else if (S_ISFIFO(mode)) - inode->i_fop = &def_fifo_fops; + inode->i_fop = &pipefifo_fops; else if (S_ISSOCK(mode)) inode->i_fop = &bad_sock_fops; else diff --git a/fs/internal.h b/fs/internal.h index 4be78237d89..eaa75f75b62 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -130,3 +130,8 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); * read_write.c */ extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); + +/* + * pipe.c + */ +extern const struct file_operations pipefifo_fops; diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index f6c5ba027f4..95457576e43 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -979,7 +979,7 @@ static const struct seq_operations jbd2_seq_info_ops = { static int jbd2_seq_info_open(struct inode *inode, struct file *file) { - journal_t *journal = PDE(inode)->data; + journal_t *journal = PDE_DATA(inode); struct jbd2_stats_proc_session *s; int rc, size; diff --git a/fs/mount.h b/fs/mount.h index cd500798040..64a858143ff 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -18,6 +18,12 @@ struct mnt_pcp { int mnt_writers; }; +struct mountpoint { + struct list_head m_hash; + struct dentry *m_dentry; + int m_count; +}; + struct mount { struct list_head mnt_hash; struct mount *mnt_parent; @@ -40,6 +46,7 @@ struct mount { struct list_head mnt_slave; /* slave list entry */ struct mount *mnt_master; /* slave is on master->mnt_slave_list */ struct mnt_namespace *mnt_ns; /* containing namespace */ + struct mountpoint *mnt_mp; /* where is it mounted */ #ifdef CONFIG_FSNOTIFY struct hlist_head mnt_fsnotify_marks; __u32 mnt_fsnotify_mask; diff --git a/fs/namespace.c b/fs/namespace.c index 341d3f56408..b4f96a5230a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -21,7 +21,8 @@ #include <linux/fs_struct.h> /* get_fs_root et.al. */ #include <linux/fsnotify.h> /* fsnotify_vfsmount_delete */ #include <linux/uaccess.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> +#include <linux/magic.h> #include "pnode.h" #include "internal.h" @@ -36,6 +37,7 @@ static int mnt_id_start = 0; static int mnt_group_start = 1; static struct list_head *mount_hashtable __read_mostly; +static struct list_head *mountpoint_hashtable __read_mostly; static struct kmem_cache *mnt_cache __read_mostly; static struct rw_semaphore namespace_sem; @@ -605,6 +607,51 @@ struct vfsmount *lookup_mnt(struct path *path) } } +static struct mountpoint *new_mountpoint(struct dentry *dentry) +{ + struct list_head *chain = mountpoint_hashtable + hash(NULL, dentry); + struct mountpoint *mp; + + list_for_each_entry(mp, chain, m_hash) { + if (mp->m_dentry == dentry) { + /* might be worth a WARN_ON() */ + if (d_unlinked(dentry)) + return ERR_PTR(-ENOENT); + mp->m_count++; + return mp; + } + } + + mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); + if (!mp) + return ERR_PTR(-ENOMEM); + + spin_lock(&dentry->d_lock); + if (d_unlinked(dentry)) { + spin_unlock(&dentry->d_lock); + kfree(mp); + return ERR_PTR(-ENOENT); + } + dentry->d_flags |= DCACHE_MOUNTED; + spin_unlock(&dentry->d_lock); + mp->m_dentry = dentry; + mp->m_count = 1; + list_add(&mp->m_hash, chain); + return mp; +} + +static void put_mountpoint(struct mountpoint *mp) +{ + if (!--mp->m_count) { + struct dentry *dentry = mp->m_dentry; + spin_lock(&dentry->d_lock); + dentry->d_flags &= ~DCACHE_MOUNTED; + spin_unlock(&dentry->d_lock); + list_del(&mp->m_hash); + kfree(mp); + } +} + static inline int check_mnt(struct mount *mnt) { return mnt->mnt_ns == current->nsproxy->mnt_ns; @@ -633,27 +680,6 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns) } /* - * Clear dentry's mounted state if it has no remaining mounts. - * vfsmount_lock must be held for write. - */ -static void dentry_reset_mounted(struct dentry *dentry) -{ - unsigned u; - - for (u = 0; u < HASH_SIZE; u++) { - struct mount *p; - - list_for_each_entry(p, &mount_hashtable[u], mnt_hash) { - if (p->mnt_mountpoint == dentry) - return; - } - } - spin_lock(&dentry->d_lock); - dentry->d_flags &= ~DCACHE_MOUNTED; - spin_unlock(&dentry->d_lock); -} - -/* * vfsmount lock must be held for write */ static void detach_mnt(struct mount *mnt, struct path *old_path) @@ -664,32 +690,35 @@ static void detach_mnt(struct mount *mnt, struct path *old_path) mnt->mnt_mountpoint = mnt->mnt.mnt_root; list_del_init(&mnt->mnt_child); list_del_init(&mnt->mnt_hash); - dentry_reset_mounted(old_path->dentry); + put_mountpoint(mnt->mnt_mp); + mnt->mnt_mp = NULL; } /* * vfsmount lock must be held for write */ -void mnt_set_mountpoint(struct mount *mnt, struct dentry *dentry, +void mnt_set_mountpoint(struct mount *mnt, + struct mountpoint *mp, struct mount *child_mnt) { + mp->m_count++; mnt_add_count(mnt, 1); /* essentially, that's mntget */ - child_mnt->mnt_mountpoint = dget(dentry); + child_mnt->mnt_mountpoint = dget(mp->m_dentry); child_mnt->mnt_parent = mnt; - spin_lock(&dentry->d_lock); - dentry->d_flags |= DCACHE_MOUNTED; - spin_unlock(&dentry->d_lock); + child_mnt->mnt_mp = mp; } /* * vfsmount lock must be held for write */ -static void attach_mnt(struct mount *mnt, struct path *path) +static void attach_mnt(struct mount *mnt, + struct mount *parent, + struct mountpoint *mp) { - mnt_set_mountpoint(real_mount(path->mnt), path->dentry, mnt); + mnt_set_mountpoint(parent, mp, mnt); list_add_tail(&mnt->mnt_hash, mount_hashtable + - hash(path->mnt, path->dentry)); - list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); + hash(&parent->mnt, mp->m_dentry)); + list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); } /* @@ -1095,11 +1124,23 @@ int may_umount(struct vfsmount *mnt) EXPORT_SYMBOL(may_umount); -void release_mounts(struct list_head *head) +static LIST_HEAD(unmounted); /* protected by namespace_sem */ + +static void namespace_unlock(void) { struct mount *mnt; - while (!list_empty(head)) { - mnt = list_first_entry(head, struct mount, mnt_hash); + LIST_HEAD(head); + + if (likely(list_empty(&unmounted))) { + up_write(&namespace_sem); + return; + } + + list_splice_init(&unmounted, &head); + up_write(&namespace_sem); + + while (!list_empty(&head)) { + mnt = list_first_entry(&head, struct mount, mnt_hash); list_del_init(&mnt->mnt_hash); if (mnt_has_parent(mnt)) { struct dentry *dentry; @@ -1119,11 +1160,16 @@ void release_mounts(struct list_head *head) } } +static inline void namespace_lock(void) +{ + down_write(&namespace_sem); +} + /* * vfsmount lock must be held for write * namespace_sem must be held for write */ -void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) +void umount_tree(struct mount *mnt, int propagate) { LIST_HEAD(tmp_list); struct mount *p; @@ -1142,20 +1188,20 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) list_del_init(&p->mnt_child); if (mnt_has_parent(p)) { p->mnt_parent->mnt_ghosts++; - dentry_reset_mounted(p->mnt_mountpoint); + put_mountpoint(p->mnt_mp); + p->mnt_mp = NULL; } change_mnt_propagation(p, MS_PRIVATE); } - list_splice(&tmp_list, kill); + list_splice(&tmp_list, &unmounted); } -static void shrink_submounts(struct mount *mnt, struct list_head *umounts); +static void shrink_submounts(struct mount *mnt); static int do_umount(struct mount *mnt, int flags) { struct super_block *sb = mnt->mnt.mnt_sb; int retval; - LIST_HEAD(umount_list); retval = security_sb_umount(&mnt->mnt, flags); if (retval) @@ -1222,22 +1268,21 @@ static int do_umount(struct mount *mnt, int flags) return retval; } - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); event++; if (!(flags & MNT_DETACH)) - shrink_submounts(mnt, &umount_list); + shrink_submounts(mnt); retval = -EBUSY; if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { if (!list_empty(&mnt->mnt_list)) - umount_tree(mnt, 1, &umount_list); + umount_tree(mnt, 1); retval = 0; } br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); - release_mounts(&umount_list); + namespace_unlock(); return retval; } @@ -1310,13 +1355,13 @@ static bool mnt_ns_loop(struct path *path) * mount namespace loop? */ struct inode *inode = path->dentry->d_inode; - struct proc_inode *ei; + struct proc_ns *ei; struct mnt_namespace *mnt_ns; if (!proc_ns_inode(inode)) return false; - ei = PROC_I(inode); + ei = get_proc_ns(inode); if (ei->ns_ops != &mntns_operations) return false; @@ -1327,8 +1372,7 @@ static bool mnt_ns_loop(struct path *path) struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, int flag) { - struct mount *res, *p, *q, *r; - struct path path; + struct mount *res, *p, *q, *r, *parent; if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) return ERR_PTR(-EINVAL); @@ -1355,25 +1399,22 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, q = q->mnt_parent; } p = s; - path.mnt = &q->mnt; - path.dentry = p->mnt_mountpoint; + parent = q; q = clone_mnt(p, p->mnt.mnt_root, flag); if (IS_ERR(q)) goto out; br_write_lock(&vfsmount_lock); list_add_tail(&q->mnt_list, &res->mnt_list); - attach_mnt(q, &path); + attach_mnt(q, parent, p->mnt_mp); br_write_unlock(&vfsmount_lock); } } return res; out: if (res) { - LIST_HEAD(umount_list); br_write_lock(&vfsmount_lock); - umount_tree(res, 0, &umount_list); + umount_tree(res, 0); br_write_unlock(&vfsmount_lock); - release_mounts(&umount_list); } return q; } @@ -1383,10 +1424,10 @@ out: struct vfsmount *collect_mounts(struct path *path) { struct mount *tree; - down_write(&namespace_sem); + namespace_lock(); tree = copy_tree(real_mount(path->mnt), path->dentry, CL_COPY_ALL | CL_PRIVATE); - up_write(&namespace_sem); + namespace_unlock(); if (IS_ERR(tree)) return NULL; return &tree->mnt; @@ -1394,13 +1435,11 @@ struct vfsmount *collect_mounts(struct path *path) void drop_collected_mounts(struct vfsmount *mnt) { - LIST_HEAD(umount_list); - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); - umount_tree(real_mount(mnt), 0, &umount_list); + umount_tree(real_mount(mnt), 0); br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); - release_mounts(&umount_list); + namespace_unlock(); } int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, @@ -1509,11 +1548,11 @@ static int invent_group_ids(struct mount *mnt, bool recurse) * in allocations. */ static int attach_recursive_mnt(struct mount *source_mnt, - struct path *path, struct path *parent_path) + struct mount *dest_mnt, + struct mountpoint *dest_mp, + struct path *parent_path) { LIST_HEAD(tree_list); - struct mount *dest_mnt = real_mount(path->mnt); - struct dentry *dest_dentry = path->dentry; struct mount *child, *p; int err; @@ -1522,7 +1561,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, if (err) goto out; } - err = propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list); + err = propagate_mnt(dest_mnt, dest_mp, source_mnt, &tree_list); if (err) goto out_cleanup_ids; @@ -1534,10 +1573,10 @@ static int attach_recursive_mnt(struct mount *source_mnt, } if (parent_path) { detach_mnt(source_mnt, parent_path); - attach_mnt(source_mnt, path); + attach_mnt(source_mnt, dest_mnt, dest_mp); touch_mnt_namespace(source_mnt->mnt_ns); } else { - mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); + mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt); commit_tree(source_mnt); } @@ -1556,46 +1595,53 @@ static int attach_recursive_mnt(struct mount *source_mnt, return err; } -static int lock_mount(struct path *path) +static struct mountpoint *lock_mount(struct path *path) { struct vfsmount *mnt; + struct dentry *dentry = path->dentry; retry: - mutex_lock(&path->dentry->d_inode->i_mutex); - if (unlikely(cant_mount(path->dentry))) { - mutex_unlock(&path->dentry->d_inode->i_mutex); - return -ENOENT; + mutex_lock(&dentry->d_inode->i_mutex); + if (unlikely(cant_mount(dentry))) { + mutex_unlock(&dentry->d_inode->i_mutex); + return ERR_PTR(-ENOENT); } - down_write(&namespace_sem); + namespace_lock(); mnt = lookup_mnt(path); - if (likely(!mnt)) - return 0; - up_write(&namespace_sem); + if (likely(!mnt)) { + struct mountpoint *mp = new_mountpoint(dentry); + if (IS_ERR(mp)) { + namespace_unlock(); + mutex_unlock(&dentry->d_inode->i_mutex); + return mp; + } + return mp; + } + namespace_unlock(); mutex_unlock(&path->dentry->d_inode->i_mutex); path_put(path); path->mnt = mnt; - path->dentry = dget(mnt->mnt_root); + dentry = path->dentry = dget(mnt->mnt_root); goto retry; } -static void unlock_mount(struct path *path) +static void unlock_mount(struct mountpoint *where) { - up_write(&namespace_sem); - mutex_unlock(&path->dentry->d_inode->i_mutex); + struct dentry *dentry = where->m_dentry; + put_mountpoint(where); + namespace_unlock(); + mutex_unlock(&dentry->d_inode->i_mutex); } -static int graft_tree(struct mount *mnt, struct path *path) +static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) { if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER) return -EINVAL; - if (S_ISDIR(path->dentry->d_inode->i_mode) != + if (S_ISDIR(mp->m_dentry->d_inode->i_mode) != S_ISDIR(mnt->mnt.mnt_root->d_inode->i_mode)) return -ENOTDIR; - if (d_unlinked(path->dentry)) - return -ENOENT; - - return attach_recursive_mnt(mnt, path, NULL); + return attach_recursive_mnt(mnt, p, mp, NULL); } /* @@ -1633,7 +1679,7 @@ static int do_change_type(struct path *path, int flag) if (!type) return -EINVAL; - down_write(&namespace_sem); + namespace_lock(); if (type == MS_SHARED) { err = invent_group_ids(mnt, recurse); if (err) @@ -1646,7 +1692,7 @@ static int do_change_type(struct path *path, int flag) br_write_unlock(&vfsmount_lock); out_unlock: - up_write(&namespace_sem); + namespace_unlock(); return err; } @@ -1656,9 +1702,9 @@ static int do_change_type(struct path *path, int flag) static int do_loopback(struct path *path, const char *old_name, int recurse) { - LIST_HEAD(umount_list); struct path old_path; - struct mount *mnt = NULL, *old; + struct mount *mnt = NULL, *old, *parent; + struct mountpoint *mp; int err; if (!old_name || !*old_name) return -EINVAL; @@ -1670,17 +1716,19 @@ static int do_loopback(struct path *path, const char *old_name, if (mnt_ns_loop(&old_path)) goto out; - err = lock_mount(path); - if (err) + mp = lock_mount(path); + err = PTR_ERR(mp); + if (IS_ERR(mp)) goto out; old = real_mount(old_path.mnt); + parent = real_mount(path->mnt); err = -EINVAL; if (IS_MNT_UNBINDABLE(old)) goto out2; - if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) + if (!check_mnt(parent) || !check_mnt(old)) goto out2; if (recurse) @@ -1693,15 +1741,14 @@ static int do_loopback(struct path *path, const char *old_name, goto out2; } - err = graft_tree(mnt, path); + err = graft_tree(mnt, parent, mp); if (err) { br_write_lock(&vfsmount_lock); - umount_tree(mnt, 0, &umount_list); + umount_tree(mnt, 0); br_write_unlock(&vfsmount_lock); } out2: - unlock_mount(path); - release_mounts(&umount_list); + unlock_mount(mp); out: path_put(&old_path); return err; @@ -1786,6 +1833,7 @@ static int do_move_mount(struct path *path, const char *old_name) struct path old_path, parent_path; struct mount *p; struct mount *old; + struct mountpoint *mp; int err; if (!old_name || !*old_name) return -EINVAL; @@ -1793,8 +1841,9 @@ static int do_move_mount(struct path *path, const char *old_name) if (err) return err; - err = lock_mount(path); - if (err < 0) + mp = lock_mount(path); + err = PTR_ERR(mp); + if (IS_ERR(mp)) goto out; old = real_mount(old_path.mnt); @@ -1804,9 +1853,6 @@ static int do_move_mount(struct path *path, const char *old_name) if (!check_mnt(p) || !check_mnt(old)) goto out1; - if (d_unlinked(path->dentry)) - goto out1; - err = -EINVAL; if (old_path.dentry != old_path.mnt->mnt_root) goto out1; @@ -1833,7 +1879,7 @@ static int do_move_mount(struct path *path, const char *old_name) if (p == old) goto out1; - err = attach_recursive_mnt(old, path, &parent_path); + err = attach_recursive_mnt(old, real_mount(path->mnt), mp, &parent_path); if (err) goto out1; @@ -1841,7 +1887,7 @@ static int do_move_mount(struct path *path, const char *old_name) * automatically */ list_del_init(&old->mnt_expire); out1: - unlock_mount(path); + unlock_mount(mp); out: if (!err) path_put(&parent_path); @@ -1877,21 +1923,24 @@ static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) */ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags) { + struct mountpoint *mp; + struct mount *parent; int err; mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL); - err = lock_mount(path); - if (err) - return err; + mp = lock_mount(path); + if (IS_ERR(mp)) + return PTR_ERR(mp); + parent = real_mount(path->mnt); err = -EINVAL; - if (unlikely(!check_mnt(real_mount(path->mnt)))) { + if (unlikely(!check_mnt(parent))) { /* that's acceptable only for automounts done in private ns */ if (!(mnt_flags & MNT_SHRINKABLE)) goto unlock; /* ... and for those we'd better have mountpoint still alive */ - if (!real_mount(path->mnt)->mnt_ns) + if (!parent->mnt_ns) goto unlock; } @@ -1906,10 +1955,10 @@ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags) goto unlock; newmnt->mnt.mnt_flags = mnt_flags; - err = graft_tree(newmnt, path); + err = graft_tree(newmnt, parent, mp); unlock: - unlock_mount(path); + unlock_mount(mp); return err; } @@ -1982,11 +2031,11 @@ int finish_automount(struct vfsmount *m, struct path *path) fail: /* remove m from any expiration list it may be on */ if (!list_empty(&mnt->mnt_expire)) { - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); list_del_init(&mnt->mnt_expire); br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); + namespace_unlock(); } mntput(m); mntput(m); @@ -2000,13 +2049,13 @@ fail: */ void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list) { - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list); br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); + namespace_unlock(); } EXPORT_SYMBOL(mnt_set_expiry); @@ -2019,12 +2068,11 @@ void mark_mounts_for_expiry(struct list_head *mounts) { struct mount *mnt, *next; LIST_HEAD(graveyard); - LIST_HEAD(umounts); if (list_empty(mounts)) return; - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); /* extract from the expiration list every vfsmount that matches the @@ -2042,12 +2090,10 @@ void mark_mounts_for_expiry(struct list_head *mounts) while (!list_empty(&graveyard)) { mnt = list_first_entry(&graveyard, struct mount, mnt_expire); touch_mnt_namespace(mnt->mnt_ns); - umount_tree(mnt, 1, &umounts); + umount_tree(mnt, 1); } br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); - - release_mounts(&umounts); + namespace_unlock(); } EXPORT_SYMBOL_GPL(mark_mounts_for_expiry); @@ -2104,7 +2150,7 @@ resume: * * vfsmount_lock must be held for write */ -static void shrink_submounts(struct mount *mnt, struct list_head *umounts) +static void shrink_submounts(struct mount *mnt) { LIST_HEAD(graveyard); struct mount *m; @@ -2115,7 +2161,7 @@ static void shrink_submounts(struct mount *mnt, struct list_head *umounts) m = list_first_entry(&graveyard, struct mount, mnt_expire); touch_mnt_namespace(m->mnt_ns); - umount_tree(m, 1, umounts); + umount_tree(m, 1); } } } @@ -2342,14 +2388,14 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, if (IS_ERR(new_ns)) return new_ns; - down_write(&namespace_sem); + namespace_lock(); /* First pass: copy the tree topology */ copy_flags = CL_COPY_ALL | CL_EXPIRE; if (user_ns != mnt_ns->user_ns) copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED; new = copy_tree(old, old->mnt.mnt_root, copy_flags); if (IS_ERR(new)) { - up_write(&namespace_sem); + namespace_unlock(); free_mnt_ns(new_ns); return ERR_CAST(new); } @@ -2380,7 +2426,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, p = next_mnt(p, old); q = next_mnt(q, new); } - up_write(&namespace_sem); + namespace_unlock(); if (rootmnt) mntput(rootmnt); @@ -2550,7 +2596,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, const char __user *, put_old) { struct path new, old, parent_path, root_parent, root; - struct mount *new_mnt, *root_mnt; + struct mount *new_mnt, *root_mnt, *old_mnt; + struct mountpoint *old_mp, *root_mp; int error; if (!may_mount()) @@ -2569,14 +2616,16 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, goto out2; get_fs_root(current->fs, &root); - error = lock_mount(&old); - if (error) + old_mp = lock_mount(&old); + error = PTR_ERR(old_mp); + if (IS_ERR(old_mp)) goto out3; error = -EINVAL; new_mnt = real_mount(new.mnt); root_mnt = real_mount(root.mnt); - if (IS_MNT_SHARED(real_mount(old.mnt)) || + old_mnt = real_mount(old.mnt); + if (IS_MNT_SHARED(old_mnt) || IS_MNT_SHARED(new_mnt->mnt_parent) || IS_MNT_SHARED(root_mnt->mnt_parent)) goto out4; @@ -2585,37 +2634,37 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, error = -ENOENT; if (d_unlinked(new.dentry)) goto out4; - if (d_unlinked(old.dentry)) - goto out4; error = -EBUSY; - if (new.mnt == root.mnt || - old.mnt == root.mnt) + if (new_mnt == root_mnt || old_mnt == root_mnt) goto out4; /* loop, on the same file system */ error = -EINVAL; if (root.mnt->mnt_root != root.dentry) goto out4; /* not a mountpoint */ if (!mnt_has_parent(root_mnt)) goto out4; /* not attached */ + root_mp = root_mnt->mnt_mp; if (new.mnt->mnt_root != new.dentry) goto out4; /* not a mountpoint */ if (!mnt_has_parent(new_mnt)) goto out4; /* not attached */ /* make sure we can reach put_old from new_root */ - if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new)) + if (!is_path_reachable(old_mnt, old.dentry, &new)) goto out4; + root_mp->m_count++; /* pin it so it won't go away */ br_write_lock(&vfsmount_lock); detach_mnt(new_mnt, &parent_path); detach_mnt(root_mnt, &root_parent); /* mount old root on put_old */ - attach_mnt(root_mnt, &old); + attach_mnt(root_mnt, old_mnt, old_mp); /* mount new_root on / */ - attach_mnt(new_mnt, &root_parent); + attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp); touch_mnt_namespace(current->nsproxy->mnt_ns); br_write_unlock(&vfsmount_lock); chroot_fs_refs(&root, &new); + put_mountpoint(root_mp); error = 0; out4: - unlock_mount(&old); + unlock_mount(old_mp); if (!error) { path_put(&root_parent); path_put(&parent_path); @@ -2670,14 +2719,17 @@ void __init mnt_init(void) 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC); + mountpoint_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC); - if (!mount_hashtable) + if (!mount_hashtable || !mountpoint_hashtable) panic("Failed to allocate mount hash table\n"); printk(KERN_INFO "Mount-cache hash table entries: %lu\n", HASH_SIZE); for (u = 0; u < HASH_SIZE; u++) INIT_LIST_HEAD(&mount_hashtable[u]); + for (u = 0; u < HASH_SIZE; u++) + INIT_LIST_HEAD(&mountpoint_hashtable[u]); br_lock_init(&vfsmount_lock); @@ -2694,16 +2746,13 @@ void __init mnt_init(void) void put_mnt_ns(struct mnt_namespace *ns) { - LIST_HEAD(umount_list); - if (!atomic_dec_and_test(&ns->count)) return; - down_write(&namespace_sem); + namespace_lock(); br_write_lock(&vfsmount_lock); - umount_tree(ns->root, 0, &umount_list); + umount_tree(ns->root, 0); br_write_unlock(&vfsmount_lock); - up_write(&namespace_sem); - release_mounts(&umount_list); + namespace_unlock(); free_mnt_ns(ns); } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index f33455b4d95..5bee0313dff 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -177,7 +177,7 @@ static int export_features_open(struct inode *inode, struct file *file) return single_open(file, export_features_show, NULL); } -static struct file_operations export_features_operations = { +static const struct file_operations export_features_operations = { .open = export_features_open, .read = seq_read, .llseek = seq_lseek, @@ -196,7 +196,7 @@ static int supported_enctypes_open(struct inode *inode, struct file *file) return single_open(file, supported_enctypes_show, NULL); } -static struct file_operations supported_enctypes_ops = { +static const struct file_operations supported_enctypes_ops = { .open = supported_enctypes_open, .read = seq_read, .llseek = seq_lseek, diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index c616a70e8cf..959815c1e01 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -287,9 +287,6 @@ static int inotify_release(struct inode *ignored, struct file *file) pr_debug("%s: group=%p\n", __func__, group); - if (file->f_flags & FASYNC) - fsnotify_fasync(-1, file, 0); - /* free this group, matching get was inotify_init->fsnotify_obtain_group */ fsnotify_destroy_group(group); diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 5b2d4f0853a..1da4b81e6f7 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2129,7 +2129,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, BUG_ON(iocb->ki_pos != pos); - sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos); mutex_unlock(&inode->i_mutex); @@ -2138,7 +2137,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0) ret = err; } - sb_end_write(inode->i_sb); return ret; } diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6474cb44004..8a7509f9e6f 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2248,8 +2248,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (iocb->ki_left == 0) return 0; - sb_start_write(inode->i_sb); - appending = file->f_flags & O_APPEND ? 1 : 0; direct_io = file->f_flags & O_DIRECT ? 1 : 0; @@ -2423,7 +2421,6 @@ out_sems: ocfs2_iocb_clear_sem_locked(iocb); mutex_unlock(&inode->i_mutex); - sb_end_write(inode->i_sb); if (written) ret = written; @@ -2468,8 +2465,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, out->f_path.dentry->d_name.len, out->f_path.dentry->d_name.name, len); - if (pipe->inode) - mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); + pipe_lock(pipe); splice_from_pipe_begin(&sd); do { @@ -2489,8 +2485,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, } while (ret > 0); splice_from_pipe_end(pipe, &sd); - if (pipe->inode) - mutex_unlock(&pipe->inode->i_mutex); + pipe_unlock(pipe); if (sd.num_spliced) ret = sd.num_spliced; diff --git a/fs/pipe.c b/fs/pipe.c index 2234f3f61f8..a029a14bacf 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -25,6 +25,8 @@ #include <asm/uaccess.h> #include <asm/ioctls.h> +#include "internal.h" + /* * The max size that a non-root user is allowed to grow the pipe. Can * be set by root in /proc/sys/fs/pipe-max-size @@ -53,8 +55,8 @@ unsigned int pipe_min_size = PAGE_SIZE; static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass) { - if (pipe->inode) - mutex_lock_nested(&pipe->inode->i_mutex, subclass); + if (pipe->files) + mutex_lock_nested(&pipe->mutex, subclass); } void pipe_lock(struct pipe_inode_info *pipe) @@ -68,11 +70,21 @@ EXPORT_SYMBOL(pipe_lock); void pipe_unlock(struct pipe_inode_info *pipe) { - if (pipe->inode) - mutex_unlock(&pipe->inode->i_mutex); + if (pipe->files) + mutex_unlock(&pipe->mutex); } EXPORT_SYMBOL(pipe_unlock); +static inline void __pipe_lock(struct pipe_inode_info *pipe) +{ + mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT); +} + +static inline void __pipe_unlock(struct pipe_inode_info *pipe) +{ + mutex_unlock(&pipe->mutex); +} + void pipe_double_lock(struct pipe_inode_info *pipe1, struct pipe_inode_info *pipe2) { @@ -361,8 +373,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t pos) { struct file *filp = iocb->ki_filp; - struct inode *inode = file_inode(filp); - struct pipe_inode_info *pipe; + struct pipe_inode_info *pipe = filp->private_data; int do_wakeup; ssize_t ret; struct iovec *iov = (struct iovec *)_iov; @@ -375,8 +386,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, do_wakeup = 0; ret = 0; - mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; + __pipe_lock(pipe); for (;;) { int bufs = pipe->nrbufs; if (bufs) { @@ -464,7 +474,7 @@ redo: } pipe_wait(pipe); } - mutex_unlock(&inode->i_mutex); + __pipe_unlock(pipe); /* Signal writers asynchronously that there is more room. */ if (do_wakeup) { @@ -486,8 +496,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t ppos) { struct file *filp = iocb->ki_filp; - struct inode *inode = file_inode(filp); - struct pipe_inode_info *pipe; + struct pipe_inode_info *pipe = filp->private_data; ssize_t ret; int do_wakeup; struct iovec *iov = (struct iovec *)_iov; @@ -501,8 +510,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, do_wakeup = 0; ret = 0; - mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; + __pipe_lock(pipe); if (!pipe->readers) { send_sig(SIGPIPE, current, 0); @@ -649,7 +657,7 @@ redo2: pipe->waiting_writers--; } out: - mutex_unlock(&inode->i_mutex); + __pipe_unlock(pipe); if (do_wakeup) { wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); @@ -662,29 +670,14 @@ out: return ret; } -static ssize_t -bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) -{ - return -EBADF; -} - -static ssize_t -bad_pipe_w(struct file *filp, const char __user *buf, size_t count, - loff_t *ppos) -{ - return -EBADF; -} - static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct inode *inode = file_inode(filp); - struct pipe_inode_info *pipe; + struct pipe_inode_info *pipe = filp->private_data; int count, buf, nrbufs; switch (cmd) { case FIONREAD: - mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; + __pipe_lock(pipe); count = 0; buf = pipe->curbuf; nrbufs = pipe->nrbufs; @@ -692,7 +685,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) count += pipe->bufs[buf].len; buf = (buf+1) & (pipe->buffers - 1); } - mutex_unlock(&inode->i_mutex); + __pipe_unlock(pipe); return put_user(count, (int __user *)arg); default: @@ -705,8 +698,7 @@ static unsigned int pipe_poll(struct file *filp, poll_table *wait) { unsigned int mask; - struct inode *inode = file_inode(filp); - struct pipe_inode_info *pipe = inode->i_pipe; + struct pipe_inode_info *pipe = filp->private_data; int nrbufs; poll_wait(filp, &pipe->wait, wait); @@ -734,197 +726,56 @@ pipe_poll(struct file *filp, poll_table *wait) } static int -pipe_release(struct inode *inode, int decr, int decw) +pipe_release(struct inode *inode, struct file *file) { - struct pipe_inode_info *pipe; + struct pipe_inode_info *pipe = inode->i_pipe; + int kill = 0; - mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; - pipe->readers -= decr; - pipe->writers -= decw; + __pipe_lock(pipe); + if (file->f_mode & FMODE_READ) + pipe->readers--; + if (file->f_mode & FMODE_WRITE) + pipe->writers--; - if (!pipe->readers && !pipe->writers) { - free_pipe_info(inode); - } else { + if (pipe->readers || pipe->writers) { wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); } - mutex_unlock(&inode->i_mutex); - - return 0; -} - -static int -pipe_read_fasync(int fd, struct file *filp, int on) -{ - struct inode *inode = file_inode(filp); - int retval; - - mutex_lock(&inode->i_mutex); - retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); - mutex_unlock(&inode->i_mutex); - - return retval; -} - - -static int -pipe_write_fasync(int fd, struct file *filp, int on) -{ - struct inode *inode = file_inode(filp); - int retval; + spin_lock(&inode->i_lock); + if (!--pipe->files) { + inode->i_pipe = NULL; + kill = 1; + } + spin_unlock(&inode->i_lock); + __pipe_unlock(pipe); - mutex_lock(&inode->i_mutex); - retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); - mutex_unlock(&inode->i_mutex); + if (kill) + free_pipe_info(pipe); - return retval; + return 0; } - static int -pipe_rdwr_fasync(int fd, struct file *filp, int on) +pipe_fasync(int fd, struct file *filp, int on) { - struct inode *inode = file_inode(filp); - struct pipe_inode_info *pipe = inode->i_pipe; - int retval; + struct pipe_inode_info *pipe = filp->private_data; + int retval = 0; - mutex_lock(&inode->i_mutex); - retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); - if (retval >= 0) { + __pipe_lock(pipe); + if (filp->f_mode & FMODE_READ) + retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); + if ((filp->f_mode & FMODE_WRITE) && retval >= 0) { retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); - if (retval < 0) /* this can happen only if on == T */ + if (retval < 0 && (filp->f_mode & FMODE_READ)) + /* this can happen only if on == T */ fasync_helper(-1, filp, 0, &pipe->fasync_readers); } - mutex_unlock(&inode->i_mutex); + __pipe_unlock(pipe); return retval; } - -static int -pipe_read_release(struct inode *inode, struct file *filp) -{ - return pipe_release(inode, 1, 0); -} - -static int -pipe_write_release(struct inode *inode, struct file *filp) -{ - return pipe_release(inode, 0, 1); -} - -static int -pipe_rdwr_release(struct inode *inode, struct file *filp) -{ - int decr, decw; - - decr = (filp->f_mode & FMODE_READ) != 0; - decw = (filp->f_mode & FMODE_WRITE) != 0; - return pipe_release(inode, decr, decw); -} - -static int -pipe_read_open(struct inode *inode, struct file *filp) -{ - int ret = -ENOENT; - - mutex_lock(&inode->i_mutex); - - if (inode->i_pipe) { - ret = 0; - inode->i_pipe->readers++; - } - - mutex_unlock(&inode->i_mutex); - - return ret; -} - -static int -pipe_write_open(struct inode *inode, struct file *filp) -{ - int ret = -ENOENT; - - mutex_lock(&inode->i_mutex); - - if (inode->i_pipe) { - ret = 0; - inode->i_pipe->writers++; - } - - mutex_unlock(&inode->i_mutex); - - return ret; -} - -static int -pipe_rdwr_open(struct inode *inode, struct file *filp) -{ - int ret = -ENOENT; - - if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE))) - return -EINVAL; - - mutex_lock(&inode->i_mutex); - - if (inode->i_pipe) { - ret = 0; - if (filp->f_mode & FMODE_READ) - inode->i_pipe->readers++; - if (filp->f_mode & FMODE_WRITE) - inode->i_pipe->writers++; - } - - mutex_unlock(&inode->i_mutex); - - return ret; -} - -/* - * The file_operations structs are not static because they - * are also used in linux/fs/fifo.c to do operations on FIFOs. - * - * Pipes reuse fifos' file_operations structs. - */ -const struct file_operations read_pipefifo_fops = { - .llseek = no_llseek, - .read = do_sync_read, - .aio_read = pipe_read, - .write = bad_pipe_w, - .poll = pipe_poll, - .unlocked_ioctl = pipe_ioctl, - .open = pipe_read_open, - .release = pipe_read_release, - .fasync = pipe_read_fasync, -}; - -const struct file_operations write_pipefifo_fops = { - .llseek = no_llseek, - .read = bad_pipe_r, - .write = do_sync_write, - .aio_write = pipe_write, - .poll = pipe_poll, - .unlocked_ioctl = pipe_ioctl, - .open = pipe_write_open, - .release = pipe_write_release, - .fasync = pipe_write_fasync, -}; - -const struct file_operations rdwr_pipefifo_fops = { - .llseek = no_llseek, - .read = do_sync_read, - .aio_read = pipe_read, - .write = do_sync_write, - .aio_write = pipe_write, - .poll = pipe_poll, - .unlocked_ioctl = pipe_ioctl, - .open = pipe_rdwr_open, - .release = pipe_rdwr_release, - .fasync = pipe_rdwr_fasync, -}; - -struct pipe_inode_info * alloc_pipe_info(struct inode *inode) +struct pipe_inode_info *alloc_pipe_info(void) { struct pipe_inode_info *pipe; @@ -934,8 +785,8 @@ struct pipe_inode_info * alloc_pipe_info(struct inode *inode) if (pipe->bufs) { init_waitqueue_head(&pipe->wait); pipe->r_counter = pipe->w_counter = 1; - pipe->inode = inode; pipe->buffers = PIPE_DEF_BUFFERS; + mutex_init(&pipe->mutex); return pipe; } kfree(pipe); @@ -944,7 +795,7 @@ struct pipe_inode_info * alloc_pipe_info(struct inode *inode) return NULL; } -void __free_pipe_info(struct pipe_inode_info *pipe) +void free_pipe_info(struct pipe_inode_info *pipe) { int i; @@ -959,12 +810,6 @@ void __free_pipe_info(struct pipe_inode_info *pipe) kfree(pipe); } -void free_pipe_info(struct inode *inode) -{ - __free_pipe_info(inode->i_pipe); - inode->i_pipe = NULL; -} - static struct vfsmount *pipe_mnt __read_mostly; /* @@ -990,13 +835,14 @@ static struct inode * get_pipe_inode(void) inode->i_ino = get_next_ino(); - pipe = alloc_pipe_info(inode); + pipe = alloc_pipe_info(); if (!pipe) goto fail_iput; - inode->i_pipe = pipe; + inode->i_pipe = pipe; + pipe->files = 2; pipe->readers = pipe->writers = 1; - inode->i_fop = &rdwr_pipefifo_fops; + inode->i_fop = &pipefifo_fops; /* * Mark the inode dirty from the very beginning, @@ -1039,17 +885,19 @@ int create_pipe_files(struct file **res, int flags) d_instantiate(path.dentry, inode); err = -ENFILE; - f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops); + f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops); if (IS_ERR(f)) goto err_dentry; f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); + f->private_data = inode->i_pipe; - res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops); + res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops); if (IS_ERR(res[0])) goto err_file; path_get(&path); + res[0]->private_data = inode->i_pipe; res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK); res[1] = f; return 0; @@ -1057,12 +905,12 @@ int create_pipe_files(struct file **res, int flags) err_file: put_filp(f); err_dentry: - free_pipe_info(inode); + free_pipe_info(inode->i_pipe); path_put(&path); return err; err_inode: - free_pipe_info(inode); + free_pipe_info(inode->i_pipe); iput(inode); return err; } @@ -1144,6 +992,168 @@ SYSCALL_DEFINE1(pipe, int __user *, fildes) return sys_pipe2(fildes, 0); } +static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt) +{ + int cur = *cnt; + + while (cur == *cnt) { + pipe_wait(pipe); + if (signal_pending(current)) + break; + } + return cur == *cnt ? -ERESTARTSYS : 0; +} + +static void wake_up_partner(struct pipe_inode_info *pipe) +{ + wake_up_interruptible(&pipe->wait); +} + +static int fifo_open(struct inode *inode, struct file *filp) +{ + struct pipe_inode_info *pipe; + bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC; + int kill = 0; + int ret; + + filp->f_version = 0; + + spin_lock(&inode->i_lock); + if (inode->i_pipe) { + pipe = inode->i_pipe; + pipe->files++; + spin_unlock(&inode->i_lock); + } else { + spin_unlock(&inode->i_lock); + pipe = alloc_pipe_info(); + if (!pipe) + return -ENOMEM; + pipe->files = 1; + spin_lock(&inode->i_lock); + if (unlikely(inode->i_pipe)) { + inode->i_pipe->files++; + spin_unlock(&inode->i_lock); + free_pipe_info(pipe); + pipe = inode->i_pipe; + } else { + inode->i_pipe = pipe; + spin_unlock(&inode->i_lock); + } + } + filp->private_data = pipe; + /* OK, we have a pipe and it's pinned down */ + + __pipe_lock(pipe); + + /* We can only do regular read/write on fifos */ + filp->f_mode &= (FMODE_READ | FMODE_WRITE); + + switch (filp->f_mode) { + case FMODE_READ: + /* + * O_RDONLY + * POSIX.1 says that O_NONBLOCK means return with the FIFO + * opened, even when there is no process writing the FIFO. + */ + pipe->r_counter++; + if (pipe->readers++ == 0) + wake_up_partner(pipe); + + if (!is_pipe && !pipe->writers) { + if ((filp->f_flags & O_NONBLOCK)) { + /* suppress POLLHUP until we have + * seen a writer */ + filp->f_version = pipe->w_counter; + } else { + if (wait_for_partner(pipe, &pipe->w_counter)) + goto err_rd; + } + } + break; + + case FMODE_WRITE: + /* + * O_WRONLY + * POSIX.1 says that O_NONBLOCK means return -1 with + * errno=ENXIO when there is no process reading the FIFO. + */ + ret = -ENXIO; + if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers) + goto err; + + pipe->w_counter++; + if (!pipe->writers++) + wake_up_partner(pipe); + + if (!is_pipe && !pipe->readers) { + if (wait_for_partner(pipe, &pipe->r_counter)) + goto err_wr; + } + break; + + case FMODE_READ | FMODE_WRITE: + /* + * O_RDWR + * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. + * This implementation will NEVER block on a O_RDWR open, since + * the process can at least talk to itself. + */ + + pipe->readers++; + pipe->writers++; + pipe->r_counter++; + pipe->w_counter++; + if (pipe->readers == 1 || pipe->writers == 1) + wake_up_partner(pipe); + break; + + default: + ret = -EINVAL; + goto err; + } + + /* Ok! */ + __pipe_unlock(pipe); + return 0; + +err_rd: + if (!--pipe->readers) + wake_up_interruptible(&pipe->wait); + ret = -ERESTARTSYS; + goto err; + +err_wr: + if (!--pipe->writers) + wake_up_interruptible(&pipe->wait); + ret = -ERESTARTSYS; + goto err; + +err: + spin_lock(&inode->i_lock); + if (!--pipe->files) { + inode->i_pipe = NULL; + kill = 1; + } + spin_unlock(&inode->i_lock); + __pipe_unlock(pipe); + if (kill) + free_pipe_info(pipe); + return ret; +} + +const struct file_operations pipefifo_fops = { + .open = fifo_open, + .llseek = no_llseek, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, + .poll = pipe_poll, + .unlocked_ioctl = pipe_ioctl, + .release = pipe_release, + .fasync = pipe_fasync, +}; + /* * Allocate a new array of pipe buffers and copy the info over. Returns the * pipe size if successful, or return -ERROR on error. @@ -1229,9 +1239,7 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, */ struct pipe_inode_info *get_pipe_info(struct file *file) { - struct inode *i = file_inode(file); - - return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL; + return file->f_op == &pipefifo_fops ? file->private_data : NULL; } long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1243,7 +1251,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) if (!pipe) return -EBADF; - mutex_lock(&pipe->inode->i_mutex); + __pipe_lock(pipe); switch (cmd) { case F_SETPIPE_SZ: { @@ -1272,7 +1280,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) } out: - mutex_unlock(&pipe->inode->i_mutex); + __pipe_unlock(pipe); return ret; } diff --git a/fs/pnode.c b/fs/pnode.c index 8b29d2164da..3d2a7141b87 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -218,7 +218,7 @@ static struct mount *get_source(struct mount *dest, * @source_mnt: source mount. * @tree_list : list of heads of trees to be attached. */ -int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, +int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, struct mount *source_mnt, struct list_head *tree_list) { struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; @@ -227,7 +227,6 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, struct mount *prev_dest_mnt = dest_mnt; struct mount *prev_src_mnt = source_mnt; LIST_HEAD(tmp_list); - LIST_HEAD(umount_list); for (m = propagation_next(dest_mnt, dest_mnt); m; m = propagation_next(m, dest_mnt)) { @@ -250,8 +249,8 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, goto out; } - if (is_subdir(dest_dentry, m->mnt.mnt_root)) { - mnt_set_mountpoint(m, dest_dentry, child); + if (is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) { + mnt_set_mountpoint(m, dest_mp, child); list_add_tail(&child->mnt_hash, tree_list); } else { /* @@ -267,10 +266,9 @@ out: br_write_lock(&vfsmount_lock); while (!list_empty(&tmp_list)) { child = list_first_entry(&tmp_list, struct mount, mnt_hash); - umount_tree(child, 0, &umount_list); + umount_tree(child, 0); } br_write_unlock(&vfsmount_lock); - release_mounts(&umount_list); return ret; } diff --git a/fs/pnode.h b/fs/pnode.h index a0493d5ebfb..b091445c1c4 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -32,17 +32,16 @@ static inline void set_mnt_shared(struct mount *mnt) } void change_mnt_propagation(struct mount *, int); -int propagate_mnt(struct mount *, struct dentry *, struct mount *, +int propagate_mnt(struct mount *, struct mountpoint *, struct mount *, struct list_head *); int propagate_umount(struct list_head *); int propagate_mount_busy(struct mount *, int); void mnt_release_group_id(struct mount *); int get_dominating_id(struct mount *mnt, const struct path *root); unsigned int mnt_get_count(struct mount *mnt); -void mnt_set_mountpoint(struct mount *, struct dentry *, +void mnt_set_mountpoint(struct mount *, struct mountpoint *, struct mount *); -void release_mounts(struct list_head *); -void umount_tree(struct mount *, int, struct list_head *); +void umount_tree(struct mount *, int); struct mount *copy_tree(struct mount *, struct dentry *, int); bool is_path_reachable(struct mount *, struct dentry *, const struct path *root); diff --git a/fs/proc/base.c b/fs/proc/base.c index 3861bcec41f..dd51e50001f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -405,6 +405,37 @@ static const struct file_operations proc_lstats_operations = { #endif +#ifdef CONFIG_CGROUPS +static int cgroup_open(struct inode *inode, struct file *file) +{ + struct pid *pid = PROC_I(inode)->pid; + return single_open(file, proc_cgroup_show, pid); +} + +static const struct file_operations proc_cgroup_operations = { + .open = cgroup_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +#ifdef CONFIG_PROC_PID_CPUSET + +static int cpuset_open(struct inode *inode, struct file *file) +{ + struct pid *pid = PROC_I(inode)->pid; + return single_open(file, proc_cpuset_show, pid); +} + +static const struct file_operations proc_cpuset_operations = { + .open = cpuset_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + static int proc_oom_score(struct task_struct *task, char *buffer) { unsigned long totalpages = totalram_pages + total_swap_pages; @@ -1621,6 +1652,15 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags) return 0; } +int pid_delete_dentry(const struct dentry *dentry) +{ + /* Is the task we represent dead? + * If so, then don't put the dentry on the lru list, + * kill it immediately. + */ + return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; +} + const struct dentry_operations pid_dentry_operations = { .d_revalidate = pid_revalidate, @@ -2893,7 +2933,7 @@ retry: return iter; } -#define TGID_OFFSET (FIRST_PROCESS_ENTRY) +#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1) static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct tgid_iter iter) @@ -2916,13 +2956,21 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) struct tgid_iter iter; struct pid_namespace *ns; filldir_t __filldir; + loff_t pos = filp->f_pos; - if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) + if (pos >= PID_MAX_LIMIT + TGID_OFFSET) goto out; - ns = filp->f_dentry->d_sb->s_fs_info; + if (pos == TGID_OFFSET - 1) { + if (proc_fill_cache(filp, dirent, filldir, "self", 4, + NULL, NULL, NULL) < 0) + goto out; + iter.tgid = 0; + } else { + iter.tgid = pos - TGID_OFFSET; + } iter.task = NULL; - iter.tgid = filp->f_pos - TGID_OFFSET; + ns = filp->f_dentry->d_sb->s_fs_info; for (iter = next_tgid(ns, iter); iter.task; iter.tgid += 1, iter = next_tgid(ns, iter)) { diff --git a/fs/proc/fd.h b/fs/proc/fd.h index cbb1d47deda..7c047f256ae 100644 --- a/fs/proc/fd.h +++ b/fs/proc/fd.h @@ -11,4 +11,9 @@ extern const struct inode_operations proc_fdinfo_inode_operations; extern int proc_fd_permission(struct inode *inode, int mask); +static inline int proc_fd(struct inode *inode) +{ + return PROC_I(inode)->fd; +} + #endif /* __PROCFS_FD_H__ */ diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 21e1a8f1659..a2596afffae 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -36,212 +36,6 @@ static int proc_match(unsigned int len, const char *name, struct proc_dir_entry return !memcmp(name, de->name, len); } -/* buffer size is one page but our output routines use some slack for overruns */ -#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) - -static ssize_t -__proc_file_read(struct file *file, char __user *buf, size_t nbytes, - loff_t *ppos) -{ - struct inode * inode = file_inode(file); - char *page; - ssize_t retval=0; - int eof=0; - ssize_t n, count; - char *start; - struct proc_dir_entry * dp; - unsigned long long pos; - - /* - * Gaah, please just use "seq_file" instead. The legacy /proc - * interfaces cut loff_t down to off_t for reads, and ignore - * the offset entirely for writes.. - */ - pos = *ppos; - if (pos > MAX_NON_LFS) - return 0; - if (nbytes > MAX_NON_LFS - pos) - nbytes = MAX_NON_LFS - pos; - - dp = PDE(inode); - if (!(page = (char*) __get_free_page(GFP_TEMPORARY))) - return -ENOMEM; - - while ((nbytes > 0) && !eof) { - count = min_t(size_t, PROC_BLOCK_SIZE, nbytes); - - start = NULL; - if (dp->read_proc) { - /* - * How to be a proc read function - * ------------------------------ - * Prototype: - * int f(char *buffer, char **start, off_t offset, - * int count, int *peof, void *dat) - * - * Assume that the buffer is "count" bytes in size. - * - * If you know you have supplied all the data you - * have, set *peof. - * - * You have three ways to return data: - * 0) Leave *start = NULL. (This is the default.) - * Put the data of the requested offset at that - * offset within the buffer. Return the number (n) - * of bytes there are from the beginning of the - * buffer up to the last byte of data. If the - * number of supplied bytes (= n - offset) is - * greater than zero and you didn't signal eof - * and the reader is prepared to take more data - * you will be called again with the requested - * offset advanced by the number of bytes - * absorbed. This interface is useful for files - * no larger than the buffer. - * 1) Set *start = an unsigned long value less than - * the buffer address but greater than zero. - * Put the data of the requested offset at the - * beginning of the buffer. Return the number of - * bytes of data placed there. If this number is - * greater than zero and you didn't signal eof - * and the reader is prepared to take more data - * you will be called again with the requested - * offset advanced by *start. This interface is - * useful when you have a large file consisting - * of a series of blocks which you want to count - * and return as wholes. - * (Hack by Paul.Russell@rustcorp.com.au) - * 2) Set *start = an address within the buffer. - * Put the data of the requested offset at *start. - * Return the number of bytes of data placed there. - * If this number is greater than zero and you - * didn't signal eof and the reader is prepared to - * take more data you will be called again with the - * requested offset advanced by the number of bytes - * absorbed. - */ - n = dp->read_proc(page, &start, *ppos, - count, &eof, dp->data); - } else - break; - - if (n == 0) /* end of file */ - break; - if (n < 0) { /* error */ - if (retval == 0) - retval = n; - break; - } - - if (start == NULL) { - if (n > PAGE_SIZE) /* Apparent buffer overflow */ - n = PAGE_SIZE; - n -= *ppos; - if (n <= 0) - break; - if (n > count) - n = count; - start = page + *ppos; - } else if (start < page) { - if (n > PAGE_SIZE) /* Apparent buffer overflow */ - n = PAGE_SIZE; - if (n > count) { - /* - * Don't reduce n because doing so might - * cut off part of a data block. - */ - pr_warn("proc_file_read: count exceeded\n"); - } - } else /* start >= page */ { - unsigned long startoff = (unsigned long)(start - page); - if (n > (PAGE_SIZE - startoff)) /* buffer overflow? */ - n = PAGE_SIZE - startoff; - if (n > count) - n = count; - } - - n -= copy_to_user(buf, start < page ? page : start, n); - if (n == 0) { - if (retval == 0) - retval = -EFAULT; - break; - } - - *ppos += start < page ? (unsigned long)start : n; - nbytes -= n; - buf += n; - retval += n; - } - free_page((unsigned long) page); - return retval; -} - -static ssize_t -proc_file_read(struct file *file, char __user *buf, size_t nbytes, - loff_t *ppos) -{ - struct proc_dir_entry *pde = PDE(file_inode(file)); - ssize_t rv = -EIO; - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; - } - pde->pde_users++; - spin_unlock(&pde->pde_unload_lock); - - rv = __proc_file_read(file, buf, nbytes, ppos); - - pde_users_dec(pde); - return rv; -} - -static ssize_t -proc_file_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct proc_dir_entry *pde = PDE(file_inode(file)); - ssize_t rv = -EIO; - - if (pde->write_proc) { - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; - } - pde->pde_users++; - spin_unlock(&pde->pde_unload_lock); - - /* FIXME: does this routine need ppos? probably... */ - rv = pde->write_proc(file, buffer, count, pde->data); - pde_users_dec(pde); - } - return rv; -} - - -static loff_t -proc_file_lseek(struct file *file, loff_t offset, int orig) -{ - loff_t retval = -EINVAL; - switch (orig) { - case 1: - offset += file->f_pos; - /* fallthrough */ - case 0: - if (offset < 0 || offset > MAX_NON_LFS) - break; - file->f_pos = retval = offset; - } - return retval; -} - -static const struct file_operations proc_file_operations = { - .llseek = proc_file_lseek, - .read = proc_file_read, - .write = proc_file_write, -}; - static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = dentry->d_inode; @@ -371,7 +165,7 @@ void proc_free_inum(unsigned int inum) static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) { - nd_set_link(nd, PDE(dentry->d_inode)->data); + nd_set_link(nd, __PDE_DATA(dentry->d_inode)); return NULL; } @@ -541,19 +335,17 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp return ret; if (S_ISDIR(dp->mode)) { - if (dp->proc_iops == NULL) { - dp->proc_fops = &proc_dir_operations; - dp->proc_iops = &proc_dir_inode_operations; - } + dp->proc_fops = &proc_dir_operations; + dp->proc_iops = &proc_dir_inode_operations; dir->nlink++; } else if (S_ISLNK(dp->mode)) { - if (dp->proc_iops == NULL) - dp->proc_iops = &proc_link_inode_operations; + dp->proc_iops = &proc_link_inode_operations; } else if (S_ISREG(dp->mode)) { - if (dp->proc_fops == NULL) - dp->proc_fops = &proc_file_operations; - if (dp->proc_iops == NULL) - dp->proc_iops = &proc_file_inode_operations; + BUG_ON(dp->proc_fops == NULL); + dp->proc_iops = &proc_file_inode_operations; + } else { + WARN_ON(1); + return -EINVAL; } spin_lock(&proc_subdir_lock); @@ -636,13 +428,17 @@ struct proc_dir_entry *proc_symlink(const char *name, } EXPORT_SYMBOL(proc_symlink); -struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, - struct proc_dir_entry *parent) +struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, + struct proc_dir_entry *parent, void *data) { struct proc_dir_entry *ent; + if (mode == 0) + mode = S_IRUGO | S_IXUGO; + ent = __proc_create(&parent, name, S_IFDIR | mode, 2); if (ent) { + ent->data = data; if (proc_register(parent, ent) < 0) { kfree(ent); ent = NULL; @@ -650,82 +446,39 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, } return ent; } -EXPORT_SYMBOL(proc_mkdir_mode); +EXPORT_SYMBOL_GPL(proc_mkdir_data); -struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, - struct proc_dir_entry *parent) +struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, + struct proc_dir_entry *parent) { - struct proc_dir_entry *ent; - - ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2); - if (ent) { - ent->data = net; - if (proc_register(parent, ent) < 0) { - kfree(ent); - ent = NULL; - } - } - return ent; + return proc_mkdir_data(name, mode, parent, NULL); } -EXPORT_SYMBOL_GPL(proc_net_mkdir); +EXPORT_SYMBOL(proc_mkdir_mode); struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) { - return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent); + return proc_mkdir_data(name, 0, parent, NULL); } EXPORT_SYMBOL(proc_mkdir); -struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode, - struct proc_dir_entry *parent) -{ - struct proc_dir_entry *ent; - nlink_t nlink; - - if (S_ISDIR(mode)) { - if ((mode & S_IALLUGO) == 0) - mode |= S_IRUGO | S_IXUGO; - nlink = 2; - } else { - if ((mode & S_IFMT) == 0) - mode |= S_IFREG; - if ((mode & S_IALLUGO) == 0) - mode |= S_IRUGO; - nlink = 1; - } - - ent = __proc_create(&parent, name, mode, nlink); - if (ent) { - if (proc_register(parent, ent) < 0) { - kfree(ent); - ent = NULL; - } - } - return ent; -} -EXPORT_SYMBOL(create_proc_entry); - struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops, void *data) { struct proc_dir_entry *pde; - nlink_t nlink; + if ((mode & S_IFMT) == 0) + mode |= S_IFREG; - if (S_ISDIR(mode)) { - if ((mode & S_IALLUGO) == 0) - mode |= S_IRUGO | S_IXUGO; - nlink = 2; - } else { - if ((mode & S_IFMT) == 0) - mode |= S_IFREG; - if ((mode & S_IALLUGO) == 0) - mode |= S_IRUGO; - nlink = 1; + if (!S_ISREG(mode)) { + WARN_ON(1); /* use proc_mkdir() */ + return NULL; } - pde = __proc_create(&parent, name, mode, nlink); + if ((mode & S_IALLUGO) == 0) + mode |= S_IRUGO; + pde = __proc_create(&parent, name, mode, 1); if (!pde) goto out; pde->proc_fops = proc_fops; @@ -739,6 +492,19 @@ out: return NULL; } EXPORT_SYMBOL(proc_create_data); + +void proc_set_size(struct proc_dir_entry *de, loff_t size) +{ + de->size = size; +} +EXPORT_SYMBOL(proc_set_size); + +void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) +{ + de->uid = uid; + de->gid = gid; +} +EXPORT_SYMBOL(proc_set_user); static void free_proc_entry(struct proc_dir_entry *de) { @@ -755,41 +521,6 @@ void pde_put(struct proc_dir_entry *pde) free_proc_entry(pde); } -static void entry_rundown(struct proc_dir_entry *de) -{ - spin_lock(&de->pde_unload_lock); - /* - * Stop accepting new callers into module. If you're - * dynamically allocating ->proc_fops, save a pointer somewhere. - */ - de->proc_fops = NULL; - /* Wait until all existing callers into module are done. */ - if (de->pde_users > 0) { - DECLARE_COMPLETION_ONSTACK(c); - - if (!de->pde_unload_completion) - de->pde_unload_completion = &c; - - spin_unlock(&de->pde_unload_lock); - - wait_for_completion(de->pde_unload_completion); - - spin_lock(&de->pde_unload_lock); - } - - while (!list_empty(&de->pde_openers)) { - struct pde_opener *pdeo; - - pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh); - list_del(&pdeo->lh); - spin_unlock(&de->pde_unload_lock); - pdeo->release(pdeo->inode, pdeo->file); - kfree(pdeo); - spin_lock(&de->pde_unload_lock); - } - spin_unlock(&de->pde_unload_lock); -} - /* * Remove a /proc entry and free it if it's not currently in use. */ @@ -821,7 +552,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) return; } - entry_rundown(de); + proc_entry_rundown(de); if (S_ISDIR(de->mode)) parent->nlink--; @@ -870,7 +601,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) } spin_unlock(&proc_subdir_lock); - entry_rundown(de); + proc_entry_rundown(de); next = de->parent; if (S_ISDIR(de->mode)) next->nlink--; @@ -886,3 +617,23 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) return 0; } EXPORT_SYMBOL(remove_proc_subtree); + +void *proc_get_parent_data(const struct inode *inode) +{ + struct proc_dir_entry *de = PDE(inode); + return de->parent->data; +} +EXPORT_SYMBOL_GPL(proc_get_parent_data); + +void proc_remove(struct proc_dir_entry *de) +{ + if (de) + remove_proc_subtree(de->name, de->parent); +} +EXPORT_SYMBOL(proc_remove); + +void *PDE_DATA(const struct inode *inode) +{ + return __PDE_DATA(inode); +} +EXPORT_SYMBOL(PDE_DATA); diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 869116c2afb..073aea60cf8 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -22,6 +22,7 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/mount.h> +#include <linux/magic.h> #include <asm/uaccess.h> @@ -50,8 +51,8 @@ static void proc_evict_inode(struct inode *inode) sysctl_head_put(head); } /* Release any associated namespace */ - ns_ops = PROC_I(inode)->ns_ops; - ns = PROC_I(inode)->ns; + ns_ops = PROC_I(inode)->ns.ns_ops; + ns = PROC_I(inode)->ns.ns; if (ns_ops && ns) ns_ops->put(ns); } @@ -72,8 +73,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb) ei->pde = NULL; ei->sysctl = NULL; ei->sysctl_entry = NULL; - ei->ns = NULL; - ei->ns_ops = NULL; + ei->ns.ns = NULL; + ei->ns.ns_ops = NULL; inode = &ei->vfs_inode; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; return inode; @@ -129,96 +130,100 @@ static const struct super_operations proc_sops = { .show_options = proc_show_options, }; -static void __pde_users_dec(struct proc_dir_entry *pde) +enum {BIAS = -1U<<31}; + +static inline int use_pde(struct proc_dir_entry *pde) +{ + return atomic_inc_unless_negative(&pde->in_use); +} + +static void unuse_pde(struct proc_dir_entry *pde) { - pde->pde_users--; - if (pde->pde_unload_completion && pde->pde_users == 0) + if (atomic_dec_return(&pde->in_use) == BIAS) complete(pde->pde_unload_completion); } -void pde_users_dec(struct proc_dir_entry *pde) +/* pde is locked */ +static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo) { - spin_lock(&pde->pde_unload_lock); - __pde_users_dec(pde); - spin_unlock(&pde->pde_unload_lock); + if (pdeo->closing) { + /* somebody else is doing that, just wait */ + DECLARE_COMPLETION_ONSTACK(c); + pdeo->c = &c; + spin_unlock(&pde->pde_unload_lock); + wait_for_completion(&c); + spin_lock(&pde->pde_unload_lock); + } else { + struct file *file; + pdeo->closing = 1; + spin_unlock(&pde->pde_unload_lock); + file = pdeo->file; + pde->proc_fops->release(file_inode(file), file); + spin_lock(&pde->pde_unload_lock); + list_del_init(&pdeo->lh); + if (pdeo->c) + complete(pdeo->c); + kfree(pdeo); + } +} + +void proc_entry_rundown(struct proc_dir_entry *de) +{ + DECLARE_COMPLETION_ONSTACK(c); + /* Wait until all existing callers into module are done. */ + de->pde_unload_completion = &c; + if (atomic_add_return(BIAS, &de->in_use) != BIAS) + wait_for_completion(&c); + + spin_lock(&de->pde_unload_lock); + while (!list_empty(&de->pde_openers)) { + struct pde_opener *pdeo; + pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh); + close_pdeo(de, pdeo); + } + spin_unlock(&de->pde_unload_lock); } static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence) { struct proc_dir_entry *pde = PDE(file_inode(file)); loff_t rv = -EINVAL; - loff_t (*llseek)(struct file *, loff_t, int); - - spin_lock(&pde->pde_unload_lock); - /* - * remove_proc_entry() is going to delete PDE (as part of module - * cleanup sequence). No new callers into module allowed. - */ - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + loff_t (*llseek)(struct file *, loff_t, int); + llseek = pde->proc_fops->llseek; + if (!llseek) + llseek = default_llseek; + rv = llseek(file, offset, whence); + unuse_pde(pde); } - /* - * Bump refcount so that remove_proc_entry will wail for ->llseek to - * complete. - */ - pde->pde_users++; - /* - * Save function pointer under lock, to protect against ->proc_fops - * NULL'ifying right after ->pde_unload_lock is dropped. - */ - llseek = pde->proc_fops->llseek; - spin_unlock(&pde->pde_unload_lock); - - if (!llseek) - llseek = default_llseek; - rv = llseek(file, offset, whence); - - pde_users_dec(pde); return rv; } static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { + ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); struct proc_dir_entry *pde = PDE(file_inode(file)); ssize_t rv = -EIO; - ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + read = pde->proc_fops->read; + if (read) + rv = read(file, buf, count, ppos); + unuse_pde(pde); } - pde->pde_users++; - read = pde->proc_fops->read; - spin_unlock(&pde->pde_unload_lock); - - if (read) - rv = read(file, buf, count, ppos); - - pde_users_dec(pde); return rv; } static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); struct proc_dir_entry *pde = PDE(file_inode(file)); ssize_t rv = -EIO; - ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + write = pde->proc_fops->write; + if (write) + rv = write(file, buf, count, ppos); + unuse_pde(pde); } - pde->pde_users++; - write = pde->proc_fops->write; - spin_unlock(&pde->pde_unload_lock); - - if (write) - rv = write(file, buf, count, ppos); - - pde_users_dec(pde); return rv; } @@ -227,20 +232,12 @@ static unsigned int proc_reg_poll(struct file *file, struct poll_table_struct *p struct proc_dir_entry *pde = PDE(file_inode(file)); unsigned int rv = DEFAULT_POLLMASK; unsigned int (*poll)(struct file *, struct poll_table_struct *); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + poll = pde->proc_fops->poll; + if (poll) + rv = poll(file, pts); + unuse_pde(pde); } - pde->pde_users++; - poll = pde->proc_fops->poll; - spin_unlock(&pde->pde_unload_lock); - - if (poll) - rv = poll(file, pts); - - pde_users_dec(pde); return rv; } @@ -249,20 +246,12 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne struct proc_dir_entry *pde = PDE(file_inode(file)); long rv = -ENOTTY; long (*ioctl)(struct file *, unsigned int, unsigned long); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + ioctl = pde->proc_fops->unlocked_ioctl; + if (ioctl) + rv = ioctl(file, cmd, arg); + unuse_pde(pde); } - pde->pde_users++; - ioctl = pde->proc_fops->unlocked_ioctl; - spin_unlock(&pde->pde_unload_lock); - - if (ioctl) - rv = ioctl(file, cmd, arg); - - pde_users_dec(pde); return rv; } @@ -272,20 +261,12 @@ static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned struct proc_dir_entry *pde = PDE(file_inode(file)); long rv = -ENOTTY; long (*compat_ioctl)(struct file *, unsigned int, unsigned long); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + compat_ioctl = pde->proc_fops->compat_ioctl; + if (compat_ioctl) + rv = compat_ioctl(file, cmd, arg); + unuse_pde(pde); } - pde->pde_users++; - compat_ioctl = pde->proc_fops->compat_ioctl; - spin_unlock(&pde->pde_unload_lock); - - if (compat_ioctl) - rv = compat_ioctl(file, cmd, arg); - - pde_users_dec(pde); return rv; } #endif @@ -295,20 +276,12 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma) struct proc_dir_entry *pde = PDE(file_inode(file)); int rv = -EIO; int (*mmap)(struct file *, struct vm_area_struct *); - - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); - return rv; + if (use_pde(pde)) { + mmap = pde->proc_fops->mmap; + if (mmap) + rv = mmap(file, vma); + unuse_pde(pde); } - pde->pde_users++; - mmap = pde->proc_fops->mmap; - spin_unlock(&pde->pde_unload_lock); - - if (mmap) - rv = mmap(file, vma); - - pde_users_dec(pde); return rv; } @@ -330,91 +303,47 @@ static int proc_reg_open(struct inode *inode, struct file *file) * by hand in remove_proc_entry(). For this, save opener's credentials * for later. */ - pdeo = kmalloc(sizeof(struct pde_opener), GFP_KERNEL); + pdeo = kzalloc(sizeof(struct pde_opener), GFP_KERNEL); if (!pdeo) return -ENOMEM; - spin_lock(&pde->pde_unload_lock); - if (!pde->proc_fops) { - spin_unlock(&pde->pde_unload_lock); + if (!use_pde(pde)) { kfree(pdeo); return -ENOENT; } - pde->pde_users++; open = pde->proc_fops->open; release = pde->proc_fops->release; - spin_unlock(&pde->pde_unload_lock); if (open) rv = open(inode, file); - spin_lock(&pde->pde_unload_lock); if (rv == 0 && release) { /* To know what to release. */ - pdeo->inode = inode; pdeo->file = file; /* Strictly for "too late" ->release in proc_reg_release(). */ - pdeo->release = release; + spin_lock(&pde->pde_unload_lock); list_add(&pdeo->lh, &pde->pde_openers); + spin_unlock(&pde->pde_unload_lock); } else kfree(pdeo); - __pde_users_dec(pde); - spin_unlock(&pde->pde_unload_lock); - return rv; -} - -static struct pde_opener *find_pde_opener(struct proc_dir_entry *pde, - struct inode *inode, struct file *file) -{ - struct pde_opener *pdeo; - list_for_each_entry(pdeo, &pde->pde_openers, lh) { - if (pdeo->inode == inode && pdeo->file == file) - return pdeo; - } - return NULL; + unuse_pde(pde); + return rv; } static int proc_reg_release(struct inode *inode, struct file *file) { struct proc_dir_entry *pde = PDE(inode); - int rv = 0; - int (*release)(struct inode *, struct file *); struct pde_opener *pdeo; - spin_lock(&pde->pde_unload_lock); - pdeo = find_pde_opener(pde, inode, file); - if (!pde->proc_fops) { - /* - * Can't simply exit, __fput() will think that everything is OK, - * and move on to freeing struct file. remove_proc_entry() will - * find slacker in opener's list and will try to do non-trivial - * things with struct file. Therefore, remove opener from list. - * - * But if opener is removed from list, who will ->release it? - */ - if (pdeo) { - list_del(&pdeo->lh); - spin_unlock(&pde->pde_unload_lock); - rv = pdeo->release(inode, file); - kfree(pdeo); - } else - spin_unlock(&pde->pde_unload_lock); - return rv; - } - pde->pde_users++; - release = pde->proc_fops->release; - if (pdeo) { - list_del(&pdeo->lh); - kfree(pdeo); + list_for_each_entry(pdeo, &pde->pde_openers, lh) { + if (pdeo->file == file) { + close_pdeo(pde, pdeo); + break; + } } spin_unlock(&pde->pde_unload_lock); - - if (release) - rv = release(inode, file); - - pde_users_dec(pde); - return rv; + return 0; } static const struct file_operations proc_reg_file_ops = { @@ -462,8 +391,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) inode->i_size = de->size; if (de->nlink) set_nlink(inode, de->nlink); - if (de->proc_iops) - inode->i_op = de->proc_iops; + WARN_ON(!de->proc_iops); + inode->i_op = de->proc_iops; if (de->proc_fops) { if (S_ISREG(inode->i_mode)) { #ifdef CONFIG_COMPAT @@ -506,5 +435,5 @@ int proc_fill_super(struct super_block *s) return -ENOMEM; } - return 0; + return proc_setup_self(s); } diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 75710357a51..d600fb098b6 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -1,4 +1,4 @@ -/* internal.h: internal procfs definitions +/* Internal procfs definitions * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) @@ -9,62 +9,83 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/sched.h> #include <linux/proc_fs.h> +#include <linux/proc_ns.h> +#include <linux/spinlock.h> +#include <linux/atomic.h> #include <linux/binfmts.h> -struct ctl_table_header; -struct mempolicy; -extern struct proc_dir_entry proc_root; -extern void proc_self_init(void); -#ifdef CONFIG_PROC_SYSCTL -extern int proc_sys_init(void); -extern void sysctl_head_put(struct ctl_table_header *head); -#else -static inline void proc_sys_init(void) { } -static inline void sysctl_head_put(struct ctl_table_header *head) { } -#endif -#ifdef CONFIG_NET -extern int proc_net_init(void); -#else -static inline int proc_net_init(void) { return 0; } -#endif +struct ctl_table_header; +struct mempolicy; -extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *task); -extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *task); -extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *task); -extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *task); -extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); +/* + * This is not completely implemented yet. The idea is to + * create an in-memory tree (like the actual /proc filesystem + * tree) of these proc_dir_entries, so that we can dynamically + * add new files to /proc. + * + * The "next" pointer creates a linked list of one /proc directory, + * while parent/subdir create the directory structure (every + * /proc file has a parent, but "subdir" is NULL for all + * non-directory entries). + */ +struct proc_dir_entry { + unsigned int low_ino; + umode_t mode; + nlink_t nlink; + kuid_t uid; + kgid_t gid; + loff_t size; + const struct inode_operations *proc_iops; + const struct file_operations *proc_fops; + struct proc_dir_entry *next, *parent, *subdir; + void *data; + atomic_t count; /* use count */ + atomic_t in_use; /* number of callers into module in progress; */ + /* negative -> it's going away RSN */ + struct completion *pde_unload_completion; + struct list_head pde_openers; /* who did ->open, but not ->release */ + spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ + u8 namelen; + char name[]; +}; -extern const struct file_operations proc_tid_children_operations; -extern const struct file_operations proc_pid_maps_operations; -extern const struct file_operations proc_tid_maps_operations; -extern const struct file_operations proc_pid_numa_maps_operations; -extern const struct file_operations proc_tid_numa_maps_operations; -extern const struct file_operations proc_pid_smaps_operations; -extern const struct file_operations proc_tid_smaps_operations; -extern const struct file_operations proc_clear_refs_operations; -extern const struct file_operations proc_pagemap_operations; -extern const struct file_operations proc_net_operations; -extern const struct inode_operations proc_net_inode_operations; -extern const struct inode_operations proc_pid_link_inode_operations; +union proc_op { + int (*proc_get_link)(struct dentry *, struct path *); + int (*proc_read)(struct task_struct *task, char *page); + int (*proc_show)(struct seq_file *m, + struct pid_namespace *ns, struct pid *pid, + struct task_struct *task); +}; -struct proc_maps_private { +struct proc_inode { struct pid *pid; - struct task_struct *task; -#ifdef CONFIG_MMU - struct vm_area_struct *tail_vma; -#endif -#ifdef CONFIG_NUMA - struct mempolicy *task_mempolicy; -#endif + int fd; + union proc_op op; + struct proc_dir_entry *pde; + struct ctl_table_header *sysctl; + struct ctl_table *sysctl_entry; + struct proc_ns ns; + struct inode vfs_inode; }; -void proc_init_inodecache(void); +/* + * General functions + */ +static inline struct proc_inode *PROC_I(const struct inode *inode) +{ + return container_of(inode, struct proc_inode, vfs_inode); +} + +static inline struct proc_dir_entry *PDE(const struct inode *inode) +{ + return PROC_I(inode)->pde; +} + +static inline void *__PDE_DATA(const struct inode *inode) +{ + return PDE(inode)->data; +} static inline struct pid *proc_pid(struct inode *inode) { @@ -76,11 +97,6 @@ static inline struct task_struct *get_proc_task(struct inode *inode) return get_pid_task(proc_pid(inode), PIDTYPE_PID); } -static inline int proc_fd(struct inode *inode) -{ - return PROC_I(inode)->fd; -} - static inline int task_dumpable(struct task_struct *task) { int dumpable = 0; @@ -96,15 +112,6 @@ static inline int task_dumpable(struct task_struct *task) return 0; } -static inline int pid_delete_dentry(const struct dentry * dentry) -{ - /* Is the task we represent dead? - * If so, then don't put the dentry on the lru list, - * kill it immediately. - */ - return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; -} - static inline unsigned name_to_int(struct dentry *dentry) { const char *name = dentry->d_name.name; @@ -127,63 +134,165 @@ out: return ~0U; } -struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, - struct dentry *dentry); -int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, - filldir_t filldir); +/* + * Offset of the first process in the /proc root directory.. + */ +#define FIRST_PROCESS_ENTRY 256 + +/* Worst case buffer size needed for holding an integer. */ +#define PROC_NUMBUF 13 -struct pde_opener { - struct inode *inode; - struct file *file; - int (*release)(struct inode *, struct file *); - struct list_head lh; -}; -void pde_users_dec(struct proc_dir_entry *pde); +/* + * array.c + */ +extern const struct file_operations proc_tid_children_operations; +extern int proc_tid_stat(struct seq_file *, struct pid_namespace *, + struct pid *, struct task_struct *); +extern int proc_tgid_stat(struct seq_file *, struct pid_namespace *, + struct pid *, struct task_struct *); +extern int proc_pid_status(struct seq_file *, struct pid_namespace *, + struct pid *, struct task_struct *); +extern int proc_pid_statm(struct seq_file *, struct pid_namespace *, + struct pid *, struct task_struct *); + +/* + * base.c + */ +extern const struct dentry_operations pid_dentry_operations; +extern int pid_getattr(struct vfsmount *, struct dentry *, struct kstat *); +extern int proc_setattr(struct dentry *, struct iattr *); +extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *); +extern int pid_revalidate(struct dentry *, unsigned int); +extern int pid_delete_dentry(const struct dentry *); +extern int proc_pid_readdir(struct file *, void *, filldir_t); +extern struct dentry *proc_pid_lookup(struct inode *, struct dentry *, unsigned int); +extern loff_t mem_lseek(struct file *, loff_t, int); + +/* Lookups */ +typedef struct dentry *instantiate_t(struct inode *, struct dentry *, + struct task_struct *, const void *); +extern int proc_fill_cache(struct file *, void *, filldir_t, const char *, int, + instantiate_t, struct task_struct *, const void *); + +/* + * generic.c + */ extern spinlock_t proc_subdir_lock; -struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int); -int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); -unsigned long task_vsize(struct mm_struct *); -unsigned long task_statm(struct mm_struct *, - unsigned long *, unsigned long *, unsigned long *, unsigned long *); -void task_mem(struct seq_file *, struct mm_struct *); +extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int); +extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *, + struct dentry *); +extern int proc_readdir(struct file *, void *, filldir_t); +extern int proc_readdir_de(struct proc_dir_entry *, struct file *, void *, filldir_t); static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) { atomic_inc(&pde->count); return pde; } -void pde_put(struct proc_dir_entry *pde); - -int proc_fill_super(struct super_block *); -struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); -int proc_remount(struct super_block *sb, int *flags, char *data); +extern void pde_put(struct proc_dir_entry *); /* - * These are generic /proc routines that use the internal - * "struct proc_dir_entry" tree to traverse the filesystem. - * - * The /proc root directory has extended versions to take care - * of the /proc/<pid> subdirectories. + * inode.c */ -int proc_readdir(struct file *, void *, filldir_t); -struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int); +struct pde_opener { + struct file *file; + struct list_head lh; + int closing; + struct completion *c; +}; +extern const struct inode_operations proc_pid_link_inode_operations; +extern void proc_init_inodecache(void); +extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); +extern int proc_fill_super(struct super_block *); +extern void proc_entry_rundown(struct proc_dir_entry *); -/* Lookups */ -typedef struct dentry *instantiate_t(struct inode *, struct dentry *, - struct task_struct *, const void *); -int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, - const char *name, int len, - instantiate_t instantiate, struct task_struct *task, const void *ptr); -int pid_revalidate(struct dentry *dentry, unsigned int flags); -struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task); -extern const struct dentry_operations pid_dentry_operations; -int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); -int proc_setattr(struct dentry *dentry, struct iattr *attr); +/* + * proc_devtree.c + */ +#ifdef CONFIG_PROC_DEVICETREE +extern void proc_device_tree_init(void); +#endif +/* + * proc_namespaces.c + */ extern const struct inode_operations proc_ns_dir_inode_operations; extern const struct file_operations proc_ns_dir_operations; +/* + * proc_net.c + */ +extern const struct file_operations proc_net_operations; +extern const struct inode_operations proc_net_inode_operations; + +#ifdef CONFIG_NET +extern int proc_net_init(void); +#else +static inline int proc_net_init(void) { return 0; } +#endif + +/* + * proc_self.c + */ +extern int proc_setup_self(struct super_block *); + +/* + * proc_sysctl.c + */ +#ifdef CONFIG_PROC_SYSCTL +extern int proc_sys_init(void); +extern void sysctl_head_put(struct ctl_table_header *); +#else +static inline void proc_sys_init(void) { } +static inline void sysctl_head_put(struct ctl_table_header *head) { } +#endif + +/* + * proc_tty.c + */ +#ifdef CONFIG_TTY +extern void proc_tty_init(void); +#else +static inline void proc_tty_init(void) {} +#endif + +/* + * root.c + */ +extern struct proc_dir_entry proc_root; + +extern void proc_self_init(void); +extern int proc_remount(struct super_block *, int *, char *); + +/* + * task_[no]mmu.c + */ +struct proc_maps_private { + struct pid *pid; + struct task_struct *task; +#ifdef CONFIG_MMU + struct vm_area_struct *tail_vma; +#endif +#ifdef CONFIG_NUMA + struct mempolicy *task_mempolicy; +#endif +}; + +extern const struct file_operations proc_pid_maps_operations; +extern const struct file_operations proc_tid_maps_operations; +extern const struct file_operations proc_pid_numa_maps_operations; +extern const struct file_operations proc_tid_numa_maps_operations; +extern const struct file_operations proc_pid_smaps_operations; +extern const struct file_operations proc_tid_smaps_operations; +extern const struct file_operations proc_clear_refs_operations; +extern const struct file_operations proc_pagemap_operations; + +extern unsigned long task_vsize(struct mm_struct *); +extern unsigned long task_statm(struct mm_struct *, + unsigned long *, unsigned long *, + unsigned long *, unsigned long *); +extern void task_mem(struct seq_file *, struct mm_struct *); diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index f6a13f489e3..0a22194e5d5 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -11,6 +11,7 @@ #include <linux/mm.h> #include <linux/proc_fs.h> +#include <linux/kcore.h> #include <linux/user.h> #include <linux/capability.h> #include <linux/elf.h> @@ -28,6 +29,7 @@ #include <linux/ioport.h> #include <linux/memory.h> #include <asm/sections.h> +#include "internal.h" #define CORE_STR "CORE" diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 66b51c0383d..54bdc6701e9 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -51,7 +51,7 @@ static int ns_delete_dentry(const struct dentry *dentry) static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) { struct inode *inode = dentry->d_inode; - const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; + const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns.ns_ops; return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]", ns_ops->name, inode->i_ino); @@ -95,8 +95,8 @@ static struct dentry *proc_ns_get_dentry(struct super_block *sb, inode->i_op = &ns_inode_operations; inode->i_mode = S_IFREG | S_IRUGO; inode->i_fop = &ns_file_operations; - ei->ns_ops = ns_ops; - ei->ns = ns; + ei->ns.ns_ops = ns_ops; + ei->ns.ns = ns; unlock_new_inode(inode); } else { ns_ops->put(ns); @@ -128,7 +128,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd) if (!ptrace_may_access(task, PTRACE_MODE_READ)) goto out_put_task; - ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns_ops); + ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops); if (IS_ERR(ns_path.dentry)) { error = ERR_CAST(ns_path.dentry); goto out_put_task; @@ -148,7 +148,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl { struct inode *inode = dentry->d_inode; struct proc_inode *ei = PROC_I(inode); - const struct proc_ns_operations *ns_ops = ei->ns_ops; + const struct proc_ns_operations *ns_ops = ei->ns.ns_ops; struct task_struct *task; void *ns; char name[50]; @@ -202,7 +202,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir, ei = PROC_I(inode); inode->i_mode = S_IFLNK|S_IRWXUGO; inode->i_op = &proc_ns_link_inode_operations; - ei->ns_ops = ns_ops; + ei->ns.ns_ops = ns_ops; d_set_d_op(dentry, &pid_dentry_operations); d_add(dentry, inode); @@ -337,6 +337,11 @@ out_invalid: return ERR_PTR(-EINVAL); } +struct proc_ns *get_proc_ns(struct inode *inode) +{ + return &PROC_I(inode)->ns; +} + bool proc_ns_inode(struct inode *inode) { return inode->i_fop == &ns_file_operations; diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 30b590f5bd3..505afc950e0 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -41,7 +41,7 @@ static int property_proc_show(struct seq_file *m, void *v) static int property_proc_open(struct inode *inode, struct file *file) { - return single_open(file, property_proc_show, PDE(inode)->data); + return single_open(file, property_proc_show, __PDE_DATA(inode)); } static const struct file_operations property_proc_fops = { diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index b4ac6572474..986e83220d5 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -26,6 +26,10 @@ #include "internal.h" +static inline struct net *PDE_NET(struct proc_dir_entry *pde) +{ + return pde->parent->data; +} static struct net *get_proc_net(const struct inode *inode) { diff --git a/fs/proc/root.c b/fs/proc/root.c index 9c7fab1d23f..41a6ea93f48 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -141,6 +141,8 @@ static void proc_kill_sb(struct super_block *sb) struct pid_namespace *ns; ns = (struct pid_namespace *)sb->s_fs_info; + if (ns->proc_self) + dput(ns->proc_self); kill_anon_super(sb); put_pid_ns(ns); } diff --git a/fs/proc/self.c b/fs/proc/self.c index aa5cc3bff14..6b6a993b5c2 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -1,6 +1,8 @@ -#include <linux/proc_fs.h> #include <linux/sched.h> #include <linux/namei.h> +#include <linux/slab.h> +#include <linux/pid_namespace.h> +#include "internal.h" /* * /proc/self: @@ -48,12 +50,43 @@ static const struct inode_operations proc_self_inode_operations = { .put_link = proc_self_put_link, }; -void __init proc_self_init(void) +static unsigned self_inum; + +int proc_setup_self(struct super_block *s) { - struct proc_dir_entry *proc_self_symlink; - mode_t mode; + struct inode *root_inode = s->s_root->d_inode; + struct pid_namespace *ns = s->s_fs_info; + struct dentry *self; + + mutex_lock(&root_inode->i_mutex); + self = d_alloc_name(s->s_root, "self"); + if (self) { + struct inode *inode = new_inode_pseudo(s); + if (inode) { + inode->i_ino = self_inum; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mode = S_IFLNK | S_IRWXUGO; + inode->i_uid = GLOBAL_ROOT_UID; + inode->i_gid = GLOBAL_ROOT_GID; + inode->i_op = &proc_self_inode_operations; + d_add(self, inode); + } else { + dput(self); + self = ERR_PTR(-ENOMEM); + } + } else { + self = ERR_PTR(-ENOMEM); + } + mutex_unlock(&root_inode->i_mutex); + if (IS_ERR(self)) { + pr_err("proc_fill_super: can't allocate /proc/self\n"); + return PTR_ERR(self); + } + ns->proc_self = self; + return 0; +} - mode = S_IFLNK | S_IRWXUGO; - proc_self_symlink = proc_create("self", mode, NULL, NULL ); - proc_self_symlink->proc_iops = &proc_self_inode_operations; +void __init proc_self_init(void) +{ + proc_alloc_inum(&self_inum); } diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index b870f740ab5..17f7e080d7f 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -8,7 +8,7 @@ */ #include <linux/mm.h> -#include <linux/proc_fs.h> +#include <linux/kcore.h> #include <linux/user.h> #include <linux/elf.h> #include <linux/elfcore.h> @@ -22,6 +22,7 @@ #include <linux/list.h> #include <asm/uaccess.h> #include <asm/io.h> +#include "internal.h" /* List representing chunks of contiguous memory areas and their offsets in * vmcore file. @@ -698,7 +699,7 @@ void vmcore_cleanup(void) struct list_head *pos, *next; if (proc_vmcore) { - remove_proc_entry(proc_vmcore->name, proc_vmcore->parent); + proc_remove(proc_vmcore); proc_vmcore = NULL; } diff --git a/fs/read_write.c b/fs/read_write.c index 8274a794253..605dbbcb197 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -459,6 +459,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; + file_start_write(file); if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else @@ -468,6 +469,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ add_wchar(current, ret); } inc_syscw(current); + file_end_write(file); } return ret; @@ -576,7 +578,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) } EXPORT_SYMBOL(iov_shorten); -ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, +static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) { struct kiocb kiocb; @@ -601,7 +603,7 @@ ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, } /* Do it by hand, with file-ops */ -ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, +static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, unsigned long nr_segs, loff_t *ppos, io_fn_t fn) { struct iovec *vector = iov; @@ -743,6 +745,7 @@ static ssize_t do_readv_writev(int type, struct file *file, } else { fn = (io_fn_t)file->f_op->write; fnv = file->f_op->aio_write; + file_start_write(file); } if (fnv) @@ -751,6 +754,9 @@ static ssize_t do_readv_writev(int type, struct file *file, else ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); + if (type != READ) + file_end_write(file); + out: if (iov != iovstack) kfree(iov); @@ -881,6 +887,201 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, return ret; } +#ifdef CONFIG_COMPAT + +static ssize_t compat_do_readv_writev(int type, struct file *file, + const struct compat_iovec __user *uvector, + unsigned long nr_segs, loff_t *pos) +{ + compat_ssize_t tot_len; + struct iovec iovstack[UIO_FASTIOV]; + struct iovec *iov = iovstack; + ssize_t ret; + io_fn_t fn; + iov_fn_t fnv; + + ret = -EINVAL; + if (!file->f_op) + goto out; + + ret = -EFAULT; + if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) + goto out; + + ret = compat_rw_copy_check_uvector(type, uvector, nr_segs, + UIO_FASTIOV, iovstack, &iov); + if (ret <= 0) + goto out; + + tot_len = ret; + ret = rw_verify_area(type, file, pos, tot_len); + if (ret < 0) + goto out; + + fnv = NULL; + if (type == READ) { + fn = file->f_op->read; + fnv = file->f_op->aio_read; + } else { + fn = (io_fn_t)file->f_op->write; + fnv = file->f_op->aio_write; + file_start_write(file); + } + + if (fnv) + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, + pos, fnv); + else + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); + + if (type != READ) + file_end_write(file); + +out: + if (iov != iovstack) + kfree(iov); + if ((ret + (type == READ)) > 0) { + if (type == READ) + fsnotify_access(file); + else + fsnotify_modify(file); + } + return ret; +} + +static size_t compat_readv(struct file *file, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t *pos) +{ + ssize_t ret = -EBADF; + + if (!(file->f_mode & FMODE_READ)) + goto out; + + ret = -EINVAL; + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) + goto out; + + ret = compat_do_readv_writev(READ, file, vec, vlen, pos); + +out: + if (ret > 0) + add_rchar(current, ret); + inc_syscr(current); + return ret; +} + +COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen) +{ + struct fd f = fdget(fd); + ssize_t ret; + loff_t pos; + + if (!f.file) + return -EBADF; + pos = f.file->f_pos; + ret = compat_readv(f.file, vec, vlen, &pos); + f.file->f_pos = pos; + fdput(f); + return ret; +} + +COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos) +{ + struct fd f; + ssize_t ret; + + if (pos < 0) + return -EINVAL; + f = fdget(fd); + if (!f.file) + return -EBADF; + ret = -ESPIPE; + if (f.file->f_mode & FMODE_PREAD) + ret = compat_readv(f.file, vec, vlen, &pos); + fdput(f); + return ret; +} + +COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, u32, pos_low, u32, pos_high) +{ + loff_t pos = ((loff_t)pos_high << 32) | pos_low; + return compat_sys_preadv64(fd, vec, vlen, pos); +} + +static size_t compat_writev(struct file *file, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t *pos) +{ + ssize_t ret = -EBADF; + + if (!(file->f_mode & FMODE_WRITE)) + goto out; + + ret = -EINVAL; + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) + goto out; + + ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); + +out: + if (ret > 0) + add_wchar(current, ret); + inc_syscw(current); + return ret; +} + +COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd, + const struct compat_iovec __user *, vec, + unsigned long, vlen) +{ + struct fd f = fdget(fd); + ssize_t ret; + loff_t pos; + + if (!f.file) + return -EBADF; + pos = f.file->f_pos; + ret = compat_writev(f.file, vec, vlen, &pos); + f.file->f_pos = pos; + fdput(f); + return ret; +} + +COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos) +{ + struct fd f; + ssize_t ret; + + if (pos < 0) + return -EINVAL; + f = fdget(fd); + if (!f.file) + return -EBADF; + ret = -ESPIPE; + if (f.file->f_mode & FMODE_PWRITE) + ret = compat_writev(f.file, vec, vlen, &pos); + fdput(f); + return ret; +} + +COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, u32, pos_low, u32, pos_high) +{ + loff_t pos = ((loff_t)pos_high << 32) | pos_low; + return compat_sys_pwritev64(fd, vec, vlen, pos); +} +#endif + static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, loff_t max) { diff --git a/fs/read_write.h b/fs/read_write.h index d07b954c6e0..0ec530d9305 100644 --- a/fs/read_write.h +++ b/fs/read_write.h @@ -7,8 +7,3 @@ typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *, unsigned long, loff_t); - -ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, - unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); -ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, - unsigned long nr_segs, loff_t *ppos, io_fn_t fn); diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 6165bd4784f..dcaafcfc23b 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -234,68 +234,9 @@ int reiserfs_commit_page(struct inode *inode, struct page *page, return ret; } -/* Write @count bytes at position @ppos in a file indicated by @file - from the buffer @buf. - - generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want - something simple that works. It is not for serious use by general purpose filesystems, excepting the one that it was - written for (ext2/3). This is for several reasons: - - * It has no understanding of any filesystem specific optimizations. - - * It enters the filesystem repeatedly for each page that is written. - - * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key - * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time - * to reiserfs which allows for fewer tree traversals. - - * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks. - - * Asking the block allocation code for blocks one at a time is slightly less efficient. - - All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to - use it, but we were in a hurry to make code freeze, and so it couldn't be revised then. This new code should make - things right finally. - - Future Features: providing search_by_key with hints. - -*/ -static ssize_t reiserfs_file_write(struct file *file, /* the file we are going to write into */ - const char __user * buf, /* pointer to user supplied data - (in userspace) */ - size_t count, /* amount of bytes to write */ - loff_t * ppos /* pointer to position in file that we start writing at. Should be updated to - * new current position before returning. */ - ) -{ - struct inode *inode = file_inode(file); // Inode of the file that we are writing to. - /* To simplify coding at this time, we store - locked pages in array for now */ - struct reiserfs_transaction_handle th; - th.t_trans_id = 0; - - /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items - * lying around (most of the disk, in fact). Despite the filesystem - * now being a v3.6 format, the old items still can't support large - * file sizes. Catch this case here, as the rest of the VFS layer is - * oblivious to the different limitations between old and new items. - * reiserfs_setattr catches this for truncates. This chunk is lifted - * from generic_write_checks. */ - if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 && - *ppos + count > MAX_NON_LFS) { - if (*ppos >= MAX_NON_LFS) { - return -EFBIG; - } - if (count > MAX_NON_LFS - (unsigned long)*ppos) - count = MAX_NON_LFS - (unsigned long)*ppos; - } - - return do_sync_write(file, buf, count, ppos); -} - const struct file_operations reiserfs_file_operations = { .read = do_sync_read, - .write = reiserfs_file_write, + .write = do_sync_write, .unlocked_ioctl = reiserfs_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = reiserfs_compat_ioctl, diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 9cc0740adff..33532f79b4f 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c @@ -394,20 +394,24 @@ static int set_sb(struct super_block *sb, void *data) return -ENOENT; } +struct reiserfs_seq_private { + struct super_block *sb; + int (*show) (struct seq_file *, struct super_block *); +}; + static void *r_start(struct seq_file *m, loff_t * pos) { - struct proc_dir_entry *de = m->private; - struct super_block *s = de->parent->data; + struct reiserfs_seq_private *priv = m->private; loff_t l = *pos; if (l) return NULL; - if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, s))) + if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb))) return NULL; - up_write(&s->s_umount); - return s; + up_write(&priv->sb->s_umount); + return priv->sb; } static void *r_next(struct seq_file *m, void *v, loff_t * pos) @@ -426,9 +430,8 @@ static void r_stop(struct seq_file *m, void *v) static int r_show(struct seq_file *m, void *v) { - struct proc_dir_entry *de = m->private; - int (*show) (struct seq_file *, struct super_block *) = de->data; - return show(m, v); + struct reiserfs_seq_private *priv = m->private; + return priv->show(m, v); } static const struct seq_operations r_ops = { @@ -440,11 +443,15 @@ static const struct seq_operations r_ops = { static int r_open(struct inode *inode, struct file *file) { - int ret = seq_open(file, &r_ops); + struct reiserfs_seq_private *priv; + int ret = seq_open_private(file, &r_ops, + sizeof(struct reiserfs_seq_private)); if (!ret) { struct seq_file *m = file->private_data; - m->private = PDE(inode); + priv = m->private; + priv->sb = proc_get_parent_data(inode); + priv->show = PDE_DATA(inode); } return ret; } @@ -453,7 +460,7 @@ static const struct file_operations r_file_operations = { .open = r_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, .owner = THIS_MODULE, }; @@ -479,9 +486,8 @@ int reiserfs_proc_info_init(struct super_block *sb) *s = '!'; spin_lock_init(&__PINFO(sb).lock); - REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root); + REISERFS_SB(sb)->procdir = proc_mkdir_data(b, 0, proc_info_root, sb); if (REISERFS_SB(sb)->procdir) { - REISERFS_SB(sb)->procdir->data = sb; add_file(sb, "version", show_version); add_file(sb, "super", show_super); add_file(sb, "per-level", show_per_level); @@ -499,29 +505,17 @@ int reiserfs_proc_info_init(struct super_block *sb) int reiserfs_proc_info_done(struct super_block *sb) { struct proc_dir_entry *de = REISERFS_SB(sb)->procdir; - char b[BDEVNAME_SIZE]; - char *s; + if (de) { + char b[BDEVNAME_SIZE]; + char *s; - /* Some block devices use /'s */ - strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); - s = strchr(b, '/'); - if (s) - *s = '!'; + /* Some block devices use /'s */ + strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); + s = strchr(b, '/'); + if (s) + *s = '!'; - if (de) { - remove_proc_entry("journal", de); - remove_proc_entry("oidmap", de); - remove_proc_entry("on-disk-super", de); - remove_proc_entry("bitmap", de); - remove_proc_entry("per-level", de); - remove_proc_entry("super", de); - remove_proc_entry("version", de); - } - spin_lock(&__PINFO(sb).lock); - __PINFO(sb).exiting = 1; - spin_unlock(&__PINFO(sb).lock); - if (proc_info_root) { - remove_proc_entry(b, proc_info_root); + remove_proc_subtree(b, proc_info_root); REISERFS_SB(sb)->procdir = NULL; } return 0; diff --git a/fs/seq_file.c b/fs/seq_file.c index 38bb59f3f2a..774c1eb7f1c 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -599,6 +599,24 @@ int single_open(struct file *file, int (*show)(struct seq_file *, void *), } EXPORT_SYMBOL(single_open); +int single_open_size(struct file *file, int (*show)(struct seq_file *, void *), + void *data, size_t size) +{ + char *buf = kmalloc(size, GFP_KERNEL); + int ret; + if (!buf) + return -ENOMEM; + ret = single_open(file, show, data); + if (ret) { + kfree(buf); + return ret; + } + ((struct seq_file *)file->private_data)->buf = buf; + ((struct seq_file *)file->private_data)->size = size; + return 0; +} +EXPORT_SYMBOL(single_open_size); + int single_release(struct inode *inode, struct file *file) { const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; diff --git a/fs/splice.c b/fs/splice.c index 6b485b8753b..e6b25598c8c 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -219,7 +219,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, page_nr++; ret += buf->len; - if (pipe->inode) + if (pipe->files) do_wakeup = 1; if (!--spd->nr_pages) @@ -829,7 +829,7 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, ops->release(pipe, buf); pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); pipe->nrbufs--; - if (pipe->inode) + if (pipe->files) sd->need_wakeup = true; } @@ -1001,8 +1001,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, }; ssize_t ret; - sb_start_write(inode->i_sb); - pipe_lock(pipe); splice_from_pipe_begin(&sd); @@ -1038,7 +1036,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, *ppos += ret; balance_dirty_pages_ratelimited(mapping); } - sb_end_write(inode->i_sb); return ret; } @@ -1118,7 +1115,10 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, else splice_write = default_file_splice_write; - return splice_write(pipe, out, ppos, len, flags); + file_start_write(out); + ret = splice_write(pipe, out, ppos, len, flags); + file_end_write(out); + return ret; } /* @@ -1184,7 +1184,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, */ pipe = current->splice_pipe; if (unlikely(!pipe)) { - pipe = alloc_pipe_info(NULL); + pipe = alloc_pipe_info(); if (!pipe) return -ENOMEM; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f03bf1a456f..3800128d217 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -775,8 +775,6 @@ xfs_file_aio_write( if (ocount == 0) return 0; - sb_start_write(inode->i_sb); - if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { ret = -EIO; goto out; @@ -800,7 +798,6 @@ xfs_file_aio_write( } out: - sb_end_write(inode->i_sb); return ret; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2d94d7413d7..60c33f14408 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1022,7 +1022,7 @@ struct drm_info_list { struct drm_info_node { struct list_head list; struct drm_minor *minor; - struct drm_info_list *info_ent; + const struct drm_info_list *info_ent; struct dentry *dent; }; @@ -1546,8 +1546,7 @@ extern struct idr drm_minors_idr; extern struct drm_local_map *drm_getsarea(struct drm_device *dev); /* Proc support (drm_proc.h) */ -extern int drm_proc_init(struct drm_minor *minor, int minor_id, - struct proc_dir_entry *root); +extern int drm_proc_init(struct drm_minor *minor, struct proc_dir_entry *root); extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); /* Debugfs support */ diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c3a09149f79..70cf138690e 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -118,5 +118,6 @@ extern int prepare_bprm_creds(struct linux_binprm *bprm); extern void install_exec_creds(struct linux_binprm *bprm); extern void set_binfmt(struct linux_binfmt *new); extern void free_bprm(struct linux_binprm *); +extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t); #endif /* _LINUX_BINFMTS_H */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 646ab9d15e4..3bff9ce09cf 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -39,7 +39,7 @@ extern int cgroupstats_build(struct cgroupstats *stats, extern int cgroup_load_subsys(struct cgroup_subsys *ss); extern void cgroup_unload_subsys(struct cgroup_subsys *ss); -extern const struct file_operations proc_cgroup_operations; +extern int proc_cgroup_show(struct seq_file *, void *); /* * Define the enumeration of all cgroup subsystems. diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index ccd1de8ad82..cc1b01cf203 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -63,10 +63,9 @@ extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1, extern int cpuset_memory_pressure_enabled; extern void __cpuset_memory_pressure_bump(void); -extern const struct file_operations proc_cpuset_operations; -struct seq_file; extern void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task); +extern int proc_cpuset_show(struct seq_file *, void *); extern int cpuset_mem_spread_node(void); extern int cpuset_slab_spread_node(void); diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index fb7dacae052..085197bd881 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -27,7 +27,6 @@ struct fdtable { unsigned long *close_on_exec; unsigned long *open_fds; struct rcu_head rcu; - struct fdtable *next; }; static inline bool close_on_exec(int fd, const struct fdtable *fdt) diff --git a/include/linux/fs.h b/include/linux/fs.h index 17d8b159621..e8cd6b83967 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2082,7 +2082,6 @@ extern int sync_filesystem(struct super_block *); extern const struct file_operations def_blk_fops; extern const struct file_operations def_chr_fops; extern const struct file_operations bad_sock_fops; -extern const struct file_operations def_fifo_fops; #ifdef CONFIG_BLOCK extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); @@ -2154,10 +2153,6 @@ extern void init_special_inode(struct inode *, umode_t, dev_t); extern void make_bad_inode(struct inode *); extern int is_bad_inode(struct inode *); -extern const struct file_operations read_pipefifo_fops; -extern const struct file_operations write_pipefifo_fops; -extern const struct file_operations rdwr_pipefifo_fops; - #ifdef CONFIG_BLOCK /* * return READ, READA, or WRITE @@ -2225,6 +2220,20 @@ static inline struct inode *file_inode(struct file *f) return f->f_inode; } +static inline void file_start_write(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return; + __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); +} + +static inline void file_end_write(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return; + __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); +} + /* * get_write_access() gets write permission for a file. * put_write_access() releases this write permission. diff --git a/include/linux/kcore.h b/include/linux/kcore.h new file mode 100644 index 00000000000..d9276228664 --- /dev/null +++ b/include/linux/kcore.h @@ -0,0 +1,38 @@ +/* + * /proc/kcore definitions + */ +#ifndef _LINUX_KCORE_H +#define _LINUX_KCORE_H + +enum kcore_type { + KCORE_TEXT, + KCORE_VMALLOC, + KCORE_RAM, + KCORE_VMEMMAP, + KCORE_OTHER, +}; + +struct kcore_list { + struct list_head list; + unsigned long addr; + size_t size; + int type; +}; + +struct vmcore { + struct list_head list; + unsigned long long paddr; + unsigned long long size; + loff_t offset; +}; + +#ifdef CONFIG_PROC_KCORE +extern void kclist_add(struct kcore_list *, void *, size_t, int type); +#else +static inline +void kclist_add(struct kcore_list *new, void *addr, size_t size, int type) +{ +} +#endif + +#endif /* _LINUX_KCORE_H */ diff --git a/include/linux/nubus.h b/include/linux/nubus.h index a8696bbdfbc..b3740527571 100644 --- a/include/linux/nubus.h +++ b/include/linux/nubus.h @@ -80,7 +80,11 @@ extern struct nubus_board* nubus_boards; /* Generic NuBus interface functions, modelled after the PCI interface */ void nubus_scan_bus(void); +#ifdef CONFIG_PROC_FS extern void nubus_proc_init(void); +#else +static inline void nubus_proc_init(void) {} +#endif int get_nubus_list(char *buf); int nubus_proc_attach_device(struct nubus_dev *dev); int nubus_proc_detach_device(struct nubus_dev *dev); diff --git a/include/linux/of.h b/include/linux/of.h index a0f12928494..2d25ff8fe39 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -540,4 +540,14 @@ static inline int of_property_read_u32(const struct device_node *np, return of_property_read_u32_array(np, propname, out_value, 1); } +#if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE) +extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); +extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); +extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde, + struct property *prop); +extern void proc_device_tree_update_prop(struct proc_dir_entry *pde, + struct property *newprop, + struct property *oldprop); +#endif + #endif /* _LINUX_OF_H */ diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 8ac32836690..731e4ecee3b 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -30,6 +30,7 @@ struct pid_namespace { struct pid_namespace *parent; #ifdef CONFIG_PROC_FS struct vfsmount *proc_mnt; + struct dentry *proc_self; #endif #ifdef CONFIG_BSD_PROCESS_ACCT struct bsd_acct_struct *bacct; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ad1a427b526..b8809fef61f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -27,6 +27,7 @@ struct pipe_buffer { /** * struct pipe_inode_info - a linux kernel pipe + * @mutex: mutex protecting the whole thing * @wait: reader/writer wait point in case of empty/full pipe * @nrbufs: the number of non-empty pipe buffers in this pipe * @buffers: total number of buffers (should be a power of 2) @@ -34,26 +35,27 @@ struct pipe_buffer { * @tmp_page: cached released page * @readers: number of current readers of this pipe * @writers: number of current writers of this pipe + * @files: number of struct file refering this pipe (protected by ->i_lock) * @waiting_writers: number of writers blocked waiting for room * @r_counter: reader counter * @w_counter: writer counter * @fasync_readers: reader side fasync * @fasync_writers: writer side fasync - * @inode: inode this pipe is attached to * @bufs: the circular array of pipe buffers **/ struct pipe_inode_info { + struct mutex mutex; wait_queue_head_t wait; unsigned int nrbufs, curbuf, buffers; unsigned int readers; unsigned int writers; + unsigned int files; unsigned int waiting_writers; unsigned int r_counter; unsigned int w_counter; struct page *tmp_page; struct fasync_struct *fasync_readers; struct fasync_struct *fasync_writers; - struct inode *inode; struct pipe_buffer *bufs; }; @@ -144,9 +146,8 @@ int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct pipe_inode_info *pipe); -struct pipe_inode_info * alloc_pipe_info(struct inode * inode); -void free_pipe_info(struct inode * inode); -void __free_pipe_info(struct pipe_inode_info *); +struct pipe_inode_info *alloc_pipe_info(void); +void free_pipe_info(struct pipe_inode_info *); /* Generic pipe buffer ops functions */ void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 94dfb2aa553..608e60a74c3 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -1,318 +1,79 @@ -#ifndef _LINUX_PROC_FS_H -#define _LINUX_PROC_FS_H - -#include <linux/slab.h> -#include <linux/fs.h> -#include <linux/spinlock.h> -#include <linux/magic.h> -#include <linux/atomic.h> - -struct net; -struct completion; -struct mm_struct; - /* * The proc filesystem constants/structures */ +#ifndef _LINUX_PROC_FS_H +#define _LINUX_PROC_FS_H -/* - * Offset of the first process in the /proc root directory.. - */ -#define FIRST_PROCESS_ENTRY 256 - -/* Worst case buffer size needed for holding an integer. */ -#define PROC_NUMBUF 13 - -/* - * We always define these enumerators - */ - -enum { - PROC_ROOT_INO = 1, - PROC_IPC_INIT_INO = 0xEFFFFFFFU, - PROC_UTS_INIT_INO = 0xEFFFFFFEU, - PROC_USER_INIT_INO = 0xEFFFFFFDU, - PROC_PID_INIT_INO = 0xEFFFFFFCU, -}; - -/* - * This is not completely implemented yet. The idea is to - * create an in-memory tree (like the actual /proc filesystem - * tree) of these proc_dir_entries, so that we can dynamically - * add new files to /proc. - * - * The "next" pointer creates a linked list of one /proc directory, - * while parent/subdir create the directory structure (every - * /proc file has a parent, but "subdir" is NULL for all - * non-directory entries). - */ - -typedef int (read_proc_t)(char *page, char **start, off_t off, - int count, int *eof, void *data); -typedef int (write_proc_t)(struct file *file, const char __user *buffer, - unsigned long count, void *data); - -struct proc_dir_entry { - unsigned int low_ino; - umode_t mode; - nlink_t nlink; - kuid_t uid; - kgid_t gid; - loff_t size; - const struct inode_operations *proc_iops; - /* - * NULL ->proc_fops means "PDE is going away RSN" or - * "PDE is just created". In either case, e.g. ->read_proc won't be - * called because it's too late or too early, respectively. - * - * If you're allocating ->proc_fops dynamically, save a pointer - * somewhere. - */ - const struct file_operations *proc_fops; - struct proc_dir_entry *next, *parent, *subdir; - void *data; - read_proc_t *read_proc; - write_proc_t *write_proc; - atomic_t count; /* use count */ - int pde_users; /* number of callers into module in progress */ - struct completion *pde_unload_completion; - struct list_head pde_openers; /* who did ->open, but not ->release */ - spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ - u8 namelen; - char name[]; -}; - -enum kcore_type { - KCORE_TEXT, - KCORE_VMALLOC, - KCORE_RAM, - KCORE_VMEMMAP, - KCORE_OTHER, -}; - -struct kcore_list { - struct list_head list; - unsigned long addr; - size_t size; - int type; -}; +#include <linux/types.h> +#include <linux/fs.h> -struct vmcore { - struct list_head list; - unsigned long long paddr; - unsigned long long size; - loff_t offset; -}; +struct proc_dir_entry; #ifdef CONFIG_PROC_FS extern void proc_root_init(void); - -void proc_flush_task(struct task_struct *task); - -extern struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode, - struct proc_dir_entry *parent); -struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, - struct proc_dir_entry *parent, - const struct file_operations *proc_fops, - void *data); -extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); -extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent); - -struct pid_namespace; - -extern int pid_ns_prepare_proc(struct pid_namespace *ns); -extern void pid_ns_release_proc(struct pid_namespace *ns); - -/* - * proc_tty.c - */ -struct tty_driver; -#ifdef CONFIG_TTY -extern void proc_tty_init(void); -#else -static inline void proc_tty_init(void) -{ } -#endif -extern void proc_tty_register_driver(struct tty_driver *driver); -extern void proc_tty_unregister_driver(struct tty_driver *driver); - -/* - * proc_devtree.c - */ -#ifdef CONFIG_PROC_DEVICETREE -struct device_node; -struct property; -extern void proc_device_tree_init(void); -extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); -extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); -extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde, - struct property *prop); -extern void proc_device_tree_update_prop(struct proc_dir_entry *pde, - struct property *newprop, - struct property *oldprop); -#endif /* CONFIG_PROC_DEVICETREE */ +extern void proc_flush_task(struct task_struct *); extern struct proc_dir_entry *proc_symlink(const char *, struct proc_dir_entry *, const char *); -extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *); -extern struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, - struct proc_dir_entry *parent); - -static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode, - struct proc_dir_entry *parent, const struct file_operations *proc_fops) +extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *); +extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, + struct proc_dir_entry *, void *); +extern struct proc_dir_entry *proc_mkdir_mode(const char *, umode_t, + struct proc_dir_entry *); + +extern struct proc_dir_entry *proc_create_data(const char *, umode_t, + struct proc_dir_entry *, + const struct file_operations *, + void *); + +static inline struct proc_dir_entry *proc_create( + const char *name, umode_t mode, struct proc_dir_entry *parent, + const struct file_operations *proc_fops) { return proc_create_data(name, mode, parent, proc_fops, NULL); } -static inline struct proc_dir_entry *create_proc_read_entry(const char *name, - umode_t mode, struct proc_dir_entry *base, - read_proc_t *read_proc, void * data) -{ - struct proc_dir_entry *res=create_proc_entry(name,mode,base); - if (res) { - res->read_proc=read_proc; - res->data=data; - } - return res; -} - -extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, - struct proc_dir_entry *parent); - -extern struct file *proc_ns_fget(int fd); -extern bool proc_ns_inode(struct inode *inode); +extern void proc_set_size(struct proc_dir_entry *, loff_t); +extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t); +extern void *PDE_DATA(const struct inode *); +extern void *proc_get_parent_data(const struct inode *); +extern void proc_remove(struct proc_dir_entry *); +extern void remove_proc_entry(const char *, struct proc_dir_entry *); +extern int remove_proc_subtree(const char *, struct proc_dir_entry *); -extern int proc_alloc_inum(unsigned int *pino); -extern void proc_free_inum(unsigned int inum); -#else +#else /* CONFIG_PROC_FS */ static inline void proc_flush_task(struct task_struct *task) { } -static inline struct proc_dir_entry *create_proc_entry(const char *name, - umode_t mode, struct proc_dir_entry *parent) { return NULL; } - -#define proc_create(name, mode, parent, fops) ({ (void)(mode), NULL; }) - -static inline struct proc_dir_entry *proc_create_data(const char *name, - umode_t mode, struct proc_dir_entry *parent, - const struct file_operations *proc_fops, void *data) -{ - return NULL; -} -#define remove_proc_entry(name, parent) do {} while (0) -#define remove_proc_subtree(name, parent) do {} while (0) - static inline struct proc_dir_entry *proc_symlink(const char *name, - struct proc_dir_entry *parent,const char *dest) {return NULL;} + struct proc_dir_entry *parent,const char *dest) { return NULL;} static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} +static inline struct proc_dir_entry *proc_mkdir_data(const char *name, + umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; } static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, struct proc_dir_entry *parent) { return NULL; } +#define proc_create(name, mode, parent, proc_fops) ({NULL;}) +#define proc_create_data(name, mode, parent, proc_fops, data) ({NULL;}) -static inline struct proc_dir_entry *create_proc_read_entry(const char *name, - umode_t mode, struct proc_dir_entry *base, - read_proc_t *read_proc, void * data) { return NULL; } - -struct tty_driver; -static inline void proc_tty_register_driver(struct tty_driver *driver) {}; -static inline void proc_tty_unregister_driver(struct tty_driver *driver) {}; +static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {} +static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {} +static inline void *PDE_DATA(const struct inode *inode) {BUG(); return NULL;} +static inline void *proc_get_parent_data(const struct inode *inode) { BUG(); return NULL; } -static inline int pid_ns_prepare_proc(struct pid_namespace *ns) -{ - return 0; -} - -static inline void pid_ns_release_proc(struct pid_namespace *ns) -{ -} - -static inline struct file *proc_ns_fget(int fd) -{ - return ERR_PTR(-EINVAL); -} - -static inline bool proc_ns_inode(struct inode *inode) -{ - return false; -} +static inline void proc_remove(struct proc_dir_entry *de) {} +#define remove_proc_entry(name, parent) do {} while (0) +static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; } -static inline int proc_alloc_inum(unsigned int *inum) -{ - *inum = 1; - return 0; -} -static inline void proc_free_inum(unsigned int inum) -{ -} #endif /* CONFIG_PROC_FS */ -#if !defined(CONFIG_PROC_KCORE) -static inline void -kclist_add(struct kcore_list *new, void *addr, size_t size, int type) +static inline struct proc_dir_entry *proc_net_mkdir( + struct net *net, const char *name, struct proc_dir_entry *parent) { + return proc_mkdir_data(name, 0, parent, net); } -#else -extern void kclist_add(struct kcore_list *, void *, size_t, int type); -#endif - -struct nsproxy; -struct proc_ns_operations { - const char *name; - int type; - void *(*get)(struct task_struct *task); - void (*put)(void *ns); - int (*install)(struct nsproxy *nsproxy, void *ns); - unsigned int (*inum)(void *ns); -}; -extern const struct proc_ns_operations netns_operations; -extern const struct proc_ns_operations utsns_operations; -extern const struct proc_ns_operations ipcns_operations; -extern const struct proc_ns_operations pidns_operations; -extern const struct proc_ns_operations userns_operations; -extern const struct proc_ns_operations mntns_operations; - -union proc_op { - int (*proc_get_link)(struct dentry *, struct path *); - int (*proc_read)(struct task_struct *task, char *page); - int (*proc_show)(struct seq_file *m, - struct pid_namespace *ns, struct pid *pid, - struct task_struct *task); -}; - -struct ctl_table_header; -struct ctl_table; - -struct proc_inode { - struct pid *pid; - int fd; - union proc_op op; - struct proc_dir_entry *pde; - struct ctl_table_header *sysctl; - struct ctl_table *sysctl_entry; - void *ns; - const struct proc_ns_operations *ns_ops; - struct inode vfs_inode; -}; - -static inline struct proc_inode *PROC_I(const struct inode *inode) -{ - return container_of(inode, struct proc_inode, vfs_inode); -} - -static inline struct proc_dir_entry *PDE(const struct inode *inode) -{ - return PROC_I(inode)->pde; -} - -static inline struct net *PDE_NET(struct proc_dir_entry *pde) -{ - return pde->parent->data; -} - -#include <linux/signal.h> -void render_sigset_t(struct seq_file *m, const char *header, sigset_t *set); #endif /* _LINUX_PROC_FS_H */ diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h new file mode 100644 index 00000000000..34a1e105bef --- /dev/null +++ b/include/linux/proc_ns.h @@ -0,0 +1,74 @@ +/* + * procfs namespace bits + */ +#ifndef _LINUX_PROC_NS_H +#define _LINUX_PROC_NS_H + +struct pid_namespace; +struct nsproxy; + +struct proc_ns_operations { + const char *name; + int type; + void *(*get)(struct task_struct *task); + void (*put)(void *ns); + int (*install)(struct nsproxy *nsproxy, void *ns); + unsigned int (*inum)(void *ns); +}; + +struct proc_ns { + void *ns; + const struct proc_ns_operations *ns_ops; +}; + +extern const struct proc_ns_operations netns_operations; +extern const struct proc_ns_operations utsns_operations; +extern const struct proc_ns_operations ipcns_operations; +extern const struct proc_ns_operations pidns_operations; +extern const struct proc_ns_operations userns_operations; +extern const struct proc_ns_operations mntns_operations; + +/* + * We always define these enumerators + */ +enum { + PROC_ROOT_INO = 1, + PROC_IPC_INIT_INO = 0xEFFFFFFFU, + PROC_UTS_INIT_INO = 0xEFFFFFFEU, + PROC_USER_INIT_INO = 0xEFFFFFFDU, + PROC_PID_INIT_INO = 0xEFFFFFFCU, +}; + +#ifdef CONFIG_PROC_FS + +extern int pid_ns_prepare_proc(struct pid_namespace *ns); +extern void pid_ns_release_proc(struct pid_namespace *ns); +extern struct file *proc_ns_fget(int fd); +extern struct proc_ns *get_proc_ns(struct inode *); +extern int proc_alloc_inum(unsigned int *pino); +extern void proc_free_inum(unsigned int inum); +extern bool proc_ns_inode(struct inode *inode); + +#else /* CONFIG_PROC_FS */ + +static inline int pid_ns_prepare_proc(struct pid_namespace *ns) { return 0; } +static inline void pid_ns_release_proc(struct pid_namespace *ns) {} + +static inline struct file *proc_ns_fget(int fd) +{ + return ERR_PTR(-EINVAL); +} + +static inline struct proc_ns *get_proc_ns(struct inode *inode) { return NULL; } + +static inline int proc_alloc_inum(unsigned int *inum) +{ + *inum = 1; + return 0; +} +static inline void proc_free_inum(unsigned int inum) {} +static inline bool proc_ns_inode(struct inode *inode) { return false; } + +#endif /* CONFIG_PROC_FS */ + +#endif /* _LINUX_PROC_NS_H */ diff --git a/include/linux/profile.h b/include/linux/profile.h index 21123902366..aaad3861beb 100644 --- a/include/linux/profile.h +++ b/include/linux/profile.h @@ -18,10 +18,10 @@ struct pt_regs; struct notifier_block; #if defined(CONFIG_PROFILING) && defined(CONFIG_PROC_FS) -void create_prof_cpu_mask(struct proc_dir_entry *de); +void create_prof_cpu_mask(void); int create_proc_profile(void); #else -static inline void create_prof_cpu_mask(struct proc_dir_entry *de) +static inline void create_prof_cpu_mask(void) { } diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 68a04a343ca..2da29ac178f 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -123,6 +123,7 @@ static inline int seq_nodemask_list(struct seq_file *m, nodemask_t *mask) } int single_open(struct file *, int (*)(struct seq_file *, void *), void *); +int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t); int single_release(struct inode *, struct file *); void *__seq_open_private(struct file *, const struct seq_operations *, int); int seq_open_private(struct file *, const struct seq_operations *, int); diff --git a/include/linux/signal.h b/include/linux/signal.h index 9475c5cb28b..d897484730c 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -434,4 +434,9 @@ void signals_init(void); int restore_altstack(const stack_t __user *); int __save_altstack(stack_t __user *, unsigned long); +#ifdef CONFIG_PROC_FS +struct seq_file; +extern void render_sigset_t(struct seq_file *, const char *, sigset_t *); +#endif + #endif /* _LINUX_SIGNAL_H */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 367a9dfc4ea..7e92bd86a80 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -691,5 +691,12 @@ do { \ finish_wait(&wq, &__wait); \ } while (0) +#ifdef CONFIG_PROC_FS +extern void proc_tty_register_driver(struct tty_driver *); +extern void proc_tty_unregister_driver(struct tty_driver *); +#else +static inline void proc_tty_register_driver(struct tty_driver *d) {} +static inline void proc_tty_unregister_driver(struct tty_driver *d) {} +#endif #endif diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 6912ef9a188..10eb9b38901 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -226,7 +226,6 @@ struct bt_sock_list { struct hlist_head head; rwlock_t lock; #ifdef CONFIG_PROC_FS - struct file_operations fops; int (* custom_seq_show)(struct seq_file *, void *); #endif }; @@ -330,7 +329,7 @@ extern void hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); -extern int bt_procfs_init(struct module* module, struct net *net, const char *name, +extern int bt_procfs_init(struct net *net, const char *name, struct bt_sock_list* sk_list, int (* seq_show)(struct seq_file *, void *)); extern void bt_procfs_cleanup(struct net *net, const char *name); diff --git a/include/net/lib80211.h b/include/net/lib80211.h index d178c26a555..be95b926280 100644 --- a/include/net/lib80211.h +++ b/include/net/lib80211.h @@ -30,6 +30,8 @@ #include <linux/skbuff.h> #include <linux/ieee80211.h> #include <linux/timer.h> +#include <linux/seq_file.h> + /* print_ssid() is intended to be used in debug (and possibly error) * messages. It should never be used for passing ssid to user space. */ const char *print_ssid(char *buf, const char *ssid, u8 ssid_len); @@ -75,7 +77,7 @@ struct lib80211_crypto_ops { /* procfs handler for printing out key information and possible * statistics */ - char *(*print_stats) (char *p, void *priv); + void (*print_stats) (struct seq_file *m, void *priv); /* Crypto specific flag get/set for configuration settings */ unsigned long (*get_flags) (void *priv); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 2b6956e9853..75524357221 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -6,6 +6,7 @@ #include <linux/types.h> #include <linux/workqueue.h> #include <linux/mutex.h> +#include <linux/seq_file.h> #include <scsi/scsi.h> struct request_queue; @@ -340,7 +341,8 @@ struct scsi_host_template { * * Status: OBSOLETE */ - int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int); + int (*show_info)(struct seq_file *, struct Scsi_Host *); + int (*write_info)(struct Scsi_Host *, char *, int); /* * This is an optional routine that allows the transport to become @@ -375,7 +377,7 @@ struct scsi_host_template { /* * Used to store the procfs directory if a driver implements the - * proc_info method. + * show_info method. */ struct proc_dir_entry *proc_dir; diff --git a/init/version.c b/init/version.c index 58170f18912..1a4718e500f 100644 --- a/init/version.c +++ b/init/version.c @@ -12,7 +12,7 @@ #include <linux/utsname.h> #include <generated/utsrelease.h> #include <linux/version.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #ifndef CONFIG_KALLSYMS #define version(a) Version_ ## a diff --git a/ipc/msgutil.c b/ipc/msgutil.c index d43439e6eb4..491e71f2a1b 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -16,7 +16,7 @@ #include <linux/msg.h> #include <linux/ipc_namespace.h> #include <linux/utsname.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #include <linux/uaccess.h> #include "util.h" diff --git a/ipc/namespace.c b/ipc/namespace.c index 7c1fa451b0b..7ee61bf4493 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -12,7 +12,7 @@ #include <linux/fs.h> #include <linux/mount.h> #include <linux/user_namespace.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #include "util.h" diff --git a/ipc/util.c b/ipc/util.c index 579201e4bc0..abfc13e8677 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -1031,7 +1031,7 @@ static int sysvipc_proc_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = iter; - iter->iface = PDE(inode)->data; + iter->iface = PDE_DATA(inode); iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); out: return ret; diff --git a/kernel/acct.c b/kernel/acct.c index b9bd7f098ee..85389fe2abd 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -543,6 +543,7 @@ static void do_acct_process(struct bsd_acct_struct *acct, * Kernel segment override to datasegment and write it * to the accounting file. */ + file_start_write(file); fs = get_fs(); set_fs(KERNEL_DS); /* @@ -554,6 +555,7 @@ static void do_acct_process(struct bsd_acct_struct *acct, sizeof(acct_t), &file->f_pos); current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; set_fs(fs); + file_end_write(file); out: revert_creds(orig_cred); } diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d3abce2d645..2a9926275f8 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4678,7 +4678,7 @@ out: */ /* TODO: Use a proper seq_file iterator */ -static int proc_cgroup_show(struct seq_file *m, void *v) +int proc_cgroup_show(struct seq_file *m, void *v) { struct pid *pid; struct task_struct *tsk; @@ -4730,19 +4730,6 @@ out: return retval; } -static int cgroup_open(struct inode *inode, struct file *file) -{ - struct pid *pid = PROC_I(inode)->pid; - return single_open(file, proc_cgroup_show, pid); -} - -const struct file_operations proc_cgroup_operations = { - .open = cgroup_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* Display information about each subsystem and each hierarchy */ static int proc_cgroupstats_show(struct seq_file *m, void *v) { diff --git a/kernel/configs.c b/kernel/configs.c index 42e8fa075ee..c18b1f1ae51 100644 --- a/kernel/configs.c +++ b/kernel/configs.c @@ -79,7 +79,7 @@ static int __init ikconfig_init(void) if (!entry) return -ENOMEM; - entry->size = kernel_config_data_size; + proc_set_size(entry, kernel_config_data_size); return 0; } diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 12331120767..64b3f791bbe 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -2609,7 +2609,7 @@ void __cpuset_memory_pressure_bump(void) * and we take cpuset_mutex, keeping cpuset_attach() from changing it * anyway. */ -static int proc_cpuset_show(struct seq_file *m, void *unused_v) +int proc_cpuset_show(struct seq_file *m, void *unused_v) { struct pid *pid; struct task_struct *tsk; @@ -2643,19 +2643,6 @@ out_free: out: return retval; } - -static int cpuset_open(struct inode *inode, struct file *file) -{ - struct pid *pid = PROC_I(inode)->pid; - return single_open(file, proc_cpuset_show, pid); -} - -const struct file_operations proc_cpuset_operations = { - .open = cpuset_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; #endif /* CONFIG_PROC_PID_CPUSET */ /* Display task mems_allowed in /proc/<pid>/status file. */ diff --git a/kernel/exit.c b/kernel/exit.c index 6e3151ec900..af2eb3cbd49 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -847,7 +847,7 @@ void do_exit(long code) exit_io_context(tsk); if (tsk->splice_pipe) - __free_pipe_info(tsk->splice_pipe); + free_pipe_info(tsk->splice_pipe); if (tsk->task_frag.page) put_page(tsk->task_frag.page); diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 397db02209e..19ed5c425c3 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -76,7 +76,7 @@ static int irq_affinity_list_proc_show(struct seq_file *m, void *v) static ssize_t write_irq_affinity(int type, struct file *file, const char __user *buffer, size_t count, loff_t *pos) { - unsigned int irq = (int)(long)PDE(file_inode(file))->data; + unsigned int irq = (int)(long)PDE_DATA(file_inode(file)); cpumask_var_t new_value; int err; @@ -131,17 +131,17 @@ static ssize_t irq_affinity_list_proc_write(struct file *file, static int irq_affinity_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_affinity_proc_show, PDE(inode)->data); + return single_open(file, irq_affinity_proc_show, PDE_DATA(inode)); } static int irq_affinity_list_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_affinity_list_proc_show, PDE(inode)->data); + return single_open(file, irq_affinity_list_proc_show, PDE_DATA(inode)); } static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_affinity_hint_proc_show, PDE(inode)->data); + return single_open(file, irq_affinity_hint_proc_show, PDE_DATA(inode)); } static const struct file_operations irq_affinity_proc_fops = { @@ -212,7 +212,7 @@ out: static int default_affinity_open(struct inode *inode, struct file *file) { - return single_open(file, default_affinity_show, PDE(inode)->data); + return single_open(file, default_affinity_show, PDE_DATA(inode)); } static const struct file_operations default_affinity_proc_fops = { @@ -233,7 +233,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v) static int irq_node_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_node_proc_show, PDE(inode)->data); + return single_open(file, irq_node_proc_show, PDE_DATA(inode)); } static const struct file_operations irq_node_proc_fops = { @@ -256,7 +256,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v) static int irq_spurious_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_spurious_proc_show, PDE(inode)->data); + return single_open(file, irq_spurious_proc_show, PDE_DATA(inode)); } static const struct file_operations irq_spurious_proc_fops = { @@ -366,11 +366,7 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) void unregister_handler_proc(unsigned int irq, struct irqaction *action) { - if (action->dir) { - struct irq_desc *desc = irq_to_desc(irq); - - remove_proc_entry(action->dir->name, desc->dir); - } + proc_remove(action->dir); } static void register_default_affinity_proc(void) diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index afc0456f227..364ceab15f0 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -22,7 +22,7 @@ #include <linux/pid_namespace.h> #include <net/net_namespace.h> #include <linux/ipc_namespace.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #include <linux/file.h> #include <linux/syscalls.h> @@ -241,7 +241,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) const struct proc_ns_operations *ops; struct task_struct *tsk = current; struct nsproxy *new_nsproxy; - struct proc_inode *ei; + struct proc_ns *ei; struct file *file; int err; @@ -250,7 +250,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) return PTR_ERR(file); err = -EINVAL; - ei = PROC_I(file_inode(file)); + ei = get_proc_ns(file_inode(file)); ops = ei->ns_ops; if (nstype && (ops->type != nstype)) goto out; diff --git a/kernel/pid.c b/kernel/pid.c index 6283d6412af..0db3e791a06 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -36,6 +36,7 @@ #include <linux/pid_namespace.h> #include <linux/init_task.h> #include <linux/syscalls.h> +#include <linux/proc_ns.h> #include <linux/proc_fs.h> #define pid_hashfn(nr, ns) \ diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 69473c4a653..6917e8edb48 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -15,7 +15,7 @@ #include <linux/err.h> #include <linux/acct.h> #include <linux/slab.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #include <linux/reboot.h> #include <linux/export.h> diff --git a/kernel/profile.c b/kernel/profile.c index dc3384ee874..0bf40073766 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -462,10 +462,10 @@ static const struct file_operations prof_cpu_mask_proc_fops = { .write = prof_cpu_mask_proc_write, }; -void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir) +void create_prof_cpu_mask(void) { /* create /proc/irq/prof_cpu_mask */ - proc_create("prof_cpu_mask", 0600, root_irq_dir, &prof_cpu_mask_proc_fops); + proc_create("irq/prof_cpu_mask", 0600, NULL, &prof_cpu_mask_proc_fops); } /* @@ -600,7 +600,7 @@ int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */ NULL, &proc_profile_operations); if (!entry) return 0; - entry->size = (1+prof_len) * sizeof(atomic_t); + proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t)); hotcpu_notifier(profile_cpu_callback, 0); return 0; } diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c index e036eda1a9c..da98af347e8 100644 --- a/kernel/sched/stats.c +++ b/kernel/sched/stats.c @@ -130,16 +130,11 @@ static int schedstat_open(struct inode *inode, struct file *file) return seq_open(file, &schedstat_sops); } -static int schedstat_release(struct inode *inode, struct file *file) -{ - return 0; -}; - static const struct file_operations proc_schedstat_operations = { .open = schedstat_open, .read = seq_read, .llseek = seq_lseek, - .release = schedstat_release, + .release = seq_release, }; static int __init proc_schedstat_init(void) diff --git a/kernel/user.c b/kernel/user.c index 8e635a18ab5..69b4c3d48cd 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -16,7 +16,7 @@ #include <linux/interrupt.h> #include <linux/export.h> #include <linux/user_namespace.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> /* * userns count is 1 for root user, 1 for init_uts_ns, diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index e134d8f365d..d8c30db06c5 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -9,7 +9,7 @@ #include <linux/nsproxy.h> #include <linux/slab.h> #include <linux/user_namespace.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> #include <linux/highuid.h> #include <linux/cred.h> #include <linux/securebits.h> diff --git a/kernel/utsname.c b/kernel/utsname.c index a47fc5de311..2fc8576efaa 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -15,7 +15,7 @@ #include <linux/err.h> #include <linux/slab.h> #include <linux/user_namespace.h> -#include <linux/proc_fs.h> +#include <linux/proc_ns.h> static struct uts_namespace *create_uts_ns(void) { diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c index 44b92cb6224..eb4a04afea8 100644 --- a/lib/notifier-error-inject.c +++ b/lib/notifier-error-inject.c @@ -17,7 +17,7 @@ static int debugfs_errno_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set, "%lld\n"); -static struct dentry *debugfs_create_errno(const char *name, mode_t mode, +static struct dentry *debugfs_create_errno(const char *name, umode_t mode, struct dentry *parent, int *value) { return debugfs_create_file(name, mode, parent, value, &fops_errno); @@ -50,7 +50,7 @@ struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent, struct notifier_err_inject *err_inject, int priority) { struct notifier_err_inject_action *action; - mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; + umode_t mode = S_IFREG | S_IRUSR | S_IWUSR; struct dentry *dir; struct dentry *actions_dir; diff --git a/mm/filemap.c b/mm/filemap.c index e989fb1eaa7..7905fe721aa 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2546,7 +2546,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, BUG_ON(iocb->ki_pos != pos); - sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); mutex_unlock(&inode->i_mutex); @@ -2558,7 +2557,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0 && ret > 0) ret = err; } - sb_end_write(inode->i_sb); return ret; } EXPORT_SYMBOL(generic_file_aio_write); diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index a912da6ddfd..28fe26b64f8 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c @@ -404,8 +404,6 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, loff_t pos; ssize_t ret; - sb_start_write(inode->i_sb); - mutex_lock(&inode->i_mutex); if (!access_ok(VERIFY_READ, buf, len)) { @@ -439,7 +437,6 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, current->backing_dev_info = NULL; out_up: mutex_unlock(&inode->i_mutex); - sb_end_write(inode->i_sb); return ret; } EXPORT_SYMBOL_GPL(xip_file_write); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 72043d6c88c..b12fd861260 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -27,10 +27,30 @@ #include <linux/pfn.h> #include <linux/kmemleak.h> #include <linux/atomic.h> +#include <linux/llist.h> #include <asm/uaccess.h> #include <asm/tlbflush.h> #include <asm/shmparam.h> +struct vfree_deferred { + struct llist_head list; + struct work_struct wq; +}; +static DEFINE_PER_CPU(struct vfree_deferred, vfree_deferred); + +static void __vunmap(const void *, int); + +static void free_work(struct work_struct *w) +{ + struct vfree_deferred *p = container_of(w, struct vfree_deferred, wq); + struct llist_node *llnode = llist_del_all(&p->list); + while (llnode) { + void *p = llnode; + llnode = llist_next(llnode); + __vunmap(p, 1); + } +} + /*** Page table manipulation functions ***/ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) @@ -1175,10 +1195,14 @@ void __init vmalloc_init(void) for_each_possible_cpu(i) { struct vmap_block_queue *vbq; + struct vfree_deferred *p; vbq = &per_cpu(vmap_block_queue, i); spin_lock_init(&vbq->lock); INIT_LIST_HEAD(&vbq->free); + p = &per_cpu(vfree_deferred, i); + init_llist_head(&p->list); + INIT_WORK(&p->wq, free_work); } /* Import existing vmlist entries. */ @@ -1486,7 +1510,7 @@ static void __vunmap(const void *addr, int deallocate_pages) kfree(area); return; } - + /** * vfree - release memory allocated by vmalloc() * @addr: memory base address @@ -1495,15 +1519,25 @@ static void __vunmap(const void *addr, int deallocate_pages) * obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is * NULL, no operation is performed. * - * Must not be called in interrupt context. + * Must not be called in NMI context (strictly speaking, only if we don't + * have CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG, but making the calling + * conventions for vfree() arch-depenedent would be a really bad idea) + * */ void vfree(const void *addr) { - BUG_ON(in_interrupt()); + BUG_ON(in_nmi()); kmemleak_free(addr); - __vunmap(addr, 1); + if (!addr) + return; + if (unlikely(in_interrupt())) { + struct vfree_deferred *p = &__get_cpu_var(vfree_deferred); + llist_add((struct llist_node *)addr, &p->list); + schedule_work(&p->wq); + } else + __vunmap(addr, 1); } EXPORT_SYMBOL(vfree); @@ -1520,7 +1554,8 @@ void vunmap(const void *addr) { BUG_ON(in_interrupt()); might_sleep(); - __vunmap(addr, 0); + if (addr) + __vunmap(addr, 0); } EXPORT_SYMBOL(vunmap); diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index dc526ec965e..1d0e89213a2 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -93,7 +93,7 @@ static const struct file_operations vlan_fops = { static int vlandev_seq_open(struct inode *inode, struct file *file) { - return single_open(file, vlandev_seq_show, PDE(inode)->data); + return single_open(file, vlandev_seq_show, PDE_DATA(inode)); } static const struct file_operations vlandev_fops = { @@ -184,14 +184,9 @@ int vlan_proc_add_dev(struct net_device *vlandev) */ int vlan_proc_rem_dev(struct net_device *vlandev) { - struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); - /** NOTE: This will consume the memory pointed to by dent, it seems. */ - if (vlan_dev_priv(vlandev)->dent) { - remove_proc_entry(vlan_dev_priv(vlandev)->dent->name, - vn->proc_vlan_dir); - vlan_dev_priv(vlandev)->dent = NULL; - } + proc_remove(vlan_dev_priv(vlandev)->dent); + vlan_dev_priv(vlandev)->dent = NULL; return 0; } diff --git a/net/atm/proc.c b/net/atm/proc.c index 6ac35ff0d6b..bbb6461a4b7 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -385,7 +385,7 @@ static ssize_t proc_dev_atm_read(struct file *file, char __user *buf, page = get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; - dev = PDE(file_inode(file))->data; + dev = PDE_DATA(file_inode(file)); if (!dev->ops->proc_read) length = -EINVAL; else { diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index e5338f787d6..9096137c889 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -609,7 +609,7 @@ static int bt_seq_open(struct inode *inode, struct file *file) struct bt_sock_list *sk_list; struct bt_seq_state *s; - sk_list = PDE(inode)->data; + sk_list = PDE_DATA(inode); s = __seq_open_private(file, &bt_seq_ops, sizeof(struct bt_seq_state)); if (!s) @@ -619,26 +619,21 @@ static int bt_seq_open(struct inode *inode, struct file *file) return 0; } -int bt_procfs_init(struct module* module, struct net *net, const char *name, +static const struct file_operations bt_fops = { + .open = bt_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private +}; + +int bt_procfs_init(struct net *net, const char *name, struct bt_sock_list* sk_list, int (* seq_show)(struct seq_file *, void *)) { - struct proc_dir_entry * pde; - sk_list->custom_seq_show = seq_show; - sk_list->fops.owner = module; - sk_list->fops.open = bt_seq_open; - sk_list->fops.read = seq_read; - sk_list->fops.llseek = seq_lseek; - sk_list->fops.release = seq_release_private; - - pde = proc_create(name, 0, net->proc_net, &sk_list->fops); - if (!pde) + if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list)) return -ENOMEM; - - pde->data = sk_list; - return 0; } @@ -647,7 +642,7 @@ void bt_procfs_cleanup(struct net *net, const char *name) remove_proc_entry(name, net->proc_net); } #else -int bt_procfs_init(struct module* module, struct net *net, const char *name, +int bt_procfs_init(struct net *net, const char *name, struct bt_sock_list* sk_list, int (* seq_show)(struct seq_file *, void *)) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 5b1c04e2882..5f051290dab 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -234,7 +234,7 @@ int __init bnep_sock_init(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "bnep", &bnep_sk_list, NULL); + err = bt_procfs_init(&init_net, "bnep", &bnep_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create BNEP proc file"); bt_sock_unregister(BTPROTO_BNEP); diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index a4a9d4b6816..cd75e4d64b9 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -539,7 +539,7 @@ static int cmtp_proc_show(struct seq_file *m, void *v) static int cmtp_proc_open(struct inode *inode, struct file *file) { - return single_open(file, cmtp_proc_show, PDE(inode)->data); + return single_open(file, cmtp_proc_show, PDE_DATA(inode)); } static const struct file_operations cmtp_proc_fops = { diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 58d9edebab4..d82787d417b 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -245,7 +245,7 @@ int cmtp_init_sockets(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "cmtp", &cmtp_sk_list, NULL); + err = bt_procfs_init(&init_net, "cmtp", &cmtp_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create CMTP proc file"); bt_sock_unregister(BTPROTO_HIDP); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index aa4354fca77..9bd7d959e38 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -1107,7 +1107,7 @@ int __init hci_sock_init(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "hci", &hci_sk_list, NULL); + err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create HCI proc file"); bt_sock_unregister(BTPROTO_HCI); diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 2f4cbb0865c..cb3fdde1968 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -275,7 +275,7 @@ int __init hidp_init_sockets(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "hidp", &hidp_sk_list, NULL); + err = bt_procfs_init(&init_net, "hidp", &hidp_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create HIDP proc file"); bt_sock_unregister(BTPROTO_HIDP); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 141e7b058b7..36fed40c162 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1298,7 +1298,7 @@ int __init l2cap_init_sockets(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, + err = bt_procfs_init(&init_net, "l2cap", &l2cap_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create L2CAP proc file"); diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index a8638b58c4b..30b3721dc6d 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -1037,7 +1037,7 @@ int __init rfcomm_init_sockets(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "rfcomm", &rfcomm_sk_list, NULL); + err = bt_procfs_init(&init_net, "rfcomm", &rfcomm_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create RFCOMM proc file"); bt_sock_unregister(BTPROTO_RFCOMM); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 373d81e6e8f..e7bd4eea575 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1119,7 +1119,7 @@ int __init sco_init(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "sco", &sco_sk_list, NULL); + err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create SCO proc file"); bt_sock_unregister(BTPROTO_SCO); diff --git a/net/can/bcm.c b/net/can/bcm.c index 5dcb20076f3..8f113e6ff32 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -226,7 +226,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) static int bcm_proc_open(struct inode *inode, struct file *file) { - return single_open(file, bcm_proc_show, PDE(inode)->data); + return single_open(file, bcm_proc_show, PDE_DATA(inode)); } static const struct file_operations bcm_proc_fops = { diff --git a/net/can/proc.c b/net/can/proc.c index 1ab8c888f10..b543470c8f8 100644 --- a/net/can/proc.c +++ b/net/can/proc.c @@ -378,7 +378,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v) static int can_rcvlist_proc_open(struct inode *inode, struct file *file) { - return single_open(file, can_rcvlist_proc_show, PDE(inode)->data); + return single_open(file, can_rcvlist_proc_show, PDE_DATA(inode)); } static const struct file_operations can_rcvlist_proc_fops = { diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 89a3a07d85f..5c56b217b99 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -2705,7 +2705,7 @@ static int neigh_stat_seq_open(struct inode *inode, struct file *file) if (!ret) { struct seq_file *sf = file->private_data; - sf->private = PDE(inode)->data; + sf->private = PDE_DATA(inode); } return ret; }; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 80e271d9e64..f9765203675 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -10,7 +10,8 @@ #include <linux/idr.h> #include <linux/rculist.h> #include <linux/nsproxy.h> -#include <linux/proc_fs.h> +#include <linux/fs.h> +#include <linux/proc_ns.h> #include <linux/file.h> #include <linux/export.h> #include <linux/user_namespace.h> @@ -336,7 +337,7 @@ EXPORT_SYMBOL_GPL(__put_net); struct net *get_net_ns_by_fd(int fd) { - struct proc_inode *ei; + struct proc_ns *ei; struct file *file; struct net *net; @@ -344,7 +345,7 @@ struct net *get_net_ns_by_fd(int fd) if (IS_ERR(file)) return ERR_CAST(file); - ei = PROC_I(file_inode(file)); + ei = get_proc_ns(file_inode(file)); if (ei->ns_ops == &netns_operations) net = get_net(ei->ns); else diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 5c217427a66..11f2704c381 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -508,7 +508,7 @@ out: static int pgctrl_open(struct inode *inode, struct file *file) { - return single_open(file, pgctrl_show, PDE(inode)->data); + return single_open(file, pgctrl_show, PDE_DATA(inode)); } static const struct file_operations pktgen_fops = { @@ -1685,7 +1685,7 @@ static ssize_t pktgen_if_write(struct file *file, static int pktgen_if_open(struct inode *inode, struct file *file) { - return single_open(file, pktgen_if_show, PDE(inode)->data); + return single_open(file, pktgen_if_show, PDE_DATA(inode)); } static const struct file_operations pktgen_if_fops = { @@ -1823,7 +1823,7 @@ out: static int pktgen_thread_open(struct inode *inode, struct file *file) { - return single_open(file, pktgen_thread_show, PDE(inode)->data); + return single_open(file, pktgen_thread_show, PDE_DATA(inode)); } static const struct file_operations pktgen_thread_fops = { @@ -1904,7 +1904,7 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d if (pkt_dev->odev != dev) continue; - remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); + proc_remove(pkt_dev->entry); pkt_dev->entry = proc_create_data(dev->name, 0600, pn->proc_dir, @@ -3574,8 +3574,6 @@ static void _rem_dev_from_if_list(struct pktgen_thread *t, static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) { - struct pktgen_net *pn = t->net; - pr_debug("remove_device pkt_dev=%p\n", pkt_dev); if (pkt_dev->running) { @@ -3595,7 +3593,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, _rem_dev_from_if_list(t, pkt_dev); if (pkt_dev->entry) - remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); + proc_remove(pkt_dev->entry); #ifdef CONFIG_XFRM free_SAs(pkt_dev); diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 5852b249054..0b732efd32e 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -105,7 +105,7 @@ clusterip_config_entry_put(struct clusterip_config *c) * functions are also incrementing the refcount on their own, * so it's safe to remove the entry even if it's in use. */ #ifdef CONFIG_PROC_FS - remove_proc_entry(c->pde->name, c->pde->parent); + proc_remove(c->pde); #endif return; } @@ -631,7 +631,7 @@ static int clusterip_proc_open(struct inode *inode, struct file *file) if (!ret) { struct seq_file *sf = file->private_data; - struct clusterip_config *c = PDE(inode)->data; + struct clusterip_config *c = PDE_DATA(inode); sf->private = c; @@ -643,7 +643,7 @@ static int clusterip_proc_open(struct inode *inode, struct file *file) static int clusterip_proc_release(struct inode *inode, struct file *file) { - struct clusterip_config *c = PDE(inode)->data; + struct clusterip_config *c = PDE_DATA(inode); int ret; ret = seq_release(inode, file); @@ -657,7 +657,7 @@ static int clusterip_proc_release(struct inode *inode, struct file *file) static ssize_t clusterip_proc_write(struct file *file, const char __user *input, size_t size, loff_t *ofs) { - struct clusterip_config *c = PDE(file_inode(file))->data; + struct clusterip_config *c = PDE_DATA(file_inode(file)); #define PROC_WRITELEN 10 char buffer[PROC_WRITELEN+1]; unsigned long nodenum; @@ -736,7 +736,7 @@ static void __exit clusterip_tg_exit(void) { pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION); #ifdef CONFIG_PROC_FS - remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); + proc_remove(clusterip_procdir); #endif nf_unregister_hook(&cip_arp_ops); xt_unregister_target(&clusterip_tg_reg); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d979657b8a1..719652305a2 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2583,7 +2583,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v) int tcp_seq_open(struct inode *inode, struct file *file) { - struct tcp_seq_afinfo *afinfo = PDE(inode)->data; + struct tcp_seq_afinfo *afinfo = PDE_DATA(inode); struct tcp_iter_state *s; int err; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 3159d16441d..6abbe645512 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2100,7 +2100,7 @@ static void udp_seq_stop(struct seq_file *seq, void *v) int udp_seq_open(struct inode *inode, struct file *file) { - struct udp_seq_afinfo *afinfo = PDE(inode)->data; + struct udp_seq_afinfo *afinfo = PDE_DATA(inode); struct udp_iter_state *s; int err; diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 115cc58898f..f3c1ff4357f 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -251,7 +251,7 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v) static int snmp6_dev_seq_open(struct inode *inode, struct file *file) { - return single_open(file, snmp6_dev_seq_show, PDE(inode)->data); + return single_open(file, snmp6_dev_seq_show, PDE_DATA(inode)); } static const struct file_operations snmp6_dev_seq_fops = { @@ -291,8 +291,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev) return -ENOENT; if (!idev->stats.proc_dir_entry) return -EINVAL; - remove_proc_entry(idev->stats.proc_dir_entry->name, - net->mib.proc_net_devsnmp6); + proc_remove(idev->stats.proc_dir_entry); idev->stats.proc_dir_entry = NULL; return 0; } diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 1a73b18683b..8b03028cca6 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1000,7 +1000,7 @@ static int xt_table_open(struct inode *inode, struct file *file) sizeof(struct xt_names_priv)); if (!ret) { priv = ((struct seq_file *)file->private_data)->private; - priv->af = (unsigned long)PDE(inode)->data; + priv->af = (unsigned long)PDE_DATA(inode); } return ret; } @@ -1148,7 +1148,7 @@ static int xt_match_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = trav; - trav->nfproto = (unsigned long)PDE(inode)->data; + trav->nfproto = (unsigned long)PDE_DATA(inode); return 0; } @@ -1212,7 +1212,7 @@ static int xt_target_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = trav; - trav->nfproto = (unsigned long)PDE(inode)->data; + trav->nfproto = (unsigned long)PDE_DATA(inode); return 0; } diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 0199e7bb8f8..9ff035c7140 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -108,6 +108,7 @@ struct xt_hashlimit_htable { /* seq_file stuff */ struct proc_dir_entry *pde; + const char *name; struct net *net; struct hlist_head hash[0]; /* hashtable itself */ @@ -254,6 +255,11 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, hinfo->count = 0; hinfo->family = family; hinfo->rnd_initialized = false; + hinfo->name = kstrdup(minfo->name, GFP_KERNEL); + if (!hinfo->name) { + vfree(hinfo); + return -ENOMEM; + } spin_lock_init(&hinfo->lock); hinfo->pde = proc_create_data(minfo->name, 0, @@ -261,6 +267,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit, &dl_file_ops, hinfo); if (hinfo->pde == NULL) { + kfree(hinfo->name); vfree(hinfo); return -ENOMEM; } @@ -331,9 +338,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo) parent = hashlimit_net->ip6t_hashlimit; if(parent != NULL) - remove_proc_entry(hinfo->pde->name, parent); + remove_proc_entry(hinfo->name, parent); htable_selective_cleanup(hinfo, select_all); + kfree(hinfo->name); vfree(hinfo); } @@ -345,7 +353,7 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net, struct xt_hashlimit_htable *hinfo; hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) { - if (!strcmp(name, hinfo->pde->name) && + if (!strcmp(name, hinfo->name) && hinfo->family == family) { hinfo->use++; return hinfo; @@ -842,7 +850,7 @@ static int dl_proc_open(struct inode *inode, struct file *file) if (!ret) { struct seq_file *sf = file->private_data; - sf->private = PDE(inode)->data; + sf->private = PDE_DATA(inode); } return ret; } @@ -888,7 +896,7 @@ static void __net_exit hashlimit_proc_net_exit(struct net *net) pde = hashlimit_net->ip6t_hashlimit; hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) - remove_proc_entry(hinfo->pde->name, pde); + remove_proc_entry(hinfo->name, pde); hashlimit_net->ipt_hashlimit = NULL; hashlimit_net->ip6t_hashlimit = NULL; diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index d9cad315229..1e657cf715c 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -401,8 +401,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ret = -ENOMEM; goto out; } - pde->uid = uid; - pde->gid = gid; + proc_set_user(pde, uid, gid); #endif spin_lock_bh(&recent_lock); list_add_tail(&t->list, &recent_net->tables); @@ -525,14 +524,13 @@ static const struct seq_operations recent_seq_ops = { static int recent_seq_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *pde = PDE(inode); struct recent_iter_state *st; st = __seq_open_private(file, &recent_seq_ops, sizeof(*st)); if (st == NULL) return -ENOMEM; - st->table = pde->data; + st->table = PDE_DATA(inode); return 0; } @@ -540,8 +538,7 @@ static ssize_t recent_mt_proc_write(struct file *file, const char __user *input, size_t size, loff_t *loff) { - const struct proc_dir_entry *pde = PDE(file_inode(file)); - struct recent_table *t = pde->data; + struct recent_table *t = PDE_DATA(file_inode(file)); struct recent_entry *e; char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; const char *c = buf; diff --git a/net/socket.c b/net/socket.c index 280283f03cc..b416093997d 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1160,15 +1160,6 @@ static int sock_mmap(struct file *file, struct vm_area_struct *vma) static int sock_close(struct inode *inode, struct file *filp) { - /* - * It was possible the inode is NULL we were - * closing an unfinished socket. - */ - - if (!inode) { - printk(KERN_DEBUG "sock_close: NULL inode\n"); - return 0; - } sock_release(SOCKET_I(inode)); return 0; } diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index ce2d180d05a..f1889be8091 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1460,7 +1460,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf, static ssize_t cache_read_procfs(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { - struct cache_detail *cd = PDE(file_inode(filp))->data; + struct cache_detail *cd = PDE_DATA(file_inode(filp)); return cache_read(filp, buf, count, ppos, cd); } @@ -1468,14 +1468,14 @@ static ssize_t cache_read_procfs(struct file *filp, char __user *buf, static ssize_t cache_write_procfs(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { - struct cache_detail *cd = PDE(file_inode(filp))->data; + struct cache_detail *cd = PDE_DATA(file_inode(filp)); return cache_write(filp, buf, count, ppos, cd); } static unsigned int cache_poll_procfs(struct file *filp, poll_table *wait) { - struct cache_detail *cd = PDE(file_inode(filp))->data; + struct cache_detail *cd = PDE_DATA(file_inode(filp)); return cache_poll(filp, wait, cd); } @@ -1484,21 +1484,21 @@ static long cache_ioctl_procfs(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return cache_ioctl(inode, filp, cmd, arg, cd); } static int cache_open_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return cache_open(inode, filp, cd); } static int cache_release_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return cache_release(inode, filp, cd); } @@ -1516,14 +1516,14 @@ static const struct file_operations cache_file_operations_procfs = { static int content_open_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return content_open(inode, filp, cd); } static int content_release_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return content_release(inode, filp, cd); } @@ -1537,14 +1537,14 @@ static const struct file_operations content_file_operations_procfs = { static int open_flush_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return open_flush(inode, filp, cd); } static int release_flush_procfs(struct inode *inode, struct file *filp) { - struct cache_detail *cd = PDE(inode)->data; + struct cache_detail *cd = PDE_DATA(inode); return release_flush(inode, filp, cd); } @@ -1552,7 +1552,7 @@ static int release_flush_procfs(struct inode *inode, struct file *filp) static ssize_t read_flush_procfs(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { - struct cache_detail *cd = PDE(file_inode(filp))->data; + struct cache_detail *cd = PDE_DATA(file_inode(filp)); return read_flush(filp, buf, count, ppos, cd); } @@ -1561,7 +1561,7 @@ static ssize_t write_flush_procfs(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { - struct cache_detail *cd = PDE(file_inode(filp))->data; + struct cache_detail *cd = PDE_DATA(file_inode(filp)); return write_flush(filp, buf, count, ppos, cd); } diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index bc2068ee795..21b75cb08c0 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -64,7 +64,7 @@ static int rpc_proc_show(struct seq_file *seq, void *v) { static int rpc_proc_open(struct inode *inode, struct file *file) { - return single_open(file, rpc_proc_show, PDE(inode)->data); + return single_open(file, rpc_proc_show, PDE_DATA(inode)); } static const struct file_operations rpc_proc_fops = { diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index 1526c211db6..dc0e59e53db 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c @@ -430,24 +430,23 @@ static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) return CCMP_TK_LEN; } -static char *lib80211_ccmp_print_stats(char *p, void *priv) +static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv) { struct lib80211_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2], - ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5], - ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2], - ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5], - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; + seq_printf(m, + "key[%d] alg=CCMP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "format_errors=%d replays=%d decrypt_errors=%d\n", + ccmp->key_idx, ccmp->key_set, + ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2], + ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5], + ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2], + ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5], + ccmp->dot11RSNAStatsCCMPFormatErrors, + ccmp->dot11RSNAStatsCCMPReplays, + ccmp->dot11RSNAStatsCCMPDecryptErrors); } static struct lib80211_crypto_ops lib80211_crypt_ccmp = { diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index d475cfc8568..8c90ba79e56 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c @@ -703,30 +703,30 @@ static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv) return TKIP_KEY_LEN; } -static char *lib80211_tkip_print_stats(char *p, void *priv) +static void lib80211_tkip_print_stats(struct seq_file *m, void *priv) { struct lib80211_tkip_data *tkip = priv; - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; + seq_printf(m, + "key[%d] alg=TKIP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "replays=%d icv_errors=%d local_mic_failures=%d\n", + tkip->key_idx, tkip->key_set, + (tkip->tx_iv32 >> 24) & 0xff, + (tkip->tx_iv32 >> 16) & 0xff, + (tkip->tx_iv32 >> 8) & 0xff, + tkip->tx_iv32 & 0xff, + (tkip->tx_iv16 >> 8) & 0xff, + tkip->tx_iv16 & 0xff, + (tkip->rx_iv32 >> 24) & 0xff, + (tkip->rx_iv32 >> 16) & 0xff, + (tkip->rx_iv32 >> 8) & 0xff, + tkip->rx_iv32 & 0xff, + (tkip->rx_iv16 >> 8) & 0xff, + tkip->rx_iv16 & 0xff, + tkip->dot11RSNAStatsTKIPReplays, + tkip->dot11RSNAStatsTKIPICVErrors, + tkip->dot11RSNAStatsTKIPLocalMICFailures); } static struct lib80211_crypto_ops lib80211_crypt_tkip = { diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c index c1304018fc1..1c292e4ea7b 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/net/wireless/lib80211_crypt_wep.c @@ -253,11 +253,10 @@ static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv) return wep->key_len; } -static char *lib80211_wep_print_stats(char *p, void *priv) +static void lib80211_wep_print_stats(struct seq_file *m, void *priv) { struct lib80211_wep_data *wep = priv; - p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len); - return p; + seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len); } static struct lib80211_crypto_ops lib80211_crypt_wep = { diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 2ffde4631ae..0917f047f2c 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c @@ -187,7 +187,6 @@ static int x25_seq_forward_open(struct inode *inode, struct file *file) } static const struct file_operations x25_seq_socket_fops = { - .owner = THIS_MODULE, .open = x25_seq_socket_open, .read = seq_read, .llseek = seq_lseek, @@ -195,7 +194,6 @@ static const struct file_operations x25_seq_socket_fops = { }; static const struct file_operations x25_seq_route_fops = { - .owner = THIS_MODULE, .open = x25_seq_route_open, .read = seq_read, .llseek = seq_lseek, @@ -203,55 +201,38 @@ static const struct file_operations x25_seq_route_fops = { }; static const struct file_operations x25_seq_forward_fops = { - .owner = THIS_MODULE, .open = x25_seq_forward_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; -static struct proc_dir_entry *x25_proc_dir; - int __init x25_proc_init(void) { - struct proc_dir_entry *p; - int rc = -ENOMEM; + if (!proc_mkdir("x25", init_net.proc_net)) + return -ENOMEM; - x25_proc_dir = proc_mkdir("x25", init_net.proc_net); - if (!x25_proc_dir) + if (!proc_create("x25/route", S_IRUGO, init_net.proc_net, + &x25_seq_route_fops)) goto out; - p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops); - if (!p) - goto out_route; - - p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops); - if (!p) - goto out_socket; + if (!proc_create("x25/socket", S_IRUGO, init_net.proc_net, + &x25_seq_socket_fops)) + goto out; - p = proc_create("forward", S_IRUGO, x25_proc_dir, - &x25_seq_forward_fops); - if (!p) - goto out_forward; - rc = 0; + if (!proc_create("x25/forward", S_IRUGO, init_net.proc_net, + &x25_seq_forward_fops)) + goto out; + return 0; out: - return rc; -out_forward: - remove_proc_entry("socket", x25_proc_dir); -out_socket: - remove_proc_entry("route", x25_proc_dir); -out_route: - remove_proc_entry("x25", init_net.proc_net); - goto out; + remove_proc_subtree("x25", init_net.proc_net); + return -ENOMEM; } void __exit x25_proc_exit(void) { - remove_proc_entry("forward", x25_proc_dir); - remove_proc_entry("route", x25_proc_dir); - remove_proc_entry("socket", x25_proc_dir); - remove_proc_entry("x25", init_net.proc_net); + remove_proc_subtree("x25", init_net.proc_net); } #else /* CONFIG_PROC_FS */ diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index f89a0333b81..283862aebdc 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -2681,10 +2681,8 @@ out: * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. * * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns 0. */ -int tomoyo_close_control(struct tomoyo_io_buffer *head) +void tomoyo_close_control(struct tomoyo_io_buffer *head) { /* * If the file is /sys/kernel/security/tomoyo/query , decrement the @@ -2694,7 +2692,6 @@ int tomoyo_close_control(struct tomoyo_io_buffer *head) atomic_dec_and_test(&tomoyo_query_observers)) wake_up_all(&tomoyo_answer_wait); tomoyo_notify_gc(head, false); - return 0; } /** diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index d4f166bc350..b897d486201 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -958,7 +958,7 @@ const struct tomoyo_path_info *tomoyo_path_matches_group (const struct tomoyo_path_info *pathname, const struct tomoyo_group *group); int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, struct path *path, const int flag); -int tomoyo_close_control(struct tomoyo_io_buffer *head); +void tomoyo_close_control(struct tomoyo_io_buffer *head); int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env); int tomoyo_execute_permission(struct tomoyo_request_info *r, const struct tomoyo_path_info *filename); diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c index fcf32783b66..179a955b319 100644 --- a/security/tomoyo/securityfs_if.c +++ b/security/tomoyo/securityfs_if.c @@ -143,14 +143,13 @@ static int tomoyo_open(struct inode *inode, struct file *file) /** * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface. * - * @inode: Pointer to "struct inode". * @file: Pointer to "struct file". * - * Returns 0 on success, negative value otherwise. */ static int tomoyo_release(struct inode *inode, struct file *file) { - return tomoyo_close_control(file->private_data); + tomoyo_close_control(file->private_data); + return 0; } /** diff --git a/sound/core/info.c b/sound/core/info.c index 5bb97e7d325..3c9bd6b10a9 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -153,13 +153,6 @@ EXPORT_SYMBOL(snd_seq_root); struct snd_info_entry *snd_oss_root; #endif -static void snd_remove_proc_entry(struct proc_dir_entry *parent, - struct proc_dir_entry *de) -{ - if (de) - remove_proc_entry(de->name, parent); -} - static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) { struct snd_info_private_data *data; @@ -310,12 +303,10 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) struct snd_info_entry *entry; struct snd_info_private_data *data; struct snd_info_buffer *buffer; - struct proc_dir_entry *p; int mode, err; mutex_lock(&info_mutex); - p = PDE(inode); - entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; + entry = PDE_DATA(inode); if (entry == NULL || ! entry->p) { mutex_unlock(&info_mutex); return -ENODEV; @@ -582,7 +573,7 @@ int __exit snd_info_done(void) #ifdef CONFIG_SND_OSSEMUL snd_info_free_entry(snd_oss_root); #endif - snd_remove_proc_entry(NULL, snd_proc_root); + proc_remove(snd_proc_root); } return 0; } @@ -644,7 +635,7 @@ void snd_info_card_id_change(struct snd_card *card) { mutex_lock(&info_mutex); if (card->proc_root_link) { - snd_remove_proc_entry(snd_proc_root, card->proc_root_link); + proc_remove(card->proc_root_link); card->proc_root_link = NULL; } if (strcmp(card->id, card->proc_root->name)) @@ -663,10 +654,8 @@ void snd_info_card_disconnect(struct snd_card *card) if (!card) return; mutex_lock(&info_mutex); - if (card->proc_root_link) { - snd_remove_proc_entry(snd_proc_root, card->proc_root_link); - card->proc_root_link = NULL; - } + proc_remove(card->proc_root_link); + card->proc_root_link = NULL; if (card->proc_root) snd_info_disconnect(card->proc_root); mutex_unlock(&info_mutex); @@ -858,7 +847,7 @@ static void snd_info_disconnect(struct snd_info_entry *entry) list_del_init(&entry->list); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; snd_BUG_ON(!root); - snd_remove_proc_entry(root, entry->p); + proc_remove(entry->p); entry->p = NULL; } @@ -959,15 +948,21 @@ int snd_info_register(struct snd_info_entry * entry) return -ENXIO; root = entry->parent == NULL ? snd_proc_root : entry->parent->p; mutex_lock(&info_mutex); - p = create_proc_entry(entry->name, entry->mode, root); - if (!p) { - mutex_unlock(&info_mutex); - return -ENOMEM; + if (S_ISDIR(entry->mode)) { + p = proc_mkdir_mode(entry->name, entry->mode, root); + if (!p) { + mutex_unlock(&info_mutex); + return -ENOMEM; + } + } else { + p = proc_create_data(entry->name, entry->mode, root, + &snd_info_entry_operations, entry); + if (!p) { + mutex_unlock(&info_mutex); + return -ENOMEM; + } + proc_set_size(p, entry->size); } - if (!S_ISDIR(entry->mode)) - p->proc_fops = &snd_info_entry_operations; - p->size = entry->size; - p->data = entry; entry->p = p; if (entry->parent) list_add_tail(&entry->list, &entry->parent->children); diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index c918313c220..bac43b5b6e9 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -835,7 +835,7 @@ static void sq_reset(void) shared_resources_initialised = 0 ; } -static int sq_fsync(struct file *filp, struct dentry *dentry) +static int sq_fsync(void) { int rc = 0; int timeout = 5; @@ -874,7 +874,7 @@ static int sq_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) { if (write_sq.busy) - rc = sq_fsync(file, file->f_path.dentry); + rc = sq_fsync(); sq_reset_output() ; /* make sure dma is stopped and all is quiet */ write_sq_release_buffers(); @@ -1025,7 +1025,7 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) */ result = 0 ; if (file->f_mode & FMODE_WRITE) { - result = sq_fsync(file, file->f_path.dentry); + result = sq_fsync(); sq_reset_output() ; } /* if we are the shared resource owner then release them */ diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c index e1490346805..b155137ee31 100644 --- a/sound/sound_firmware.c +++ b/sound/sound_firmware.c @@ -1,6 +1,7 @@ #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/fs.h> +#include <linux/file.h> #include <linux/mm.h> #include <linux/sched.h> #include <asm/uaccess.h> @@ -23,14 +24,14 @@ static int do_mod_firmware_load(const char *fn, char **fp) if (l <= 0 || l > 131072) { printk(KERN_INFO "Invalid firmware '%s'\n", fn); - filp_close(filp, NULL); + fput(filp); return 0; } dp = vmalloc(l); if (dp == NULL) { printk(KERN_INFO "Out of memory loading '%s'.\n", fn); - filp_close(filp, NULL); + fput(filp); return 0; } pos = 0; @@ -38,10 +39,10 @@ static int do_mod_firmware_load(const char *fn, char **fp) { printk(KERN_INFO "Failed to read '%s'.\n", fn); vfree(dp); - filp_close(filp, NULL); + fput(filp); return 0; } - filp_close(filp, NULL); + fput(filp); *fp = dp; return (int) l; } |