OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [usb/] [inode.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*****************************************************************************/
2
 
3
/*
4
 *      inode.c  --  Inode/Dentry functions for the USB device file system.
5
 *
6
 *      Copyright (C) 2000
7
 *          Thomas Sailer (sailer@ife.ee.ethz.ch)
8
 *
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.
13
 *
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.
18
 *
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.
22
 *
23
 *  $Id: inode.c,v 1.1.1.1 2004-04-15 01:54:15 phoenix Exp $
24
 *
25
 *  History:
26
 *   0.1  04.01.2000  Created
27
 */
28
 
29
/*****************************************************************************/
30
 
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 <linux/usbdevice_fs.h>
42
#include <asm/uaccess.h>
43
 
44
/* --------------------------------------------------------------------- */
45
 
46
/*
47
 * This list of superblocks is still used,
48
 * but since usbdevfs became FS_SINGLE
49
 * there is only one super_block.
50
 */
51
static LIST_HEAD(superlist);
52
 
53
struct special {
54
        const char *name;
55
        struct file_operations *fops;
56
        struct inode *inode;
57
        struct list_head inodes;
58
};
59
 
60
static struct special special[] = {
61
        { "devices", &usbdevfs_devices_fops,  },
62
        { "drivers", &usbdevfs_drivers_fops,  }
63
};
64
 
65
#define NRSPECIAL (sizeof(special)/sizeof(special[0]))
66
 
67
/* --------------------------------------------------------------------- */
68
 
69
static int dnumber(struct dentry *dentry)
70
{
71
        const char *name;
72
        unsigned int s;
73
 
74
        if (dentry->d_name.len != 3)
75
                return -1;
76
        name = dentry->d_name.name;
77
        if (name[0] < '0' || name[0] > '9' ||
78
            name[1] < '0' || name[1] > '9' ||
79
            name[2] < '0' || name[2] > '9')
80
                return -1;
81
        s = name[0] - '0';
82
        s = s * 10 + name[1] - '0';
83
        s = s * 10 + name[2] - '0';
84
        return s;
85
}
86
 
87
/*
88
 * utility functions; should be called with the kernel lock held
89
 * to protect against busses/devices appearing/disappearing
90
 */
91
 
92
static void new_dev_inode(struct usb_device *dev, struct super_block *sb)
93
{
94
        struct inode *inode;
95
        unsigned int devnum = dev->devnum;
96
        unsigned int busnum = dev->bus->busnum;
97
 
98
        if (devnum < 1 || devnum > 127 || busnum > 255)
99
                return;
100
        inode = iget(sb, IDEVICE | (busnum << 8) | devnum);
101
        if (!inode) {
102
                printk(KERN_ERR "usbdevfs: cannot create inode for bus %u device %u\n", busnum, devnum);
103
                return;
104
        }
105
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
106
        inode->i_uid = sb->u.usbdevfs_sb.devuid;
107
        inode->i_gid = sb->u.usbdevfs_sb.devgid;
108
        inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG;
109
        inode->i_fop = &usbdevfs_device_file_operations;
110
        inode->i_size = sizeof(struct usb_device_descriptor);
111
        inode->u.usbdev_i.p.dev = dev;
112
        list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
113
        list_add_tail(&inode->u.usbdev_i.dlist, &dev->inodes);
114
}
115
 
116
static void recurse_new_dev_inode(struct usb_device *dev, struct super_block *sb)
117
{
118
        unsigned int i;
119
 
120
        if (!dev)
121
                return;
122
        new_dev_inode(dev, sb);
123
        for (i = 0; i < dev->maxchild; i++) {
124
                if (!dev->children[i])
125
                        continue;
126
                recurse_new_dev_inode(dev->children[i], sb);
127
        }
128
}
129
 
130
static void new_bus_inode(struct usb_bus *bus, struct super_block *sb)
131
{
132
        struct inode *inode;
133
        unsigned int busnum = bus->busnum;
134
 
135
        if (busnum > 255)
136
                return;
137
        inode = iget(sb, IBUS | (busnum << 8));
138
        if (!inode) {
139
                printk(KERN_ERR "usbdevfs: cannot create inode for bus %u\n", busnum);
140
                return;
141
        }
142
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
143
        inode->i_uid = sb->u.usbdevfs_sb.busuid;
144
        inode->i_gid = sb->u.usbdevfs_sb.busgid;
145
        inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR;
146
        inode->i_op = &usbdevfs_bus_inode_operations;
147
        inode->i_fop = &usbdevfs_bus_file_operations;
148
        inode->u.usbdev_i.p.bus = bus;
149
        list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
150
        list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes);
151
}
152
 
