!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/usb/   drwxr-xr-x
Free 318.37 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     inode.c (19.87 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*****************************************************************************/

/*
 *    inode.c  --  Inode/Dentry functions for the USB device file system.
 *
 *    Copyright (C) 2000
 *          Thomas Sailer (sailer@ife.ee.ethz.ch)
 *
 *    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.
 *
 *  $Id: inode.c,v 1.3 2000/01/11 13:58:25 tom Exp $
 *
 *  History:
 *   0.1  04.01.2000  Created
 */

/*****************************************************************************/

#define __NO_VERSION__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/locks.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <asm/uaccess.h>

/* --------------------------------------------------------------------- */

/*
 * This list of superblocks is still used,
 * but since usbdevfs became FS_SINGLE
 * there is only one super_block.
 */
static LIST_HEAD(superlist);

struct special {
    const char *name;
    struct file_operations *fops;
    struct inode *inode;
    struct list_head inodes;
};

static struct special special[] = { 
    { "devices", &usbdevfs_devices_fops,  },
    { "drivers", &usbdevfs_drivers_fops,  }
};

#define NRSPECIAL (sizeof(special)/sizeof(special[0]))

/* --------------------------------------------------------------------- */

static int dnumber(struct dentry *dentry)
{
    const char *name;
    unsigned int s;

    if (dentry->d_name.len != 3)
        return -1;
    name = dentry->d_name.name;
    if (name[0] < '0' || name[0] > '9' ||
        name[1] < '0' || name[1] > '9' ||
        name[2] < '0' || name[2] > '9')
        return -1;
    s = name[0] - '0';
    s = s * 10 + name[1] - '0';
    s = s * 10 + name[2] - '0';
    return s;
}

/*
 * utility functions; should be called with the kernel lock held
 * to protect against busses/devices appearing/disappearing
 */

static void new_dev_inode(struct usb_device *dev, struct super_block *sb)
{
    struct inode *inode;
    unsigned int devnum = dev->devnum;
    unsigned int busnum = dev->bus->busnum;

    if (devnum < 1 || devnum > 127 || busnum > 255)
        return;
    inode = iget(sb, IDEVICE | (busnum << 8) | devnum);
    if (!inode) {
        printk(KERN_ERR "usbdevfs: cannot create inode for bus %u device %u\n", busnum, devnum);
        return;
    }
    inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
    inode->i_uid = sb->u.usbdevfs_sb.devuid;
    inode->i_gid = sb->u.usbdevfs_sb.devgid;
    inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG;
    inode->i_fop = &usbdevfs_device_file_operations;
    inode->i_size = sizeof(struct usb_device_descriptor);
    inode->u.usbdev_i.p.dev = dev;
    list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
    list_add_tail(&inode->u.usbdev_i.dlist, &dev->inodes);
}

static void recurse_new_dev_inode(struct usb_device *dev, struct super_block *sb)
{
    unsigned int i;

    if (!dev)
        return;
    new_dev_inode(dev, sb);
    for (i = 0; i < dev->maxchild; i++) {
                if (!dev->children[i])
                        continue;
        recurse_new_dev_inode(dev->children[i], sb);
    }
}

static void new_bus_inode(struct usb_bus *bus, struct super_block *sb)
{
    struct inode *inode;
    unsigned int busnum = bus->busnum;

    if (busnum > 255)
        return;
    inode = iget(sb, IBUS | (busnum << 8));
    if (!inode) {
        printk(KERN_ERR "usbdevfs: cannot create inode for bus %u\n", busnum);
        return;
    }
    inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
    inode->i_uid = sb->u.usbdevfs_sb.busuid;
    inode->i_gid = sb->u.usbdevfs_sb.busgid;
    inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR;
    inode->i_op = &usbdevfs_bus_inode_operations;
    inode->i_fop = &usbdevfs_bus_file_operations;
    inode->u.usbdev_i.p.bus = bus;
    list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
    list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes);
}

static void free_inode(struct inode *inode)
{
    inode->u.usbdev_i.p.bus = NULL;
    inode->u.usbdev_i.p.dev = NULL;
    inode->i_mode &= ~S_IRWXUGO;
    inode->i_uid = inode->i_gid = 0;
    inode->i_size = 0;
    list_del(&inode->u.usbdev_i.slist);
    INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
    list_del(&inode->u.usbdev_i.dlist);
    INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
    iput(inode);
}

