Subversion Repositories shark

Rev

Rev 436 | Rev 455 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
432 giacomo 1
 
2
#include <ll/i386/hw-instr.h>
436 giacomo 3
#include <ll/i386/cons.h>
432 giacomo 4
 
5
#include <linuxcomp.h>
6
 
7
#include <linux/time.h>
8
#include <linux/sched.h>
436 giacomo 9
#include <linux/ioport.h>
437 giacomo 10
#include <linux/errno.h>
436 giacomo 11
#include <asm/io.h>
437 giacomo 12
#include <linux/ctype.h>
13
#include <linux/device.h>
432 giacomo 14
 
437 giacomo 15
unsigned char _ctype[] = {
16
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
17
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
18
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
19
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
20
_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
21
_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
22
_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
23
_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
24
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
25
_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
26
_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
27
_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
28
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
29
_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
30
_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
31
_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
32
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
33
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
34
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
35
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
36
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
37
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
38
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
39
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
40
 
41
 
42
 
432 giacomo 43
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
44
 
436 giacomo 45
struct resource ioport_resource = {
46
        .name   = "PCI IO",
47
        .start  = 0x0000,
48
        .end    = IO_SPACE_LIMIT,
49
        .flags  = IORESOURCE_IO,
50
};
51
 
52
struct resource iomem_resource = {
53
        .name   = "PCI mem",
54
        .start  = 0UL,
55
        .end    = ~0UL,
56
        .flags  = IORESOURCE_MEM,
57
};
58
 
437 giacomo 59
/* Return the conflict entry if you can't request it */
60
static struct resource * __request_resource(struct resource *root, struct resource *new)
61
{
62
        unsigned long start = new->start;
63
        unsigned long end = new->end;
64
        struct resource *tmp, **p;
436 giacomo 65
 
437 giacomo 66
        if (end < start)
67
                return root;
68
        if (start < root->start)
69
                return root;
70
        if (end > root->end)
71
                return root;
72
        p = &root->child;
73
        for (;;) {
74
                tmp = *p;
75
                if (!tmp || tmp->start > end) {
76
                        new->sibling = tmp;
77
                        *p = new;
78
                        new->parent = root;
79
                        return NULL;
80
                }
81
                p = &tmp->sibling;
82
                if (tmp->end < start)
83
                        continue;
84
                return tmp;
85
        }
436 giacomo 86
}
87
 
437 giacomo 88
static int __release_resource(struct resource *old)
89
{
90
        struct resource *tmp, **p;
91
 
92
        p = &old->parent->child;
93
        for (;;) {
94
                tmp = *p;
95
                if (!tmp)
96
                        break;
97
                if (tmp == old) {
98
                        *p = tmp->sibling;
99
                        old->parent = NULL;
100
                        return 0;
101
                }
102
                p = &tmp->sibling;
103
        }
104
        return -EINVAL;
105
}
106
 
107
int release_resource(struct resource *old)
108
{
109
        int retval;
110
 
111
        retval = __release_resource(old);
112
 
113
        return retval;
114
}
115
 
116
int request_resource(struct resource *root, struct resource *new)
117
{
118
        struct resource *conflict;
119
 
120
        conflict = __request_resource(root, new);
121
 
122
        return conflict ? -EBUSY : 0;
123
}
124
 
125
 
126
 
127
struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name)
128
{
129
        struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
130
 
131
        if (res) {
132
                memset(res, 0, sizeof(*res));
133
                res->name = name;
134
                res->start = start;
135
                res->end = start + n - 1;
136
                res->flags = IORESOURCE_BUSY;
137
 
138
                for (;;) {
139
                        struct resource *conflict;
140
 
141
                        conflict = __request_resource(parent, res);
142
                        if (!conflict)
143
                                break;
144
                        if (conflict != parent) {
145
                                parent = conflict;
146
                                if (!(conflict->flags & IORESOURCE_BUSY))
147
                                        continue;
148
                        }
149
 
150
                        /* Uhhuh, that didn't work out.. */
151
                        kfree(res);
152
                        res = NULL;
153
                        break;
154
                }
155
        }
156
        return res;
157
}
158
 
159
void __release_region(struct resource *parent, unsigned long start, unsigned long n)
160
{
161
        struct resource **p;
162
        unsigned long end;
163
 
164
        p = &parent->child;
165
        end = start + n - 1;
166
 
167
        for (;;) {
168
                struct resource *res = *p;
169
 
170
                if (!res)
171
                        break;
172
                if (res->start <= start && res->end >= end) {
173
                        if (!(res->flags & IORESOURCE_BUSY)) {
174
                                p = &res->child;
175
                                continue;
176
                        }
177
                        if (res->start != start || res->end != end)
178
                                break;
179
                        *p = res->sibling;
180
                        kfree(res);
181
                        return;
182
                }
183
                p = &res->sibling;
184
        }
185
        printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end);
186
}
187
 
188
static int find_resource(struct resource *root, struct resource *new,
189
                         unsigned long size,
190
                         unsigned long min, unsigned long max,
191
                         unsigned long align,
192
                         void (*alignf)(void *, struct resource *,
193
                                        unsigned long, unsigned long),
194
                         void *alignf_data)
195
{
196
        struct resource *this = root->child;
197
 
198
        new->start = root->start;
199
        /*
200
         * Skip past an allocated resource that starts at 0, since the assignment
201
         * of this->start - 1 to new->end below would cause an underflow.
202
         */
203
        if (this && this->start == 0) {
204
                new->start = this->end + 1;
205
                this = this->sibling;
206
        }
207
        for(;;) {
208
                if (this)
209
                        new->end = this->start - 1;
210
                else
211
                        new->end = root->end;
212
                if (new->start < min)
213
                        new->start = min;
214
                if (new->end > max)
215
                        new->end = max;
216
                new->start = (new->start + align - 1) & ~(align - 1);
217
                if (alignf)
218
                        alignf(alignf_data, new, size, align);
219
                if (new->start < new->end && new->end - new->start + 1 >= size) {
220
                        new->end = new->start + size - 1;
221
                        return 0;
222
                }
223
                if (!this)
224
                        break;
225
                new->start = this->end + 1;
226
                this = this->sibling;
227
        }
228
        return -EBUSY;
229
}
230
 
231
int allocate_resource(struct resource *root, struct resource *new,
232
                      unsigned long size,
233
                      unsigned long min, unsigned long max,
234
                      unsigned long align,
235
                      void (*alignf)(void *, struct resource *,
236
                                     unsigned long, unsigned long),
237
                      void *alignf_data)
238
{
239
        int err;
240
 
241
 
242
        err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
243
        if (err >= 0 && __request_resource(root, new))
244
                err = -EBUSY;
245
 
246
        return err;
247
}
248
 
249
void device_initialize(struct device *dev)
250
{
251
        kobject_init(&dev->kobj);
252
        INIT_LIST_HEAD(&dev->node);
253
        INIT_LIST_HEAD(&dev->children);
254
        INIT_LIST_HEAD(&dev->driver_list);
255
        INIT_LIST_HEAD(&dev->bus_list);
256
}
257
 
258
int device_add(struct device *dev)
259
{
260
        struct device * parent;
261
        int error;
262
 
263
        dev = get_device(dev);
264
        if (!dev || !strlen(dev->bus_id))
265
                return -EINVAL;
266
 
267
        parent = get_device(dev->parent);
268
 
269
        pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
270
 
271
        /* first, register with generic layer. */
272
        kobject_set_name(&dev->kobj,dev->bus_id);
273
        if (parent)
274
                dev->kobj.parent = &parent->kobj;
275
 
276
        if ((error = kobject_add(&dev->kobj)))
277
                goto Error;
278
        if (parent)
279
                list_add_tail(&dev->node,&parent->children);
280
 
281
 Done:
282
        put_device(dev);
283
        return error;
284
 Error:
285
        if (parent)
286
                put_device(parent);
287
        goto Done;
288
}
289
 