153
static void free_inode(struct inode *inode)
154
{
155
        inode->u.usbdev_i.p.bus = NULL;
156
        inode->u.usbdev_i.p.dev = NULL;
157
        inode->i_mode &= ~S_IRWXUGO;
158
        inode->i_uid = inode->i_gid = 0;
159
        inode->i_size = 0;
160
        list_del(&inode->u.usbdev_i.slist);
161
        list_del(&inode->u.usbdev_i.dlist);
162
        iput(inode);
163
}
164
 
165
static int parse_options(struct super_block *s, char *data)
166
{
167
        uid_t devuid = 0, busuid = 0, listuid = 0;
168
        gid_t devgid = 0, busgid = 0, listgid = 0;
169
        umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode = S_IRUGO;
170
        char *curopt = NULL, *value;
171
 
172
        /* parse options */
173
        if (data)
174
                curopt = strtok(data, ",");
175
        for (; curopt; curopt = strtok(NULL, ",")) {
176
                if ((value = strchr(curopt, '=')) != NULL)
177
                        *value++ = 0;
178
                if (!strcmp(curopt, "devuid")) {
179
                        if (!value || !value[0])
180
                                return -EINVAL;
181
                        devuid = simple_strtoul(value, &value, 0);
182
                        if (*value)
183
                                return -EINVAL;
184
                }
185
                if (!strcmp(curopt, "devgid")) {
186
                        if (!value || !value[0])
187
                                return -EINVAL;
188
                        devgid = simple_strtoul(value, &value, 0);
189
                        if (*value)
190
                                return -EINVAL;
191
                }
192
                if (!strcmp(curopt, "devmode")) {
193
                        if (!value || !value[0])
194
                                return -EINVAL;
195
                        devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
196
                        if (*value)
197
                                return -EINVAL;
198
                }
199
                if (!strcmp(curopt, "busuid")) {
200
                        if (!value || !value[0])
201
                                return -EINVAL;
202
                        busuid = simple_strtoul(value, &value, 0);
203
                        if (*value)
204
                                return -EINVAL;
205
                }
206
                if (!strcmp(curopt, "busgid")) {
207
                        if (!value || !value[0])
208
                                return -EINVAL;
209
                        busgid = simple_strtoul(value, &value, 0);
210
                        if (*value)
211
                                return -EINVAL;
212
                }
213
                if (!strcmp(curopt, "busmode")) {
214
                        if (!value || !value[0])
215
                                return -EINVAL;
216
                        busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
217
                        if (*value)
218
                                return -EINVAL;
219
                }
220
                if (!strcmp(curopt, "listuid")) {
221
                        if (!value || !value[0])
222
                                return -EINVAL;
223
                        listuid = simple_strtoul(value, &value, 0);
224
                        if (*value)
225
                                return -EINVAL;
226
                }
227
                if (!strcmp(curopt, "listgid")) {
228
                        if (!value || !value[0])
229
                                return -EINVAL;
230
                        listgid = simple_strtoul(value, &value, 0);
231
                        if (*value)
232
                                return -EINVAL;
233
                }
234
                if (!strcmp(curopt, "listmode")) {
235
                        if (!value || !value[0])
236
                                return -EINVAL;
237
                        listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
238
                        if (*value)
239
                                return -EINVAL;
240
                }
241
        }
242
 
243
        s->u.usbdevfs_sb.devuid = devuid;
244
        s->u.usbdevfs_sb.devgid = devgid;
245
        s->u.usbdevfs_sb.devmode = devmode;
246
        s->u.usbdevfs_sb.busuid = busuid;
247
        s->u.usbdevfs_sb.busgid = busgid;
248
        s->u.usbdevfs_sb.busmode = busmode;
249
        s->u.usbdevfs_sb.listuid = listuid;
250
        s->u.usbdevfs_sb.listgid = listgid;
251
        s->u.usbdevfs_sb.listmode = listmode;
252
 
253
        return 0;
254
}
255
 
256
static struct usb_bus *usbdevfs_findbus(int busnr)
257
{
258
        struct list_head *list;
259
        struct usb_bus *bus;
260
 
261
        down (&usb_bus_list_lock);
262
        for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
263
                bus = list_entry(list, struct usb_bus, bus_list);
264
                if (bus->busnum == busnr) {
265
                        up (&usb_bus_list_lock);
266
                        return bus;
267
                }
268
        }