static int parse_options(struct super_block *s, char *data)
{
    uid_t devuid = 0, busuid = 0, listuid = 0;
    gid_t devgid = 0, busgid = 0, listgid = 0;
    umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode = S_IRUGO;
    char *curopt = NULL, *value;

    /* parse options */
    if (data)
        curopt = strtok(data, ",");
    for (; curopt; curopt = strtok(NULL, ",")) {
        if ((value = strchr(curopt, '=')) != NULL)
            *value++ = 0;
        if (!strcmp(curopt, "devuid")) {
            if (!value || !value[0])
                return -EINVAL;
            devuid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "devgid")) {
            if (!value || !value[0])
                return -EINVAL;
            devgid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "devmode")) {
            if (!value || !value[0])
                return -EINVAL;
            devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "busuid")) {
            if (!value || !value[0])
                return -EINVAL;
            busuid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "busgid")) {
            if (!value || !value[0])
                return -EINVAL;
            busgid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "busmode")) {
            if (!value || !value[0])
                return -EINVAL;
            busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "listuid")) {
            if (!value || !value[0])
                return -EINVAL;
            listuid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "listgid")) {
            if (!value || !value[0])
                return -EINVAL;
            listgid = simple_strtoul(value, &value, 0);
            if (*value)
                return -EINVAL;
        }
        if (!strcmp(curopt, "listmode")) {
            if (!value || !value[0])
                return -EINVAL;
            listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
            if (*value)
                return -EINVAL;
        }
    }

    s->u.usbdevfs_sb.devuid = devuid;
    s->u.usbdevfs_sb.devgid = devgid;
    s->u.usbdevfs_sb.devmode = devmode;
    s->u.usbdevfs_sb.busuid = busuid;
    s->u.usbdevfs_sb.busgid = busgid;
    s->u.usbdevfs_sb.busmode = busmode;
    s->u.usbdevfs_sb.listuid = listuid;
    s->u.usbdevfs_sb.listgid = listgid;
    s->u.usbdevfs_sb.listmode = listmode;

    return 0;
}

static struct usb_bus *usbdevfs_findbus(int busnr)
{
        struct list_head *list;
        struct usb_bus *bus;

    down (&usb_bus_list_lock);
        for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
                bus = list_entry(list, struct usb_bus, bus_list);
                if (bus->busnum == busnr) {
            up (&usb_bus_list_lock);
                        return bus;
        }
        }
    up (&usb_bus_list_lock);
        return NULL;
}

#if 0
static struct usb_device *finddev(struct usb_device *dev, int devnr)
{
        unsigned int i;
        struct usb_device *d2;

        if (!dev)
                return NULL;
        if (dev->devnum == devnr)
                return dev;
        for (i = 0; i < dev->maxchild; i++) {
                if (!dev->children[i])
                        continue;
                if ((d2 = finddev(dev->children[i], devnr)))
                        return d2;
        }
        return NULL;
}

static struct usb_device *usbdevfs_finddevice(struct usb_bus *bus, int devnr)
{
        return finddev(bus->root_hub, devnr);
}
#endif

/* --------------------------------------------------------------------- */

static int usbdevfs_revalidate(struct dentry *dentry, int flags)
{
    struct inode *inode = dentry->d_inode;

        if (!inode)
                return 0;
    if (ITYPE(inode->i_ino) == IBUS && !inode->u.usbdev_i.p.bus)
        return 0;
    if (ITYPE(inode->i_ino) == IDEVICE && !inode->u.usbdev_i.p.dev)
        return 0;
    return 1;
}

static struct dentry_operations usbdevfs_dentry_operations = {
    d_revalidate:    usbdevfs_revalidate,
};

static struct dentry *usbdevfs_root_lookup(struct inode *dir, struct dentry *dentry)
{
    int busnr;
    unsigned long ino = 0;
    unsigned int i;
    struct inode *inode;