290
void device_del(struct device * dev)
291
{
292
        struct device * parent = dev->parent;
293
 
294
        if (parent)
295
                list_del_init(&dev->node);
296
 
297
        kobject_del(&dev->kobj);
298
        if (parent)
299
                put_device(parent);
300
}
301
 
302
#define to_drv(obj) container_of(obj,struct device_driver,kobj)
303
 
304
struct device_driver * get_driver(struct device_driver * drv)
305
{
306
        return drv ? to_drv(kobject_get(&drv->kobj)) : NULL;
307
}
308
 
309
void put_driver(struct device_driver * drv)
310
{
311
        kobject_put(&drv->kobj);
312
}
313
 
314
void driver_unregister(struct device_driver * drv)
315
{
316
}
317
 
318
int driver_register(struct device_driver * drv)
319
{
320
        INIT_LIST_HEAD(&drv->devices);
321
        return 0;
322
}
323
 
324
#define to_dev(obj) container_of(obj,struct device,kobj)
325
 
326
struct device * get_device(struct device * dev)
327
{
328
        return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
329
}
330
 
331
void put_device(struct device * dev)
332
{
333
        kobject_put(&dev->kobj);
334
}
335
 
336
int device_register(struct device *dev)
337
{
338
        return device_add(dev);
339
}
340
 
341
void device_unregister(struct device * dev)
342
{
343
        pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id);
344
        device_del(dev);
345
        put_device(dev);
346
}
347
 
348
int bus_register(struct bus_type * bus)
349
{
350
        return 0;
351
}
352
 
353
int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
354
{ return 0; }
355
 
356
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
357
{
358
        unsigned long result = 0,value;
359
 
360
        if (!base) {
361
                base = 10;
362
                if (*cp == '0') {
363
                        base = 8;
364
                        cp++;
365
                        if ((*cp == 'x') && isxdigit(cp[1])) {
366
                                cp++;
367
                                base = 16;
368
                        }
369
                }
370
        }
371
        while (isxdigit(*cp) &&
372
               (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
373
                result = result*base + value;
374
                cp++;
375
        }
376
        if (endp)
377
                *endp = (char *)cp;
378
        return result;
379
}
380
 
381
 
382
long simple_strtol(const char *cp,char **endp,unsigned int base)
383
{
384
        if(*cp=='-')
385
                return -simple_strtoul(cp+1,endp,base);
386
        return simple_strtoul(cp,endp,base);
387
}
388
 
436 giacomo 389
void dump_stack(void) { }
390
 
391
void panic(const char * fmt, ...) {
392
 
393
  cprintf((char *)(fmt));
394
 
395
}
396
 
397
extern void * malloc(size_t size);
398
 
399
void *__kmalloc(size_t size, int flags) {
400
 
401
  return malloc(size);
402
 
403
}
404
 
405
extern void free(void *);
406
 
407
void kfree(const void *ptr) {
408
 
409
  free((void *)(ptr));
410
 
411
}
412
 
413
unsigned long pci_mem_start = 0x10000000;
414
 
432 giacomo 415
signed long schedule_timeout(signed long timeout) {
416
 
417
  SYS_FLAGS f;
418
  struct timespec t;
419
 
420
  f = ll_fsave();
421
  sti();
422
 
423
  jiffies_to_timespec(timeout, &t);
424
 
425
  nanosleep(&t,NULL);
426
 
427
  ll_frestore(f);
428
 
429
  return 0;
430
 
431
}
436 giacomo 432
 
433
void __const_udelay(unsigned long usecs) {
434
 
435
  SYS_FLAGS f;
436
  struct timespec t;
437
 
438
  f = ll_fsave();
439
  sti();
440
 
441
  t.tv_sec = 0;
442
  t.tv_nsec = usecs * 1000;
443
 
444
  nanosleep(&t,NULL);
445
 
446
  ll_frestore(f);
447
 
448
}
449