269
        up (&usb_bus_list_lock);
270
        return NULL;
271
}
272
 
273
#if 0
274
static struct usb_device *finddev(struct usb_device *dev, int devnr)
275
{
276
        unsigned int i;
277
        struct usb_device *d2;
278
 
279
        if (!dev)
280
                return NULL;
281
        if (dev->devnum == devnr)
282
                return dev;
283
        for (i = 0; i < dev->maxchild; i++) {
284
                if (!dev->children[i])
285
                        continue;
286
                if ((d2 = finddev(dev->children[i], devnr)))
287
                        return d2;
288
        }
289
        return NULL;
290
}
291
 
292
static struct usb_device *usbdevfs_finddevice(struct usb_bus *bus, int devnr)
293
{
294
        return finddev(bus->root_hub, devnr);
295
}
296
#endif
297
 
298
/* --------------------------------------------------------------------- */
299
 
300
static int usbdevfs_revalidate(struct dentry *dentry, int flags)
301
{
302
        struct inode *inode = dentry->d_inode;
303
 
304
        if (!inode)
305
                return 0;
306
        if (ITYPE(inode->i_ino) == IBUS && !inode->u.usbdev_i.p.bus)
307
                return 0;
308
        if (ITYPE(inode->i_ino) == IDEVICE && !inode->u.usbdev_i.p.dev)
309
                return 0;
310
        return 1;
311
}
312
 
313
static struct dentry_operations usbdevfs_dentry_operations = {
314
        d_revalidate:   usbdevfs_revalidate,
315
};
316
 
317
static struct dentry *usbdevfs_root_lookup(struct inode *dir, struct dentry *dentry)
318
{
319
        int busnr;
320
        unsigned long ino = 0;
321
        unsigned int i;
322
        struct inode *inode;
323
 
324
        /* sanity check */
325
        if (dir->i_ino != IROOT)
326
                return ERR_PTR(-EINVAL);
327
        dentry->d_op = &usbdevfs_dentry_operations;
328
        busnr = dnumber(dentry);
329
        if (busnr >= 0 && busnr <= 255)
330
                ino = IBUS | (busnr << 8);
331
        if (!ino) {
332
                for (i = 0; i < NRSPECIAL; i++) {
333
                        if (strlen(special[i].name) == dentry->d_name.len &&
334
                            !strncmp(special[i].name, dentry->d_name.name, dentry->d_name.len)) {
335
                                ino = ISPECIAL | (i + IROOT + 1);
336
                                break;
337
                        }
338
                }
339
        }
340
        if (!ino)
341
                return ERR_PTR(-ENOENT);
342
        inode = iget(dir->i_sb, ino);
343
        if (!inode)
344
                return ERR_PTR(-EINVAL);
345
        if (inode && ITYPE(ino) == IBUS && inode->u.usbdev_i.p.bus == NULL) {
346
                iput(inode);
347
                inode = NULL;
348
        }
349
        d_add(dentry, inode);
350
        return NULL;
351
}
352
 
353
static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry)
354
{
355
        struct inode *inode;
356
        int devnr;
357
 
358
        /* sanity check */
359
        if (ITYPE(dir->i_ino) != IBUS)
360
                return ERR_PTR(-EINVAL);
361
        dentry->d_op = &usbdevfs_dentry_operations;
362
        devnr = dnumber(dentry);
363
        if (devnr < 1 || devnr > 127)
364
                return ERR_PTR(-ENOENT);
365
        inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff << 8)) | devnr);
366
        if (!inode)
367
                return ERR_PTR(-EINVAL);
368
        if (inode && inode->u.usbdev_i.p.dev == NULL) {
369
                iput(inode);
370
                inode = NULL;
371
        }
372
        d_add(dentry, inode);
373
        return NULL;
374
}
375
 
