00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <linux/module.h>
00011 #include <linux/errno.h>
00012 #include <linux/ioport.h>
00013 #include <linux/init.h>
00014 #include <linux/slab.h>
00015 #include <linux/spinlock.h>
00016 #include <linux/fs.h>
00017 #include <linux/proc_fs.h>
00018 #include <linux/seq_file.h>
00019 #include <linux/device.h>
00020 #include <linux/pfn.h>
00021 #include <asm/io.h>
00022
00023
00024 struct resource ioport_resource = {
00025 .name = "PCI IO",
00026 .start = 0,
00027 .end = IO_SPACE_LIMIT,
00028 .flags = IORESOURCE_IO,
00029 };
00030 EXPORT_SYMBOL(ioport_resource);
00031
00032 struct resource iomem_resource = {
00033 .name = "PCI mem",
00034 .start = 0,
00035 .end = -1,
00036 .flags = IORESOURCE_MEM,
00037 };
00038 EXPORT_SYMBOL(iomem_resource);
00039
00040 static DEFINE_RWLOCK(resource_lock);
00041
00042 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
00043 {
00044 struct resource *p = v;
00045 (*pos)++;
00046 if (p->child)
00047 return p->child;
00048 while (!p->sibling && p->parent)
00049 p = p->parent;
00050 return p->sibling;
00051 }
00052
00053 #ifdef CONFIG_PROC_FS
00054
00055 enum { MAX_IORES_LEVEL = 5 };
00056
00057 static void *r_start(struct seq_file *m, loff_t *pos)
00058 __acquires(resource_lock)
00059 {
00060 struct resource *p = m->private;
00061 loff_t l = 0;
00062 read_lock(&resource_lock);
00063 for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
00064 ;
00065 return p;
00066 }
00067
00068 static void r_stop(struct seq_file *m, void *v)
00069 __releases(resource_lock)
00070 {
00071 read_unlock(&resource_lock);
00072 }
00073
00074 static int r_show(struct seq_file *m, void *v)
00075 {
00076 struct resource *root = m->private;
00077 struct resource *r = v, *p;
00078 int width = root->end < 0x10000 ? 4 : 8;
00079 int depth;
00080
00081 for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
00082 if (p->parent == root)
00083 break;
00084 seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
00085 depth * 2, "",
00086 width, (unsigned long long) r->start,
00087 width, (unsigned long long) r->end,
00088 r->name ? r->name : "<BAD>");
00089 return 0;
00090 }
00091
00092 static const struct seq_operations resource_op = {
00093 .start = r_start,
00094 .next = r_next,
00095 .stop = r_stop,
00096 .show = r_show,
00097 };
00098
00099 static int ioports_open(struct inode *inode, struct file *file)
00100 {
00101 int res = seq_open(file, &resource_op);
00102 if (!res) {
00103 struct seq_file *m = file->private_data;
00104 m->private = &ioport_resource;
00105 }
00106 return res;
00107 }
00108
00109 static int iomem_open(struct inode *inode, struct file *file)
00110 {
00111 int res = seq_open(file, &resource_op);
00112 if (!res) {
00113 struct seq_file *m = file->private_data;
00114 m->private = &iomem_resource;
00115 }
00116 return res;
00117 }
00118
00119 static const struct file_operations proc_ioports_operations = {
00120 .open = ioports_open,
00121 .read = seq_read,
00122 .llseek = seq_lseek,
00123 .release = seq_release,
00124 };
00125
00126 static const struct file_operations proc_iomem_operations = {
00127 .open = iomem_open,
00128 .read = seq_read,
00129 .llseek = seq_lseek,
00130 .release = seq_release,
00131 };
00132
00133 static int __init ioresources_init(void)
00134 {
00135 proc_create("ioports", 0, NULL, &proc_ioports_operations);
00136 proc_create("iomem", 0, NULL, &proc_iomem_operations);
00137 return 0;
00138 }
00139 __initcall(ioresources_init);
00140
00141 #endif
00142
00143
00144 static struct resource * __request_resource(struct resource *root, struct resource *new)
00145 {
00146 resource_size_t start = new->start;
00147 resource_size_t end = new->end;
00148 struct resource *tmp, **p;
00149
00150 if (end < start)
00151 return root;
00152 if (start < root->start)
00153 return root;
00154 if (end > root->end)
00155 return root;
00156 p = &root->child;
00157 for (;;) {
00158 tmp = *p;
00159 if (!tmp || tmp->start > end) {
00160 new->sibling = tmp;
00161 *p = new;
00162 new->parent = root;
00163 return NULL;
00164 }
00165 p = &tmp->sibling;
00166 if (tmp->end < start)
00167 continue;
00168 return tmp;
00169 }
00170 }
00171
00172 static int __release_resource(struct resource *old)
00173 {
00174 struct resource *tmp, **p;
00175
00176 p = &old->parent->child;
00177 for (;;) {
00178 tmp = *p;
00179 if (!tmp)
00180 break;
00181 if (tmp == old) {
00182 *p = tmp->sibling;
00183 old->parent = NULL;
00184 return 0;
00185 }
00186 p = &tmp->sibling;
00187 }
00188 return -EINVAL;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 int request_resource(struct resource *root, struct resource *new)
00199 {
00200 struct resource *conflict;
00201
00202 write_lock(&resource_lock);
00203 conflict = __request_resource(root, new);
00204 write_unlock(&resource_lock);
00205 return conflict ? -EBUSY : 0;
00206 }
00207
00208 EXPORT_SYMBOL(request_resource);
00209
00210
00211
00212
00213
00214 int release_resource(struct resource *old)
00215 {
00216 int retval;
00217
00218 write_lock(&resource_lock);
00219 retval = __release_resource(old);
00220 write_unlock(&resource_lock);
00221 return retval;
00222 }
00223
00224 EXPORT_SYMBOL(release_resource);
00225
00226 #if defined(CONFIG_MEMORY_HOTPLUG) && !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
00227
00228
00229
00230
00231
00232 static int find_next_system_ram(struct resource *res)
00233 {
00234 resource_size_t start, end;
00235 struct resource *p;
00236
00237 BUG_ON(!res);
00238
00239 start = res->start;
00240 end = res->end;
00241 BUG_ON(start >= end);
00242
00243 read_lock(&resource_lock);
00244 for (p = iomem_resource.child; p ; p = p->sibling) {
00245
00246 if (p->flags != res->flags)
00247 continue;
00248 if (p->start > end) {
00249 p = NULL;
00250 break;
00251 }
00252 if ((p->end >= start) && (p->start < end))
00253 break;
00254 }
00255 read_unlock(&resource_lock);
00256 if (!p)
00257 return -1;
00258
00259 if (res->start < p->start)
00260 res->start = p->start;
00261 if (res->end > p->end)
00262 res->end = p->end;
00263 return 0;
00264 }
00265 int
00266 walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
00267 int (*func)(unsigned long, unsigned long, void *))
00268 {
00269 struct resource res;
00270 unsigned long pfn, len;
00271 u64 orig_end;
00272 int ret = -1;
00273 res.start = (u64) start_pfn << PAGE_SHIFT;
00274 res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
00275 res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
00276 orig_end = res.end;
00277 while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
00278 pfn = (unsigned long)(res.start >> PAGE_SHIFT);
00279 len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT);
00280 ret = (*func)(pfn, len, arg);
00281 if (ret)
00282 break;
00283 res.start = res.end + 1;
00284 res.end = orig_end;
00285 }
00286 return ret;
00287 }
00288
00289 #endif
00290
00291
00292
00293
00294 static int find_resource(struct resource *root, struct resource *new,
00295 resource_size_t size, resource_size_t min,
00296 resource_size_t max, resource_size_t align,
00297 void (*alignf)(void *, struct resource *,
00298 resource_size_t, resource_size_t),
00299 void *alignf_data)
00300 {
00301 struct resource *this = root->child;
00302
00303 new->start = root->start;
00304
00305
00306
00307
00308 if (this && this->start == 0) {
00309 new->start = this->end + 1;
00310 this = this->sibling;
00311 }
00312 for(;;) {
00313 if (this)
00314 new->end = this->start - 1;
00315 else
00316 new->end = root->end;
00317 if (new->start < min)
00318 new->start = min;
00319 if (new->end > max)
00320 new->end = max;
00321 new->start = ALIGN(new->start, align);
00322 if (alignf)
00323 alignf(alignf_data, new, size, align);
00324 if (new->start < new->end && new->end - new->start >= size - 1) {
00325 new->end = new->start + size - 1;
00326 return 0;
00327 }
00328 if (!this)
00329 break;
00330 new->start = this->end + 1;
00331 this = this->sibling;
00332 }
00333 return -EBUSY;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 int allocate_resource(struct resource *root, struct resource *new,
00348 resource_size_t size, resource_size_t min,
00349 resource_size_t max, resource_size_t align,
00350 void (*alignf)(void *, struct resource *,
00351 resource_size_t, resource_size_t),
00352 void *alignf_data)
00353 {
00354 int err;
00355
00356 write_lock(&resource_lock);
00357 err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
00358 if (err >= 0 && __request_resource(root, new))
00359 err = -EBUSY;
00360 write_unlock(&resource_lock);
00361 return err;
00362 }
00363
00364 EXPORT_SYMBOL(allocate_resource);
00365
00366
00367
00368
00369
00370 static struct resource * __insert_resource(struct resource *parent, struct resource *new)
00371 {
00372 struct resource *first, *next;
00373
00374 for (;; parent = first) {
00375 first = __request_resource(parent, new);
00376 if (!first)
00377 return first;
00378
00379 if (first == parent)
00380 return first;
00381
00382 if ((first->start > new->start) || (first->end < new->end))
00383 break;
00384 if ((first->start == new->start) && (first->end == new->end))
00385 break;
00386 }
00387
00388 for (next = first; ; next = next->sibling) {
00389
00390 if (next->start < new->start || next->end > new->end)
00391 return next;
00392 if (!next->sibling)
00393 break;
00394 if (next->sibling->start > new->end)
00395 break;
00396 }
00397
00398 new->parent = parent;
00399 new->sibling = next->sibling;
00400 new->child = first;
00401
00402 next->sibling = NULL;
00403 for (next = first; next; next = next->sibling)
00404 next->parent = new;
00405
00406 if (parent->child == first) {
00407 parent->child = new;
00408 } else {
00409 next = parent->child;
00410 while (next->sibling != first)
00411 next = next->sibling;
00412 next->sibling = new;
00413 }
00414 return NULL;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 int insert_resource(struct resource *parent, struct resource *new)
00431 {
00432 struct resource *conflict;
00433
00434 write_lock(&resource_lock);
00435 conflict = __insert_resource(parent, new);
00436 write_unlock(&resource_lock);
00437 return conflict ? -EBUSY : 0;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 void insert_resource_expand_to_fit(struct resource *root, struct resource *new)
00449 {
00450 if (new->parent)
00451 return;
00452
00453 write_lock(&resource_lock);
00454 for (;;) {
00455 struct resource *conflict;
00456
00457 conflict = __insert_resource(root, new);
00458 if (!conflict)
00459 break;
00460 if (conflict == root)
00461 break;
00462
00463
00464 if (conflict->start < new->start)
00465 new->start = conflict->start;
00466 if (conflict->end > new->end)
00467 new->end = conflict->end;
00468
00469 printk("Expanded resource %s due to conflict with %s\n", new->name, conflict->name);
00470 }
00471 write_unlock(&resource_lock);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
00485 {
00486 struct resource *tmp, *parent = res->parent;
00487 resource_size_t end = start + size - 1;
00488 int result = -EBUSY;
00489
00490 write_lock(&resource_lock);
00491
00492 if ((start < parent->start) || (end > parent->end))
00493 goto out;
00494
00495 for (tmp = res->child; tmp; tmp = tmp->sibling) {
00496 if ((tmp->start < start) || (tmp->end > end))
00497 goto out;
00498 }
00499
00500 if (res->sibling && (res->sibling->start <= end))
00501 goto out;
00502
00503 tmp = parent->child;
00504 if (tmp != res) {
00505 while (tmp->sibling != res)
00506 tmp = tmp->sibling;
00507 if (start <= tmp->end)
00508 goto out;
00509 }
00510
00511 res->start = start;
00512 res->end = end;
00513 result = 0;
00514
00515 out:
00516 write_unlock(&resource_lock);
00517 return result;
00518 }
00519
00520 static void __init __reserve_region_with_split(struct resource *root,
00521 resource_size_t start, resource_size_t end,
00522 const char *name)
00523 {
00524 struct resource *parent = root;
00525 struct resource *conflict;
00526 struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC);
00527
00528 if (!res)
00529 return;
00530
00531 res->name = name;
00532 res->start = start;
00533 res->end = end;
00534 res->flags = IORESOURCE_BUSY;
00535
00536 for (;;) {
00537 conflict = __request_resource(parent, res);
00538 if (!conflict)
00539 break;
00540 if (conflict != parent) {
00541 parent = conflict;
00542 if (!(conflict->flags & IORESOURCE_BUSY))
00543 continue;
00544 }
00545
00546
00547 kfree(res);
00548 res = NULL;
00549 break;
00550 }
00551
00552 if (!res) {
00553
00554
00555
00556 if (conflict->start <= start && conflict->end >= end)
00557 return;
00558
00559 if (conflict->start > start)
00560 __reserve_region_with_split(root, start, conflict->start-1, name);
00561 if (!(conflict->flags & IORESOURCE_BUSY)) {
00562 resource_size_t common_start, common_end;
00563
00564 common_start = max(conflict->start, start);
00565 common_end = min(conflict->end, end);
00566 if (common_start < common_end)
00567 __reserve_region_with_split(root, common_start, common_end, name);
00568 }
00569 if (conflict->end < end)
00570 __reserve_region_with_split(root, conflict->end+1, end, name);
00571 }
00572
00573 }
00574
00575 void __init reserve_region_with_split(struct resource *root,
00576 resource_size_t start, resource_size_t end,
00577 const char *name)
00578 {
00579 write_lock(&resource_lock);
00580 __reserve_region_with_split(root, start, end, name);
00581 write_unlock(&resource_lock);
00582 }
00583
00584 EXPORT_SYMBOL(adjust_resource);
00585
00586
00587
00588
00589
00590
00591
00592 resource_size_t resource_alignment(struct resource *res)
00593 {
00594 switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) {
00595 case IORESOURCE_SIZEALIGN:
00596 return resource_size(res);
00597 case IORESOURCE_STARTALIGN:
00598 return res->start;
00599 default:
00600 return 0;
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 #ifndef DDE_LINUX
00618
00619
00620
00621
00622
00623
00624
00625
00626 struct resource * __request_region(struct resource *parent,
00627 resource_size_t start, resource_size_t n,
00628 const char *name, int flags)
00629 {
00630 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
00631
00632 if (!res)
00633 return NULL;
00634
00635 res->name = name;
00636 res->start = start;
00637 res->end = start + n - 1;
00638 res->flags = IORESOURCE_BUSY;
00639 res->flags |= flags;
00640
00641 write_lock(&resource_lock);
00642
00643 for (;;) {
00644 struct resource *conflict;
00645
00646 conflict = __request_resource(parent, res);
00647 if (!conflict)
00648 break;
00649 if (conflict != parent) {
00650 parent = conflict;
00651 if (!(conflict->flags & IORESOURCE_BUSY))
00652 continue;
00653 }
00654
00655
00656 kfree(res);
00657 res = NULL;
00658 break;
00659 }
00660 write_unlock(&resource_lock);
00661 return res;
00662 }
00663 EXPORT_SYMBOL(__request_region);
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 int __check_region(struct resource *parent, resource_size_t start,
00681 resource_size_t n)
00682 {
00683 struct resource * res;
00684
00685 res = __request_region(parent, start, n, "check-region", 0);
00686 if (!res)
00687 return -EBUSY;
00688
00689 release_resource(res);
00690 kfree(res);
00691 return 0;
00692 }
00693 EXPORT_SYMBOL(__check_region);
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 void __release_region(struct resource *parent, resource_size_t start,
00704 resource_size_t n)
00705 {
00706 struct resource **p;
00707 resource_size_t end;
00708
00709 p = &parent->child;
00710 end = start + n - 1;
00711
00712 write_lock(&resource_lock);
00713
00714 for (;;) {
00715 struct resource *res = *p;
00716
00717 if (!res)
00718 break;
00719 if (res->start <= start && res->end >= end) {
00720 if (!(res->flags & IORESOURCE_BUSY)) {
00721 p = &res->child;
00722 continue;
00723 }
00724 if (res->start != start || res->end != end)
00725 break;
00726 *p = res->sibling;
00727 write_unlock(&resource_lock);
00728 kfree(res);
00729 return;
00730 }
00731 p = &res->sibling;
00732 }
00733
00734 write_unlock(&resource_lock);
00735
00736 printk(KERN_WARNING "Trying to free nonexistent resource "
00737 "<%016llx-%016llx>\n", (unsigned long long)start,
00738 (unsigned long long)end);
00739 }
00740 EXPORT_SYMBOL(__release_region);
00741 #endif
00742
00743
00744
00745
00746 struct region_devres {
00747 struct resource *parent;
00748 resource_size_t start;
00749 resource_size_t n;
00750 };
00751
00752 static void devm_region_release(struct device *dev, void *res)
00753 {
00754 struct region_devres *this = res;
00755
00756 __release_region(this->parent, this->start, this->n);
00757 }
00758
00759 static int devm_region_match(struct device *dev, void *res, void *match_data)
00760 {
00761 struct region_devres *this = res, *match = match_data;
00762
00763 return this->parent == match->parent &&
00764 this->start == match->start && this->n == match->n;
00765 }
00766
00767 struct resource * __devm_request_region(struct device *dev,
00768 struct resource *parent, resource_size_t start,
00769 resource_size_t n, const char *name)
00770 {
00771 struct region_devres *dr = NULL;
00772 struct resource *res;
00773
00774 dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
00775 GFP_KERNEL);
00776 if (!dr)
00777 return NULL;
00778
00779 dr->parent = parent;
00780 dr->start = start;
00781 dr->n = n;
00782
00783 res = __request_region(parent, start, n, name, 0);
00784 if (res)
00785 devres_add(dev, dr);
00786 else
00787 devres_free(dr);
00788
00789 return res;
00790 }
00791 EXPORT_SYMBOL(__devm_request_region);
00792
00793 void __devm_release_region(struct device *dev, struct resource *parent,
00794 resource_size_t start, resource_size_t n)
00795 {
00796 struct region_devres match_data = { parent, start, n };
00797
00798 __release_region(parent, start, n);
00799 WARN_ON(devres_destroy(dev, devm_region_release, devm_region_match,
00800 &match_data));
00801 }
00802 EXPORT_SYMBOL(__devm_release_region);
00803
00804
00805
00806
00807 #define MAXRESERVE 4
00808 static int __init reserve_setup(char *str)
00809 {
00810 static int reserved;
00811 static struct resource reserve[MAXRESERVE];
00812
00813 for (;;) {
00814 int io_start, io_num;
00815 int x = reserved;
00816
00817 if (get_option (&str, &io_start) != 2)
00818 break;
00819 if (get_option (&str, &io_num) == 0)
00820 break;
00821 if (x < MAXRESERVE) {
00822 struct resource *res = reserve + x;
00823 res->name = "reserved";
00824 res->start = io_start;
00825 res->end = io_start + io_num - 1;
00826 res->flags = IORESOURCE_BUSY;
00827 res->child = NULL;
00828 if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
00829 reserved = x+1;
00830 }
00831 }
00832 return 1;
00833 }
00834
00835 __setup("reserve=", reserve_setup);
00836
00837
00838
00839
00840
00841 int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
00842 {
00843 struct resource *p = &iomem_resource;
00844 int err = 0;
00845 loff_t l;
00846
00847 read_lock(&resource_lock);
00848 for (p = p->child; p ; p = r_next(NULL, p, &l)) {
00849
00850
00851
00852
00853 if (p->start >= addr + size)
00854 continue;
00855 if (p->end < addr)
00856 continue;
00857 if (PFN_DOWN(p->start) <= PFN_DOWN(addr) &&
00858 PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1))
00859 continue;
00860
00861
00862
00863
00864
00865
00866 if (p->flags & IORESOURCE_BUSY)
00867 continue;
00868
00869 printk(KERN_WARNING "resource map sanity check conflict: "
00870 "0x%llx 0x%llx 0x%llx 0x%llx %s\n",
00871 (unsigned long long)addr,
00872 (unsigned long long)(addr + size - 1),
00873 (unsigned long long)p->start,
00874 (unsigned long long)p->end,
00875 p->name);
00876 err = -1;
00877 break;
00878 }
00879 read_unlock(&resource_lock);
00880
00881 return err;
00882 }
00883
00884 #ifdef CONFIG_STRICT_DEVMEM
00885 static int strict_iomem_checks = 1;
00886 #else
00887 static int strict_iomem_checks;
00888 #endif
00889
00890
00891
00892
00893
00894 int iomem_is_exclusive(u64 addr)
00895 {
00896 struct resource *p = &iomem_resource;
00897 int err = 0;
00898 loff_t l;
00899 int size = PAGE_SIZE;
00900
00901 if (!strict_iomem_checks)
00902 return 0;
00903
00904 addr = addr & PAGE_MASK;
00905
00906 read_lock(&resource_lock);
00907 for (p = p->child; p ; p = r_next(NULL, p, &l)) {
00908
00909
00910
00911
00912 if (p->start >= addr + size)
00913 break;
00914 if (p->end < addr)
00915 continue;
00916 if (p->flags & IORESOURCE_BUSY &&
00917 p->flags & IORESOURCE_EXCLUSIVE) {
00918 err = 1;
00919 break;
00920 }
00921 }
00922 read_unlock(&resource_lock);
00923
00924 return err;
00925 }
00926
00927 static int __init strict_iomem(char *str)
00928 {
00929 if (strstr(str, "relaxed"))
00930 strict_iomem_checks = 0;
00931 if (strstr(str, "strict"))
00932 strict_iomem_checks = 1;
00933 return 1;
00934 }
00935
00936 __setup("iomem=", strict_iomem);