Merge with 2.3.99-pre1.
[linux-2.6/linux-mips.git] / drivers / usb / inode.c
blobc30f2eaff5c0658ef0bb7187dacd3e32b8894d0b
1 /*****************************************************************************/
3 /*
4 * inode.c -- Inode/Dentry functions for the USB device file system.
6 * Copyright (C) 2000
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 $
25 * History:
26 * 0.1 04.01.2000 Created
29 /*****************************************************************************/
31 #define __NO_VERSION__
32 #include <linux/config.h>
33 #include <linux/module.h>
34 #include <linux/fs.h>
35 #include <linux/sched.h>
36 #include <linux/smp_lock.h>
37 #include <linux/locks.h>
38 #include <linux/init.h>
39 #include <linux/proc_fs.h>
40 #include <linux/usb.h>
41 #include <asm/uaccess.h>
43 #include "usbdevice_fs.h"
45 /* --------------------------------------------------------------------- */
47 static LIST_HEAD(superlist);
49 struct special {
50 const char *name;
51 struct file_operations *fops;
52 struct list_head inodes;
55 static struct special special[] = {
56 { "devices", &usbdevfs_devices_fops, },
57 { "drivers", &usbdevfs_drivers_fops, }
60 #define NRSPECIAL (sizeof(special)/sizeof(special[0]))
62 /* --------------------------------------------------------------------- */
64 static int dnumber(struct dentry *dentry)
66 const char *name;
67 unsigned int s;
69 if (dentry->d_name.len != 3)
70 return -1;
71 name = dentry->d_name.name;
72 if (name[0] < '0' || name[0] > '9' ||
73 name[1] < '0' || name[1] > '9' ||
74 name[2] < '0' || name[2] > '9')
75 return -1;
76 s = name[0] - '0';
77 s = s * 10 + name[1] - '0';
78 s = s * 10 + name[2] - '0';
79 return s;
83 * utility functions; should be called with the kernel lock held
84 * to protect against busses/devices appearing/disappearing
87 static void new_dev_inode(struct usb_device *dev, struct super_block *sb)
89 struct inode *inode;
90 unsigned int devnum = dev->devnum;
91 unsigned int busnum = dev->bus->busnum;
93 if (devnum < 1 || devnum > 127 || busnum > 255)
94 return;
95 inode = iget(sb, IDEVICE | (busnum << 8) | devnum);
96 if (!inode) {
97 printk(KERN_ERR "usbdevfs: cannot create inode for bus %u device %u\n", busnum, devnum);
98 return;
100 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
101 inode->i_uid = sb->u.usbdevfs_sb.devuid;
102 inode->i_gid = sb->u.usbdevfs_sb.devgid;
103 inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG;
104 inode->i_fop = &usbdevfs_device_file_operations;
105 inode->i_size = sizeof(struct usb_device_descriptor);
106 inode->u.usbdev_i.p.dev = dev;
107 list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
108 list_add_tail(&inode->u.usbdev_i.dlist, &dev->inodes);
111 static void recurse_new_dev_inode(struct usb_device *dev, struct super_block *sb)
113 unsigned int i;
115 if (!dev)
116 return;
117 new_dev_inode(dev, sb);
118 for (i = 0; i < dev->maxchild; i++) {
119 if (!dev->children[i])
120 continue;
121 recurse_new_dev_inode(dev->children[i], sb);
125 static void new_bus_inode(struct usb_bus *bus, struct super_block *sb)
127 struct inode *inode;
128 unsigned int busnum = bus->busnum;
130 if (busnum > 255)
131 return;
132 inode = iget(sb, IBUS | (busnum << 8));
133 if (!inode) {
134 printk(KERN_ERR "usbdevfs: cannot create inode for bus %u\n", busnum);
135 return;
137 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
138 inode->i_uid = sb->u.usbdevfs_sb.busuid;
139 inode->i_gid = sb->u.usbdevfs_sb.busgid;
140 inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR;
141 inode->i_op = &usbdevfs_bus_inode_operations;
142 inode->i_fop = &usbdevfs_bus_file_operations;
143 inode->u.usbdev_i.p.bus = bus;
144 list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
145 list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes);
148 static void free_inode(struct inode *inode)
150 inode->u.usbdev_i.p.bus = NULL;
151 inode->u.usbdev_i.p.dev = NULL;
152 inode->i_mode &= ~S_IRWXUGO;
153 inode->i_uid = inode->i_gid = 0;
154 inode->i_size = 0;
155 list_del(&inode->u.usbdev_i.slist);
156 INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
157 list_del(&inode->u.usbdev_i.dlist);
158 INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
159 iput(inode);
162 static struct usb_bus *usbdevfs_findbus(int busnr)
164 struct list_head *list;
165 struct usb_bus *bus;
167 for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
168 bus = list_entry(list, struct usb_bus, bus_list);
169 if (bus->busnum == busnr)
170 return bus;
172 return NULL;
175 #if 0
176 static struct usb_device *finddev(struct usb_device *dev, int devnr)
178 unsigned int i;
179 struct usb_device *d2;
181 if (!dev)
182 return NULL;
183 if (dev->devnum == devnr)
184 return dev;
185 for (i = 0; i < dev->maxchild; i++) {
186 if (!dev->children[i])
187 continue;
188 if ((d2 = finddev(dev->children[i], devnr)))
189 return d2;
191 return NULL;
194 static struct usb_device *usbdevfs_finddevice(struct usb_bus *bus, int devnr)
196 return finddev(bus->root_hub, devnr);
198 #endif
200 /* --------------------------------------------------------------------- */
202 static int usbdevfs_revalidate(struct dentry *dentry, int flags)
204 struct inode *inode = dentry->d_inode;
206 if (!inode)
207 return 0;
208 if (ITYPE(inode->i_ino) == IBUS && !inode->u.usbdev_i.p.bus)
209 return 0;
210 if (ITYPE(inode->i_ino) == IDEVICE && !inode->u.usbdev_i.p.dev)
211 return 0;
212 return 1;
215 static struct dentry_operations usbdevfs_dentry_operations = {
216 d_revalidate: usbdevfs_revalidate,
219 static struct dentry *usbdevfs_root_lookup(struct inode *dir, struct dentry *dentry)
221 int busnr;
222 unsigned long ino = 0;
223 unsigned int i;
224 struct inode *inode;
226 /* sanity check */
227 if (dir->i_ino != IROOT)
228 return ERR_PTR(-EINVAL);
229 dentry->d_op = &usbdevfs_dentry_operations;
230 busnr = dnumber(dentry);
231 if (busnr >= 0 && busnr <= 255)
232 ino = IBUS | (busnr << 8);
233 if (!ino) {
234 for (i = 0; i < NRSPECIAL; i++) {
235 if (strlen(special[i].name) == dentry->d_name.len &&
236 !strncmp(special[i].name, dentry->d_name.name, dentry->d_name.len)) {
237 ino = ISPECIAL | (i + IROOT + 1);
238 break;
242 if (!ino)
243 return ERR_PTR(-ENOENT);
244 inode = iget(dir->i_sb, ino);
245 if (!inode)
246 return ERR_PTR(-EINVAL);
247 if (inode && ITYPE(ino) == IBUS && inode->u.usbdev_i.p.bus == NULL) {
248 iput(inode);
249 inode = NULL;
251 d_add(dentry, inode);
252 return NULL;
255 static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry)
257 struct inode *inode;
258 int devnr;
260 /* sanity check */
261 if (ITYPE(dir->i_ino) != IBUS)
262 return ERR_PTR(-EINVAL);
263 dentry->d_op = &usbdevfs_dentry_operations;
264 devnr = dnumber(dentry);
265 if (devnr < 1 || devnr > 127)
266 return ERR_PTR(-ENOENT);
267 inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff << 8)) | devnr);
268 if (!inode)
269 return ERR_PTR(-EINVAL);
270 if (inode && inode->u.usbdev_i.p.dev == NULL) {
271 iput(inode);
272 inode = NULL;
274 d_add(dentry, inode);
275 return NULL;
278 static int usbdevfs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
280 struct inode *inode = filp->f_dentry->d_inode;
281 unsigned long ino = inode->i_ino;
282 struct special *spec;
283 struct list_head *list;
284 struct usb_bus *bus;
285 char numbuf[8];
286 unsigned int i;
288 /* sanity check */
289 if (ino != IROOT)
290 return -EINVAL;
291 i = filp->f_pos;
292 switch (i) {
293 case 0:
294 if (filldir(dirent, ".", 1, i, IROOT) < 0)
295 return 0;
296 filp->f_pos++;
297 i++;
298 /* fall through */
300 case 1:
301 if (filldir(dirent, "..", 2, i, IROOT) < 0)
302 return 0;
303 filp->f_pos++;
304 i++;
305 /* fall through */
307 default:
309 while (i >= 2 && i < 2+NRSPECIAL) {
310 spec = &special[filp->f_pos-2];
311 if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT)) < 0)
312 return 0;
313 filp->f_pos++;
314 i++;
316 if (i < 2+NRSPECIAL)
317 return 0;
318 i -= 2+NRSPECIAL;
319 lock_kernel();
320 for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
321 if (i > 0) {
322 i--;
323 continue;
325 bus = list_entry(list, struct usb_bus, bus_list);
326 sprintf(numbuf, "%03d", bus->busnum);
327 if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8)) < 0)
328 break;
329 filp->f_pos++;
331 unlock_kernel();
332 return 0;
336 static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct file *filp, void *dirent, filldir_t filldir)
338 char numbuf[8];
339 unsigned int i;
341 if (!dev)
342 return pos;
343 sprintf(numbuf, "%03d", dev->devnum);
344 if (pos > 0)
345 pos--;
346 else {
347 if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff)) < 0)
348 return -1;
349 filp->f_pos++;
351 for (i = 0; i < dev->maxchild; i++) {
352 if (!dev->children[i])
353 continue;
354 pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);
355 if (pos < 0)
356 return -1;
358 return pos;
361 static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir)
363 struct inode *inode = filp->f_dentry->d_inode;
364 unsigned long ino = inode->i_ino;
365 struct usb_bus *bus;
367 /* sanity check */
368 if (ITYPE(ino) != IBUS)
369 return -EINVAL;
370 switch ((unsigned int)filp->f_pos) {
371 case 0:
372 if (filldir(dirent, ".", 1, filp->f_pos, ino) < 0)
373 return 0;
374 filp->f_pos++;
375 /* fall through */
377 case 1:
378 if (filldir(dirent, "..", 2, filp->f_pos, IROOT) < 0)
379 return 0;
380 filp->f_pos++;
381 /* fall through */
383 default:
384 lock_kernel();
385 bus = usbdevfs_findbus(IBUSNR(ino));
386 bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir);
387 unlock_kernel();
388 return 0;
392 static struct file_operations usbdevfs_root_file_operations = {
393 readdir: usbdevfs_root_readdir,
396 static struct inode_operations usbdevfs_root_inode_operations = {
397 lookup: usbdevfs_root_lookup,
400 static struct file_operations usbdevfs_bus_file_operations = {
401 readdir: usbdevfs_bus_readdir,
404 static struct inode_operations usbdevfs_bus_inode_operations = {
405 lookup: usbdevfs_bus_lookup,
408 static void usbdevfs_read_inode(struct inode *inode)
410 struct special *spec;
412 inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;
413 inode->i_mode = S_IFREG;
414 inode->i_gid = inode->i_uid = 0;
415 INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);
416 INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
417 inode->u.usbdev_i.p.dev = NULL;
418 inode->u.usbdev_i.p.bus = NULL;
419 switch (ITYPE(inode->i_ino)) {
420 case ISPECIAL:
421 if (inode->i_ino == IROOT) {
422 inode->i_op = &usbdevfs_root_inode_operations;
423 inode->i_fop = &usbdevfs_root_file_operations;
424 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
425 return;
427 if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
428 return;
429 spec = &special[inode->i_ino-(IROOT+1)];
430 inode->i_fop = spec->fops;
431 return;
433 case IDEVICE:
434 return;
436 case IBUS:
437 return;
439 default:
440 return;
444 static void usbdevfs_put_super(struct super_block *sb)
446 list_del(&sb->u.usbdevfs_sb.slist);
447 INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist);
448 while (!list_empty(&sb->u.usbdevfs_sb.ilist))
449 free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode, u.usbdev_i.slist));
452 static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf)
454 buf->f_type = USBDEVICE_SUPER_MAGIC;
455 buf->f_bsize = PAGE_SIZE/sizeof(long); /* ??? */
456 buf->f_bfree = 0;
457 buf->f_bavail = 0;
458 buf->f_ffree = 0;
459 buf->f_namelen = NAME_MAX;
460 return 0;
463 static struct super_operations usbdevfs_sops = {
464 read_inode: usbdevfs_read_inode,
465 put_super: usbdevfs_put_super,
466 statfs: usbdevfs_statfs,
469 struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
471 struct inode *root_inode, *inode;
472 struct list_head *blist;
473 struct usb_bus *bus;
474 unsigned int i;
475 uid_t devuid = 0, busuid = 0, listuid = 0;
476 gid_t devgid = 0, busgid = 0, listgid = 0;
477 umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode = S_IRUGO;
478 char *curopt = NULL, *value;
480 /* parse options */
481 if (data)
482 curopt = strtok(data, ",");
483 for (; curopt; curopt = strtok(NULL, ",")) {
484 if ((value = strchr(curopt, '=')) != NULL)
485 *value++ = 0;
486 if (!strcmp(curopt, "devuid")) {
487 if (!value || !value[0])
488 goto opterr;
489 devuid = simple_strtoul(value, &value, 0);
490 if (*value)
491 goto opterr;
493 if (!strcmp(curopt, "devgid")) {
494 if (!value || !value[0])
495 goto opterr;
496 devgid = simple_strtoul(value, &value, 0);
497 if (*value)
498 goto opterr;
500 if (!strcmp(curopt, "devmode")) {
501 if (!value || !value[0])
502 goto opterr;
503 devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
504 if (*value)
505 goto opterr;
507 if (!strcmp(curopt, "busuid")) {
508 if (!value || !value[0])
509 goto opterr;
510 busuid = simple_strtoul(value, &value, 0);
511 if (*value)
512 goto opterr;
514 if (!strcmp(curopt, "busgid")) {
515 if (!value || !value[0])
516 goto opterr;
517 busgid = simple_strtoul(value, &value, 0);
518 if (*value)
519 goto opterr;
521 if (!strcmp(curopt, "busmode")) {
522 if (!value || !value[0])
523 goto opterr;
524 busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
525 if (*value)
526 goto opterr;
528 if (!strcmp(curopt, "listuid")) {
529 if (!value || !value[0])
530 goto opterr;
531 listuid = simple_strtoul(value, &value, 0);
532 if (*value)
533 goto opterr;
535 if (!strcmp(curopt, "listgid")) {
536 if (!value || !value[0])
537 goto opterr;
538 listgid = simple_strtoul(value, &value, 0);
539 if (*value)
540 goto opterr;
542 if (!strcmp(curopt, "listmode")) {
543 if (!value || !value[0])
544 goto opterr;
545 listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
546 if (*value)
547 goto opterr;
550 /* fill superblock */
551 s->s_blocksize = 1024;
552 s->s_blocksize_bits = 10;
553 s->s_magic = USBDEVICE_SUPER_MAGIC;
554 s->s_op = &usbdevfs_sops;
555 INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);
556 INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);
557 s->u.usbdevfs_sb.devuid = devuid;
558 s->u.usbdevfs_sb.devgid = devgid;
559 s->u.usbdevfs_sb.devmode = devmode;
560 s->u.usbdevfs_sb.busuid = busuid;
561 s->u.usbdevfs_sb.busgid = busgid;
562 s->u.usbdevfs_sb.busmode = busmode;
563 root_inode = iget(s, IROOT);
564 if (!root_inode)
565 goto out_no_root;
566 s->s_root = d_alloc_root(root_inode);
567 if (!s->s_root)
568 goto out_no_root;
569 list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
570 for (i = 0; i < NRSPECIAL; i++) {
571 if (!(inode = iget(s, IROOT+1+i)))
572 continue;
573 inode->i_uid = listuid;
574 inode->i_gid = listgid;
575 inode->i_mode = listmode | S_IFREG;
576 list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
577 list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
579 lock_kernel();
580 for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
581 bus = list_entry(blist, struct usb_bus, bus_list);
582 new_bus_inode(bus, s);
583 recurse_new_dev_inode(bus->root_hub, s);
585 unlock_kernel();
586 return s;
588 out_no_root:
589 printk("usbdevfs_read_super: get root inode failed\n");
590 iput(root_inode);
591 return NULL;
593 opterr:
594 printk(KERN_WARNING "usbdevfs: mount parameter error\n");
595 return NULL;
598 static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, 0);
600 /* --------------------------------------------------------------------- */
602 void usbdevfs_add_bus(struct usb_bus *bus)
604 struct list_head *slist;
606 lock_kernel();
607 for (slist = superlist.next; slist != &superlist; slist = slist->next)
608 new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
609 unlock_kernel();
610 usbdevfs_conn_disc_event();
613 void usbdevfs_remove_bus(struct usb_bus *bus)
615 lock_kernel();
616 while (!list_empty(&bus->inodes))
617 free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));
618 unlock_kernel();
619 usbdevfs_conn_disc_event();
622 void usbdevfs_add_device(struct usb_device *dev)
624 struct list_head *slist;
626 lock_kernel();
627 for (slist = superlist.next; slist != &superlist; slist = slist->next)
628 new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
629 unlock_kernel();
630 usbdevfs_conn_disc_event();
633 void usbdevfs_remove_device(struct usb_device *dev)
635 struct dev_state *ds;
636 struct siginfo sinfo;
638 lock_kernel();
639 while (!list_empty(&dev->inodes))
640 free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist));
641 while (!list_empty(&dev->filelist)) {
642 ds = list_entry(dev->filelist.next, struct dev_state, list);
643 list_del(&ds->list);
644 INIT_LIST_HEAD(&ds->list);
645 down_write(&ds->devsem);
646 ds->dev = NULL;
647 up_write(&ds->devsem);
648 if (ds->discsignr) {
649 sinfo.si_signo = SIGPIPE;
650 sinfo.si_errno = EPIPE;
651 sinfo.si_code = SI_ASYNCIO;
652 sinfo.si_addr = ds->disccontext;
653 send_sig_info(ds->discsignr, &sinfo, ds->disctask);
656 unlock_kernel();
657 usbdevfs_conn_disc_event();
660 /* --------------------------------------------------------------------- */
662 #ifdef CONFIG_PROC_FS
663 static struct proc_dir_entry *usbdir = NULL;
664 #endif
666 int __init usbdevfs_init(void)
668 int ret;
670 for (ret = 0; ret < NRSPECIAL; ret++) {
671 INIT_LIST_HEAD(&special[ret].inodes);
673 if ((ret = usb_register(&usbdevfs_driver)))
674 return ret;
675 if ((ret = register_filesystem(&usbdevice_fs_type)))
676 usb_deregister(&usbdevfs_driver);
677 #ifdef CONFIG_PROC_FS
678 /* create mount point for usbdevfs */
679 usbdir = proc_mkdir("usb", proc_bus);
680 #endif
681 return ret;
684 void __exit usbdevfs_cleanup(void)
686 usb_deregister(&usbdevfs_driver);
687 unregister_filesystem(&usbdevice_fs_type);
688 #ifdef CONFIG_PROC_FS
689 if (usbdir)
690 remove_proc_entry("usb", proc_bus);
691 #endif
694 #if 0
695 module_init(usbdevfs_init);
696 module_exit(usbdevfs_cleanup);
697 #endif