376
static int usbdevfs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
377
{
378
        struct inode *inode = filp->f_dentry->d_inode;
379
        unsigned long ino = inode->i_ino;
380
        struct special *spec;
381
        struct list_head *list;
382
        struct usb_bus *bus;
383
        char numbuf[8];
384
        unsigned int i;
385
 
386
        /* sanity check */
387
        if (ino != IROOT)
388
                return -EINVAL;
389
        i = filp->f_pos;
390
        switch (i) {
391
        case 0:
392
                if (filldir(dirent, ".", 1, i, IROOT, DT_DIR) < 0)
393
                        return 0;
394
                filp->f_pos++;
395
                i++;
396
                /* fall through */
397
 
398
        case 1:
399
                if (filldir(dirent, "..", 2, i, IROOT, DT_DIR) < 0)
400
                        return 0;
401
                filp->f_pos++;
402
                i++;
403
                /* fall through */
404
 
405
        default:
406
 
407
                while (i >= 2 && i < 2+NRSPECIAL) {
408
                        spec = &special[filp->f_pos-2];
409
                        if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT), DT_UNKNOWN) < 0)
410
                                return 0;
411
                        filp->f_pos++;
412
                        i++;
413
                }
414
                if (i < 2+NRSPECIAL)
415
                        return 0;
416
                i -= 2+NRSPECIAL;
417
                down (&usb_bus_list_lock);
418
                for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
419
                        if (i > 0) {
420
                                i--;
421
                                continue;
422
                        }
423
                        bus = list_entry(list, struct usb_bus, bus_list);
424
                        sprintf(numbuf, "%03d", bus->busnum);
425
                        if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8), DT_UNKNOWN) < 0)
426
                                break;
427
                        filp->f_pos++;
428
                }
429
                up (&usb_bus_list_lock);
430
                return 0;
431
        }
432
}
433
 
434
static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct file *filp, void *dirent, filldir_t filldir)
435
{
436
        char numbuf[8];
437
        unsigned int i;
438
 
439
        if (!dev)
440
                return pos;
441
        sprintf(numbuf, "%03d", dev->devnum);
442
        if (pos > 0)
443
                pos--;
444
        else {
445
                if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff), DT_UNKNOWN) < 0)
446
                        return -1;
447
                filp->f_pos++;
448
        }
449
        for (i = 0; i < dev->maxchild; i++) {
450
                if (!dev->children[i])
451
                        continue;
452
                pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);
453
                if (pos < 0)
454
                        return -1;
455
        }
456
        return pos;
457
}
458
 
459
static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir)
460
{
461
        struct inode *inode = filp->f_dentry->d_inode;
462
        unsigned long ino = inode->i_ino;
463
        struct usb_bus *bus;
464
 
465
        /* sanity check */
466
        if (ITYPE(ino) != IBUS)
467
                return -EINVAL;
468
        switch ((unsigned int)filp->f_pos) {
469
        case 0:
470
                if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)
471
                        return 0;
472
                filp->f_pos++;
473
                /* fall through */
474
 
475
        case 1:
476
                if (filldir(dirent, "..", 2, filp->f_pos, IROOT, DT_DIR) < 0)
477
                        return 0;
478
                filp->f_pos++;
479
                /* fall through */
480
 
481
        default:
482
                lock_kernel();
483
                bus = usbdevfs_findbus(IBUSNR(ino));
484
                bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir);
485
                unlock_kernel();
486
                return 0;
487
        }
488
}
489
 
490
static struct file_operations usbdevfs_root_file_operations = {
491
        readdir: usbdevfs_root_readdir,
492
};
493
 
494
static struct inode_operations usbdevfs_root_inode_operations = {
495
        lookup: usbdevfs_root_lookup,
496
};
497
 
498
static struct file_operations usbdevfs_bus_file_operations = {
499
        readdir: usbdevfs_bus_readdir,
500
};
501
 
502
static struct inode_operations usbdevfs_bus_inode_operations = {
503
        lookup: usbdevfs_bus_lookup,
504
};
505
 
506
static void usbdevfs_read_inode(struct inode *inode)
507
{
508
        struct special *spec;
509
 
510
        inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;
511
        inode->i_mode = S_IFREG;
512
        inode->i_gid = inode->i_uid = 0;
513
        inode->u.usbdev_i.p.dev = NULL;
514
        inode->u.usbdev_i.p.bus = NULL;
515
        switch (ITYPE(inode->i_ino)) {
516
        case ISPECIAL:
517
                if (inode->i_ino == IROOT) {
518
                        inode->i_op = &usbdevfs_root_inode_operations;
519
                        inode->i_fop = &usbdevfs_root_file_operations;
520
                        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
521
                        return;
522
                }
523
                if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
524
                        return;
525
                spec = &special[inode->i_ino-(IROOT+1)];
526
                inode->i_fop = spec->fops;
527
                return;
528
 
529
        case IDEVICE:
530
                return;
531
 
532
        case IBUS:
533
                return;
534
 
535
        default:
536
                return;
537
        }
538
}
539
 
