Import 2.3.48
[davej-history.git] / drivers / usb / inode.c
blob2306615f0f514d42dd64f1aaa92acc947859a6be
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/module.h>
33 #include <linux/fs.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>
41 #include "usb.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;
51 struct special {
52 const char *name;
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)
68 const char *name;
69 unsigned int s;
71 if (dentry->d_name.len != 3)
72 return -1;
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')
77 return -1;
78 s = name[0] - '0';
79 s = s * 10 + name[1] - '0';
80 s = s * 10 + name[2] - '0';
81 return s;
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)
91 struct inode *inode;
92 unsigned int devnum = dev->devnum;
93 unsigned int busnum = dev->bus->busnum;
95 if (devnum < 1 || devnum > 127 || busnum > 255)
96 return;
97 inode = iget(sb, IDEVICE | (busnum << 8) | devnum);
98 if (!inode) {
99 printk(KERN_ERR "usbdevfs: cannot create inode for bus %u device %u\n", busnum, devnum);
100 return;
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)
115 unsigned int i;
117 if (!dev)
118 return;
119 new_dev_inode(dev, sb);
120 for (i = 0; i < dev->maxchild; i++) {
121 if (!dev->children[i])
122 continue;
123 recurse_new_dev_inode(dev->children[i], sb);
127 static void new_bus_inode(struct usb_bus *bus, struct super_block *sb)
129 struct inode *inode;
130 unsigned int busnum = bus->busnum;
132 if (busnum > 255)
133 return;
134 inode = iget(sb, IBUS | (busnum << 8));
135 if (!inode) {
136 printk(KERN_ERR "usbdevfs: cannot create inode for bus %u\n", busnum);
137 return;
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;
156 inode->i_size = 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);
161 iput(inode);
164 static struct usb_bus *usbdevfs_findbus(int busnr)
166 struct list_head *list;
167 struct usb_bus *bus;
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)
172 return bus;
174 return NULL;
177 #if 0
178 static struct usb_device *finddev(struct usb_device *dev, int devnr)
180 unsigned int i;
181 struct usb_device *d2;
183 if (!dev)
184 return NULL;
185 if (dev->devnum == devnr)
186 return dev;
187 for (i = 0; i < dev->maxchild; i++) {
188 if (!dev->children[i])
189 continue;
190 if ((d2 = finddev(dev->children[i], devnr)))
191 return d2;
193 return NULL;
196 static struct usb_device *usbdevfs_finddevice(struct usb_bus *bus, int devnr)
198 return finddev(bus->root_hub, devnr);
200 #endif
202 /* --------------------------------------------------------------------- */
204 static int usbdevfs_revalidate(struct dentry *dentry, int flags)
206 struct inode *inode = dentry->d_inode;
208 if (!inode)
209 return 0;
210 if (ITYPE(inode->i_ino) == IBUS && !inode->u.usbdev_i.p.bus)
211 return 0;
212 if (ITYPE(inode->i_ino) == IDEVICE && !inode->u.usbdev_i.p.dev)
213 return 0;
214 return 1;
217 static struct dentry_operations usbdevfs_dentry_operations = {
218 usbdevfs_revalidate, /* d_revalidate */
219 NULL, /* d_hash */
220 NULL, /* d_compare */
223 static struct dentry *usbdevfs_root_lookup(struct inode *dir, struct dentry *dentry)
225 int busnr;
226 unsigned long ino = 0;
227 unsigned int i;
228 struct inode *inode;
230 /* sanity check */
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);
237 if (!ino) {
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);
242 break;
246 if (!ino)
247 return ERR_PTR(-ENOENT);
248 inode = iget(dir->i_sb, ino);
249 if (!inode)
250 return ERR_PTR(-EINVAL);
251 if (inode && ITYPE(ino) == IBUS && inode->u.usbdev_i.p.bus == NULL) {
252 iput(inode);
253 inode = NULL;
255 d_add(dentry, inode);
256 return NULL;
259 static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry)
261 struct inode *inode;
262 int devnr;
264 /* sanity check */
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);
272 if (!inode)
273 return ERR_PTR(-EINVAL);
274 if (inode && inode->u.usbdev_i.p.dev == NULL) {
275 iput(inode);
276 inode = NULL;
278 d_add(dentry, inode);
279 return NULL;
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;
288 struct usb_bus *bus;
289 char numbuf[8];
290 unsigned int i;
292 /* sanity check */
293 if (ino != IROOT)
294 return -EINVAL;
295 i = filp->f_pos;
296 switch (i) {
297 case 0:
298 if (filldir(dirent, ".", 1, i, IROOT) < 0)
299 return 0;
300 filp->f_pos++;
301 i++;
302 /* fall through */
304 case 1:
305 if (filldir(dirent, "..", 2, i, IROOT) < 0)
306 return 0;
307 filp->f_pos++;
308 i++;
309 /* fall through */
311 default:
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)
316 return 0;
317 filp->f_pos++;
318 i++;
320 if (i < 2+NRSPECIAL)
321 return 0;
322 i -= 2+NRSPECIAL;
323 lock_kernel();
324 for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
325 if (i > 0) {
326 i--;
327 continue;
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)
332 break;
333 filp->f_pos++;
335 unlock_kernel();
336 return 0;
340 static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct file *filp, void *dirent, filldir_t filldir)
342 char numbuf[8];
343 unsigned int i;
345 if (!dev)
346 return pos;
347 sprintf(numbuf, "%03d", dev->devnum);
348 if (pos > 0)
349 pos--;
350 else {
351 if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff)) < 0)
352 return -1;
353 filp->f_pos++;
355 for (i = 0; i < dev->maxchild; i++) {
356 if (!dev->children[i])
357 continue;
358 pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);
359 if (pos < 0)
360 return -1;
362 return pos;
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;
369 struct usb_bus *bus;
371 /* sanity check */
372 if (ITYPE(ino) != IBUS)
373 return -EINVAL;
374 switch ((unsigned int)filp->f_pos) {
375 case 0:
376 if (filldir(dirent, ".", 1, filp->f_pos, ino) < 0)
377 return 0;
378 filp->f_pos++;
379 /* fall through */
381 case 1:
382 if (filldir(dirent, "..", 2, filp->f_pos, IROOT) < 0)
383 return 0;
384 filp->f_pos++;
385 /* fall through */
387 default:
388 lock_kernel();
389 bus = usbdevfs_findbus(IBUSNR(ino));
390 bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir);
391 unlock_kernel();
392 return 0;
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)) {
424 case ISPECIAL:
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;
429 return;
431 if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
432 return;
433 spec = &special[inode->i_ino-(IROOT+1)];
434 inode->i_fop = spec->fops;
435 return;
437 case IDEVICE:
438 return;
440 case IBUS:
441 return;
443 default:
444 return;
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));
454 MOD_DEC_USE_COUNT;
457 static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
459 struct statfs tmp;
461 tmp.f_type = USBDEVICE_SUPER_MAGIC;
462 tmp.f_bsize = PAGE_SIZE/sizeof(long); /* ??? */
463 tmp.f_blocks = 0;
464 tmp.f_bfree = 0;
465 tmp.f_bavail = 0;
466 tmp.f_files = 0;
467 tmp.f_ffree = 0;
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;
482 struct usb_bus *bus;
483 unsigned int i;
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;
489 /* parse options */
490 if (data)
491 curopt = strtok(data, ",");
492 for (; curopt; curopt = strtok(NULL, ",")) {
493 if ((value = strchr(curopt, '=')) != NULL)
494 *value++ = 0;
495 if (!strcmp(curopt, "devuid")) {
496 if (!value || !value[0])
497 goto opterr;
498 devuid = simple_strtoul(value, &value, 0);
499 if (*value)
500 goto opterr;
502 if (!strcmp(curopt, "devgid")) {
503 if (!value || !value[0])
504 goto opterr;
505 devgid = simple_strtoul(value, &value, 0);
506 if (*value)
507 goto opterr;
509 if (!strcmp(curopt, "devmode")) {
510 if (!value || !value[0])
511 goto opterr;
512 devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
513 if (*value)
514 goto opterr;
516 if (!strcmp(curopt, "busuid")) {
517 if (!value || !value[0])
518 goto opterr;
519 busuid = simple_strtoul(value, &value, 0);
520 if (*value)
521 goto opterr;
523 if (!strcmp(curopt, "busgid")) {
524 if (!value || !value[0])
525 goto opterr;
526 busgid = simple_strtoul(value, &value, 0);
527 if (*value)
528 goto opterr;
530 if (!strcmp(curopt, "busmode")) {
531 if (!value || !value[0])
532 goto opterr;
533 busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
534 if (*value)
535 goto opterr;
537 if (!strcmp(curopt, "listuid")) {
538 if (!value || !value[0])
539 goto opterr;
540 listuid = simple_strtoul(value, &value, 0);
541 if (*value)
542 goto opterr;
544 if (!strcmp(curopt, "listgid")) {
545 if (!value || !value[0])
546 goto opterr;
547 listgid = simple_strtoul(value, &value, 0);
548 if (*value)
549 goto opterr;
551 if (!strcmp(curopt, "listmode")) {
552 if (!value || !value[0])
553 goto opterr;
554 listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
555 if (*value)
556 goto opterr;
559 /* fill superblock */
560 MOD_INC_USE_COUNT;
561 lock_super(s);
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);
575 if (!root_inode)
576 goto out_no_root;
577 s->s_root = d_alloc_root(root_inode);
578 if (!s->s_root)
579 goto out_no_root;
580 list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
581 unlock_super(s);
582 for (i = 0; i < NRSPECIAL; i++) {
583 if (!(inode = iget(s, IROOT+1+i)))
584 continue;
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);
591 lock_kernel();
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);
597 unlock_kernel();
598 return s;
600 out_no_root:
601 printk("usbdevfs_read_super: get root inode failed\n");
602 iput(root_inode);
603 s->s_dev = 0;
604 unlock_super(s);
605 MOD_DEC_USE_COUNT;
606 return NULL;
608 opterr:
609 printk(KERN_WARNING "usbdevfs: mount parameter error\n");
610 s->s_dev = 0;
611 return NULL;
614 static struct file_system_type usbdevice_fs_type = {
615 "usbdevfs",
617 usbdevfs_read_super,
618 NULL
621 /* --------------------------------------------------------------------- */
623 void usbdevfs_add_bus(struct usb_bus *bus)
625 struct list_head *slist;
627 lock_kernel();
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));
630 unlock_kernel();
631 usbdevfs_conn_disc_event();
634 void usbdevfs_remove_bus(struct usb_bus *bus)
636 lock_kernel();
637 while (!list_empty(&bus->inodes))
638 free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));
639 unlock_kernel();
640 usbdevfs_conn_disc_event();
643 void usbdevfs_add_device(struct usb_device *dev)
645 struct list_head *slist;
647 lock_kernel();
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));
650 unlock_kernel();
651 usbdevfs_conn_disc_event();
654 void usbdevfs_remove_device(struct usb_device *dev)
656 struct dev_state *ds;
657 struct siginfo sinfo;
659 lock_kernel();
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);
664 list_del(&ds->list);
665 INIT_LIST_HEAD(&ds->list);
666 down_write(&ds->devsem);
667 ds->dev = NULL;
668 up_write(&ds->devsem);
669 if (ds->discsignr) {
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);
677 unlock_kernel();
678 usbdevfs_conn_disc_event();
681 /* --------------------------------------------------------------------- */
683 static struct proc_dir_entry *usbdir = NULL;
685 int __init usbdevfs_init(void)
687 int ret;
689 for (ret = 0; ret < NRSPECIAL; ret++) {
690 INIT_LIST_HEAD(&special[ret].inodes);
692 if ((ret = usb_register(&usbdevfs_driver)))
693 return ret;
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);
698 return ret;
701 void __exit usbdevfs_cleanup(void)
703 usb_deregister(&usbdevfs_driver);
704 unregister_filesystem(&usbdevice_fs_type);
705 if (usbdir)
706 remove_proc_entry("usb", proc_bus);
709 #if 0
710 module_init(usbdevfs_init);
711 module_exit(usbdevfs_cleanup);
712 #endif