Commit e3d848c7 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

USB: usbfs and usbdevfs both work at the same time now.

parent 67d0f1a8
...@@ -491,7 +491,7 @@ static int usbdev_open(struct inode *inode, struct file *file) ...@@ -491,7 +491,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
*/ */
lock_kernel(); lock_kernel();
ret = -ENOENT; ret = -ENOENT;
dev = file->f_dentry->d_parent->d_fsdata; dev = inode->u.generic_ip;
if (!dev) if (!dev)
goto out; goto out;
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -43,11 +43,13 @@ ...@@ -43,11 +43,13 @@
static struct super_operations usbfs_ops; static struct super_operations usbfs_ops;
static struct file_operations default_file_operations; static struct file_operations default_file_operations;
static struct inode_operations usbfs_dir_inode_operations; static struct inode_operations usbfs_dir_inode_operations;
static struct vfsmount *usbdevfs_mount;
static struct vfsmount *usbfs_mount; static struct vfsmount *usbfs_mount;
static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED; static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
static int mount_count; /* = 0 */ static int mount_count; /* = 0 */
static struct dentry *devices_dentry; static struct dentry *devices_usbdevfs_dentry;
static struct dentry *devices_usbfs_dentry;
static int num_buses; /* = 0 */ static int num_buses; /* = 0 */
static uid_t devuid; /* = 0 */ static uid_t devuid; /* = 0 */
...@@ -319,12 +321,8 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) ...@@ -319,12 +321,8 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
static int default_open (struct inode *inode, struct file *file) static int default_open (struct inode *inode, struct file *file)
{ {
void *data; if (inode->u.generic_ip)
file->private_data = inode->u.generic_ip;
data = file->f_dentry->d_parent->d_fsdata;
if (!data)
return -EFAULT;
file->private_data = data;
return 0; return 0;
} }
...@@ -393,13 +391,11 @@ static struct dentry * get_dentry(struct dentry *parent, const char *name) ...@@ -393,13 +391,11 @@ static struct dentry * get_dentry(struct dentry *parent, const char *name)
* @mode: type of file * @mode: type of file
* @parent: dentry of directory to create it in * @parent: dentry of directory to create it in
* @dentry: resulting dentry of file * @dentry: resulting dentry of file
* @data: data to put in this dentry
* *
* This function handles both regular files and directories. * This function handles both regular files and directories.
*/ */
static int fs_create_by_name (const char *name, mode_t mode, static int fs_create_by_name (const char *name, mode_t mode,
struct dentry *parent, struct dentry **dentry, struct dentry *parent, struct dentry **dentry)
void *data)
{ {
int error = 0; int error = 0;
...@@ -423,7 +419,6 @@ static int fs_create_by_name (const char *name, mode_t mode, ...@@ -423,7 +419,6 @@ static int fs_create_by_name (const char *name, mode_t mode,
down(&parent->d_inode->i_sem); down(&parent->d_inode->i_sem);
*dentry = get_dentry (parent, name); *dentry = get_dentry (parent, name);
if (!IS_ERR(dentry)) { if (!IS_ERR(dentry)) {
(*dentry)->d_fsdata = data;
if ((mode & S_IFMT) == S_IFDIR) if ((mode & S_IFMT) == S_IFDIR)
error = usbfs_mkdir (parent->d_inode, *dentry, mode); error = usbfs_mkdir (parent->d_inode, *dentry, mode);
else else
...@@ -445,11 +440,13 @@ static struct dentry *fs_create_file (const char *name, mode_t mode, ...@@ -445,11 +440,13 @@ static struct dentry *fs_create_file (const char *name, mode_t mode,
dbg("creating file '%s'",name); dbg("creating file '%s'",name);
error = fs_create_by_name (name, mode, parent, &dentry, data); error = fs_create_by_name (name, mode, parent, &dentry);
if (error) { if (error) {
dentry = NULL; dentry = NULL;
} else { } else {
if (dentry->d_inode) { if (dentry->d_inode) {
if (data)
dentry->d_inode->u.generic_ip = data;
if (fops) if (fops)
dentry->d_inode->i_fop = fops; dentry->d_inode->i_fop = fops;
dentry->d_inode->i_uid = uid; dentry->d_inode->i_uid = uid;
...@@ -511,32 +508,32 @@ static struct file_system_type usb_fs_type = { ...@@ -511,32 +508,32 @@ static struct file_system_type usb_fs_type = {
}; };
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static int get_mount (void) static int get_mount (struct file_system_type *fs_type, struct vfsmount **mount)
{ {
struct vfsmount *mnt; struct vfsmount *mnt;
spin_lock (&mount_lock); spin_lock (&mount_lock);
if (usbfs_mount) { if (*mount) {
mntget(usbfs_mount); mntget(*mount);
++mount_count; ++mount_count;
spin_unlock (&mount_lock); spin_unlock (&mount_lock);
goto go_ahead; goto go_ahead;
} }
spin_unlock (&mount_lock); spin_unlock (&mount_lock);
mnt = kern_mount (&usbdevice_fs_type); mnt = kern_mount (fs_type);
if (IS_ERR(mnt)) { if (IS_ERR(mnt)) {
err ("could not mount the fs...erroring out!\n"); err ("could not mount the fs...erroring out!\n");
return -ENODEV; return -ENODEV;
} }
spin_lock (&mount_lock); spin_lock (&mount_lock);
if (!usbfs_mount) { if (!*mount) {
usbfs_mount = mnt; *mount = mnt;
++mount_count; ++mount_count;
spin_unlock (&mount_lock); spin_unlock (&mount_lock);
goto go_ahead; goto go_ahead;
} }
mntget(usbfs_mount); mntget(*mount);
++mount_count; ++mount_count;
spin_unlock (&mount_lock); spin_unlock (&mount_lock);
mntput(mnt); mntput(mnt);
...@@ -546,15 +543,15 @@ static int get_mount (void) ...@@ -546,15 +543,15 @@ static int get_mount (void)
return 0; return 0;
} }
static void remove_mount (void) static void put_mount (struct vfsmount **mount)
{ {
struct vfsmount *mnt; struct vfsmount *mnt;
spin_lock (&mount_lock); spin_lock (&mount_lock);
mnt = usbfs_mount; mnt = *mount;
--mount_count; --mount_count;
if (!mount_count) if (!mount_count)
usbfs_mount = NULL; *mount = NULL;
spin_unlock (&mount_lock); spin_unlock (&mount_lock);
mntput(mnt); mntput(mnt);
...@@ -563,18 +560,31 @@ static void remove_mount (void) ...@@ -563,18 +560,31 @@ static void remove_mount (void)
static int create_special_files (void) static int create_special_files (void)
{ {
struct dentry *parent;
int retval; int retval;
/* create the devices special file */ /* create the devices special file */
retval = get_mount (); retval = get_mount (&usbdevice_fs_type, &usbdevfs_mount);
if (retval) if (retval)
return retval; return retval;
devices_dentry = fs_create_file ("devices", retval = get_mount (&usb_fs_type, &usbfs_mount);
listmode | S_IFREG, if (retval) {
NULL, NULL, put_mount (&usbfs_mount);
&usbdevfs_devices_fops, return retval;
listuid, listgid); }
if (devices_dentry == NULL) { parent = usbfs_mount->mnt_sb->s_root;
devices_usbfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
NULL, &usbdevfs_devices_fops,
listuid, listgid);
if (devices_usbfs_dentry == NULL) {
err ("Unable to create devices usbfs file");
return -ENODEV;
}
parent = usbdevfs_mount->mnt_sb->s_root;
devices_usbdevfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
NULL, &usbdevfs_devices_fops,
listuid, listgid);
if (devices_usbdevfs_dentry == NULL) {
err ("Unable to create devices usbfs file"); err ("Unable to create devices usbfs file");
return -ENODEV; return -ENODEV;
} }
...@@ -584,18 +594,27 @@ static int create_special_files (void) ...@@ -584,18 +594,27 @@ static int create_special_files (void)
static void remove_special_files (void) static void remove_special_files (void)
{ {
if (devices_dentry) if (devices_usbdevfs_dentry)
fs_remove_file (devices_dentry); fs_remove_file (devices_usbdevfs_dentry);
devices_dentry = NULL; if (devices_usbfs_dentry)
remove_mount(); fs_remove_file (devices_usbfs_dentry);
devices_usbdevfs_dentry = NULL;
devices_usbfs_dentry = NULL;
put_mount (&usbdevfs_mount);
put_mount (&usbfs_mount);
} }
void usbfs_update_special (void) void usbfs_update_special (void)
{ {
struct inode *inode; struct inode *inode;
if (devices_dentry) { if (devices_usbdevfs_dentry) {
inode = devices_dentry->d_inode; inode = devices_usbdevfs_dentry->d_inode;
if (inode)
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
}
if (devices_usbfs_dentry) {
inode = devices_usbfs_dentry->d_inode;
if (inode) if (inode)
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
} }
...@@ -603,6 +622,7 @@ void usbfs_update_special (void) ...@@ -603,6 +622,7 @@ void usbfs_update_special (void)
void usbfs_add_bus(struct usb_bus *bus) void usbfs_add_bus(struct usb_bus *bus)
{ {
struct dentry *parent;
char name[8]; char name[8];
int retval; int retval;
...@@ -615,12 +635,22 @@ void usbfs_add_bus(struct usb_bus *bus) ...@@ -615,12 +635,22 @@ void usbfs_add_bus(struct usb_bus *bus)
++num_buses; ++num_buses;
sprintf (name, "%03d", bus->busnum); sprintf (name, "%03d", bus->busnum);
bus->dentry = fs_create_file (name,
busmode | S_IFDIR, parent = usbfs_mount->mnt_sb->s_root;
NULL, bus, NULL, bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
busuid, busgid); bus, NULL, busuid, busgid);
if (bus->dentry == NULL) if (bus->usbfs_dentry == NULL) {
err ("error creating usbfs bus entry");
return; return;
}
parent = usbdevfs_mount->mnt_sb->s_root;
bus->usbdevfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
bus, NULL, busuid, busgid);
if (bus->usbdevfs_dentry == NULL) {
err ("error creating usbdevfs bus entry");
return;
}
usbfs_update_special(); usbfs_update_special();
usbdevfs_conn_disc_event(); usbdevfs_conn_disc_event();
...@@ -629,9 +659,13 @@ void usbfs_add_bus(struct usb_bus *bus) ...@@ -629,9 +659,13 @@ void usbfs_add_bus(struct usb_bus *bus)
void usbfs_remove_bus(struct usb_bus *bus) void usbfs_remove_bus(struct usb_bus *bus)
{ {
if (bus->dentry) { if (bus->usbfs_dentry) {
fs_remove_file (bus->dentry); fs_remove_file (bus->usbfs_dentry);
bus->dentry = NULL; bus->usbfs_dentry = NULL;
}
if (bus->usbdevfs_dentry) {
fs_remove_file (bus->usbdevfs_dentry);
bus->usbdevfs_dentry = NULL;
} }
--num_buses; --num_buses;
...@@ -651,13 +685,22 @@ void usbfs_add_device(struct usb_device *dev) ...@@ -651,13 +685,22 @@ void usbfs_add_device(struct usb_device *dev)
int i_size; int i_size;
sprintf (name, "%03d", dev->devnum); sprintf (name, "%03d", dev->devnum);
dev->dentry = fs_create_file (name, dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
devmode | S_IFREG, dev->bus->usbfs_dentry, dev,
dev->bus->dentry, dev, &usbdevfs_device_file_operations,
&usbdevfs_device_file_operations, devuid, devgid);
devuid, devgid); if (dev->usbfs_dentry == NULL) {
if (dev->dentry == NULL) err ("error creating usbfs device entry");
return;
}
dev->usbdevfs_dentry = fs_create_file (name, devmode | S_IFREG,
dev->bus->usbdevfs_dentry, dev,
&usbdevfs_device_file_operations,
devuid, devgid);
if (dev->usbdevfs_dentry == NULL) {
err ("error creating usbdevfs device entry");
return; return;
}
/* Set the size of the device's file to be /* Set the size of the device's file to be
* equal to the size of the device descriptors. */ * equal to the size of the device descriptors. */
...@@ -667,8 +710,10 @@ void usbfs_add_device(struct usb_device *dev) ...@@ -667,8 +710,10 @@ void usbfs_add_device(struct usb_device *dev)
(struct usb_config_descriptor *)dev->rawdescriptors[i]; (struct usb_config_descriptor *)dev->rawdescriptors[i];
i_size += le16_to_cpu (config->wTotalLength); i_size += le16_to_cpu (config->wTotalLength);
} }
if (dev->dentry->d_inode) if (dev->usbfs_dentry->d_inode)
dev->dentry->d_inode->i_size = i_size; dev->usbfs_dentry->d_inode->i_size = i_size;
if (dev->usbdevfs_dentry->d_inode)
dev->usbdevfs_dentry->d_inode->i_size = i_size;
usbfs_update_special(); usbfs_update_special();
usbdevfs_conn_disc_event(); usbdevfs_conn_disc_event();
...@@ -679,9 +724,13 @@ void usbfs_remove_device(struct usb_device *dev) ...@@ -679,9 +724,13 @@ void usbfs_remove_device(struct usb_device *dev)
struct dev_state *ds; struct dev_state *ds;
struct siginfo sinfo; struct siginfo sinfo;
if (dev->dentry) { if (dev->usbfs_dentry) {
fs_remove_file (dev->dentry); fs_remove_file (dev->usbfs_dentry);
dev->dentry = NULL; dev->usbfs_dentry = NULL;
}
if (dev->usbdevfs_dentry) {
fs_remove_file (dev->usbdevfs_dentry);
dev->usbdevfs_dentry = NULL;
} }
while (!list_empty(&dev->filelist)) { while (!list_empty(&dev->filelist)) {
ds = list_entry(dev->filelist.next, struct dev_state, list); ds = list_entry(dev->filelist.next, struct dev_state, list);
......
...@@ -351,7 +351,8 @@ struct usb_bus { ...@@ -351,7 +351,8 @@ 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 */
struct dentry *dentry; /* usbfs dentry entry for the bus */ struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
struct dentry *usbdevfs_dentry; /* usbdevfs dentry entry for the bus */
atomic_t refcnt; atomic_t refcnt;
}; };
...@@ -410,7 +411,8 @@ struct usb_device { ...@@ -410,7 +411,8 @@ struct usb_device {
void *hcpriv; /* Host Controller private data */ void *hcpriv; /* Host Controller private data */
struct list_head filelist; struct list_head filelist;
struct dentry *dentry; /* usbfs dentry entry for the device */ struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
struct dentry *usbdevfs_dentry; /* usbdevfs dentry entry for the device */
/* /*
* Child devices - these can be either new devices * Child devices - these can be either new devices
......
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