540
static void usbdevfs_put_super(struct super_block *sb)
541
{
542
        list_del(&sb->u.usbdevfs_sb.slist);
543
        INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist);
544
        while (!list_empty(&sb->u.usbdevfs_sb.ilist))
545
                free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode, u.usbdev_i.slist));
546
}
547
 
548
static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf)
549
{
550
        buf->f_type = USBDEVICE_SUPER_MAGIC;
551
        buf->f_bsize = PAGE_SIZE/sizeof(long);   /* ??? */
552
        buf->f_bfree = 0;
553
        buf->f_bavail = 0;
554
        buf->f_ffree = 0;
555
        buf->f_namelen = NAME_MAX;
556
        return 0;
557
}
558
 
559
static int usbdevfs_remount(struct super_block *s, int *flags, char *data)
560
{
561
        struct list_head *ilist = s->u.usbdevfs_sb.ilist.next;
562
        struct inode *inode;
563
        int ret;
564
 
565
        if ((ret = parse_options(s, data))) {
566
                printk(KERN_WARNING "usbdevfs: remount parameter error\n");
567
                return ret;
568
        }
569
 
570
        for (; ilist != &s->u.usbdevfs_sb.ilist; ilist = ilist->next) {
571
                inode = list_entry(ilist, struct inode, u.usbdev_i.slist);
572
 
573
                switch (ITYPE(inode->i_ino)) {
574
                        case ISPECIAL :
575
                                inode->i_uid = s->u.usbdevfs_sb.listuid;
576
                                inode->i_gid = s->u.usbdevfs_sb.listgid;
577
                                inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
578
                                break;
579
                        case IBUS :
580
                                inode->i_uid = s->u.usbdevfs_sb.busuid;
581
                                inode->i_gid = s->u.usbdevfs_sb.busgid;
582
                                inode->i_mode = s->u.usbdevfs_sb.busmode | S_IFDIR;
583
                                break;
584
                        case IDEVICE :
585
                                inode->i_uid = s->u.usbdevfs_sb.devuid;
586
                                inode->i_gid = s->u.usbdevfs_sb.devgid;
587
                                inode->i_mode = s->u.usbdevfs_sb.devmode | S_IFREG;
588
                                break;
589
                }
590
        }
591
 
592
        return 0;
593
}
594
 
595
static struct super_operations usbdevfs_sops = {
596
        read_inode:     usbdevfs_read_inode,
597
        put_super:      usbdevfs_put_super,
598
        statfs:         usbdevfs_statfs,
599
        remount_fs:     usbdevfs_remount,
600
};
601
 
602
struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
603
{
604
        struct inode *root_inode, *inode;
605
        struct list_head *blist;
606
        struct usb_bus *bus;
607
        unsigned int i;
608
 
609
        if (parse_options(s, data)) {
610
                printk(KERN_WARNING "usbdevfs: mount parameter error\n");
611
                return NULL;
612
        }
613
 
614
        /* fill superblock */
615
        s->s_blocksize = 1024;
616
        s->s_blocksize_bits = 10;
617
        s->s_magic = USBDEVICE_SUPER_MAGIC;
618
        s->s_op = &usbdevfs_sops;
619
        INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);
620
        INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);
621
        root_inode = iget(s, IROOT);
622
        if (!root_inode)
623
                goto out_no_root;
624
        s->s_root = d_alloc_root(root_inode);
625
        if (!s->s_root)
626
                goto out_no_root;
627
        lock_kernel();
628
        list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
629
        for (i = 0; i < NRSPECIAL; i++) {
630
                if (!(inode = iget(s, IROOT+1+i)))
631
                        continue;
632
                inode->i_uid = s->u.usbdevfs_sb.listuid;
633
                inode->i_gid = s->u.usbdevfs_sb.listgid;
634
                inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
635
                special[i].inode = inode;
636
                list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
637
                list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
638
        }
639
        down (&usb_bus_list_lock);
640
        for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
641
                bus = list_entry(blist, struct usb_bus, bus_list);
642
                new_bus_inode(bus, s);
643
                recurse_new_dev_inode(bus->root_hub, s);
644
        }
645
        up (&usb_bus_list_lock);
646
        unlock_kernel();
647
        return s;
648
 
649
 out_no_root:
650
        printk("usbdevfs_read_super: get root inode failed\n");
651
        iput(root_inode);
652
        return NULL;
653
}
654
 
