1 /*****************************************************************************/
4 * inode.c -- Inode/Dentry functions for the USB device file system.
7 * Thomas Sailer (sailer@ife.ee.ethz.ch)
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.
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.
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.
23 * $Id: inode.c,v 1.3 2000/01/11 13:58:25 tom Exp $
26 * 0.1 04.01.2000 Created
29 /*****************************************************************************/
31 #define __NO_VERSION__
32 #include <linux/module.h>
34 #include <linux/sched.h>
35 #include <linux/smp_lock.h>
36 #include <linux/locks.h>
37 #include <linux/init.h>
38 #include <linux/proc_fs.h>
39 #include <asm/uaccess.h>
42 #include "usbdevice_fs.h"
44 /* --------------------------------------------------------------------- */
46 static LIST_HEAD(superlist
);
48 extern struct inode_operations usbdevfs_bus_inode_operations
;
49 extern struct file_operations usbdevfs_bus_file_operations
;
53 struct file_operations
*fops
;
54 struct list_head inodes
;
57 static struct special special
[] = {
58 { "devices", &usbdevfs_devices_fops
, },
59 { "drivers", &usbdevfs_drivers_fops
, }
62 #define NRSPECIAL (sizeof(special)/sizeof(special[0]))
64 /* --------------------------------------------------------------------- */
66 static int dnumber(struct dentry
*dentry
)
71 if (dentry
->d_name
.len
!= 3)
73 name
= dentry
->d_name
.name
;
74 if (name
[0] < '0' || name
[0] > '9' ||
75 name
[1] < '0' || name
[1] > '9' ||
76 name
[2] < '0' || name
[2] > '9')
79 s
= s
* 10 + name
[1] - '0';
80 s
= s
* 10 + name
[2] - '0';
85 * utility functions; should be called with the kernel lock held
86 * to protect against busses/devices appearing/disappearing
89 static void new_dev_inode(struct usb_device
*dev
, struct super_block
*sb
)
92 unsigned int devnum
= dev
->devnum
;
93 unsigned int busnum
= dev
->bus
->busnum
;
95 if (devnum
< 1 || devnum
> 127 || busnum
> 255)
97 inode
= iget(sb
, IDEVICE
| (busnum
<< 8) | devnum
);
99 printk(KERN_ERR
"usbdevfs: cannot create inode for bus %u device %u\n", busnum
, devnum
);
102 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
103 inode
->i_uid
= sb
->u
.usbdevfs_sb
.devuid
;
104 inode
->i_gid
= sb
->u
.usbdevfs_sb
.devgid
;
105 inode
->i_mode
= sb
->u
.usbdevfs_sb
.devmode
| S_IFREG
;
106 inode
->i_fop
= &usbdevfs_device_file_operations
;
107 inode
->i_size
= sizeof(struct usb_device_descriptor
);
108 inode
->u
.usbdev_i
.p
.dev
= dev
;
109 list_add_tail(&inode
->u
.usbdev_i
.slist
, &sb
->u
.usbdevfs_sb
.ilist
);
110 list_add_tail(&inode
->u
.usbdev_i
.dlist
, &dev
->inodes
);
113 static void recurse_new_dev_inode(struct usb_device
*dev
, struct super_block
*sb
)
119 new_dev_inode(dev
, sb
);
120 for (i
= 0; i
< dev
->maxchild
; i
++) {
121 if (!dev
->children
[i
])
123 recurse_new_dev_inode(dev
->children
[i
], sb
);
127 static void new_bus_inode(struct usb_bus
*bus
, struct super_block
*sb
)
130 unsigned int busnum
= bus
->busnum
;
134 inode
= iget(sb
, IBUS
| (busnum
<< 8));
136 printk(KERN_ERR
"usbdevfs: cannot create inode for bus %u\n", busnum
);
139 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
140 inode
->i_uid
= sb
->u
.usbdevfs_sb
.busuid
;
141 inode
->i_gid
= sb
->u
.usbdevfs_sb
.busgid
;
142 inode
->i_mode
= sb
->u
.usbdevfs_sb
.busmode
| S_IFDIR
;
143 inode
->i_op
= &usbdevfs_bus_inode_operations
;
144 inode
->i_fop
= &usbdevfs_bus_file_operations
;
145 inode
->u
.usbdev_i
.p
.bus
= bus
;
146 list_add_tail(&inode
->u
.usbdev_i
.slist
, &sb
->u
.usbdevfs_sb
.ilist
);
147 list_add_tail(&inode
->u
.usbdev_i
.dlist
, &bus
->inodes
);
150 static void free_inode(struct inode
*inode
)
152 inode
->u
.usbdev_i
.p
.bus
= NULL
;
153 inode
->u
.usbdev_i
.p
.dev
= NULL
;
154 inode
->i_mode
&= ~S_IRWXUGO
;
155 inode
->i_uid
= inode
->i_gid
= 0;
157 list_del(&inode
->u
.usbdev_i
.slist
);
158 INIT_LIST_HEAD(&inode
->u
.usbdev_i
.slist
);
159 list_del(&inode
->u
.usbdev_i
.dlist
);
160 INIT_LIST_HEAD(&inode
->u
.usbdev_i
.dlist
);
164 static struct usb_bus
*usbdevfs_findbus(int busnr
)
166 struct list_head
*list
;
169 for (list
= usb_bus_list
.next
; list
!= &usb_bus_list
; list
= list
->next
) {
170 bus
= list_entry(list
, struct usb_bus
, bus_list
);
171 if (bus
->busnum
== busnr
)
178 static struct usb_device
*finddev(struct usb_device
*dev
, int devnr
)
181 struct usb_device
*d2
;
185 if (dev
->devnum
== devnr
)
187 for (i
= 0; i
< dev
->maxchild
; i
++) {
188 if (!dev
->children
[i
])
190 if ((d2
= finddev(dev
->children
[i
], devnr
)))
196 static struct usb_device
*usbdevfs_finddevice(struct usb_bus
*bus
, int devnr
)
198 return finddev(bus
->root_hub
, devnr
);
202 /* --------------------------------------------------------------------- */
204 static int usbdevfs_revalidate(struct dentry
*dentry
, int flags
)
206 struct inode
*inode
= dentry
->d_inode
;
210 if (ITYPE(inode
->i_ino
) == IBUS
&& !inode
->u
.usbdev_i
.p
.bus
)
212 if (ITYPE(inode
->i_ino
) == IDEVICE
&& !inode
->u
.usbdev_i
.p
.dev
)
217 static struct dentry_operations usbdevfs_dentry_operations
= {
218 usbdevfs_revalidate
, /* d_revalidate */
220 NULL
, /* d_compare */
223 static struct dentry
*usbdevfs_root_lookup(struct inode
*dir
, struct dentry
*dentry
)
226 unsigned long ino
= 0;
231 if (dir
->i_ino
!= IROOT
)
232 return ERR_PTR(-EINVAL
);
233 dentry
->d_op
= &usbdevfs_dentry_operations
;
234 busnr
= dnumber(dentry
);
235 if (busnr
>= 0 && busnr
<= 255)
236 ino
= IBUS
| (busnr
<< 8);
238 for (i
= 0; i
< NRSPECIAL
; i
++) {
239 if (strlen(special
[i
].name
) == dentry
->d_name
.len
&&
240 !strncmp(special
[i
].name
, dentry
->d_name
.name
, dentry
->d_name
.len
)) {
241 ino
= ISPECIAL
| (i
+ IROOT
+ 1);
247 return ERR_PTR(-ENOENT
);
248 inode
= iget(dir
->i_sb
, ino
);
250 return ERR_PTR(-EINVAL
);
251 if (inode
&& ITYPE(ino
) == IBUS
&& inode
->u
.usbdev_i
.p
.bus
== NULL
) {
255 d_add(dentry
, inode
);
259 static struct dentry
*usbdevfs_bus_lookup(struct inode
*dir
, struct dentry
*dentry
)
265 if (ITYPE(dir
->i_ino
) != IBUS
)
266 return ERR_PTR(-EINVAL
);
267 dentry
->d_op
= &usbdevfs_dentry_operations
;
268 devnr
= dnumber(dentry
);
269 if (devnr
< 1 || devnr
> 127)
270 return ERR_PTR(-ENOENT
);
271 inode
= iget(dir
->i_sb
, IDEVICE
| (dir
->i_ino
& (0xff << 8)) | devnr
);
273 return ERR_PTR(-EINVAL
);
274 if (inode
&& inode
->u
.usbdev_i
.p
.dev
== NULL
) {
278 d_add(dentry
, inode
);
282 static int usbdevfs_root_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
284 struct inode
*inode
= filp
->f_dentry
->d_inode
;
285 unsigned long ino
= inode
->i_ino
;
286 struct special
*spec
;
287 struct list_head
*list
;
298 if (filldir(dirent
, ".", 1, i
, IROOT
) < 0)
305 if (filldir(dirent
, "..", 2, i
, IROOT
) < 0)
313 while (i
>= 2 && i
< 2+NRSPECIAL
) {
314 spec
= &special
[filp
->f_pos
-2];
315 if (filldir(dirent
, spec
->name
, strlen(spec
->name
), i
, ISPECIAL
| (filp
->f_pos
-2+IROOT
)) < 0)
324 for (list
= usb_bus_list
.next
; list
!= &usb_bus_list
; list
= list
->next
) {
329 bus
= list_entry(list
, struct usb_bus
, bus_list
);
330 sprintf(numbuf
, "%03d", bus
->busnum
);
331 if (filldir(dirent
, numbuf
, 3, filp
->f_pos
, IBUS
| ((bus
->busnum
& 0xff) << 8)) < 0)
340 static int bus_readdir(struct usb_device
*dev
, unsigned long ino
, int pos
, struct file
*filp
, void *dirent
, filldir_t filldir
)
347 sprintf(numbuf
, "%03d", dev
->devnum
);
351 if (filldir(dirent
, numbuf
, 3, filp
->f_pos
, ino
| (dev
->devnum
& 0xff)) < 0)
355 for (i
= 0; i
< dev
->maxchild
; i
++) {
356 if (!dev
->children
[i
])
358 pos
= bus_readdir(dev
->children
[i
], ino
, pos
, filp
, dirent
, filldir
);
365 static int usbdevfs_bus_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
367 struct inode
*inode
= filp
->f_dentry
->d_inode
;
368 unsigned long ino
= inode
->i_ino
;
372 if (ITYPE(ino
) != IBUS
)
374 switch ((unsigned int)filp
->f_pos
) {
376 if (filldir(dirent
, ".", 1, filp
->f_pos
, ino
) < 0)
382 if (filldir(dirent
, "..", 2, filp
->f_pos
, IROOT
) < 0)
389 bus
= usbdevfs_findbus(IBUSNR(ino
));
390 bus_readdir(bus
->root_hub
, IDEVICE
| ((bus
->busnum
& 0xff) << 8), filp
->f_pos
-2, filp
, dirent
, filldir
);
396 static struct file_operations usbdevfs_root_file_operations
= {
397 readdir
: usbdevfs_root_readdir
,
400 static struct inode_operations usbdevfs_root_inode_operations
= {
401 lookup
: usbdevfs_root_lookup
,
404 static struct file_operations usbdevfs_bus_file_operations
= {
405 readdir
: usbdevfs_bus_readdir
,
408 static struct inode_operations usbdevfs_bus_inode_operations
= {
409 lookup
: usbdevfs_bus_lookup
,
412 static void usbdevfs_read_inode(struct inode
*inode
)
414 struct special
*spec
;
416 inode
->i_ctime
= inode
->i_mtime
= inode
->i_atime
= CURRENT_TIME
;
417 inode
->i_mode
= S_IFREG
;
418 inode
->i_gid
= inode
->i_uid
= 0;
419 INIT_LIST_HEAD(&inode
->u
.usbdev_i
.dlist
);
420 INIT_LIST_HEAD(&inode
->u
.usbdev_i
.slist
);
421 inode
->u
.usbdev_i
.p
.dev
= NULL
;
422 inode
->u
.usbdev_i
.p
.bus
= NULL
;
423 switch (ITYPE(inode
->i_ino
)) {
425 if (inode
->i_ino
== IROOT
) {
426 inode
->i_op
= &usbdevfs_root_inode_operations
;
427 inode
->i_fop
= &usbdevfs_root_file_operations
;
428 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
;
431 if (inode
->i_ino
<= IROOT
|| inode
->i_ino
> IROOT
+NRSPECIAL
)
433 spec
= &special
[inode
->i_ino
-(IROOT
+1)];
434 inode
->i_fop
= spec
->fops
;
448 static void usbdevfs_put_super(struct super_block
*sb
)
450 list_del(&sb
->u
.usbdevfs_sb
.slist
);
451 INIT_LIST_HEAD(&sb
->u
.usbdevfs_sb
.slist
);
452 while (!list_empty(&sb
->u
.usbdevfs_sb
.ilist
))
453 free_inode(list_entry(sb
->u
.usbdevfs_sb
.ilist
.next
, struct inode
, u
.usbdev_i
.slist
));
457 static int usbdevfs_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
)
461 tmp
.f_type
= USBDEVICE_SUPER_MAGIC
;
462 tmp
.f_bsize
= PAGE_SIZE
/sizeof(long); /* ??? */
468 tmp
.f_namelen
= NAME_MAX
;
469 return copy_to_user(buf
, &tmp
, bufsiz
) ? -EFAULT
: 0;
472 static struct super_operations usbdevfs_sops
= {
473 read_inode
: usbdevfs_read_inode
,
474 put_super
: usbdevfs_put_super
,
475 statfs
: usbdevfs_statfs
,
478 struct super_block
*usbdevfs_read_super(struct super_block
*s
, void *data
, int silent
)
480 struct inode
*root_inode
, *inode
;
481 struct list_head
*blist
;
484 uid_t devuid
= 0, busuid
= 0, listuid
= 0;
485 gid_t devgid
= 0, busgid
= 0, listgid
= 0;
486 umode_t devmode
= S_IWUSR
| S_IRUGO
, busmode
= S_IXUGO
| S_IRUGO
, listmode
= S_IRUGO
;
487 char *curopt
= NULL
, *value
;
491 curopt
= strtok(data
, ",");
492 for (; curopt
; curopt
= strtok(NULL
, ",")) {
493 if ((value
= strchr(curopt
, '=')) != NULL
)
495 if (!strcmp(curopt
, "devuid")) {
496 if (!value
|| !value
[0])
498 devuid
= simple_strtoul(value
, &value
, 0);
502 if (!strcmp(curopt
, "devgid")) {
503 if (!value
|| !value
[0])
505 devgid
= simple_strtoul(value
, &value
, 0);
509 if (!strcmp(curopt
, "devmode")) {
510 if (!value
|| !value
[0])
512 devmode
= simple_strtoul(value
, &value
, 0) & S_IRWXUGO
;
516 if (!strcmp(curopt
, "busuid")) {
517 if (!value
|| !value
[0])
519 busuid
= simple_strtoul(value
, &value
, 0);
523 if (!strcmp(curopt
, "busgid")) {
524 if (!value
|| !value
[0])
526 busgid
= simple_strtoul(value
, &value
, 0);
530 if (!strcmp(curopt
, "busmode")) {
531 if (!value
|| !value
[0])
533 busmode
= simple_strtoul(value
, &value
, 0) & S_IRWXUGO
;
537 if (!strcmp(curopt
, "listuid")) {
538 if (!value
|| !value
[0])
540 listuid
= simple_strtoul(value
, &value
, 0);
544 if (!strcmp(curopt
, "listgid")) {
545 if (!value
|| !value
[0])
547 listgid
= simple_strtoul(value
, &value
, 0);
551 if (!strcmp(curopt
, "listmode")) {
552 if (!value
|| !value
[0])
554 listmode
= simple_strtoul(value
, &value
, 0) & S_IRWXUGO
;
559 /* fill superblock */
562 s
->s_blocksize
= 1024;
563 s
->s_blocksize_bits
= 10;
564 s
->s_magic
= USBDEVICE_SUPER_MAGIC
;
565 s
->s_op
= &usbdevfs_sops
;
566 INIT_LIST_HEAD(&s
->u
.usbdevfs_sb
.slist
);
567 INIT_LIST_HEAD(&s
->u
.usbdevfs_sb
.ilist
);
568 s
->u
.usbdevfs_sb
.devuid
= devuid
;
569 s
->u
.usbdevfs_sb
.devgid
= devgid
;
570 s
->u
.usbdevfs_sb
.devmode
= devmode
;
571 s
->u
.usbdevfs_sb
.busuid
= busuid
;
572 s
->u
.usbdevfs_sb
.busgid
= busgid
;
573 s
->u
.usbdevfs_sb
.busmode
= busmode
;
574 root_inode
= iget(s
, IROOT
);
577 s
->s_root
= d_alloc_root(root_inode
);
580 list_add_tail(&s
->u
.usbdevfs_sb
.slist
, &superlist
);
582 for (i
= 0; i
< NRSPECIAL
; i
++) {
583 if (!(inode
= iget(s
, IROOT
+1+i
)))
585 inode
->i_uid
= listuid
;
586 inode
->i_gid
= listgid
;
587 inode
->i_mode
= listmode
| S_IFREG
;
588 list_add_tail(&inode
->u
.usbdev_i
.slist
, &s
->u
.usbdevfs_sb
.ilist
);
589 list_add_tail(&inode
->u
.usbdev_i
.dlist
, &special
[i
].inodes
);
592 for (blist
= usb_bus_list
.next
; blist
!= &usb_bus_list
; blist
= blist
->next
) {
593 bus
= list_entry(blist
, struct usb_bus
, bus_list
);
594 new_bus_inode(bus
, s
);
595 recurse_new_dev_inode(bus
->root_hub
, s
);
601 printk("usbdevfs_read_super: get root inode failed\n");
609 printk(KERN_WARNING
"usbdevfs: mount parameter error\n");
614 static struct file_system_type usbdevice_fs_type
= {
621 /* --------------------------------------------------------------------- */
623 void usbdevfs_add_bus(struct usb_bus
*bus
)
625 struct list_head
*slist
;
628 for (slist
= superlist
.next
; slist
!= &superlist
; slist
= slist
->next
)
629 new_bus_inode(bus
, list_entry(slist
, struct super_block
, u
.usbdevfs_sb
.slist
));
631 usbdevfs_conn_disc_event();
634 void usbdevfs_remove_bus(struct usb_bus
*bus
)
637 while (!list_empty(&bus
->inodes
))
638 free_inode(list_entry(bus
->inodes
.next
, struct inode
, u
.usbdev_i
.dlist
));
640 usbdevfs_conn_disc_event();
643 void usbdevfs_add_device(struct usb_device
*dev
)
645 struct list_head
*slist
;
648 for (slist
= superlist
.next
; slist
!= &superlist
; slist
= slist
->next
)
649 new_dev_inode(dev
, list_entry(slist
, struct super_block
, u
.usbdevfs_sb
.slist
));
651 usbdevfs_conn_disc_event();
654 void usbdevfs_remove_device(struct usb_device
*dev
)
656 struct dev_state
*ds
;
657 struct siginfo sinfo
;
660 while (!list_empty(&dev
->inodes
))
661 free_inode(list_entry(dev
->inodes
.next
, struct inode
, u
.usbdev_i
.dlist
));
662 while (!list_empty(&dev
->filelist
)) {
663 ds
= list_entry(dev
->filelist
.next
, struct dev_state
, list
);
665 INIT_LIST_HEAD(&ds
->list
);
666 down_write(&ds
->devsem
);
668 up_write(&ds
->devsem
);
670 sinfo
.si_signo
= SIGPIPE
;
671 sinfo
.si_errno
= EPIPE
;
672 sinfo
.si_code
= SI_ASYNCIO
;
673 sinfo
.si_addr
= ds
->disccontext
;
674 send_sig_info(ds
->discsignr
, &sinfo
, ds
->disctask
);
678 usbdevfs_conn_disc_event();
681 /* --------------------------------------------------------------------- */
683 static struct proc_dir_entry
*usbdir
= NULL
;
685 int __init
usbdevfs_init(void)
689 for (ret
= 0; ret
< NRSPECIAL
; ret
++) {
690 INIT_LIST_HEAD(&special
[ret
].inodes
);
692 if ((ret
= usb_register(&usbdevfs_driver
)))
694 if ((ret
= register_filesystem(&usbdevice_fs_type
)))
695 usb_deregister(&usbdevfs_driver
);
696 /* create mount point for usbdevfs */
697 usbdir
= proc_mkdir("usb", proc_bus
);
701 void __exit
usbdevfs_cleanup(void)
703 usb_deregister(&usbdevfs_driver
);
704 unregister_filesystem(&usbdevice_fs_type
);
706 remove_proc_entry("usb", proc_bus
);
710 module_init(usbdevfs_init
);
711 module_exit(usbdevfs_cleanup
);