linux/drivers/usb/core/inode.c
<<
>>
Prefs
   1/*****************************************************************************/
   2
   3/*
   4 *      inode.c  --  Inode/Dentry functions for the USB device file system.
   5 *
   6 *      Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
   7 *      Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com)
   8 *
   9 *      This program is free software; you can redistribute it and/or modify
  10 *      it under the terms of the GNU General Public License as published by
  11 *      the Free Software Foundation; either version 2 of the License, or
  12 *      (at your option) any later version.
  13 *
  14 *      This program is distributed in the hope that it will be useful,
  15 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *      GNU General Public License for more details.
  18 *
  19 *      You should have received a copy of the GNU General Public License
  20 *      along with this program; if not, write to the Free Software
  21 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22 *
  23 *  History:
  24 *   0.1  04.01.2000  Created
  25 *   0.2  10.12.2001  converted to use the vfs layer better
  26 */
  27
  28/*****************************************************************************/
  29
  30#include <linux/module.h>
  31#include <linux/fs.h>
  32#include <linux/mount.h>
  33#include <linux/pagemap.h>
  34#include <linux/init.h>
  35#include <linux/proc_fs.h>
  36#include <linux/usb.h>
  37#include <linux/namei.h>
  38#include <linux/usbdevice_fs.h>
  39#include <linux/parser.h>
  40#include <linux/notifier.h>
  41#include <asm/byteorder.h>
  42#include "usb.h"
  43#include "hcd.h"
  44
  45static struct super_operations usbfs_ops;
  46static const struct file_operations default_file_operations;
  47static struct vfsmount *usbfs_mount;
  48static int usbfs_mount_count;   /* = 0 */
  49static int ignore_mount = 0;
  50
  51static struct dentry *devices_usbfs_dentry;
  52static int num_buses;   /* = 0 */
  53
  54static uid_t devuid;    /* = 0 */
  55static uid_t busuid;    /* = 0 */
  56static uid_t listuid;   /* = 0 */
  57static gid_t devgid;    /* = 0 */
  58static gid_t busgid;    /* = 0 */
  59static gid_t listgid;   /* = 0 */
  60static umode_t devmode = S_IWUSR | S_IRUGO;
  61static umode_t busmode = S_IXUGO | S_IRUGO;
  62static umode_t listmode = S_IRUGO;
  63
  64enum {
  65        Opt_devuid, Opt_devgid, Opt_devmode,
  66        Opt_busuid, Opt_busgid, Opt_busmode,
  67        Opt_listuid, Opt_listgid, Opt_listmode,
  68        Opt_err,
  69};
  70
  71static match_table_t tokens = {
  72        {Opt_devuid, "devuid=%u"},
  73        {Opt_devgid, "devgid=%u"},
  74        {Opt_devmode, "devmode=%o"},
  75        {Opt_busuid, "busuid=%u"},
  76        {Opt_busgid, "busgid=%u"},
  77        {Opt_busmode, "busmode=%o"},
  78        {Opt_listuid, "listuid=%u"},
  79        {Opt_listgid, "listgid=%u"},
  80        {Opt_listmode, "listmode=%o"},
  81        {Opt_err, NULL}
  82};
  83
  84static int parse_options(struct super_block *s, char *data)
  85{
  86        char *p;
  87        int option;
  88
  89        /* (re)set to defaults. */
  90        devuid = 0;
  91        busuid = 0;
  92        listuid = 0;
  93        devgid = 0;
  94        busgid = 0;
  95        listgid = 0;
  96        devmode = S_IWUSR | S_IRUGO;
  97        busmode = S_IXUGO | S_IRUGO;
  98        listmode = S_IRUGO;
  99
 100        while ((p = strsep(&data, ",")) != NULL) {
 101                substring_t args[MAX_OPT_ARGS];
 102                int token;
 103                if (!*p)
 104                        continue;
 105
 106                token = match_token(p, tokens, args);
 107                switch (token) {
 108                case Opt_devuid:
 109                        if (match_int(&args[0], &option))
 110                               return -EINVAL;
 111                        devuid = option;
 112                        break;
 113                case Opt_devgid:
 114                        if (match_int(&args[0], &option))
 115                               return -EINVAL;
 116                        devgid = option;
 117                        break;
 118                case Opt_devmode:
 119                        if (match_octal(&args[0], &option))
 120                                return -EINVAL;
 121                        devmode = option & S_IRWXUGO;
 122                        break;
 123                case Opt_busuid:
 124                        if (match_int(&args[0], &option))
 125                               return -EINVAL;
 126                        busuid = option;
 127                        break;
 128                case Opt_busgid:
 129                        if (match_int(&args[0], &option))
 130                               return -EINVAL;
 131                        busgid = option;
 132                        break;
 133                case Opt_busmode:
 134                        if (match_octal(&args[0], &option))
 135                                return -EINVAL;
 136                        busmode = option & S_IRWXUGO;
 137                        break;
 138                case Opt_listuid:
 139                        if (match_int(&args[0], &option))
 140                               return -EINVAL;
 141                        listuid = option;
 142                        break;
 143                case Opt_listgid:
 144                        if (match_int(&args[0], &option))
 145                               return -EINVAL;
 146                        listgid = option;
 147                        break;
 148                case Opt_listmode:
 149                        if (match_octal(&args[0], &option))
 150                                return -EINVAL;
 151                        listmode = option & S_IRWXUGO;
 152                        break;
 153                default:
 154                        err("usbfs: unrecognised mount option \"%s\" "
 155                            "or missing value\n", p);
 156                        return -EINVAL;
 157                }
 158        }
 159
 160        return 0;
 161}
 162
 163static void update_special(struct dentry *special)
 164{
 165        special->d_inode->i_uid = listuid;
 166        special->d_inode->i_gid = listgid;
 167        special->d_inode->i_mode = S_IFREG | listmode;
 168}
 169
 170static void update_dev(struct dentry *dev)
 171{
 172        dev->d_inode->i_uid = devuid;
 173        dev->d_inode->i_gid = devgid;
 174        dev->d_inode->i_mode = S_IFREG | devmode;
 175}
 176
 177static void update_bus(struct dentry *bus)
 178{
 179        struct dentry *dev = NULL;
 180
 181        bus->d_inode->i_uid = busuid;
 182        bus->d_inode->i_gid = busgid;
 183        bus->d_inode->i_mode = S_IFDIR | busmode;
 184
 185        mutex_lock(&bus->d_inode->i_mutex);
 186
 187        list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
 188                if (dev->d_inode)
 189                        update_dev(dev);
 190
 191        mutex_unlock(&bus->d_inode->i_mutex);
 192}
 193
 194static void update_sb(struct super_block *sb)
 195{
 196        struct dentry *root = sb->s_root;
 197        struct dentry *bus = NULL;
 198
 199        if (!root)
 200                return;
 201
 202        mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
 203
 204        list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
 205                if (bus->d_inode) {
 206                        switch (S_IFMT & bus->d_inode->i_mode) {
 207                        case S_IFDIR:
 208                                update_bus(bus);
 209                                break;
 210                        case S_IFREG:
 211                                update_special(bus);
 212                                break;
 213                        default:
 214                                warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode);
 215                                break;
 216                        }
 217                }
 218        }
 219
 220        mutex_unlock(&root->d_inode->i_mutex);
 221}
 222
 223static int remount(struct super_block *sb, int *flags, char *data)
 224{
 225        /* If this is not a real mount,
 226         * i.e. it's a simple_pin_fs from create_special_files,
 227         * then ignore it.
 228         */
 229        if (ignore_mount)
 230                return 0;
 231
 232        if (parse_options(sb, data)) {
 233                warn("usbfs: mount parameter error:");
 234                return -EINVAL;
 235        }
 236
 237        if (usbfs_mount && usbfs_mount->mnt_sb)
 238                update_sb(usbfs_mount->mnt_sb);
 239
 240        return 0;
 241}
 242
 243static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev)
 244{
 245        struct inode *inode = new_inode(sb);
 246
 247        if (inode) {
 248                inode->i_mode = mode;
 249                inode->i_uid = current->fsuid;
 250                inode->i_gid = current->fsgid;
 251                inode->i_blocks = 0;
 252                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 253                switch (mode & S_IFMT) {
 254                default:
 255                        init_special_inode(inode, mode, dev);
 256                        break;
 257                case S_IFREG:
 258                        inode->i_fop = &default_file_operations;
 259                        break;
 260                case S_IFDIR:
 261                        inode->i_op = &simple_dir_inode_operations;
 262                        inode->i_fop = &simple_dir_operations;
 263
 264                        /* directory inodes start off with i_nlink == 2 (for "." entry) */
 265                        inc_nlink(inode);
 266                        break;
 267                }
 268        }
 269        return inode; 
 270}
 271
 272/* SMP-safe */
 273static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
 274                        dev_t dev)
 275{
 276        struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev);
 277        int error = -EPERM;
 278
 279        if (dentry->d_inode)
 280                return -EEXIST;
 281
 282        if (inode) {
 283                d_instantiate(dentry, inode);
 284                dget(dentry);
 285                error = 0;
 286        }
 287        return error;
 288}
 289
 290static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
 291{
 292        int res;
 293
 294        mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
 295        res = usbfs_mknod (dir, dentry, mode, 0);
 296        if (!res)
 297                inc_nlink(dir);
 298        return res;
 299}
 300
 301static int usbfs_create (struct inode *dir, struct dentry *dentry, int mode)
 302{
 303        mode = (mode & S_IALLUGO) | S_IFREG;
 304        return usbfs_mknod (dir, dentry, mode, 0);
 305}
 306
 307static inline int usbfs_positive (struct dentry *dentry)
 308{
 309        return dentry->d_inode && !d_unhashed(dentry);
 310}
 311
 312static int usbfs_empty (struct dentry *dentry)
 313{
 314        struct list_head *list;
 315
 316        spin_lock(&dcache_lock);
 317
 318        list_for_each(list, &dentry->d_subdirs) {
 319                struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
 320                if (usbfs_positive(de)) {
 321                        spin_unlock(&dcache_lock);
 322                        return 0;
 323                }
 324        }
 325
 326        spin_unlock(&dcache_lock);
 327        return 1;
 328}
 329
 330static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
 331{
 332        struct inode *inode = dentry->d_inode;
 333        mutex_lock(&inode->i_mutex);
 334        drop_nlink(dentry->d_inode);
 335        dput(dentry);
 336        mutex_unlock(&inode->i_mutex);
 337        d_delete(dentry);
 338        return 0;
 339}
 340
 341static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
 342{
 343        int error = -ENOTEMPTY;
 344        struct inode * inode = dentry->d_inode;
 345
 346        mutex_lock(&inode->i_mutex);
 347        dentry_unhash(dentry);
 348        if (usbfs_empty(dentry)) {
 349                drop_nlink(dentry->d_inode);
 350                drop_nlink(dentry->d_inode);
 351                dput(dentry);
 352                inode->i_flags |= S_DEAD;
 353                drop_nlink(dir);
 354                error = 0;
 355        }
 356        mutex_unlock(&inode->i_mutex);
 357        if (!error)
 358                d_delete(dentry);
 359        dput(dentry);
 360        return error;
 361}
 362
 363
 364/* default file operations */
 365static ssize_t default_read_file (struct file *file, char __user *buf,
 366                                  size_t count, loff_t *ppos)
 367{
 368        return 0;
 369}
 370
 371static ssize_t default_write_file (struct file *file, const char __user *buf,
 372                                   size_t count, loff_t *ppos)
 373{
 374        return count;
 375}
 376
 377static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
 378{
 379        loff_t retval = -EINVAL;
 380
 381        mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
 382        switch(orig) {
 383        case 0:
 384                if (offset > 0) {
 385                        file->f_pos = offset;
 386                        retval = file->f_pos;
 387                } 
 388                break;
 389        case 1:
 390                if ((offset + file->f_pos) > 0) {
 391                        file->f_pos += offset;
 392                        retval = file->f_pos;
 393                } 
 394                break;
 395        default:
 396                break;
 397        }
 398        mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 399        return retval;
 400}
 401
 402static int default_open (struct inode *inode, struct file *file)
 403{
 404        if (inode->i_private)
 405                file->private_data = inode->i_private;
 406
 407        return 0;
 408}
 409
 410static const struct file_operations default_file_operations = {
 411        .read =         default_read_file,
 412        .write =        default_write_file,
 413        .open =         default_open,
 414        .llseek =       default_file_lseek,
 415};
 416
 417static struct super_operations usbfs_ops = {
 418        .statfs =       simple_statfs,
 419        .drop_inode =   generic_delete_inode,
 420        .remount_fs =   remount,
 421};
 422
 423static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
 424{
 425        struct inode *inode;
 426        struct dentry *root;
 427
 428        sb->s_blocksize = PAGE_CACHE_SIZE;
 429        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 430        sb->s_magic = USBDEVICE_SUPER_MAGIC;
 431        sb->s_op = &usbfs_ops;
 432        sb->s_time_gran = 1;
 433        inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
 434
 435        if (!inode) {
 436                dbg("%s: could not get inode!",__FUNCTION__);
 437                return -ENOMEM;
 438        }
 439
 440        root = d_alloc_root(inode);
 441        if (!root) {
 442                dbg("%s: could not get root dentry!",__FUNCTION__);
 443                iput(inode);
 444                return -ENOMEM;
 445        }
 446        sb->s_root = root;
 447        return 0;
 448}
 449
 450/*
 451 * fs_create_by_name - create a file, given a name
 452 * @name:       name of file
 453 * @mode:       type of file
 454 * @parent:     dentry of directory to create it in
 455 * @dentry:     resulting dentry of file
 456 *
 457 * This function handles both regular files and directories.
 458 */
 459static int fs_create_by_name (const char *name, mode_t mode,
 460                              struct dentry *parent, struct dentry **dentry)
 461{
 462        int error = 0;
 463
 464        /* If the parent is not specified, we create it in the root.
 465         * We need the root dentry to do this, which is in the super 
 466         * block. A pointer to that is in the struct vfsmount that we
 467         * have around.
 468         */
 469        if (!parent ) {
 470                if (usbfs_mount && usbfs_mount->mnt_sb) {
 471                        parent = usbfs_mount->mnt_sb->s_root;
 472                }
 473        }
 474
 475        if (!parent) {
 476                dbg("Ah! can not find a parent!");
 477                return -EFAULT;
 478        }
 479
 480        *dentry = NULL;
 481        mutex_lock(&parent->d_inode->i_mutex);
 482        *dentry = lookup_one_len(name, parent, strlen(name));
 483        if (!IS_ERR(dentry)) {
 484                if ((mode & S_IFMT) == S_IFDIR)
 485                        error = usbfs_mkdir (parent->d_inode, *dentry, mode);
 486                else 
 487                        error = usbfs_create (parent->d_inode, *dentry, mode);
 488        } else
 489                error = PTR_ERR(dentry);
 490        mutex_unlock(&parent->d_inode->i_mutex);
 491
 492        return error;
 493}
 494
 495static struct dentry *fs_create_file (const char *name, mode_t mode,
 496                                      struct dentry *parent, void *data,
 497                                      const struct file_operations *fops,
 498                                      uid_t uid, gid_t gid)
 499{
 500        struct dentry *dentry;
 501        int error;
 502
 503        dbg("creating file '%s'",name);
 504
 505        error = fs_create_by_name (name, mode, parent, &dentry);
 506        if (error) {
 507                dentry = NULL;
 508        } else {
 509                if (dentry->d_inode) {
 510                        if (data)
 511                                dentry->d_inode->i_private = data;
 512                        if (fops)
 513                                dentry->d_inode->i_fop = fops;
 514                        dentry->d_inode->i_uid = uid;
 515                        dentry->d_inode->i_gid = gid;
 516                }
 517        }
 518
 519        return dentry;
 520}
 521
 522static void fs_remove_file (struct dentry *dentry)
 523{
 524        struct dentry *parent = dentry->d_parent;
 525        
 526        if (!parent || !parent->d_inode)
 527                return;
 528
 529        mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT);
 530        if (usbfs_positive(dentry)) {
 531                if (dentry->d_inode) {
 532                        if (S_ISDIR(dentry->d_inode->i_mode))
 533                                usbfs_rmdir(parent->d_inode, dentry);
 534                        else
 535                                usbfs_unlink(parent->d_inode, dentry);
 536                dput(dentry);
 537                }
 538        }
 539        mutex_unlock(&parent->d_inode->i_mutex);
 540}
 541
 542/* --------------------------------------------------------------------- */
 543
 544static int usb_get_sb(struct file_system_type *fs_type,
 545        int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 546{
 547        return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt);
 548}
 549
 550static struct file_system_type usb_fs_type = {
 551        .owner =        THIS_MODULE,
 552        .name =         "usbfs",
 553        .get_sb =       usb_get_sb,
 554        .kill_sb =      kill_litter_super,
 555};
 556
 557/* --------------------------------------------------------------------- */
 558
 559static int create_special_files (void)
 560{
 561        struct dentry *parent;
 562        int retval;
 563
 564        /* the simple_pin_fs calls will call remount with no options
 565         * without this flag that would overwrite the real mount options (if any)
 566         */
 567        ignore_mount = 1;
 568
 569        /* create the devices special file */
 570        retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
 571        if (retval) {
 572                err ("Unable to get usbfs mount");
 573                goto exit;
 574        }
 575
 576        ignore_mount = 0;
 577
 578        parent = usbfs_mount->mnt_sb->s_root;
 579        devices_usbfs_dentry = fs_create_file ("devices",
 580                                               listmode | S_IFREG, parent,
 581                                               NULL, &usbfs_devices_fops,
 582                                               listuid, listgid);
 583        if (devices_usbfs_dentry == NULL) {
 584                err ("Unable to create devices usbfs file");
 585                retval = -ENODEV;
 586                goto error_clean_mounts;
 587        }
 588
 589        goto exit;
 590        
 591error_clean_mounts:
 592        simple_release_fs(&usbfs_mount, &usbfs_mount_count);
 593exit:
 594        return retval;
 595}
 596
 597static void remove_special_files (void)
 598{
 599        if (devices_usbfs_dentry)
 600                fs_remove_file (devices_usbfs_dentry);
 601        devices_usbfs_dentry = NULL;
 602        simple_release_fs(&usbfs_mount, &usbfs_mount_count);
 603}
 604
 605void usbfs_update_special (void)
 606{
 607        struct inode *inode;
 608
 609        if (devices_usbfs_dentry) {
 610                inode = devices_usbfs_dentry->d_inode;
 611                if (inode)
 612                        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 613        }
 614}
 615
 616static void usbfs_add_bus(struct usb_bus *bus)
 617{
 618        struct dentry *parent;
 619        char name[8];
 620        int retval;
 621
 622        /* create the special files if this is the first bus added */
 623        if (num_buses == 0) {
 624                retval = create_special_files();
 625                if (retval)
 626                        return;
 627        }
 628        ++num_buses;
 629
 630        sprintf (name, "%03d", bus->busnum);
 631
 632        parent = usbfs_mount->mnt_sb->s_root;
 633        bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
 634                                            bus, NULL, busuid, busgid);
 635        if (bus->usbfs_dentry == NULL) {
 636                err ("error creating usbfs bus entry");
 637                return;
 638        }
 639}
 640
 641static void usbfs_remove_bus(struct usb_bus *bus)
 642{
 643        if (bus->usbfs_dentry) {
 644                fs_remove_file (bus->usbfs_dentry);
 645                bus->usbfs_dentry = NULL;
 646        }
 647
 648        --num_buses;
 649        if (num_buses <= 0) {
 650                remove_special_files();
 651                num_buses = 0;
 652        }
 653}
 654
 655static void usbfs_add_device(struct usb_device *dev)
 656{
 657        char name[8];
 658        int i;
 659        int i_size;
 660
 661        sprintf (name, "%03d", dev->devnum);
 662        dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
 663                                            dev->bus->usbfs_dentry, dev,
 664                                            &usbdev_file_operations,
 665                                            devuid, devgid);
 666        if (dev->usbfs_dentry == NULL) {
 667                err ("error creating usbfs device entry");
 668                return;
 669        }
 670
 671        /* Set the size of the device's file to be
 672         * equal to the size of the device descriptors. */
 673        i_size = sizeof (struct usb_device_descriptor);
 674        for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
 675                struct usb_config_descriptor *config =
 676                        (struct usb_config_descriptor *)dev->rawdescriptors[i];
 677                i_size += le16_to_cpu(config->wTotalLength);
 678        }
 679        if (dev->usbfs_dentry->d_inode)
 680                dev->usbfs_dentry->d_inode->i_size = i_size;
 681}
 682
 683static void usbfs_remove_device(struct usb_device *dev)
 684{
 685        struct dev_state *ds;
 686        struct siginfo sinfo;
 687
 688        if (dev->usbfs_dentry) {
 689                fs_remove_file (dev->usbfs_dentry);
 690                dev->usbfs_dentry = NULL;
 691        }
 692        while (!list_empty(&dev->filelist)) {
 693                ds = list_entry(dev->filelist.next, struct dev_state, list);
 694                wake_up_all(&ds->wait);
 695                list_del_init(&ds->list);
 696                if (ds->discsignr) {
 697                        sinfo.si_signo = ds->discsignr;
 698                        sinfo.si_errno = EPIPE;
 699                        sinfo.si_code = SI_ASYNCIO;
 700                        sinfo.si_addr = ds->disccontext;
 701                        kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
 702                }
 703        }
 704}
 705
 706static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
 707{
 708        switch (action) {
 709        case USB_DEVICE_ADD:
 710                usbfs_add_device(dev);
 711                break;
 712        case USB_DEVICE_REMOVE:
 713                usbfs_remove_device(dev);
 714                break;
 715        case USB_BUS_ADD:
 716                usbfs_add_bus(dev);
 717                break;
 718        case USB_BUS_REMOVE:
 719                usbfs_remove_bus(dev);
 720        }
 721
 722        usbfs_update_special();
 723        usbfs_conn_disc_event();
 724        return NOTIFY_OK;
 725}
 726
 727static struct notifier_block usbfs_nb = {
 728        .notifier_call =        usbfs_notify,
 729};
 730
 731/* --------------------------------------------------------------------- */
 732
 733static struct proc_dir_entry *usbdir = NULL;
 734
 735int __init usbfs_init(void)
 736{
 737        int retval;
 738
 739        retval = register_filesystem(&usb_fs_type);
 740        if (retval)
 741                return retval;
 742
 743        usb_register_notify(&usbfs_nb);
 744
 745        /* create mount point for usbfs */
 746        usbdir = proc_mkdir("usb", proc_bus);
 747
 748        return 0;
 749}
 750
 751void usbfs_cleanup(void)
 752{
 753        usb_unregister_notify(&usbfs_nb);
 754        unregister_filesystem(&usb_fs_type);
 755        if (usbdir)
 756                remove_proc_entry("usb", proc_bus);
 757}
 758
 759