Commit 441b2211 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.27pre5

parent a5f0a0e2
......@@ -49,13 +49,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp ; mp = mp->next) {
if (!mp->ex_table_start)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr - mp->gp);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end-1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -41,13 +41,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -43,13 +43,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -45,13 +45,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -56,13 +56,18 @@ search_exception_table(unsigned long addr, unsigned long *g2)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end-1, addr, g2);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -2932,6 +2932,7 @@ put_mod_name(char *buf)
free_page((unsigned long)buf);
}
/* caller must hold modlist_lock at least in read mode */
static __inline__ struct module *find_module(const char *name)
{
struct module *mod;
......@@ -3161,7 +3162,7 @@ asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kerne
struct module *mod;
int err;
lock_kernel();
read_lock(&modlist_lock);
if (name_user == 0) {
/* This finds "kernel_module" which is not exported. */
for(mod = module_list; mod->next != NULL; mod = mod->next)
......@@ -3211,7 +3212,7 @@ asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kerne
break;
}
out:
unlock_kernel();
read_unlock(&modlist_lock);
return err;
}
......
......@@ -56,13 +56,18 @@ search_exception_table(unsigned long addr, unsigned long *g2)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end-1, addr, g2);
if (ret) return ret;
if (ret) {
read_unlock(&modlist_lock);
return ret;
}
}
read_unlock(&modlist_lock);
#endif
return 0;
......
......@@ -22,245 +22,25 @@
*
* This file contains the procfs interface for the
* QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
* Old code removed, switched to dynamic proc entry.
*/
#include <linux/config.h>
#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
/* adding proc entries from inside a module is REALLY complicated
* for pre-2.1.28 kernels. I don't want to care about it.
*/
#include <linux/proc_fs.h>
#include <linux/ftape.h>
#if LINUX_VERSION_CODE <= KERNEL_VER(1,2,13) /* bail out */
#error \
Please disable CONFIG_FT_PROC_FS in "MCONFIG" or upgrade to a newer kernel!
#endif
#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,16)
#include <linux/init.h>
#else
#define __initdata
#define __initfunc(__arg) __arg
#endif
#include <linux/qic117.h>
#include "../lowlevel/ftape-io.h"
#include "../lowlevel/ftape-ctl.h"
#include "../lowlevel/ftape-proc.h"
#include "../lowlevel/ftape-tracing.h"
static int ftape_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data);
#if LINUX_VERSION_CODE < KERNEL_VER(2,1,28)
#include <asm/segment.h> /* for memcpy_tofs() */
#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
static long ftape_proc_read(struct inode* inode, struct file* file,
char* buf, unsigned long count);
#else
static int ftape_proc_read(struct inode* inode, struct file* file,
char* buf, int count);
#endif
#define FT_PROC_REGISTER(parent, child) proc_register_dynamic(parent, child)
/*
* Structures for interfacing with the /proc filesystem.
* Router creates its own directory /proc/net/router with the folowing
* entries:
* config device configuration
* status global device statistics
* <device> entry for each WAN device
*/
/*
* Generic /proc/net/ftape/<file> file and inode operations
*/
static struct file_operations ftape_proc_fops =
{
NULL, /* lseek */
ftape_proc_read, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* no special open code */
NULL, /* flush */
NULL, /* no special release code */
NULL, /* can't fsync */
};
static struct inode_operations ftape_proc_inode_operations =
{
&ftape_proc_fops,
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL, /* revalidate */
};
/*
* Proc filesystem directory entries.
*/
static int ftape_get_info(char *page, char **start, off_t off,
int count, int dummy)
{
int dummy_eof;
return ftape_read_proc(page, start, off, count, &dummy_eof, NULL);
}
static struct proc_dir_entry proc_ftape = {
0, /* low_ino */
sizeof("ftape")-1, /* namelen */
"ftape", /* name */
S_IFREG | S_IRUGO, /* mode */
1, /* nlink */
0, /* uid */
0, /* gid */
0, /* size */
&ftape_proc_inode_operations, /* ops */
ftape_get_info, /* get_info */
NULL, /* fill_inode */
NULL, /* next */
NULL, /* parent */
NULL, /* subdir */
NULL /* data */
};
/* Read ftape proc directory entry.
*/
#define PROC_BLOCK_SIZE PAGE_SIZE
#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
static long ftape_proc_read(struct inode * inode, struct file * file,
char * buf, unsigned long nbytes)
#else
static int ftape_proc_read(struct inode * inode, struct file * file,
char * buf, int nbytes)
#endif
{
char *page;
int retval=0;
int eof=0;
int n, count;
char *start;
struct proc_dir_entry * dp;
if (nbytes < 0)
return -EINVAL;
dp = (struct proc_dir_entry *) inode->u.generic_ip;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
while ((nbytes > 0) && !eof)
{
count = PROC_BLOCK_SIZE <= nbytes ? PROC_BLOCK_SIZE : nbytes;
start = NULL;
if (dp->get_info) {
/*
* Handle backwards compatibility with the old net
* routines.
*
* XXX What gives with the file->f_flags & O_ACCMODE
* test? Seems stupid to me....
*/
n = dp->get_info(page, &start, file->f_pos, count,
(file->f_flags & O_ACCMODE) == O_RDWR);
if (n < count)
eof = 1;
} else
break;
if (!start) {
/*
* For proc files that are less than 4k
*/
start = page + file->f_pos;
n -= file->f_pos;
if (n <= 0)
break;
if (n > count)
n = count;
}
if (n == 0)
break; /* End of file */
if (n < 0) {
if (retval == 0)
retval = n;
break;
}
#if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
copy_to_user(buf, start, n);
#else
memcpy_tofs(buf, start, n);
#endif
file->f_pos += n; /* Move down the file */
nbytes -= n;
buf += n;
retval += n;
}
free_page((unsigned long) page);
return retval;
}
#else /* LINUX_VERSION_CODE < KERNEL_VER(2,1,28) */
#define FT_PROC_REGISTER(parent, child) proc_register(parent, child)
/*
* Proc filesystem directory entries.
*/
static struct proc_dir_entry proc_ftape = {
0, /* low_ino */
sizeof("ftape")-1, /* namelen */
"ftape", /* name */
S_IFREG | S_IRUGO, /* mode */
1, /* nlink */
0, /* uid */
0, /* gid */
0, /* size */
NULL, /* ops */
NULL, /* get_info */
NULL, /* fill_inode */
NULL, /* next */
NULL, /* parent */
NULL, /* subdir */
NULL, /* data */
ftape_read_proc, /* read_proc */
NULL /* write_proc */
};
#endif
static size_t get_driver_info(char *buf)
{
const char *debug_level[] = { "bugs" ,
......@@ -423,13 +203,14 @@ int ftape_read_proc(char *page, char **start, off_t off,
int __init ftape_proc_init(void)
{
return FT_PROC_REGISTER(&proc_root, &proc_ftape);
return create_proc_read_entry("ftape", 0, &proc_root,
ftape_read_proc, NULL) != NULL;
}
#ifdef MODULE
void ftape_proc_destroy(void)
{
proc_unregister(&proc_root, proc_ftape.low_ino);
remove_proc_entry("ftape", &proc_root);
}
#endif
......
......@@ -74,16 +74,6 @@
int ip2_read_procmem(char *, char **, off_t, int, int );
int ip2_read_proc(char *, char **, off_t, int, int *, void * );
struct proc_dir_entry ip2_proc_entry = {
0,
6,"ip2mem",
S_IFREG | S_IRUGO,
1, 0, 0,
0,
NULL,
ip2_read_procmem
};
/********************/
/* Type Definitions */
/********************/
......@@ -429,9 +419,7 @@ cleanup_module(void)
if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
}
if ( ( err = proc_unregister( &proc_root, ip2_proc_entry.low_ino ) ) ) {
printk(KERN_ERR "IP2: failed to unregister read_procmem (%d)\n", err);
}
remove_proc_entry("ip2mem", &proc_root);
// free memory
for (i = 0; i < IP2_MAX_BOARDS; i++) {
......@@ -673,8 +661,8 @@ old_ip2_init(void)
printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
} else
/* Register the read_procmem thing */
if ( ( err = proc_register( &proc_root, &ip2_proc_entry ) ) ) {
printk(KERN_ERR "IP2: failed to register read_procmem (%d)\n", err );
if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
printk(KERN_ERR "IP2: failed to register read_procmem\n");
} else {
#ifdef IP2DEBUG_TRACE
......
......@@ -147,7 +147,6 @@ static void join_net(u_long local);
static void start_net(u_long local);
/* void start_net(ray_dev_t *local); */
static int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare);
/* Create symbol table for registering with kernel in init_module */
EXPORT_SYMBOL(ray_dev_ioctl);
EXPORT_SYMBOL(ray_rx);
......@@ -308,18 +307,6 @@ static char hop_pattern_length[] = { 1,
static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
#ifdef CONFIG_PROC_FS
struct proc_dir_entry ray_cs_proc_entry = {
0, /* Dynamic inode # */
6,"ray_cs", /* name length and name */
S_IFREG | S_IRUGO, /* mode */
1, 0, 0, /* nlinks, owner, group */
0, /* size (unused) */
NULL, /* operations (default) */
&ray_cs_proc_read, /* function to read data */
/* The end ?? */
};
#endif
/*===========================================================================*/
static void cs_error(client_handle_t handle, int func, int ret)
{
......@@ -2695,7 +2682,8 @@ static int __init init_ray_cs(void)
rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
#ifdef CONFIG_PROC_FS
proc_register(&proc_root, &ray_cs_proc_entry);
/* [proc-namespace][fixme] It shouldn't be under root, damnit! */
create_proc_info_entry("ray_cs", 0, proc_root, ray_cs_proc_read);
#endif
if (translate != 0) translate = 1;
return 0;
......@@ -2726,7 +2714,7 @@ static void __exit exit_ray_cs(void)
ray_detach(dev_list);
}
#ifdef CONFIG_PROC_FS
proc_unregister(&proc_root, ray_cs_proc_entry.low_ino);
remove_proc_entry("ray_cs", proc_root);
#endif
} /* exit_ray_cs */
......
......@@ -247,7 +247,7 @@ static int __init isapnp_proc_init(void)
static int isapnp_proc_done(void)
{
if (isapnp_proc_entry)
proc_unregister(&proc_root, isapnp_proc_entry->low_ino);
remove_proc_entry("isapnp",&proc_root);
return 0;
}
#endif /* MODULE */
......
......@@ -71,8 +71,12 @@
#undef USE_STATIC_SCSI_MEMORY
struct proc_dir_entry *proc_scsi = NULL;
#ifdef CONFIG_PROC_FS
static int scsi_proc_info(char *buffer, char **start, off_t offset,
int length, int inout);
static void scsi_dump_status(int level);
#endif
/*
static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
......@@ -189,7 +193,6 @@ extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
|| ((HOST)->host_blocked) \
|| ((DEVICE) != NULL && (DEVICE)->device_blocked) )
static void scsi_dump_status(int level);
struct dev_info {
......@@ -1983,7 +1986,7 @@ int __init scsi_dev_init(void)
/*
* This makes /proc/scsi and /proc/scsi/scsi visible.
*/
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
if (!proc_scsi) {
printk (KERN_ERR "cannot init /proc/scsi\n");
......@@ -2178,7 +2181,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset,
* where token is one of [error,scan,mlqueue,mlcomplete,llqueue,
* llcomplete,hlqueue,hlcomplete]
*/
#if CONFIG_SCSI_LOGGING /* { */
#ifdef CONFIG_SCSI_LOGGING /* { */
if (!strncmp("log", buffer + 5, 3)) {
char *token;
......@@ -2614,7 +2617,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
scsi_hosts = tpnt;
/* Add the new driver to /proc/scsi */
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
build_proc_dir_entries(tpnt);
#endif
......@@ -2884,7 +2887,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
if (shpnt->loaded_as_module) {
pcount = next_scsi_host;
/* Remove the /proc/scsi directory entry */
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
proc_scsi_unregister(tpnt->proc_dir,
shpnt->host_no + PROC_SCSI_FILE);
#endif
......@@ -2946,7 +2949,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
break;
}
/* Rebuild the /proc/scsi directory entries */
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
proc_scsi_unregister(tpnt->proc_dir, tpnt->proc_dir->low_ino);
#endif
MOD_DEC_USE_COUNT;
......@@ -3133,6 +3136,7 @@ void scsi_unregister_module(int module_type, void *ptr)
#endif /* CONFIG_MODULES */
#ifdef CONFIG_PROC_FS
/*
* Function: scsi_dump_status
*
......@@ -3153,8 +3157,7 @@ void scsi_unregister_module(int module_type, void *ptr)
*/
static void scsi_dump_status(int level)
{
#if CONFIG_PROC_FS
#if CONFIG_SCSI_LOGGING /* { */
#ifdef CONFIG_SCSI_LOGGING /* { */
int i;
struct Scsi_Host *shpnt;
Scsi_Cmnd *SCpnt;
......@@ -3233,8 +3236,8 @@ static void scsi_dump_status(int level)
}
/* printk("wait_for_request = %p\n", &wait_for_request); */
#endif /* CONFIG_SCSI_LOGGING */ /* } */
#endif /* CONFIG_PROC_FS */
}
#endif /* CONFIG_PROC_FS */
#ifdef MODULE
......@@ -3246,7 +3249,7 @@ int init_module(void)
/*
* This makes /proc/scsi and /proc/scsi/scsi visible.
*/
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
if (!proc_scsi) {
printk (KERN_ERR "cannot init /proc/scsi\n");
......@@ -3303,7 +3306,7 @@ void cleanup_module(void)
{
remove_bh(SCSI_BH);
#if CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
/* No, we're not here anymore. Don't show the /proc/scsi files. */
remove_proc_entry ("scsi/scsi", 0);
remove_proc_entry ("scsi", 0);
......
......@@ -16,6 +16,7 @@
#define _SCSI_H
#include <linux/config.h> /* for CONFIG_SCSI_LOGGING */
#include <linux/proc_fs.h>
/*
* Some of the public constants are being moved to this file.
......@@ -404,6 +405,50 @@ extern void scsi_release_command(Scsi_Cmnd *);
extern int max_scsi_hosts;
extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
extern struct inode_operations proc_scsi_inode_operations;
extern struct proc_dir_entry *proc_scsi;
#ifdef CONFIG_PROC_FS
extern inline int proc_scsi_register(struct proc_dir_entry *driver,
struct proc_dir_entry *x)
{
x->ops = &proc_scsi_inode_operations;
if(x->low_ino < PROC_SCSI_FILE){
return(proc_register(proc_scsi, x));
}else{
return(proc_register(driver, x));
}
}
extern inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
{
extern void scsi_init_free(char *ptr, unsigned int size);
if(x < PROC_SCSI_FILE)
return(proc_unregister(proc_scsi, x));
else {
struct proc_dir_entry **p = &driver->subdir, *dp;
int ret;
while ((dp = *p) != NULL) {
if (dp->low_ino == x)
break;
p = &dp->next;
}
ret = proc_unregister(driver, x);
scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4);
return(ret);
}
}
#else
extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
#endif /* CONFIG_PROC_FS */
extern void print_command(unsigned char *);
extern void print_sense(const char *, Scsi_Cmnd *);
......
......@@ -27,6 +27,9 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/blk.h>
#include <asm/uaccess.h>
#include "scsi.h"
#include "hosts.h"
......@@ -77,7 +80,7 @@ int generic_proc_info(char *buffer, char **start, off_t offset,
/* dispatch_scsi_info is the central dispatcher
* It is the interface between the proc-fs and the SCSI subsystem code
*/
int dispatch_scsi_info(int ino, char *buffer, char **start,
static int dispatch_scsi_info(int ino, char *buffer, char **start,
off_t offset, int length, int func)
{
struct Scsi_Host *hpnt = scsi_hostlist;
......@@ -290,12 +293,6 @@ void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
return;
}
#else
void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
{
}
/* forward references */
static ssize_t proc_readscsi(struct file * file, char * buf,
size_t count, loff_t *ppos);
......@@ -305,10 +302,6 @@ static long long proc_scsilseek(struct file *, long long, int);
extern void build_proc_dir_hba_entries(uint);
/* the *_get_info() functions are in the respective scsi driver code */
int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
off_t offset, int length, int inout) = 0;
static struct file_operations proc_scsi_operations = {
proc_scsilseek, /* lseek */
proc_readscsi, /* read */
......@@ -349,26 +342,6 @@ struct inode_operations proc_scsi_inode_operations = {
NULL /* revalidate */
};
static int get_not_present_info(char *buffer, char **start, off_t offset, int length)
{
int len, pos, begin;
begin = 0;
pos = len = sprintf(buffer,
"No low-level scsi modules are currently present\n");
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);
}
#define PROC_BLOCK_SIZE (3*1024) /* 4K page size, but our output routines
* use some slack for overruns
*/
......@@ -392,11 +365,8 @@ static ssize_t proc_readscsi(struct file * file, char * buf,
if(bytes > PROC_BLOCK_SIZE)
thistime = PROC_BLOCK_SIZE;
if(dispatch_scsi_info_ptr)
length = dispatch_scsi_info_ptr(inode->i_ino, page, &start,
*ppos, thistime, 0);
else
length = get_not_present_info(page, &start, *ppos, thistime);
length = dispatch_scsi_info (inode->i_ino, page, &start,
*ppos, thistime, 0);
if(length < 0) {
free_page((ulong) page);
return(length);
......@@ -438,13 +408,10 @@ static ssize_t proc_writescsi(struct file * file, const char * buf,
return(-EOVERFLOW);
}
if(dispatch_scsi_info_ptr != NULL) {
if (!(page = (char *) __get_free_page(GFP_KERNEL)))
return(-ENOMEM);
copy_from_user(page, buf, count);
ret = dispatch_scsi_info_ptr(inode->i_ino, page, 0, 0, count, 1);
} else
return(-ENOPKG); /* Nothing here */
if (!(page = (char *) __get_free_page(GFP_KERNEL)))
return(-ENOMEM);
copy_from_user(page, buf, count);
ret = dispatch_scsi_info (inode->i_ino, page, 0, 0, count, 1);
free_page((ulong) page);
return(ret);
......@@ -467,6 +434,14 @@ static long long proc_scsilseek(struct file * file, long long offset, int orig)
}
}
#else /* if !CONFIG_PROC_FS */
void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
{
}
struct inode_operations proc_scsi_inode_operations = { 0, };
#endif /* CONFIG_PROC_FS */
/*
......
......@@ -74,6 +74,7 @@ EXPORT_SYMBOL(scsi_sleep);
EXPORT_SYMBOL(proc_print_scsidevice);
EXPORT_SYMBOL(proc_scsi);
EXPORT_SYMBOL(proc_scsi_inode_operations);
/*
* These are here only while I debug the rest of the scsi stuff.
......
......@@ -251,13 +251,15 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
struct buffer_head * bh;
int i,j;
if (!dir || !(inode = get_empty_inode()))
inode = get_empty_inode();
if (!inode)
return NULL;
sb = dir->i_sb;
inode->i_sb = sb;
inode->i_flags = 0;
j = 8192;
bh = NULL;
lock_super(sb);
for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
bh = inode->i_sb->u.minix_sb.s_imap[i];
if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
......@@ -265,17 +267,20 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
}
if (!bh || j >= 8192) {
iput(inode);
unlock_super(sb);
return NULL;
}
if (minix_set_bit(j,bh->b_data)) { /* shouldn't happen */
printk("new_inode: bit already set");
iput(inode);
unlock_super(sb);
return NULL;
}
mark_buffer_dirty(bh, 1);
j += i*8192;
if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) {
iput(inode);
unlock_super(sb);
return NULL;
}
inode->i_nlink = 1;
......
......@@ -403,9 +403,9 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned
++*pages;
if (pte_dirty(page))
++*dirty;
if (MAP_NR(pte_page(page)) >= max_mapnr)
if (pte_pagenr(page) >= max_mapnr)
continue;
if (page_count(mem_map + MAP_NR(pte_page(page))) > 1)
if (page_count(pte_page(page)) > 1)
++*shared;
} while (address < end);
}
......
......@@ -211,6 +211,7 @@ static void elf_kcore_store_hdr(char *bufp)
#ifdef CONFIG_MODULES
{
struct module *m;
read_lock(&modlist_lock);
for (m=module_list; m; m=m->next) {
dhdr = (struct elf_phdr *) bufp;
bufp += sizeof(struct elf_phdr);
......@@ -226,6 +227,7 @@ static void elf_kcore_store_hdr(char *bufp)
dhdr->p_align = 0;
elf->e_phnum++;
}
read_unlock(&modlist_lock);
}
#endif
......
......@@ -8,6 +8,7 @@
#define _LINUX_MODULE_H
#include <linux/config.h>
#include <linux/spinlock.h>
#ifdef __GENKSYMS__
# define _set_ver(sym) sym
......@@ -286,5 +287,6 @@ __attribute__((section("__ksymtab"))) = \
#define EXPORT_NO_SYMBOLS
#endif /* MODULE */
extern rwlock_t modlist_lock;
extern unsigned long get_kcore_size(void);
#endif /* _LINUX_MODULE_H */
......@@ -145,12 +145,6 @@ struct proc_dir_entry {
int deleted; /* delete flag */
};
#if 0 /* FIXME! /proc/scsi is broken right now */
extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
off_t offset, int length, int inout);
extern struct inode_operations proc_scsi_inode_operations;
#endif
#define PROC_INODE_PROPER(inode) ((inode)->i_ino & ~0xffff)
#define PROC_INODE_OPENPROM(inode) \
((inode->i_ino >= PROC_OPENPROM_FIRST) \
......@@ -161,7 +155,6 @@ extern struct inode_operations proc_scsi_inode_operations;
extern struct proc_dir_entry proc_root;
extern struct proc_dir_entry *proc_root_fs;
extern struct proc_dir_entry *proc_net;
extern struct proc_dir_entry *proc_scsi;
extern struct proc_dir_entry proc_sys;
extern struct proc_dir_entry proc_openprom;
extern struct proc_dir_entry *proc_mca;
......@@ -184,41 +177,6 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
extern inline int proc_scsi_register(struct proc_dir_entry *driver,
struct proc_dir_entry *x)
{
#if 0 /* FIXME! */
x->ops = &proc_scsi_inode_operations;
#endif
if(x->low_ino < PROC_SCSI_FILE){
return(proc_register(proc_scsi, x));
}else{
return(proc_register(driver, x));
}
}
extern inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
{
extern void scsi_init_free(char *ptr, unsigned int size);
if(x < PROC_SCSI_FILE)
return(proc_unregister(proc_scsi, x));
else {
struct proc_dir_entry **p = &driver->subdir, *dp;
int ret;
while ((dp = *p) != NULL) {
if (dp->low_ino == x)
break;
p = &dp->next;
}
ret = proc_unregister(driver, x);
scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4);
return(ret);
}
}
/*
* retrieve the proc_dir_entry associated with /proc/driver/$module_name
*/
......@@ -362,8 +320,6 @@ extern inline int proc_unregister(struct proc_dir_entry *a, int b) { return 0; }
extern inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode,
get_info_t *get_info) {return NULL;}
extern inline void proc_net_remove(const char *name) {}
extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
extern inline struct proc_dir_entry *create_proc_entry(const char *name,
mode_t mode, struct proc_dir_entry *parent) { return NULL; }
......
......@@ -13,6 +13,7 @@
* 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
* Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
* Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
* Use rw spinlock instead of global kernel lock for module_list, by TA <tigran@sco.com>
*
* This source is covered by the GNU GPL, the same as all kernel sources.
*/
......@@ -52,6 +53,8 @@ static void put_mod_name(char *buf);
static struct module *find_module(const char *name);
static void free_module(struct module *, int tag_freed);
rwlock_t modlist_lock = RW_LOCK_UNLOCKED;
/* needed for /proc/kcore, here because kernel_module is static (TA) */
unsigned long get_kcore_size(void)
......@@ -62,14 +65,13 @@ unsigned long get_kcore_size(void)
if (module_list == &kernel_module)
return ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
/* shouldn't we have a rw spinlock for module_list? */
lock_kernel();
read_lock(&modlist_lock);
for (m=module_list; m; m=m->next) {
try = (unsigned long)m + m->size;
if (try > size)
size = try;
}
unlock_kernel();
read_unlock(&modlist_lock);
return (size - PAGE_OFFSET + PAGE_SIZE);
}
......@@ -131,7 +133,7 @@ sys_create_module(const char *name_user, size_t size)
long namelen, error;
struct module *mod;
lock_kernel();
write_lock(&modlist_lock);
if (!capable(CAP_SYS_MODULE)) {
error = -EPERM;
goto err0;
......@@ -169,7 +171,7 @@ sys_create_module(const char *name_user, size_t size)
err1:
put_mod_name(name);
err0:
unlock_kernel();
write_unlock(&modlist_lock);
return error;
}
......@@ -186,7 +188,7 @@ sys_init_module(const char *name_user, struct module *mod_user)
unsigned long mod_user_size;
struct module_ref *dep;
lock_kernel();
write_lock(&modlist_lock);
if (!capable(CAP_SYS_MODULE))
goto err0;
if ((namelen = get_mod_name(name_user, &name)) < 0) {
......@@ -365,7 +367,7 @@ sys_init_module(const char *name_user, struct module *mod_user)
err1:
put_mod_name(name);
err0:
unlock_kernel();
write_unlock(&modlist_lock);
return error;
}
......@@ -377,7 +379,7 @@ sys_delete_module(const char *name_user)
long error = -EPERM;
int something_changed;
lock_kernel();
write_lock(&modlist_lock);
if (!capable(CAP_SYS_MODULE))
goto out;
......@@ -430,7 +432,7 @@ sys_delete_module(const char *name_user)
mod->flags &= ~MOD_JUST_FREED;
error = 0;
out:
unlock_kernel();
write_unlock(&modlist_lock);
return error;
}
......@@ -444,17 +446,21 @@ qm_modules(char *buf, size_t bufsize, size_t *ret)
nmod = space = 0;
read_lock(&modlist_lock);
for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
len = strlen(mod->name)+1;
if (len > bufsize)
goto calc_space_needed;
if (copy_to_user(buf, mod->name, len))
if (copy_to_user(buf, mod->name, len)) {
read_unlock(&modlist_lock);
return -EFAULT;
}
buf += len;
bufsize -= len;
space += len;
}
read_unlock(&modlist_lock);
if (put_user(nmod, ret))
return -EFAULT;
else
......@@ -465,6 +471,7 @@ qm_modules(char *buf, size_t bufsize, size_t *ret)
while ((mod = mod->next) != &kernel_module)
space += strlen(mod->name)+1;
read_unlock(&modlist_lock);
if (put_user(space, ret))
return -EFAULT;
else
......@@ -651,7 +658,7 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
struct module *mod;
int err;
lock_kernel();
read_lock(&modlist_lock);
if (name_user == NULL)
mod = &kernel_module;
else {
......@@ -697,7 +704,7 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
break;
}
out:
unlock_kernel();
read_unlock(&modlist_lock);
return err;
}
......@@ -716,7 +723,7 @@ sys_get_kernel_syms(struct kernel_sym *table)
int i;
struct kernel_sym ksym;
lock_kernel();
read_lock(&modlist_lock);
for (mod = module_list, i = 0; mod; mod = mod->next) {
/* include the count for the module name! */
i += mod->nsyms + 1;
......@@ -759,12 +766,13 @@ sys_get_kernel_syms(struct kernel_sym *table)
}
}
out:
unlock_kernel();
read_unlock(&modlist_lock);
return i;
}
/*
* Look for a module by name, ignoring modules marked for deletion.
* Callers must hold modlist_lock at least in read mode.
*/
static struct module *
......@@ -784,6 +792,7 @@ find_module(const char *name)
/*
* Free the given module.
* Callers must hold modlist_lock in exclusive (write) mode.
*/
static void
......@@ -840,6 +849,7 @@ int get_module_list(char *p)
char tmpstr[64];
struct module_ref *ref;
read_lock(&modlist_lock);
for (mod = module_list; mod != &kernel_module; mod = mod->next) {
long len;
const char *q;
......@@ -905,6 +915,7 @@ int get_module_list(char *p)
}
fini:
read_unlock(&modlist_lock);
return PAGE_SIZE - left;
}
......@@ -921,6 +932,7 @@ get_ksyms_list(char *buf, char **start, off_t offset, int length)
off_t pos = 0;
off_t begin = 0;
read_lock(&modlist_lock);
for (mod = module_list; mod; mod = mod->next) {
unsigned i;
struct module_symbol *sym;
......@@ -955,6 +967,7 @@ get_ksyms_list(char *buf, char **start, off_t offset, int length)
len -= (offset - begin);
if (len > length)
len = length;
read_unlock(&modlist_lock);
return len;
}
......@@ -971,6 +984,7 @@ get_module_symbol(char *modname, char *symname)
struct module_symbol *sym;
int i;
read_lock(&modlist_lock);
for (mp = module_list; mp; mp = mp->next) {
if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
(mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
......@@ -979,11 +993,13 @@ get_module_symbol(char *modname, char *symname)
i > 0; --i, ++sym) {
if (strcmp(sym->name, symname) == 0) {
read_unlock(&modlist_lock);
return sym->value;
}
}
}
}
read_unlock(&modlist_lock);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment