[PATCH] kernel/time.c: add missing symbol exports
[linux-2.6] / kernel / resource.c
1 /*
2  *      linux/kernel/resource.c
3  *
4  * Copyright (C) 1999   Linus Torvalds
5  * Copyright (C) 1999   Martin Mares <mj@ucw.cz>
6  *
7  * Arbitrary resource management.
8  */
9
10 #include <linux/module.h>
11 #include <linux/errno.h>
12 #include <linux/ioport.h>
13 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/spinlock.h>
16 #include <linux/fs.h>
17 #include <linux/proc_fs.h>
18 #include <linux/seq_file.h>
19 #include <linux/device.h>
20 #include <asm/io.h>
21
22
23 struct resource ioport_resource = {
24         .name   = "PCI IO",
25         .start  = 0,
26         .end    = IO_SPACE_LIMIT,
27         .flags  = IORESOURCE_IO,
28 };
29 EXPORT_SYMBOL(ioport_resource);
30
31 struct resource iomem_resource = {
32         .name   = "PCI mem",
33         .start  = 0,
34         .end    = -1,
35         .flags  = IORESOURCE_MEM,
36 };
37 EXPORT_SYMBOL(iomem_resource);
38
39 static DEFINE_RWLOCK(resource_lock);
40
41 #ifdef CONFIG_PROC_FS
42
43 enum { MAX_IORES_LEVEL = 5 };
44
45 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
46 {
47         struct resource *p = v;
48         (*pos)++;
49         if (p->child)
50                 return p->child;
51         while (!p->sibling && p->parent)
52                 p = p->parent;
53         return p->sibling;
54 }
55
56 static void *r_start(struct seq_file *m, loff_t *pos)
57         __acquires(resource_lock)
58 {
59         struct resource *p = m->private;
60         loff_t l = 0;
61         read_lock(&resource_lock);
62         for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
63                 ;
64         return p;
65 }
66
67 static void r_stop(struct seq_file *m, void *v)
68         __releases(resource_lock)
69 {
70         read_unlock(&resource_lock);
71 }
72
73 static int r_show(struct seq_file *m, void *v)
74 {
75         struct resource *root = m->private;
76         struct resource *r = v, *p;
77         int width = root->end < 0x10000 ? 4 : 8;
78         int depth;
79
80         for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
81                 if (p->parent == root)
82                         break;
83         seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
84                         depth * 2, "",
85                         width, (unsigned long long) r->start,
86                         width, (unsigned long long) r->end,
87                         r->name ? r->name : "<BAD>");
88         return 0;
89 }
90
91 static const struct seq_operations resource_op = {
92         .start  = r_start,
93         .next   = r_next,
94         .stop   = r_stop,
95         .show   = r_show,
96 };
97
98 static int ioports_open(struct inode *inode, struct file *file)
99 {
100         int res = seq_open(file, &resource_op);
101         if (!res) {
102                 struct seq_file *m = file->private_data;
103                 m->private = &ioport_resource;
104         }
105         return res;
106 }
107
108 static int iomem_open(struct inode *inode, struct file *file)
109 {
110         int res = seq_open(file, &resource_op);
111         if (!res) {
112                 struct seq_file *m = file->private_data;
113                 m->private = &iomem_resource;
114         }
115         return res;
116 }
117
118 static const struct file_operations proc_ioports_operations = {
119         .open           = ioports_open,
120         .read           = seq_read,
121         .llseek         = seq_lseek,
122         .release        = seq_release,
123 };
124
125 static const struct file_operations proc_iomem_operations = {
126         .open           = iomem_open,
127         .read           = seq_read,
128         .llseek         = seq_lseek,
129         .release        = seq_release,
130 };
131
132 static int __init ioresources_init(void)
133 {
134         struct proc_dir_entry *entry;
135
136         entry = create_proc_entry("ioports", 0, NULL);
137         if (entry)
138                 entry->proc_fops = &proc_ioports_operations;
139         entry = create_proc_entry("iomem", 0, NULL);
140         if (entry)
141                 entry->proc_fops = &proc_iomem_operations;
142         return 0;
143 }
144 __initcall(ioresources_init);
145
146 #endif /* CONFIG_PROC_FS */
147
148 /* Return the conflict entry if you can't request it */
149 static struct resource * __request_resource(struct resource *root, struct resource *new)
150 {
151         resource_size_t start = new->start;
152         resource_size_t end = new->end;
153         struct resource *tmp, **p;
154
155         if (end < start)
156                 return root;
157         if (start < root->start)
158                 return root;
159         if (end > root->end)
160                 return root;
161         p = &root->child;
162         for (;;) {
163                 tmp = *p;
164                 if (!tmp || tmp->start > end) {
165                         new->sibling = tmp;
166                         *p = new;
167                         new->parent = root;
168                         return NULL;
169                 }
170                 p = &tmp->sibling;
171                 if (tmp->end < start)
172                         continue;
173                 return tmp;
174         }
175 }
176
177 static int __release_resource(struct resource *old)
178 {
179         struct resource *tmp, **p;
180
181         p = &old->parent->child;
182         for (;;) {
183                 tmp = *p;
184                 if (!tmp)
185                         break;
186                 if (tmp == old) {
187                         *p = tmp->sibling;
188                         old->parent = NULL;
189                         return 0;
190                 }
191                 p = &tmp->sibling;
192         }
193         return -EINVAL;
194 }
195
196 /**
197  * request_resource - request and reserve an I/O or memory resource
198  * @root: root resource descriptor
199  * @new: resource descriptor desired by caller
200  *
201  * Returns 0 for success, negative error code on error.
202  */
203 int request_resource(struct resource *root, struct resource *new)
204 {
205         struct resource *conflict;
206
207         write_lock(&resource_lock);
208         conflict = __request_resource(root, new);
209         write_unlock(&resource_lock);
210         return conflict ? -EBUSY : 0;
211 }
212
213 EXPORT_SYMBOL(request_resource);
214
215 /**
216  * ____request_resource - reserve a resource, with resource conflict returned
217  * @root: root resource descriptor
218  * @new: resource descriptor desired by caller
219  *
220  * Returns:
221  * On success, NULL is returned.
222  * On error, a pointer to the conflicting resource is returned.
223  */
224 struct resource *____request_resource(struct resource *root, struct resource *new)
225 {
226         struct resource *conflict;
227
228         write_lock(&resource_lock);
229         conflict = __request_resource(root, new);
230         write_unlock(&resource_lock);
231         return conflict;
232 }
233
234 EXPORT_SYMBOL(____request_resource);
235
236 /**
237  * release_resource - release a previously reserved resource
238  * @old: resource pointer
239  */
240 int release_resource(struct resource *old)
241 {
242         int retval;
243
244         write_lock(&resource_lock);
245         retval = __release_resource(old);
246         write_unlock(&resource_lock);
247         return retval;
248 }
249
250 EXPORT_SYMBOL(release_resource);
251
252 #ifdef CONFIG_MEMORY_HOTPLUG
253 /*
254  * Finds the lowest memory reosurce exists within [res->start.res->end)
255  * the caller must specify res->start, res->end, res->flags.
256  * If found, returns 0, res is overwritten, if not found, returns -1.
257  */
258 int find_next_system_ram(struct resource *res)
259 {
260         resource_size_t start, end;
261         struct resource *p;
262
263         BUG_ON(!res);
264
265         start = res->start;
266         end = res->end;
267         BUG_ON(start >= end);
268
269         read_lock(&resource_lock);
270         for (p = iomem_resource.child; p ; p = p->sibling) {
271                 /* system ram is just marked as IORESOURCE_MEM */
272                 if (p->flags != res->flags)
273                         continue;
274                 if (p->start > end) {
275                         p = NULL;
276                         break;
277                 }
278                 if ((p->end >= start) && (p->start < end))
279                         break;
280         }
281         read_unlock(&resource_lock);
282         if (!p)
283                 return -1;
284         /* copy data */
285         if (res->start < p->start)
286                 res->start = p->start;
287         if (res->end > p->end)
288                 res->end = p->end;
289         return 0;
290 }
291 #endif
292
293 /*
294  * Find empty slot in the resource tree given range and alignment.
295  */
296 static int find_resource(struct resource *root, struct resource *new,
297                          resource_size_t size, resource_size_t min,
298                          resource_size_t max, resource_size_t align,
299                          void (*alignf)(void *, struct resource *,
300                                         resource_size_t, resource_size_t),
301                          void *alignf_data)
302 {
303         struct resource *this = root->child;
304
305         new->start = root->start;
306         /*
307          * Skip past an allocated resource that starts at 0, since the assignment
308          * of this->start - 1 to new->end below would cause an underflow.
309          */
310         if (this && this->start == 0) {
311                 new->start = this->end + 1;
312                 this = this->sibling;
313         }
314         for(;;) {
315                 if (this)
316                         new->end = this->start - 1;
317                 else
318                         new->end = root->end;
319                 if (new->start < min)
320                         new->start = min;
321                 if (new->end > max)
322                         new->end = max;
323                 new->start = ALIGN(new->start, align);
324                 if (alignf)
325                         alignf(alignf_data, new, size, align);
326                 if (new->start < new->end && new->end - new->start >= size - 1) {
327                         new->end = new->start + size - 1;
328                         return 0;
329                 }
330                 if (!this)
331                         break;
332                 new->start = this->end + 1;
333                 this = this->sibling;
334         }
335         return -EBUSY;
336 }
337
338 /**
339  * allocate_resource - allocate empty slot in the resource tree given range & alignment
340  * @root: root resource descriptor
341  * @new: resource descriptor desired by caller
342  * @size: requested resource region size
343  * @min: minimum size to allocate
344  * @max: maximum size to allocate
345  * @align: alignment requested, in bytes
346  * @alignf: alignment function, optional, called if not NULL
347  * @alignf_data: arbitrary data to pass to the @alignf function
348  */
349 int allocate_resource(struct resource *root, struct resource *new,
350                       resource_size_t size, resource_size_t min,
351                       resource_size_t max, resource_size_t align,
352                       void (*alignf)(void *, struct resource *,
353                                      resource_size_t, resource_size_t),
354                       void *alignf_data)
355 {
356         int err;
357
358         write_lock(&resource_lock);
359         err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
360         if (err >= 0 && __request_resource(root, new))
361                 err = -EBUSY;
362         write_unlock(&resource_lock);
363         return err;
364 }
365
366 EXPORT_SYMBOL(allocate_resource);
367
368 /**
369  * insert_resource - Inserts a resource in the resource tree
370  * @parent: parent of the new resource
371  * @new: new resource to insert
372  *
373  * Returns 0 on success, -EBUSY if the resource can't be inserted.
374  *
375  * This function is equivalent to request_resource when no conflict
376  * happens. If a conflict happens, and the conflicting resources
377  * entirely fit within the range of the new resource, then the new
378  * resource is inserted and the conflicting resources become children of
379  * the new resource.
380  */
381 int insert_resource(struct resource *parent, struct resource *new)
382 {
383         int result;
384         struct resource *first, *next;
385
386         write_lock(&resource_lock);
387
388         for (;; parent = first) {
389                 result = 0;
390                 first = __request_resource(parent, new);
391                 if (!first)
392                         goto out;
393
394                 result = -EBUSY;
395                 if (first == parent)
396                         goto out;
397
398                 if ((first->start > new->start) || (first->end < new->end))
399                         break;
400                 if ((first->start == new->start) && (first->end == new->end))
401                         break;
402         }
403
404         for (next = first; ; next = next->sibling) {
405                 /* Partial overlap? Bad, and unfixable */
406                 if (next->start < new->start || next->end > new->end)
407                         goto out;
408                 if (!next->sibling)
409                         break;
410                 if (next->sibling->start > new->end)
411                         break;
412         }
413
414         result = 0;
415
416         new->parent = parent;
417         new->sibling = next->sibling;
418         new->child = first;
419
420         next->sibling = NULL;
421         for (next = first; next; next = next->sibling)
422                 next->parent = new;
423
424         if (parent->child == first) {
425                 parent->child = new;
426         } else {
427                 next = parent->child;
428                 while (next->sibling != first)
429                         next = next->sibling;
430                 next->sibling = new;
431         }
432
433  out:
434         write_unlock(&resource_lock);
435         return result;
436 }
437
438 /**
439  * adjust_resource - modify a resource's start and size
440  * @res: resource to modify
441  * @start: new start value
442  * @size: new size
443  *
444  * Given an existing resource, change its start and size to match the
445  * arguments.  Returns 0 on success, -EBUSY if it can't fit.
446  * Existing children of the resource are assumed to be immutable.
447  */
448 int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
449 {
450         struct resource *tmp, *parent = res->parent;
451         resource_size_t end = start + size - 1;
452         int result = -EBUSY;
453
454         write_lock(&resource_lock);
455
456         if ((start < parent->start) || (end > parent->end))
457                 goto out;
458
459         for (tmp = res->child; tmp; tmp = tmp->sibling) {
460                 if ((tmp->start < start) || (tmp->end > end))
461                         goto out;
462         }
463
464         if (res->sibling && (res->sibling->start <= end))
465                 goto out;
466
467         tmp = parent->child;
468         if (tmp != res) {
469                 while (tmp->sibling != res)
470                         tmp = tmp->sibling;
471                 if (start <= tmp->end)
472                         goto out;
473         }
474
475         res->start = start;
476         res->end = end;
477         result = 0;
478
479  out:
480         write_unlock(&resource_lock);
481         return result;
482 }
483
484 EXPORT_SYMBOL(adjust_resource);
485
486 /*
487  * This is compatibility stuff for IO resources.
488  *
489  * Note how this, unlike the above, knows about
490  * the IO flag meanings (busy etc).
491  *
492  * request_region creates a new busy region.
493  *
494  * check_region returns non-zero if the area is already busy.
495  *
496  * release_region releases a matching busy region.
497  */
498
499 /**
500  * __request_region - create a new busy resource region
501  * @parent: parent resource descriptor
502  * @start: resource start address
503  * @n: resource region size
504  * @name: reserving caller's ID string
505  */
506 struct resource * __request_region(struct resource *parent,
507                                    resource_size_t start, resource_size_t n,
508                                    const char *name)
509 {
510         struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
511
512         if (res) {
513                 res->name = name;
514                 res->start = start;
515                 res->end = start + n - 1;
516                 res->flags = IORESOURCE_BUSY;
517
518                 write_lock(&resource_lock);
519
520                 for (;;) {
521                         struct resource *conflict;
522
523                         conflict = __request_resource(parent, res);
524                         if (!conflict)
525                                 break;
526                         if (conflict != parent) {
527                                 parent = conflict;
528                                 if (!(conflict->flags & IORESOURCE_BUSY))
529                                         continue;
530                         }
531
532                         /* Uhhuh, that didn't work out.. */
533                         kfree(res);
534                         res = NULL;
535                         break;
536                 }
537                 write_unlock(&resource_lock);
538         }
539         return res;
540 }
541 EXPORT_SYMBOL(__request_region);
542
543 /**
544  * __check_region - check if a resource region is busy or free
545  * @parent: parent resource descriptor
546  * @start: resource start address
547  * @n: resource region size
548  *
549  * Returns 0 if the region is free at the moment it is checked,
550  * returns %-EBUSY if the region is busy.
551  *
552  * NOTE:
553  * This function is deprecated because its use is racy.
554  * Even if it returns 0, a subsequent call to request_region()
555  * may fail because another driver etc. just allocated the region.
556  * Do NOT use it.  It will be removed from the kernel.
557  */
558 int __check_region(struct resource *parent, resource_size_t start,
559                         resource_size_t n)
560 {
561         struct resource * res;
562
563         res = __request_region(parent, start, n, "check-region");
564         if (!res)
565                 return -EBUSY;
566
567         release_resource(res);
568         kfree(res);
569         return 0;
570 }
571 EXPORT_SYMBOL(__check_region);
572
573 /**
574  * __release_region - release a previously reserved resource region
575  * @parent: parent resource descriptor
576  * @start: resource start address
577  * @n: resource region size
578  *
579  * The described resource region must match a currently busy region.
580  */
581 void __release_region(struct resource *parent, resource_size_t start,
582                         resource_size_t n)
583 {
584         struct resource **p;
585         resource_size_t end;
586
587         p = &parent->child;
588         end = start + n - 1;
589
590         write_lock(&resource_lock);
591
592         for (;;) {
593                 struct resource *res = *p;
594
595                 if (!res)
596                         break;
597                 if (res->start <= start && res->end >= end) {
598                         if (!(res->flags & IORESOURCE_BUSY)) {
599                                 p = &res->child;
600                                 continue;
601                         }
602                         if (res->start != start || res->end != end)
603                                 break;
604                         *p = res->sibling;
605                         write_unlock(&resource_lock);
606                         kfree(res);
607                         return;
608                 }
609                 p = &res->sibling;
610         }
611
612         write_unlock(&resource_lock);
613
614         printk(KERN_WARNING "Trying to free nonexistent resource "
615                 "<%016llx-%016llx>\n", (unsigned long long)start,
616                 (unsigned long long)end);
617 }
618 EXPORT_SYMBOL(__release_region);
619
620 /*
621  * Managed region resource
622  */
623 struct region_devres {
624         struct resource *parent;
625         resource_size_t start;
626         resource_size_t n;
627 };
628
629 static void devm_region_release(struct device *dev, void *res)
630 {
631         struct region_devres *this = res;
632
633         __release_region(this->parent, this->start, this->n);
634 }
635
636 static int devm_region_match(struct device *dev, void *res, void *match_data)
637 {
638         struct region_devres *this = res, *match = match_data;
639
640         return this->parent == match->parent &&
641                 this->start == match->start && this->n == match->n;
642 }
643
644 struct resource * __devm_request_region(struct device *dev,
645                                 struct resource *parent, resource_size_t start,
646                                 resource_size_t n, const char *name)
647 {
648         struct region_devres *dr = NULL;
649         struct resource *res;
650
651         dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
652                           GFP_KERNEL);
653         if (!dr)
654                 return NULL;
655
656         dr->parent = parent;
657         dr->start = start;
658         dr->n = n;
659
660         res = __request_region(parent, start, n, name);
661         if (res)
662                 devres_add(dev, dr);
663         else
664                 devres_free(dr);
665
666         return res;
667 }
668 EXPORT_SYMBOL(__devm_request_region);
669
670 void __devm_release_region(struct device *dev, struct resource *parent,
671                            resource_size_t start, resource_size_t n)
672 {
673         struct region_devres match_data = { parent, start, n };
674
675         __release_region(parent, start, n);
676         WARN_ON(devres_destroy(dev, devm_region_release, devm_region_match,
677                                &match_data));
678 }
679 EXPORT_SYMBOL(__devm_release_region);
680
681 /*
682  * Called from init/main.c to reserve IO ports.
683  */
684 #define MAXRESERVE 4
685 static int __init reserve_setup(char *str)
686 {
687         static int reserved;
688         static struct resource reserve[MAXRESERVE];
689
690         for (;;) {
691                 int io_start, io_num;
692                 int x = reserved;
693
694                 if (get_option (&str, &io_start) != 2)
695                         break;
696                 if (get_option (&str, &io_num)   == 0)
697                         break;
698                 if (x < MAXRESERVE) {
699                         struct resource *res = reserve + x;
700                         res->name = "reserved";
701                         res->start = io_start;
702                         res->end = io_start + io_num - 1;
703                         res->flags = IORESOURCE_BUSY;
704                         res->child = NULL;
705                         if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
706                                 reserved = x+1;
707                 }
708         }
709         return 1;
710 }
711
712 __setup("reserve=", reserve_setup);