655
/*
656
 * The usbdevfs name is now deprecated (as of 2.4.19).
657
 * It will be removed when the 2.7.x development cycle is started.
658
 * You have been warned :)
659
 */
660
static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);
661
static DECLARE_FSTYPE(usbfs_type, "usbfs", usbdevfs_read_super, FS_SINGLE);
662
 
663
/* --------------------------------------------------------------------- */
664
 
665
static void update_special_inodes (void)
666
{
667
        int i;
668
        for (i = 0; i < NRSPECIAL; i++) {
669
                struct inode *inode = special[i].inode;
670
                if (inode)
671
                        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
672
        }
673
}
674
 
675
 
676
void usbdevfs_add_bus(struct usb_bus *bus)
677
{
678
        struct list_head *slist;
679
 
680
        lock_kernel();
681
        for (slist = superlist.next; slist != &superlist; slist = slist->next)
682
                new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
683
        update_special_inodes();
684
        unlock_kernel();
685
        usbdevfs_conn_disc_event();
686
}
687
 
688
void usbdevfs_remove_bus(struct usb_bus *bus)
689
{
690
        lock_kernel();
691
        while (!list_empty(&bus->inodes))
692
                free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));
693
        update_special_inodes();
694
        unlock_kernel();
695
        usbdevfs_conn_disc_event();
696
}
697
 
698
void usbdevfs_add_device(struct usb_device *dev)
699
{
700
        struct list_head *slist;
701
 
702
        lock_kernel();
703
        for (slist = superlist.next; slist != &superlist; slist = slist->next)
704
                new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
705
        update_special_inodes();
706
        unlock_kernel();
707
        usbdevfs_conn_disc_event();
708
}
709
 
710
void usbdevfs_remove_device(struct usb_device *dev)
711
{
712
        struct dev_state *ds;
713
        struct siginfo sinfo;
714
 
715
        lock_kernel();
716
        while (!list_empty(&dev->inodes))
717
                free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist));
718
        while (!list_empty(&dev->filelist)) {
719
                ds = list_entry(dev->filelist.next, struct dev_state, list);
720
                list_del(&ds->list);
721
                INIT_LIST_HEAD(&ds->list);
722
                down_write(&ds->devsem);
723
                ds->dev = NULL;
724
                up_write(&ds->devsem);
725
                if (ds->discsignr) {
726
                        sinfo.si_signo = SIGPIPE;
727
                        sinfo.si_errno = EPIPE;
728
                        sinfo.si_code = SI_ASYNCIO;
729
                        sinfo.si_addr = ds->disccontext;
730
                        send_sig_info(ds->discsignr, &sinfo, ds->disctask);
731
                }
732
        }
733
 
734
        update_special_inodes();
735
        unlock_kernel();
736
        usbdevfs_conn_disc_event();
737
}
738
 
739
/* --------------------------------------------------------------------- */
740
 
741
#ifdef CONFIG_PROC_FS           
742
static struct proc_dir_entry *usbdir = NULL;
743
#endif  
744
 
745
int __init usbdevfs_init(void)
746
{
747
        int ret;
748
 
749
        for (ret = 0; ret < NRSPECIAL; ret++) {
750
                INIT_LIST_HEAD(&special[ret].inodes);
751
        }
752
        if ((ret = usb_register(&usbdevfs_driver)))
753
                return ret;
754
        if ((ret = register_filesystem(&usbdevice_fs_type))) {
755
                usb_deregister(&usbdevfs_driver);
756
                return ret;
757
        }
758
        if ((ret = register_filesystem(&usbfs_type))) {
759
                usb_deregister(&usbdevfs_driver);
760
                unregister_filesystem(&usbdevice_fs_type);
761
                return ret;
762
        }
763
#ifdef CONFIG_PROC_FS           
764
        /* create mount point for usbdevfs */
765
        usbdir = proc_mkdir("usb", proc_bus);
766
#endif  
767
        return ret;
768
}
769
 
770
void __exit usbdevfs_cleanup(void)
771
{
772
        usb_deregister(&usbdevfs_driver);
773
        unregister_filesystem(&usbdevice_fs_type);
774
        unregister_filesystem(&usbfs_type);
775
#ifdef CONFIG_PROC_FS   
776
        if (usbdir)
777
                remove_proc_entry("usb", proc_bus);
778
#endif
779
}
780
 
781
#if 0
782
module_init(usbdevfs_init);
783
module_exit(usbdevfs_cleanup);
784
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.