    /* sanity check */
    if (dir->i_ino != IROOT)
        return ERR_PTR(-EINVAL);
    dentry->d_op = &usbdevfs_dentry_operations;
    busnr = dnumber(dentry);
    if (busnr >= 0 && busnr <= 255)
        ino = IBUS | (busnr << 8);
    if (!ino) {
        for (i = 0; i < NRSPECIAL; i++) {
            if (strlen(special[i].name) == dentry->d_name.len && 
                !strncmp(special[i].name, dentry->d_name.name, dentry->d_name.len)) {
                ino = ISPECIAL | (i + IROOT + 1);
                break;
            }
        }
    }
    if (!ino)
        return ERR_PTR(-ENOENT);
    inode = iget(dir->i_sb, ino);
    if (!inode)
        return ERR_PTR(-EINVAL);
    if (inode && ITYPE(ino) == IBUS && inode->u.usbdev_i.p.bus == NULL) {
        iput(inode);
        inode = NULL;
    }
    d_add(dentry, inode);
    return NULL;
}

static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry)
{
    struct inode *inode;
    int devnr;

    /* sanity check */
    if (ITYPE(dir->i_ino) != IBUS)
        return ERR_PTR(-EINVAL);
    dentry->d_op = &usbdevfs_dentry_operations;
    devnr = dnumber(dentry);
    if (devnr < 1 || devnr > 127)
        return ERR_PTR(-ENOENT);
    inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff << 8)) | devnr);
    if (!inode)
        return ERR_PTR(-EINVAL);
    if (inode && inode->u.usbdev_i.p.dev == NULL) {
        iput(inode);
        inode = NULL;
    }
    d_add(dentry, inode);
    return NULL;
}

static int usbdevfs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
    struct inode *inode = filp->f_dentry->d_inode;
    unsigned long ino = inode->i_ino;
    struct special *spec;
    struct list_head *list;
    struct usb_bus *bus;
    char numbuf[8];
    unsigned int i;

    /* sanity check */
    if (ino != IROOT)
        return -EINVAL;
    i = filp->f_pos;
    switch (i) {
    case 0:
        if (filldir(dirent, ".", 1, i, IROOT, DT_DIR) < 0)
            return 0;
        filp->f_pos++;
        i++;
        /* fall through */

    case 1:
        if (filldir(dirent, "..", 2, i, IROOT, DT_DIR) < 0)
            return 0;
        filp->f_pos++;
        i++;
        /* fall through */

    default:
        
        while (i >= 2 && i < 2+NRSPECIAL) {
            spec = &special[filp->f_pos-2];
            if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT), DT_UNKNOWN) < 0)
                return 0;
            filp->f_pos++;
            i++;
        }
        if (i < 2+NRSPECIAL)
            return 0;
        i -= 2+NRSPECIAL;
        down (&usb_bus_list_lock);
        for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
            if (i > 0) {
                i--;
                continue;
            }
            bus = list_entry(list, struct usb_bus, bus_list);
            sprintf(numbuf, "%03d", bus->busnum);
            if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8), DT_UNKNOWN) < 0)
                break;
            filp->f_pos++;
        }
        up (&usb_bus_list_lock);
        return 0;
    }
}

static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct file *filp, void *dirent, filldir_t filldir)
{
    char numbuf[8];
    unsigned int i;

    if (!dev)
        return pos;
    sprintf(numbuf, "%03d", dev->devnum);
    if (pos > 0)
        pos--;
    else {
        if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff), DT_UNKNOWN) < 0)
            return -1;
        filp->f_pos++;
    }
    for (i = 0; i < dev->maxchild; i++) {
        if (!dev->children[i])
            continue;
        pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);
        if (pos < 0)
            return -1;
    }
    return pos;
}

static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
    struct inode *inode = filp->f_dentry->d_inode;
    unsigned long ino = inode->i_ino;
    struct usb_bus *bus;

    /* sanity check */
    if (ITYPE(ino) != IBUS)
        return -EINVAL;
    switch ((unsigned int)filp->f_pos) {
    case 0:
        if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)
            return 0;
        filp->f_pos++;
        /* fall through */

    case 1:
        if (filldir(dirent, "..", 2, filp->f_pos, IROOT, DT_DIR) < 0)
            return 0;
        filp->f_pos++;
        /* fall through */

    default:
        lock_kernel();
        bus = usbdevfs_findbus(IBUSNR(ino));
        bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir);
        unlock_kernel();
        return 0;
    }
}

