提交 fb28d58b 编写于 作者: G Greg Kroah-Hartman

USB: remove CONFIG_USB_DEVICEFS

This option has been deprecated for many years now, and no userspace
tools use it anymore, so it should be safe to finally remove it.
Reported-by: NKay Sievers <kay@vrfy.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 70f3c758
...@@ -87,7 +87,6 @@ kernel as built-in or modules: ...@@ -87,7 +87,6 @@ kernel as built-in or modules:
CONFIG_SOUND - Sound card support CONFIG_SOUND - Sound card support
CONFIG_SND - Advanced Linux Sound Architecture CONFIG_SND - Advanced Linux Sound Architecture
CONFIG_USB - Support for Host-side USB CONFIG_USB - Support for Host-side USB
CONFIG_USB_DEVICEFS - USB device filesystem
CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
Additionally, to use the example application, the following options need to Additionally, to use the example application, the following options need to
......
...@@ -27,35 +27,6 @@ config USB_ANNOUNCE_NEW_DEVICES ...@@ -27,35 +27,6 @@ config USB_ANNOUNCE_NEW_DEVICES
comment "Miscellaneous USB options" comment "Miscellaneous USB options"
depends on USB depends on USB
config USB_DEVICEFS
bool "USB device filesystem (DEPRECATED)"
depends on USB
---help---
If you say Y here (and to "/proc file system support" in the "File
systems" section, above), you will get a file /proc/bus/usb/devices
which lists the devices currently connected to your USB bus or
busses, and for every connected device a file named
"/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the
device number; the latter files can be used by user space programs
to talk directly to the device. These files are "virtual", meaning
they are generated on the fly and not stored on the hard drive.
You may need to mount the usbfs file system to see the files, use
mount -t usbfs none /proc/bus/usb
For the format of the various /proc/bus/usb/ files, please read
<file:Documentation/usb/proc_usb_info.txt>.
Modern Linux systems do not use this.
Usbfs entries are files and not character devices; usbfs can't
handle Access Control Lists (ACL) which are the default way to
grant access to USB devices for untrusted users of a desktop
system.
The usbfs functionality is replaced by real device-nodes managed by
udev. These nodes lived in /dev/bus/usb and are used by libusb.
config USB_DEVICE_CLASS config USB_DEVICE_CLASS
bool "USB device class-devices (DEPRECATED)" bool "USB device class-devices (DEPRECATED)"
depends on USB depends on USB
......
...@@ -9,6 +9,5 @@ usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o ...@@ -9,6 +9,5 @@ usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
usbcore-y += devio.o notify.o generic.o quirks.o devices.o usbcore-y += devio.o notify.o generic.o quirks.o devices.o
usbcore-$(CONFIG_PCI) += hcd-pci.o usbcore-$(CONFIG_PCI) += hcd-pci.o
usbcore-$(CONFIG_USB_DEVICEFS) += inode.o
obj-$(CONFIG_USB) += usbcore.o obj-$(CONFIG_USB) += usbcore.o
...@@ -727,17 +727,6 @@ static int usbdev_open(struct inode *inode, struct file *file) ...@@ -727,17 +727,6 @@ static int usbdev_open(struct inode *inode, struct file *file)
if (imajor(inode) == USB_DEVICE_MAJOR) if (imajor(inode) == USB_DEVICE_MAJOR)
dev = usbdev_lookup_by_devt(inode->i_rdev); dev = usbdev_lookup_by_devt(inode->i_rdev);
#ifdef CONFIG_USB_DEVICEFS
/* procfs file */
if (!dev) {
dev = inode->i_private;
if (dev && dev->usbfs_dentry &&
dev->usbfs_dentry->d_inode == inode)
usb_get_dev(dev);
else
dev = NULL;
}
#endif
mutex_unlock(&usbfs_mutex); mutex_unlock(&usbfs_mutex);
if (!dev) if (!dev)
......
...@@ -726,16 +726,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -726,16 +726,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
return -ENODEV; return -ENODEV;
} }
#ifdef CONFIG_USB_DEVICEFS
/* If this is available, userspace programs can directly read
* all the device descriptors we don't tell them about. Or
* act as usermode drivers.
*/
if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum))
return -ENOMEM;
#endif
/* per-device configurations are common */ /* per-device configurations are common */
if (add_uevent_var(env, "PRODUCT=%x/%x/%x", if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idVendor),
...@@ -788,15 +778,13 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver, ...@@ -788,15 +778,13 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver,
retval = driver_register(&new_udriver->drvwrap.driver); retval = driver_register(&new_udriver->drvwrap.driver);
if (!retval) { if (!retval)
pr_info("%s: registered new device driver %s\n", pr_info("%s: registered new device driver %s\n",
usbcore_name, new_udriver->name); usbcore_name, new_udriver->name);
usbfs_update_special(); else
} else {
printk(KERN_ERR "%s: error %d registering device " printk(KERN_ERR "%s: error %d registering device "
" driver %s\n", " driver %s\n",
usbcore_name, retval, new_udriver->name); usbcore_name, retval, new_udriver->name);
}
return retval; return retval;
} }
...@@ -815,7 +803,6 @@ void usb_deregister_device_driver(struct usb_device_driver *udriver) ...@@ -815,7 +803,6 @@ void usb_deregister_device_driver(struct usb_device_driver *udriver)
usbcore_name, udriver->name); usbcore_name, udriver->name);
driver_unregister(&udriver->drvwrap.driver); driver_unregister(&udriver->drvwrap.driver);
usbfs_update_special();
} }
EXPORT_SYMBOL_GPL(usb_deregister_device_driver); EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
...@@ -856,8 +843,6 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, ...@@ -856,8 +843,6 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
if (retval) if (retval)
goto out; goto out;
usbfs_update_special();
retval = usb_create_newid_files(new_driver); retval = usb_create_newid_files(new_driver);
if (retval) if (retval)
goto out_newid; goto out_newid;
...@@ -897,8 +882,6 @@ void usb_deregister(struct usb_driver *driver) ...@@ -897,8 +882,6 @@ void usb_deregister(struct usb_driver *driver)
usb_remove_newid_files(driver); usb_remove_newid_files(driver);
driver_unregister(&driver->drvwrap.driver); driver_unregister(&driver->drvwrap.driver);
usb_free_dynids(driver); usb_free_dynids(driver);
usbfs_update_special();
} }
EXPORT_SYMBOL_GPL(usb_deregister); EXPORT_SYMBOL_GPL(usb_deregister);
......
/*****************************************************************************/
/*
* inode.c -- Inode/Dentry functions for the USB device file system.
*
* Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
* Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com)
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History:
* 0.1 04.01.2000 Created
* 0.2 10.12.2001 converted to use the vfs layer better
*/
/*****************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/usb.h>
#include <linux/namei.h>
#include <linux/usbdevice_fs.h>
#include <linux/parser.h>
#include <linux/notifier.h>
#include <linux/seq_file.h>
#include <linux/usb/hcd.h>
#include <asm/byteorder.h>
#include "usb.h"
#define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO)
#define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
#define USBFS_DEFAULT_LISTMODE S_IRUGO
static const struct file_operations default_file_operations;
static struct vfsmount *usbfs_mount;
static int usbfs_mount_count; /* = 0 */
static struct dentry *devices_usbfs_dentry;
static int num_buses; /* = 0 */
static uid_t devuid; /* = 0 */
static uid_t busuid; /* = 0 */
static uid_t listuid; /* = 0 */
static gid_t devgid; /* = 0 */
static gid_t busgid; /* = 0 */
static gid_t listgid; /* = 0 */
static umode_t devmode = USBFS_DEFAULT_DEVMODE;
static umode_t busmode = USBFS_DEFAULT_BUSMODE;
static umode_t listmode = USBFS_DEFAULT_LISTMODE;
static int usbfs_show_options(struct seq_file *seq, struct dentry *root)
{
if (devuid != 0)
seq_printf(seq, ",devuid=%u", devuid);
if (devgid != 0)
seq_printf(seq, ",devgid=%u", devgid);
if (devmode != USBFS_DEFAULT_DEVMODE)
seq_printf(seq, ",devmode=%o", devmode);
if (busuid != 0)
seq_printf(seq, ",busuid=%u", busuid);
if (busgid != 0)
seq_printf(seq, ",busgid=%u", busgid);
if (busmode != USBFS_DEFAULT_BUSMODE)
seq_printf(seq, ",busmode=%o", busmode);
if (listuid != 0)
seq_printf(seq, ",listuid=%u", listuid);
if (listgid != 0)
seq_printf(seq, ",listgid=%u", listgid);
if (listmode != USBFS_DEFAULT_LISTMODE)
seq_printf(seq, ",listmode=%o", listmode);
return 0;
}
enum {
Opt_devuid, Opt_devgid, Opt_devmode,
Opt_busuid, Opt_busgid, Opt_busmode,
Opt_listuid, Opt_listgid, Opt_listmode,
Opt_err,
};
static const match_table_t tokens = {
{Opt_devuid, "devuid=%u"},
{Opt_devgid, "devgid=%u"},
{Opt_devmode, "devmode=%o"},
{Opt_busuid, "busuid=%u"},
{Opt_busgid, "busgid=%u"},
{Opt_busmode, "busmode=%o"},
{Opt_listuid, "listuid=%u"},
{Opt_listgid, "listgid=%u"},
{Opt_listmode, "listmode=%o"},
{Opt_err, NULL}
};
static int parse_options(struct super_block *s, char *data)
{
char *p;
int option;
/* (re)set to defaults. */
devuid = 0;
busuid = 0;
listuid = 0;
devgid = 0;
busgid = 0;
listgid = 0;
devmode = USBFS_DEFAULT_DEVMODE;
busmode = USBFS_DEFAULT_BUSMODE;
listmode = USBFS_DEFAULT_LISTMODE;
while ((p = strsep(&data, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
int token;
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_devuid:
if (match_int(&args[0], &option))
return -EINVAL;
devuid = option;
break;
case Opt_devgid:
if (match_int(&args[0], &option))
return -EINVAL;
devgid = option;
break;
case Opt_devmode:
if (match_octal(&args[0], &option))
return -EINVAL;
devmode = option & S_IRWXUGO;
break;
case Opt_busuid:
if (match_int(&args[0], &option))
return -EINVAL;
busuid = option;
break;
case Opt_busgid:
if (match_int(&args[0], &option))
return -EINVAL;
busgid = option;
break;
case Opt_busmode:
if (match_octal(&args[0], &option))
return -EINVAL;
busmode = option & S_IRWXUGO;
break;
case Opt_listuid:
if (match_int(&args[0], &option))
return -EINVAL;
listuid = option;
break;
case Opt_listgid:
if (match_int(&args[0], &option))
return -EINVAL;
listgid = option;
break;
case Opt_listmode:
if (match_octal(&args[0], &option))
return -EINVAL;
listmode = option & S_IRWXUGO;
break;
default:
printk(KERN_ERR "usbfs: unrecognised mount option "
"\"%s\" or missing value\n", p);
return -EINVAL;
}
}
return 0;
}
static void update_special(struct dentry *special)
{
special->d_inode->i_uid = listuid;
special->d_inode->i_gid = listgid;
special->d_inode->i_mode = S_IFREG | listmode;
}
static void update_dev(struct dentry *dev)
{
dev->d_inode->i_uid = devuid;
dev->d_inode->i_gid = devgid;
dev->d_inode->i_mode = S_IFREG | devmode;
}
static void update_bus(struct dentry *bus)
{
struct dentry *dev = NULL;
bus->d_inode->i_uid = busuid;
bus->d_inode->i_gid = busgid;
bus->d_inode->i_mode = S_IFDIR | busmode;
mutex_lock(&bus->d_inode->i_mutex);
list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
if (dev->d_inode)
update_dev(dev);
mutex_unlock(&bus->d_inode->i_mutex);
}
static void update_sb(struct super_block *sb)
{
struct dentry *root = sb->s_root;
struct dentry *bus = NULL;
if (!root)
return;
mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
if (bus->d_inode) {
switch (S_IFMT & bus->d_inode->i_mode) {
case S_IFDIR:
update_bus(bus);
break;
case S_IFREG:
update_special(bus);
break;
default:
printk(KERN_WARNING "usbfs: Unknown node %s "
"mode %x found on remount!\n",
bus->d_name.name, bus->d_inode->i_mode);
break;
}
}
}
mutex_unlock(&root->d_inode->i_mutex);
}
static int remount(struct super_block *sb, int *flags, char *data)
{
/* If this is not a real mount,
* i.e. it's a simple_pin_fs from create_special_files,
* then ignore it.
*/
if (*flags & MS_KERNMOUNT)
return 0;
if (parse_options(sb, data)) {
printk(KERN_WARNING "usbfs: mount parameter error.\n");
return -EINVAL;
}
if (usbfs_mount)
update_sb(usbfs_mount->mnt_sb);
return 0;
}
static struct inode *usbfs_get_inode (struct super_block *sb, umode_t mode, dev_t dev)
{
struct inode *inode = new_inode(sb);
if (inode) {
inode->i_ino = get_next_ino();
inode_init_owner(inode, NULL, mode);
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);
break;
case S_IFREG:
inode->i_fop = &default_file_operations;
break;
case S_IFDIR:
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode);
break;
}
}
return inode;
}
/* SMP-safe */
static int usbfs_mknod (struct inode *dir, struct dentry *dentry, umode_t mode,
dev_t dev)
{
struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev);
int error = -EPERM;
if (dentry->d_inode)
return -EEXIST;
if (inode) {
d_instantiate(dentry, inode);
dget(dentry);
error = 0;
}
return error;
}
static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, umode_t mode)
{
int res;
mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
res = usbfs_mknod (dir, dentry, mode, 0);
if (!res)
inc_nlink(dir);
return res;
}
static int usbfs_create (struct inode *dir, struct dentry *dentry, umode_t mode)
{
mode = (mode & S_IALLUGO) | S_IFREG;
return usbfs_mknod (dir, dentry, mode, 0);
}
static inline int usbfs_positive (struct dentry *dentry)
{
return dentry->d_inode && !d_unhashed(dentry);
}
static int usbfs_empty (struct dentry *dentry)
{
struct list_head *list;
spin_lock(&dentry->d_lock);
list_for_each(list, &dentry->d_subdirs) {
struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED);
if (usbfs_positive(de)) {
spin_unlock(&de->d_lock);
spin_unlock(&dentry->d_lock);
return 0;
}
spin_unlock(&de->d_lock);
}
spin_unlock(&dentry->d_lock);
return 1;
}
static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
mutex_lock(&inode->i_mutex);
drop_nlink(dentry->d_inode);
dput(dentry);
mutex_unlock(&inode->i_mutex);
d_delete(dentry);
return 0;
}
static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
{
int error = -ENOTEMPTY;
struct inode * inode = dentry->d_inode;
mutex_lock(&inode->i_mutex);
dentry_unhash(dentry);
if (usbfs_empty(dentry)) {
dont_mount(dentry);
drop_nlink(dentry->d_inode);
drop_nlink(dentry->d_inode);
dput(dentry);
inode->i_flags |= S_DEAD;
drop_nlink(dir);
error = 0;
}
mutex_unlock(&inode->i_mutex);
if (!error)
d_delete(dentry);
return error;
}
/* default file operations */
static ssize_t default_read_file (struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t default_write_file (struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}
static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
{
loff_t retval = -EINVAL;
mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
switch(orig) {
case 0:
if (offset > 0) {
file->f_pos = offset;
retval = file->f_pos;
}
break;
case 1:
if ((offset + file->f_pos) > 0) {
file->f_pos += offset;
retval = file->f_pos;
}
break;
default:
break;
}
mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
return retval;
}
static const struct file_operations default_file_operations = {
.read = default_read_file,
.write = default_write_file,
.open = simple_open,
.llseek = default_file_lseek,
};
static const struct super_operations usbfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
.remount_fs = remount,
.show_options = usbfs_show_options,
};
static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = USBDEVICE_SUPER_MAGIC;
sb->s_op = &usbfs_ops;
sb->s_time_gran = 1;
inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
sb->s_root = d_make_root(inode);
if (!sb->s_root) {
dbg("%s: could not get root dentry!",__func__);
return -ENOMEM;
}
return 0;
}
/*
* fs_create_by_name - create a file, given a name
* @name: name of file
* @mode: type of file
* @parent: dentry of directory to create it in
* @dentry: resulting dentry of file
*
* This function handles both regular files and directories.
*/
static int fs_create_by_name (const char *name, umode_t mode,
struct dentry *parent, struct dentry **dentry)
{
int error = 0;
/* If the parent is not specified, we create it in the root.
* We need the root dentry to do this, which is in the super
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
if (!parent ) {
if (usbfs_mount)
parent = usbfs_mount->mnt_root;
}
if (!parent) {
dbg("Ah! can not find a parent!");
return -EFAULT;
}
*dentry = NULL;
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(*dentry)) {
if (S_ISDIR(mode))
error = usbfs_mkdir (parent->d_inode, *dentry, mode);
else
error = usbfs_create (parent->d_inode, *dentry, mode);
} else
error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
}
static struct dentry *fs_create_file (const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops,
uid_t uid, gid_t gid)
{
struct dentry *dentry;
int error;
dbg("creating file '%s'",name);
error = fs_create_by_name (name, mode, parent, &dentry);
if (error) {
dentry = NULL;
} else {
if (dentry->d_inode) {
if (data)
dentry->d_inode->i_private = data;
if (fops)
dentry->d_inode->i_fop = fops;
dentry->d_inode->i_uid = uid;
dentry->d_inode->i_gid = gid;
}
}
return dentry;
}
static void fs_remove_file (struct dentry *dentry)
{
struct dentry *parent = dentry->d_parent;
if (!parent || !parent->d_inode)
return;
mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT);
if (usbfs_positive(dentry)) {
if (dentry->d_inode) {
if (S_ISDIR(dentry->d_inode->i_mode))
usbfs_rmdir(parent->d_inode, dentry);
else
usbfs_unlink(parent->d_inode, dentry);
dput(dentry);
}
}
mutex_unlock(&parent->d_inode->i_mutex);
}
/* --------------------------------------------------------------------- */
static struct dentry *usb_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_single(fs_type, flags, data, usbfs_fill_super);
}
static struct file_system_type usb_fs_type = {
.owner = THIS_MODULE,
.name = "usbfs",
.mount = usb_mount,
.kill_sb = kill_litter_super,
};
/* --------------------------------------------------------------------- */
static int create_special_files (void)
{
struct dentry *parent;
int retval;
/* create the devices special file */
retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
if (retval) {
printk(KERN_ERR "Unable to get usbfs mount\n");
goto exit;
}
parent = usbfs_mount->mnt_root;
devices_usbfs_dentry = fs_create_file ("devices",
listmode | S_IFREG, parent,
NULL, &usbfs_devices_fops,
listuid, listgid);
if (devices_usbfs_dentry == NULL) {
printk(KERN_ERR "Unable to create devices usbfs file\n");
retval = -ENODEV;
goto error_clean_mounts;
}
goto exit;
error_clean_mounts:
simple_release_fs(&usbfs_mount, &usbfs_mount_count);
exit:
return retval;
}
static void remove_special_files (void)
{
if (devices_usbfs_dentry)
fs_remove_file (devices_usbfs_dentry);
devices_usbfs_dentry = NULL;
simple_release_fs(&usbfs_mount, &usbfs_mount_count);
}
void usbfs_update_special (void)
{
struct inode *inode;
if (devices_usbfs_dentry) {
inode = devices_usbfs_dentry->d_inode;
if (inode)
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
}
}
static void usbfs_add_bus(struct usb_bus *bus)
{
struct dentry *parent;
char name[8];
int retval;
/* create the special files if this is the first bus added */
if (num_buses == 0) {
retval = create_special_files();
if (retval)
return;
}
++num_buses;
sprintf (name, "%03d", bus->busnum);
parent = usbfs_mount->mnt_root;
bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
bus, NULL, busuid, busgid);
if (bus->usbfs_dentry == NULL) {
printk(KERN_ERR "Error creating usbfs bus entry\n");
return;
}
}
static void usbfs_remove_bus(struct usb_bus *bus)
{
if (bus->usbfs_dentry) {
fs_remove_file (bus->usbfs_dentry);
bus->usbfs_dentry = NULL;
}
--num_buses;
if (num_buses <= 0) {
remove_special_files();
num_buses = 0;
}
}
static void usbfs_add_device(struct usb_device *dev)
{
char name[8];
int i;
int i_size;
sprintf (name, "%03d", dev->devnum);
dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
dev->bus->usbfs_dentry, dev,
&usbdev_file_operations,
devuid, devgid);
if (dev->usbfs_dentry == NULL) {
printk(KERN_ERR "Error creating usbfs device entry\n");
return;
}
/* Set the size of the device's file to be
* equal to the size of the device descriptors. */
i_size = sizeof (struct usb_device_descriptor);
for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
struct usb_config_descriptor *config =
(struct usb_config_descriptor *)dev->rawdescriptors[i];
i_size += le16_to_cpu(config->wTotalLength);
}
if (dev->usbfs_dentry->d_inode)
dev->usbfs_dentry->d_inode->i_size = i_size;
}
static void usbfs_remove_device(struct usb_device *dev)
{
if (dev->usbfs_dentry) {
fs_remove_file (dev->usbfs_dentry);
dev->usbfs_dentry = NULL;
}
}
static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
{
switch (action) {
case USB_DEVICE_ADD:
usbfs_add_device(dev);
break;
case USB_DEVICE_REMOVE:
usbfs_remove_device(dev);
break;
case USB_BUS_ADD:
usbfs_add_bus(dev);
break;
case USB_BUS_REMOVE:
usbfs_remove_bus(dev);
}
usbfs_update_special();
usbfs_conn_disc_event();
return NOTIFY_OK;
}
static struct notifier_block usbfs_nb = {
.notifier_call = usbfs_notify,
};
/* --------------------------------------------------------------------- */
static struct proc_dir_entry *usbdir = NULL;
int __init usbfs_init(void)
{
int retval;
retval = register_filesystem(&usb_fs_type);
if (retval)
return retval;
usb_register_notify(&usbfs_nb);
/* create mount point for usbfs */
usbdir = proc_mkdir("bus/usb", NULL);
return 0;
}
void usbfs_cleanup(void)
{
usb_unregister_notify(&usbfs_nb);
unregister_filesystem(&usb_fs_type);
if (usbdir)
remove_proc_entry("bus/usb", NULL);
}
...@@ -1030,9 +1030,6 @@ static int __init usb_init(void) ...@@ -1030,9 +1030,6 @@ static int __init usb_init(void)
retval = usb_devio_init(); retval = usb_devio_init();
if (retval) if (retval)
goto usb_devio_init_failed; goto usb_devio_init_failed;
retval = usbfs_init();
if (retval)
goto fs_init_failed;
retval = usb_hub_init(); retval = usb_hub_init();
if (retval) if (retval)
goto hub_init_failed; goto hub_init_failed;
...@@ -1042,8 +1039,6 @@ static int __init usb_init(void) ...@@ -1042,8 +1039,6 @@ static int __init usb_init(void)
usb_hub_cleanup(); usb_hub_cleanup();
hub_init_failed: hub_init_failed:
usbfs_cleanup();
fs_init_failed:
usb_devio_cleanup(); usb_devio_cleanup();
usb_devio_init_failed: usb_devio_init_failed:
usb_deregister(&usbfs_driver); usb_deregister(&usbfs_driver);
...@@ -1070,7 +1065,6 @@ static void __exit usb_exit(void) ...@@ -1070,7 +1065,6 @@ static void __exit usb_exit(void)
usb_deregister_device_driver(&usb_generic_driver); usb_deregister_device_driver(&usb_generic_driver);
usb_major_cleanup(); usb_major_cleanup();
usbfs_cleanup();
usb_deregister(&usbfs_driver); usb_deregister(&usbfs_driver);
usb_devio_cleanup(); usb_devio_cleanup();
usb_hub_cleanup(); usb_hub_cleanup();
......
...@@ -351,10 +351,6 @@ struct usb_bus { ...@@ -351,10 +351,6 @@ struct usb_bus {
int bandwidth_int_reqs; /* number of Interrupt requests */ int bandwidth_int_reqs; /* number of Interrupt requests */
int bandwidth_isoc_reqs; /* number of Isoc. requests */ int bandwidth_isoc_reqs; /* number of Isoc. requests */
#ifdef CONFIG_USB_DEVICEFS
struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
#endif
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
struct mon_bus *mon_bus; /* non-null when associated */ struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */ int monitored; /* non-zero when monitored */
...@@ -496,9 +492,6 @@ struct usb_device { ...@@ -496,9 +492,6 @@ struct usb_device {
#ifdef CONFIG_USB_DEVICE_CLASS #ifdef CONFIG_USB_DEVICE_CLASS
struct device *usb_classdev; struct device *usb_classdev;
#endif #endif
#ifdef CONFIG_USB_DEVICEFS
struct dentry *usbfs_dentry;
#endif
int maxchild; int maxchild;
struct usb_device **children; struct usb_device **children;
......
...@@ -582,29 +582,6 @@ static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) ...@@ -582,29 +582,6 @@ static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
} }
#endif /* CONFIG_USB_SUSPEND */ #endif /* CONFIG_USB_SUSPEND */
/*
* USB device fs stuff
*/
#ifdef CONFIG_USB_DEVICEFS
/*
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
extern void usbfs_update_special(void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
static inline void usbfs_update_special(void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
#endif /* CONFIG_USB_DEVICEFS */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册