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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [drivers/] [nubus/] [proc.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* drivers/nubus/proc.c: Proc FS interface for NuBus.
2
 
3
   By David Huggins-Daines <dhd@debian.org>
4
 
5
   Much code and many ideas from drivers/pci/proc.c:
6
   Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
7
 
8
   This is initially based on the Zorro and PCI interfaces.  However,
9
   it works somewhat differently.  The intent is to provide a
10
   structure in /proc analogous to the structure of the NuBus ROM
11
   resources.
12
 
13
   Therefore each NuBus device is in fact a directory, which may in
14
   turn contain subdirectories.  The "files" correspond to NuBus
15
   resource records.  For those types of records which we know how to
16
   convert to formats that are meaningful to userspace (mostly just
17
   icons) these files will provide "cooked" data.  Otherwise they will
18
   simply provide raw access (read-only of course) to the ROM.  */
19
 
20
#include <linux/types.h>
21
#include <linux/kernel.h>
22
#include <linux/nubus.h>
23
#include <linux/proc_fs.h>
24
#include <linux/init.h>
25
#include <asm/uaccess.h>
26
#include <asm/byteorder.h>
27
 
28
static int
29
get_nubus_dev_info(char *buf, char **start, off_t pos, int count)
30
{
31
        struct nubus_dev *dev = nubus_devices;
32
        off_t at = 0;
33
        int len, cnt;
34
 
35
        cnt = 0;
36
        while (dev && count > cnt) {
37
                len = sprintf(buf, "%x\t%04x %04x %04x %04x",
38
                              dev->board->slot,
39
                              dev->category,
40
                              dev->type,
41
                              dev->dr_sw,
42
                              dev->dr_hw);
43
                len += sprintf(buf+len,
44
                               "\t%08lx",
45
                               dev->board->slot_addr);
46
                buf[len++] = '\n';
47
                at += len;
48
                if (at >= pos) {
49
                        if (!*start) {
50
                                *start = buf + (pos - (at - len));
51
                                cnt = at - pos;
52
                        } else
53
                                cnt += len;
54
                        buf += len;
55
                }
56
                dev = dev->next;
57
        }
58
        return (count > cnt) ? cnt : count;
59
}
60
 
61
static struct proc_dir_entry *proc_bus_nubus_dir;
62
 
63
static void nubus_proc_subdir(struct nubus_dev* dev,
64
                              struct proc_dir_entry* parent,
65
                              struct nubus_dir* dir)
66
{
67
        struct nubus_dirent ent;
68
 
69
        /* Some of these are directories, others aren't */
70
        while (nubus_readdir(dir, &ent) != -1) {
71
                char name[8];
72
                struct proc_dir_entry* e;
73
 
74
                sprintf(name, "%x", ent.type);
75
                e = create_proc_entry(name, S_IFREG | S_IRUGO |
76
                                      S_IWUSR, parent);
77
                if (!e) return;
78
        }
79
}
80
 
81
/* Can't do this recursively since the root directory is structured
82
   somewhat differently from the subdirectories */
83
static void nubus_proc_populate(struct nubus_dev* dev,
84
                                struct proc_dir_entry* parent,
85
                                struct nubus_dir* root)
86
{
87
        struct nubus_dirent ent;
88
 
89
        /* We know these are all directories (board resource + one or
90
           more functional resources) */
91
        while (nubus_readdir(root, &ent) != -1) {
92
                char name[8];
93
                struct proc_dir_entry* e;
94
                struct nubus_dir dir;
95
 
96
                sprintf(name, "%x", ent.type);
97
                e = proc_mkdir(name, parent);
98
                if (!e) return;
99
 
100
                /* And descend */
101
                if (nubus_get_subdir(&ent, &dir) == -1) {
102
                        /* This shouldn't happen */
103
                        printk(KERN_ERR "NuBus root directory node %x:%x has no subdir!\n",
104
                               dev->board->slot, ent.type);
105
                        continue;
106
                } else {
107
                        nubus_proc_subdir(dev, e, &dir);
108
                }
109
        }
110
}
111
 
112
int nubus_proc_attach_device(struct nubus_dev *dev)
113
{
114
        struct proc_dir_entry *e;
115
        struct nubus_dir root;
116
        char name[8];
117
 
118
        if (dev == NULL) {
119
                printk(KERN_ERR
120
                       "NULL pointer in nubus_proc_attach_device, shoot the programmer!\n");
121
                return -1;
122
        }
123
 
124
        if (dev->board == NULL) {
125
                printk(KERN_ERR
126
                       "NULL pointer in nubus_proc_attach_device, shoot the programmer!\n");
127
                printk("dev = %p, dev->board = %p\n", dev, dev->board);
128
                return -1;
129
        }
130
 
131
        /* Create a directory */
132
        sprintf(name, "%x", dev->board->slot);
133
        e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
134
        if (!e)
135
                return -ENOMEM;
136
 
137
        /* Now recursively populate it with files */
138
        nubus_get_root_dir(dev->board, &root);
139
        nubus_proc_populate(dev, e, &root);
140
 
141
        return 0;
142
}
143
 
144
/* FIXME: this is certainly broken! */
145
int nubus_proc_detach_device(struct nubus_dev *dev)
146
{
147
        struct proc_dir_entry *e;
148
 
149
        if ((e = dev->procdir)) {
150
                if (atomic_read(&e->count))
151
                        return -EBUSY;
152
                remove_proc_entry(e->name, proc_bus_nubus_dir);
153
                dev->procdir = NULL;
154
        }
155
        return 0;
156
}
157
 
158
void __init proc_bus_nubus_add_devices(void)
159
{
160
        struct nubus_dev *dev;
161
 
162
        for(dev = nubus_devices; dev; dev = dev->next)
163
                nubus_proc_attach_device(dev);
164
}
165
 
166
void __init nubus_proc_init(void)
167
{
168
        if (!MACH_IS_MAC)
169
                return;
170
        proc_bus_nubus_dir = proc_mkdir("nubus", proc_bus);
171
        create_proc_info_entry("devices", 0, proc_bus_nubus_dir,
172
                                get_nubus_dev_info);
173
        proc_bus_nubus_add_devices();
174
}

powered by: WebSVN 2.1.0

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