]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/device.h
update
[l4.git] / l4 / pkg / io / server / src / device.h
1 /*
2  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9 #pragma once
10
11 #include <l4/sys/l4int.h>
12 #include <l4/vbus/vbus_types.h>
13 #include <l4/cxx/minmax>
14 #include <l4/cxx/string>
15
16 #include "resource.h"
17
18 #include <cstdio> 
19
20 template< typename D >
21 class Device_tree
22 {
23 private:
24   D *_n;
25   D *_p;
26   D *_c;
27   int _depth;
28
29 public:
30   Device_tree() : _n(0), _p(0), _c(0), _depth(0) {}
31
32   D *parent() const { return _p; }
33   D *children() const { return _c; }
34   D *next() const { return _n; }
35   int depth() const { return _depth; }
36
37   void set_parent(D *p) { _p = p; }
38
39   void add_sibling(D *s)
40   { _n = s; }
41
42   void add_child(D *d, D *self)
43   {
44     for (iterator i = iterator(0, d, L4VBUS_MAX_DEPTH); i != iterator(); ++i)
45       i->set_depth(i->depth() + depth() + 1);
46
47     d->set_parent(self);
48
49     if (!_c)
50       _c = d;
51     else
52       {
53         D *p;
54         for (p = _c; p->next(); p = p->next())
55           ;
56         p->add_sibling(d);
57       }
58   }
59
60   void set_depth(int d) { _depth = d; }
61
62   class iterator
63   {
64   public:
65     iterator(D *p, D *c, int depth = 0)
66     : _p(p), _c(c), _d(depth + (p ? p->depth() : 0))
67     {}
68
69     iterator(D const *p, int depth = 0)
70     : _p(p), _c(p->children()), _d(depth + p->depth())
71     {}
72
73     iterator()
74     : _c(0)
75     {}
76
77     bool operator == (iterator const &i) const
78     {
79       if (!_c && !i._c)
80         return true;
81
82       return _p == i._p && _c == i._c && _d == i._d;
83     }
84
85     bool operator != (iterator const &i) const
86     { return !operator == (i); }
87
88     D *operator -> () const { return _c; }
89     D *operator * () const { return _c; }
90
91     iterator operator ++ ()
92     {
93       if (_d > _c->depth() && _c->children())
94         // go to a child if not at max depth and there are children
95         _c = _c->children();
96       else if (_c->next())
97         // go to the next sibling
98         _c = _c->next();
99       else
100         {
101           for (D *x = _c->parent(); x && x != _p; x = x->parent())
102             if (x->next())
103               {
104                 _c = x->next();
105                 return *this;
106               }
107           _c = 0;
108         }
109
110       return *this;
111     }
112
113     iterator operator ++ (int)
114     {
115       iterator o = *this;
116       ++(*this);
117       return o;
118     }
119
120   private:
121     D const *_p;
122     D *_c;
123     int _d;
124   };
125 };
126
127 template< typename D >
128 class Device_tree_mixin
129 {
130 protected:
131   Device_tree<D> _dt;
132
133 public:
134   typedef typename Device_tree<D>::iterator iterator;
135
136   iterator begin(int depth = 0) const
137   { return iterator(static_cast<D const*>(this), depth); }
138
139   static iterator end() { return iterator(); }
140
141   void set_depth(int d) { return _dt.set_depth(d); }
142   void set_parent(D *p) { _dt.set_parent(p); }
143   void add_sibling(D *s) { _dt.add_sibling(s); }
144   virtual void add_child(D *c) { _dt.add_child(c, static_cast<D*>(this)); }
145   virtual ~Device_tree_mixin() {}
146 };
147
148 class Resource_container
149 {
150 public:
151   virtual Resource_list const *resources() const = 0;
152   virtual bool resource_allocated(Resource const *) const  = 0;
153   virtual ~Resource_container() {}
154 };
155
156
157 class Device : public Resource_container
158 {
159 public:
160   virtual Device *parent() const = 0;
161   virtual Device *children() const = 0;
162   virtual Device *next() const = 0;
163   virtual int depth() const = 0;
164
165   virtual bool request_child_resource(Resource *, Device *) = 0;
166   virtual bool alloc_child_resource(Resource *, Device *)  = 0;
167
168   void request_resource(Resource *r);
169   void request_resources();
170   void request_child_resources();
171   void allocate_pending_child_resources();
172   void allocate_pending_resources();
173   virtual void setup_resources() = 0;
174
175   virtual char const *name() const = 0;
176   virtual char const *hid() const = 0;
177   virtual bool name(cxx::String const &)  = 0;
178
179   virtual void dump(int) const {};
180
181   virtual ~Device() {}
182
183   typedef Device_tree<Device>::iterator iterator;
184
185   iterator begin(int depth = 0) const { return iterator(this, depth); }
186   static iterator end() { return iterator(); }
187
188 };
189
190
191
192 class Generic_device : public virtual Device
193 {
194 private:
195   Resource_list _resources;
196
197 public:
198   //typedef gen_iterator<Generic_device> iterator;
199
200   Resource_list const *resources() const { return &_resources; }
201   void add_resource(Resource *r)
202   { _resources.insert(r); }
203
204   virtual bool match_cid(cxx::String const &) const { return false; }
205   virtual char const *name() const { return "(noname)"; }
206   virtual char const *hid() const { return 0; }
207   virtual bool name(cxx::String const &) { return false; }
208
209
210   virtual bool request_child_resource(Resource *, Device *);
211   virtual bool alloc_child_resource(Resource *, Device *);
212   virtual void setup_resources();
213
214   virtual ~Generic_device() {}
215
216 };
217
218