static struct file_operations usbdevfs_root_file_operations = {
    readdir: usbdevfs_root_readdir,
};

static struct inode_operations usbdevfs_root_inode_operations = {
    lookup: usbdevfs_root_lookup,
};

static struct file_operations usbdevfs_bus_file_operations = {
    readdir: usbdevfs_bus_readdir,
};

static struct inode_operations usbdevfs_bus_inode_operations = {
    lookup: usbdevfs_bus_lookup,
};

static void usbdevfs_read_inode(struct inode *inode)
{
    struct special *spec;

    inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;
    inode->i_mode = S_IFREG;
    inode->i_gid = inode->i_uid = 0;
    INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
    INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
    inode->u.usbdev_i.p.dev = NULL;
    inode->u.usbdev_i.p.bus = NULL;
    switch (ITYPE(inode->i_ino)) {
    case ISPECIAL:
        if (inode->i_ino == IROOT) {
            inode->i_op = &usbdevfs_root_inode_operations;
            inode->i_fop = &usbdevfs_root_file_operations;
            inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
            return;
        }
        if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
            return;
        spec = &special[inode->i_ino-(IROOT+1)];
        inode->i_fop = spec->fops;
        return;

    case IDEVICE:
        return;

    case IBUS:
        return;

    default:
        return;
        }
}

static void usbdevfs_put_super(struct super_block *sb)
{
    list_del(&sb->u.usbdevfs_sb.slist);
    INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist);
    while (!list_empty(&sb->u.usbdevfs_sb.ilist))
        free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode, u.usbdev_i.slist));
}

static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf)
{
        buf->f_type = USBDEVICE_SUPER_MAGIC;
        buf->f_bsize = PAGE_SIZE/sizeof(long);   /* ??? */
        buf->f_bfree = 0;
        buf->f_bavail = 0;
        buf->f_ffree = 0;
        buf->f_namelen = NAME_MAX;
        return 0;
}

static int usbdevfs_remount(struct super_block *s, int *flags, char *data)
{
    struct list_head *ilist = s->u.usbdevfs_sb.ilist.next;
    struct inode *inode;
    int ret;

    if ((ret = parse_options(s, data))) {
        printk(KERN_WARNING "usbdevfs: remount parameter error\n");
        return ret;
    }

    for (; ilist != &s->u.usbdevfs_sb.ilist; ilist = ilist->next) {
        inode = list_entry(ilist, struct inode, u.usbdev_i.slist);

        switch (ITYPE(inode->i_ino)) {
            case ISPECIAL :
                inode->i_uid = s->u.usbdevfs_sb.listuid;
                inode->i_gid = s->u.usbdevfs_sb.listgid;
                inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
                break;
            case IBUS :
                inode->i_uid = s->u.usbdevfs_sb.busuid;
                inode->i_gid = s->u.usbdevfs_sb.busgid;
                inode->i_mode = s->u.usbdevfs_sb.busmode | S_IFDIR;
                break;
            case IDEVICE :
                inode->i_uid = s->u.usbdevfs_sb.devuid;
                inode->i_gid = s->u.usbdevfs_sb.devgid;
                inode->i_mode = s->u.usbdevfs_sb.devmode | S_IFREG;
                break;
        }
    }

    return 0;
}

static struct super_operations usbdevfs_sops = { 
    read_inode:    usbdevfs_read_inode,
    put_super:    usbdevfs_put_super,
    statfs:        usbdevfs_statfs,
    remount_fs:    usbdevfs_remount,
};

struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
{
        struct inode *root_inode, *inode;
    struct list_head *blist;
    struct usb_bus *bus;
    unsigned int i;

    if (parse_options(s, data)) {
        printk(KERN_WARNING "usbdevfs: mount parameter error\n");
        return NULL;
    }

    /* fill superblock */
        s->s_blocksize = 1024;
        s->s_blocksize_bits = 10;
        s->s_magic = USBDEVICE_SUPER_MAGIC;
        s->s_op = &usbdevfs_sops;
    INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);
    INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);
    root_inode = iget(s, IROOT);
        if (!root_inode)
                goto out_no_root;
        s->s_root = d_alloc_root(root_inode);
        if (!s->s_root)
                goto out_no_root;
    list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
    for (i = 0; i < NRSPECIAL; i++) {
        if (!(inode = iget(s, IROOT+1+i)))
            continue;
        inode->i_uid = s->u.usbdevfs_sb.listuid;
        inode->i_gid = s->u.usbdevfs_sb.listgid;
        inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
        special[i].inode = inode;
        list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
        list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
    }
    down (&usb_bus_list_lock);
    for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
        bus = list_entry(blist, struct usb_bus, bus_list);
        new_bus_inode(bus, s);
        recurse_new_dev_inode(bus->root_hub, s);
    }
    up (&usb_bus_list_lock);
        return s;

 out_no_root:
        printk("usbdevfs_read_super: get root inode failed\n");
        iput(root_inode);
        return NULL;
}

static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);

/* --------------------------------------------------------------------- */

static void update_special_inodes (void)
{
    int i;
    for (i = 0; i < NRSPECIAL; i++) {
        struct inode *inode = special[i].inode;
        if (inode)
            inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
    }
}


void usbdevfs_add_bus(struct usb_bus *bus)
{
    struct list_head *slist;

    lock_kernel();
    for (slist = superlist.next; slist != &superlist; slist = slist->next)
        new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
    update_special_inodes();
    unlock_kernel();
    usbdevfs_conn_disc_event();
}

void usbdevfs_remove_bus(struct usb_bus *bus)
{
    lock_kernel();
    while (!list_empty(&bus->inodes))
        free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));
    update_special_inodes();
    unlock_kernel();
    usbdevfs_conn_disc_event();
}

void usbdevfs_add_device(struct usb_device *dev)
{
    struct list_head *slist;

    lock_kernel();
    for (slist = superlist.next; slist != &superlist; slist = slist->next)
        new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
    update_special_inodes();
    unlock_kernel();
    usbdevfs_conn_disc_event();
}

void usbdevfs_remove_device(struct usb_device *dev)
{
    struct dev_state *ds;
    struct siginfo sinfo;

    lock_kernel();
    while (!list_empty(&dev->inodes))
        free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist));
    while (!list_empty(&dev->filelist)) {
        ds = list_entry(dev->filelist.next, struct dev_state, list);
        list_del(&ds->list);
        INIT_LIST_HEAD(&ds->list);
        down_write(&ds->devsem);
        ds->dev = NULL;
        up_write(&ds->devsem);
        if (ds->discsignr) {
            sinfo.si_signo = SIGPIPE;
            sinfo.si_errno = EPIPE;
            sinfo.si_code = SI_ASYNCIO;
            sinfo.si_addr = ds->disccontext;
            send_sig_info(ds->discsignr, &sinfo, ds->disctask);
        }
    }

    update_special_inodes();
    unlock_kernel();
    usbdevfs_conn_disc_event();
}

/* --------------------------------------------------------------------- */

#ifdef CONFIG_PROC_FS        
static struct proc_dir_entry *usbdir = NULL;
#endif    

int __init usbdevfs_init(void)
{
    int ret;

    for (ret = 0; ret < NRSPECIAL; ret++) {
        INIT_LIST_HEAD(&special[ret].inodes);
    }
    if ((ret = usb_register(&usbdevfs_driver)))
        return ret;
    if ((ret = register_filesystem(&usbdevice_fs_type))) {
        usb_deregister(&usbdevfs_driver);
        return ret;
    }
#ifdef CONFIG_PROC_FS        
    /* create mount point for usbdevfs */
    usbdir = proc_mkdir("usb", proc_bus);
#endif    
    return ret;
}

void __exit usbdevfs_cleanup(void)
{
    usb_deregister(&usbdevfs_driver);
    unregister_filesystem(&usbdevice_fs_type);
#ifdef CONFIG_PROC_FS    
        if (usbdir)
                remove_proc_entry("usb", proc_bus);
#endif
}

#if 0
module_init(usbdevfs_init);
module_exit(usbdevfs_cleanup);
#endif

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0282 ]--