Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1
x86/PCI: for host bridge address space collisions, show conflicting resource
frv/PCI: remove redundant warnings
x86/PCI: remove redundant warnings
PCI: don't say we claimed a resource if we failed
PCI quirk: Disable MSI on VIA K8T890 systems
PCI quirk: RS780/RS880: work around missing MSI initialization
PCI quirk: only apply CX700 PCI bus parking quirk if external VT6212L is present
PCI: complain about devices that seem to be broken
PCI: print resources consistently with %pR
PCI: make disabled window printk style match the enabled ones
PCI: break out primary/secondary/subordinate for readability
PCI: for address space collisions, show conflicting resource
resources: add interfaces that return conflict information
PCI: cleanup error return for pcix get and set mmrbc functions
PCI: fix access of PCI_X_CMD by pcix get and set mmrbc functions
PCI: kill off pci_register_set_vga_state() symbol export.
PCI: fix return value from pcix_get_max_mmrbc()

+184 -97
+1 -3
arch/frv/mb93090-mb00/pci-frv.c
··· 94 94 r = &dev->resource[idx]; 95 95 if (!r->start) 96 96 continue; 97 - if (pci_claim_resource(dev, idx) < 0) 98 - printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); 97 + pci_claim_resource(dev, idx); 99 98 } 100 99 } 101 100 pcibios_allocate_bus_resources(&bus->children); ··· 124 125 DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", 125 126 r->start, r->end, r->flags, disabled, pass); 126 127 if (pci_claim_resource(dev, idx) < 0) { 127 - printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); 128 128 /* We'll assign a new address later */ 129 129 r->end -= r->start; 130 130 r->start = 0;
+18 -4
arch/x86/pci/acpi.c
··· 122 122 struct acpi_resource_address64 addr; 123 123 acpi_status status; 124 124 unsigned long flags; 125 - struct resource *root; 126 - u64 start, end; 125 + struct resource *root, *conflict; 126 + u64 start, end, max_len; 127 127 128 128 status = resource_to_addr(acpi_res, &addr); 129 129 if (!ACPI_SUCCESS(status)) ··· 139 139 flags = IORESOURCE_IO; 140 140 } else 141 141 return AE_OK; 142 + 143 + max_len = addr.maximum - addr.minimum + 1; 144 + if (addr.address_length > max_len) { 145 + dev_printk(KERN_DEBUG, &info->bridge->dev, 146 + "host bridge window length %#llx doesn't fit in " 147 + "%#llx-%#llx, trimming\n", 148 + (unsigned long long) addr.address_length, 149 + (unsigned long long) addr.minimum, 150 + (unsigned long long) addr.maximum); 151 + addr.address_length = max_len; 152 + } 142 153 143 154 start = addr.minimum + addr.translation_offset; 144 155 end = start + addr.address_length - 1; ··· 168 157 return AE_OK; 169 158 } 170 159 171 - if (insert_resource(root, res)) { 160 + conflict = insert_resource_conflict(root, res); 161 + if (conflict) { 172 162 dev_err(&info->bridge->dev, 173 - "can't allocate host bridge window %pR\n", res); 163 + "address space collision: host bridge window %pR " 164 + "conflicts with %s %pR\n", 165 + res, conflict->name, conflict); 174 166 } else { 175 167 pci_bus_add_resource(info->bus, res, 0); 176 168 info->res_num++;
-5
arch/x86/pci/i386.c
··· 127 127 continue; 128 128 if (!r->start || 129 129 pci_claim_resource(dev, idx) < 0) { 130 - dev_info(&dev->dev, 131 - "can't reserve window %pR\n", 132 - r); 133 130 /* 134 131 * Something is wrong with the region. 135 132 * Invalidate the resource to prevent ··· 178 181 "BAR %d: reserving %pr (d=%d, p=%d)\n", 179 182 idx, r, disabled, pass); 180 183 if (pci_claim_resource(dev, idx) < 0) { 181 - dev_info(&dev->dev, 182 - "can't reserve %pR\n", r); 183 184 /* We'll assign a new address later */ 184 185 r->end -= r->start; 185 186 r->start = 0;
+1 -7
drivers/gpu/drm/radeon/radeon_irq_kms.c
··· 116 116 } 117 117 /* enable msi */ 118 118 rdev->msi_enabled = 0; 119 - /* MSIs don't seem to work on my rs780; 120 - * not sure about rs880 or other rs780s. 121 - * Needs more investigation. 122 - */ 123 - if ((rdev->family >= CHIP_RV380) && 124 - (rdev->family != CHIP_RS780) && 125 - (rdev->family != CHIP_RS880)) { 119 + if (rdev->family >= CHIP_RV380) { 126 120 int ret = pci_enable_msi(rdev->pdev); 127 121 if (!ret) { 128 122 rdev->msi_enabled = 1;
+2 -3
drivers/pci/hotplug/pciehp_hpc.c
··· 832 832 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 833 833 if (!pci_resource_len(pdev, i)) 834 834 continue; 835 - ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", 836 - i, (unsigned long long)pci_resource_len(pdev, i), 837 - (unsigned long long)pci_resource_start(pdev, i)); 835 + ctrl_info(ctrl, " PCI resource [%d] : %pR\n", 836 + i, &pdev->resource[i]); 838 837 } 839 838 ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); 840 839 ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl));
+4 -5
drivers/pci/ioapic.c
··· 31 31 acpi_status status; 32 32 unsigned long long gsb; 33 33 struct ioapic *ioapic; 34 - u64 addr; 35 34 int ret; 36 35 char *type; 36 + struct resource *res; 37 37 38 38 handle = DEVICE_ACPI_HANDLE(&dev->dev); 39 39 if (!handle) ··· 69 69 if (pci_request_region(dev, 0, type)) 70 70 goto exit_disable; 71 71 72 - addr = pci_resource_start(dev, 0); 73 - if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) 72 + res = &dev->resource[0]; 73 + if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) 74 74 goto exit_release; 75 75 76 76 pci_set_drvdata(dev, ioapic); 77 - dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, 78 - ioapic->gsi_base); 77 + dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); 79 78 return 0; 80 79 81 80 exit_release:
+20 -24
drivers/pci/pci.c
··· 2576 2576 */ 2577 2577 int pcix_get_max_mmrbc(struct pci_dev *dev) 2578 2578 { 2579 - int err, cap; 2579 + int cap; 2580 2580 u32 stat; 2581 2581 2582 2582 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2583 2583 if (!cap) 2584 2584 return -EINVAL; 2585 2585 2586 - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 2587 - if (err) 2586 + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) 2588 2587 return -EINVAL; 2589 2588 2590 - return (stat & PCI_X_STATUS_MAX_READ) >> 12; 2589 + return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); 2591 2590 } 2592 2591 EXPORT_SYMBOL(pcix_get_max_mmrbc); 2593 2592 ··· 2599 2600 */ 2600 2601 int pcix_get_mmrbc(struct pci_dev *dev) 2601 2602 { 2602 - int ret, cap; 2603 - u32 cmd; 2603 + int cap; 2604 + u16 cmd; 2604 2605 2605 2606 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2606 2607 if (!cap) 2607 2608 return -EINVAL; 2608 2609 2609 - ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 2610 - if (!ret) 2611 - ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); 2610 + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) 2611 + return -EINVAL; 2612 2612 2613 - return ret; 2613 + return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); 2614 2614 } 2615 2615 EXPORT_SYMBOL(pcix_get_mmrbc); 2616 2616 ··· 2624 2626 */ 2625 2627 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) 2626 2628 { 2627 - int cap, err = -EINVAL; 2628 - u32 stat, cmd, v, o; 2629 + int cap; 2630 + u32 stat, v, o; 2631 + u16 cmd; 2629 2632 2630 2633 if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) 2631 - goto out; 2634 + return -EINVAL; 2632 2635 2633 2636 v = ffs(mmrbc) - 10; 2634 2637 2635 2638 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2636 2639 if (!cap) 2637 - goto out; 2640 + return -EINVAL; 2638 2641 2639 - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 2640 - if (err) 2641 - goto out; 2642 + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) 2643 + return -EINVAL; 2642 2644 2643 2645 if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) 2644 2646 return -E2BIG; 2645 2647 2646 - err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 2647 - if (err) 2648 - goto out; 2648 + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) 2649 + return -EINVAL; 2649 2650 2650 2651 o = (cmd & PCI_X_CMD_MAX_READ) >> 2; 2651 2652 if (o != v) { ··· 2654 2657 2655 2658 cmd &= ~PCI_X_CMD_MAX_READ; 2656 2659 cmd |= v << 2; 2657 - err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); 2660 + if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) 2661 + return -EIO; 2658 2662 } 2659 - out: 2660 - return err; 2663 + return 0; 2661 2664 } 2662 2665 EXPORT_SYMBOL(pcix_set_mmrbc); 2663 2666 ··· 3020 3023 EXPORT_SYMBOL(pci_disable_device); 3021 3024 EXPORT_SYMBOL(pci_find_capability); 3022 3025 EXPORT_SYMBOL(pci_bus_find_capability); 3023 - EXPORT_SYMBOL(pci_register_set_vga_state); 3024 3026 EXPORT_SYMBOL(pci_release_regions); 3025 3027 EXPORT_SYMBOL(pci_request_regions); 3026 3028 EXPORT_SYMBOL(pci_request_regions_exclusive);
+33 -20
drivers/pci/probe.c
··· 174 174 pci_read_config_dword(dev, pos, &sz); 175 175 pci_write_config_dword(dev, pos, l); 176 176 177 + if (!sz) 178 + goto fail; /* BAR not implemented */ 179 + 177 180 /* 178 181 * All bits set in sz means the device isn't working properly. 179 - * If the BAR isn't implemented, all bits must be 0. If it's a 180 - * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit 181 - * 1 must be clear. 182 + * If it's a memory BAR or a ROM, bit 0 must be clear; if it's 183 + * an io BAR, bit 1 must be clear. 182 184 */ 183 - if (!sz || sz == 0xffffffff) 185 + if (sz == 0xffffffff) { 186 + dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", 187 + pos, sz); 184 188 goto fail; 189 + } 185 190 186 191 /* 187 192 * I don't know how l can have all bits set. Copied from old code. ··· 249 244 pos, res); 250 245 } 251 246 } else { 252 - sz = pci_size(l, sz, mask); 247 + u32 size = pci_size(l, sz, mask); 253 248 254 - if (!sz) 249 + if (!size) { 250 + dev_err(&dev->dev, "reg %x: invalid size " 251 + "(l %#x sz %#x mask %#x); broken device?", 252 + pos, l, sz, mask); 255 253 goto fail; 254 + } 256 255 257 256 res->start = l; 258 - res->end = l + sz; 257 + res->end = l + size; 259 258 260 259 dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); 261 260 } ··· 321 312 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 322 313 } else { 323 314 dev_printk(KERN_DEBUG, &dev->dev, 324 - " bridge window [io %04lx - %04lx] reg reading\n", 315 + " bridge window [io %#06lx-%#06lx] (disabled)\n", 325 316 base, limit); 326 317 } 327 318 } ··· 345 336 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 346 337 } else { 347 338 dev_printk(KERN_DEBUG, &dev->dev, 348 - " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n", 339 + " bridge window [mem %#010lx-%#010lx] (disabled)\n", 349 340 base, limit + 0xfffff); 350 341 } 351 342 } ··· 396 387 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 397 388 } else { 398 389 dev_printk(KERN_DEBUG, &dev->dev, 399 - " bridge window [mem 0x%08lx - %08lx pref] reg reading\n", 390 + " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", 400 391 base, limit + 0xfffff); 401 392 } 402 393 } ··· 682 673 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); 683 674 u32 buses, i, j = 0; 684 675 u16 bctl; 676 + u8 primary, secondary, subordinate; 685 677 int broken = 0; 686 678 687 679 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); 680 + primary = buses & 0xFF; 681 + secondary = (buses >> 8) & 0xFF; 682 + subordinate = (buses >> 16) & 0xFF; 688 683 689 - dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", 690 - buses & 0xffffff, pass); 684 + dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", 685 + secondary, subordinate, pass); 691 686 692 687 /* Check if setup is sensible at all */ 693 688 if (!pass && 694 - ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { 689 + (primary != bus->number || secondary <= bus->number)) { 695 690 dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); 696 691 broken = 1; 697 692 } ··· 706 693 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, 707 694 bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); 708 695 709 - if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { 710 - unsigned int cmax, busnr; 696 + if ((secondary || subordinate) && !pcibios_assign_all_busses() && 697 + !is_cardbus && !broken) { 698 + unsigned int cmax; 711 699 /* 712 700 * Bus already configured by firmware, process it in the first 713 701 * pass and just note the configuration. 714 702 */ 715 703 if (pass) 716 704 goto out; 717 - busnr = (buses >> 8) & 0xFF; 718 705 719 706 /* 720 707 * If we already got to this bus through a different bridge, ··· 723 710 * However, we continue to descend down the hierarchy and 724 711 * scan remaining child buses. 725 712 */ 726 - child = pci_find_bus(pci_domain_nr(bus), busnr); 713 + child = pci_find_bus(pci_domain_nr(bus), secondary); 727 714 if (!child) { 728 - child = pci_add_new_bus(bus, dev, busnr); 715 + child = pci_add_new_bus(bus, dev, secondary); 729 716 if (!child) 730 717 goto out; 731 - child->primary = buses & 0xFF; 732 - child->subordinate = (buses >> 16) & 0xFF; 718 + child->primary = primary; 719 + child->subordinate = subordinate; 733 720 child->bridge_ctl = bctl; 734 721 } 735 722
+54 -5
drivers/pci/quirks.c
··· 368 368 bus_region.end = res->end; 369 369 pcibios_bus_to_resource(dev, res, &bus_region); 370 370 371 - pci_claim_resource(dev, nr); 372 - dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); 371 + if (pci_claim_resource(dev, nr) == 0) 372 + dev_info(&dev->dev, "quirk: %pR claimed by %s\n", 373 + res, name); 373 374 } 374 375 } 375 376 ··· 1978 1977 /* 1979 1978 * Disable PCI Bus Parking and PCI Master read caching on CX700 1980 1979 * which causes unspecified timing errors with a VT6212L on the PCI 1981 - * bus leading to USB2.0 packet loss. The defaults are that these 1982 - * features are turned off but some BIOSes turn them on. 1980 + * bus leading to USB2.0 packet loss. 1981 + * 1982 + * This quirk is only enabled if a second (on the external PCI bus) 1983 + * VT6212L is found -- the CX700 core itself also contains a USB 1984 + * host controller with the same PCI ID as the VT6212L. 1983 1985 */ 1984 1986 1987 + /* Count VT6212L instances */ 1988 + struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, 1989 + PCI_DEVICE_ID_VIA_8235_USB_2, NULL); 1985 1990 uint8_t b; 1991 + 1992 + /* p should contain the first (internal) VT6212L -- see if we have 1993 + an external one by searching again */ 1994 + p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); 1995 + if (!p) 1996 + return; 1997 + pci_dev_put(p); 1998 + 1986 1999 if (pci_read_config_byte(dev, 0x76, &b) == 0) { 1987 2000 if (b & 0x40) { 1988 2001 /* Turn off PCI Bus Parking */ ··· 2023 2008 } 2024 2009 } 2025 2010 } 2026 - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); 2011 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); 2027 2012 2028 2013 /* 2029 2014 * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the ··· 2123 2108 } 2124 2109 } 2125 2110 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); 2111 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); 2126 2112 2127 2113 /* Go through the list of Hypertransport capabilities and 2128 2114 * return 1 if a HT MSI capability is found and enabled */ ··· 2494 2478 quirk_msi_intx_disable_bug); 2495 2479 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, 2496 2480 quirk_msi_intx_disable_bug); 2481 + 2482 + /* 2483 + * MSI does not work with the AMD RS780/RS880 internal graphics and HDMI audio 2484 + * devices unless the BIOS has initialized the nb_cntl.strap_msi_enable bit. 2485 + */ 2486 + static void __init rs780_int_gfx_disable_msi(struct pci_dev *int_gfx_bridge) 2487 + { 2488 + u32 nb_cntl; 2489 + 2490 + if (!int_gfx_bridge->subordinate) 2491 + return; 2492 + 2493 + pci_bus_write_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), 2494 + 0x60, 0); 2495 + pci_bus_read_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), 2496 + 0x64, &nb_cntl); 2497 + 2498 + if (!(nb_cntl & BIT(10))) { 2499 + dev_warn(&int_gfx_bridge->dev, 2500 + FW_WARN "RS780: MSI for internal graphics disabled\n"); 2501 + int_gfx_bridge->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; 2502 + } 2503 + } 2504 + 2505 + #define PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX 0x9602 2506 + 2507 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 2508 + PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, 2509 + rs780_int_gfx_disable_msi); 2510 + /* wrong vendor ID on M4A785TD motherboard: */ 2511 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 2512 + PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, 2513 + rs780_int_gfx_disable_msi); 2497 2514 2498 2515 #endif /* CONFIG_PCI_MSI */ 2499 2516
+8 -6
drivers/pci/setup-res.c
··· 93 93 int pci_claim_resource(struct pci_dev *dev, int resource) 94 94 { 95 95 struct resource *res = &dev->resource[resource]; 96 - struct resource *root; 97 - int err; 96 + struct resource *root, *conflict; 98 97 99 98 root = pci_find_parent_resource(dev, res); 100 99 if (!root) { ··· 102 103 return -EINVAL; 103 104 } 104 105 105 - err = request_resource(root, res); 106 - if (err) 106 + conflict = request_resource_conflict(root, res); 107 + if (conflict) { 107 108 dev_err(&dev->dev, 108 - "address space collision: %pR already in use\n", res); 109 + "address space collision: %pR conflicts with %s %pR\n", 110 + res, conflict->name, conflict); 111 + return -EBUSY; 112 + } 109 113 110 - return err; 114 + return 0; 111 115 } 112 116 EXPORT_SYMBOL(pci_claim_resource); 113 117
+4 -8
drivers/pcmcia/rsrc_nonstatic.c
··· 874 874 if (res == &ioport_resource) 875 875 continue; 876 876 dev_printk(KERN_INFO, &s->cb_dev->dev, 877 - "pcmcia: parent PCI bridge I/O " 878 - "window: 0x%llx - 0x%llx\n", 879 - (unsigned long long)res->start, 880 - (unsigned long long)res->end); 877 + "pcmcia: parent PCI bridge window: %pR\n", 878 + res); 881 879 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) 882 880 done |= IORESOURCE_IO; 883 881 ··· 885 887 if (res == &iomem_resource) 886 888 continue; 887 889 dev_printk(KERN_INFO, &s->cb_dev->dev, 888 - "pcmcia: parent PCI bridge Memory " 889 - "window: 0x%llx - 0x%llx\n", 890 - (unsigned long long)res->start, 891 - (unsigned long long)res->end); 890 + "pcmcia: parent PCI bridge window: %pR\n", 891 + res); 892 892 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) 893 893 done |= IORESOURCE_MEM; 894 894 }
+2
include/linux/ioport.h
··· 112 112 extern struct resource ioport_resource; 113 113 extern struct resource iomem_resource; 114 114 115 + extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); 115 116 extern int request_resource(struct resource *root, struct resource *new); 116 117 extern int release_resource(struct resource *new); 117 118 void release_child_resources(struct resource *new); 118 119 extern void reserve_region_with_split(struct resource *root, 119 120 resource_size_t start, resource_size_t end, 120 121 const char *name); 122 + extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); 121 123 extern int insert_resource(struct resource *parent, struct resource *new); 122 124 extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); 123 125 extern int allocate_resource(struct resource *root, struct resource *new,
+37 -7
kernel/resource.c
··· 219 219 } 220 220 221 221 /** 222 + * request_resource_conflict - request and reserve an I/O or memory resource 223 + * @root: root resource descriptor 224 + * @new: resource descriptor desired by caller 225 + * 226 + * Returns 0 for success, conflict resource on error. 227 + */ 228 + struct resource *request_resource_conflict(struct resource *root, struct resource *new) 229 + { 230 + struct resource *conflict; 231 + 232 + write_lock(&resource_lock); 233 + conflict = __request_resource(root, new); 234 + write_unlock(&resource_lock); 235 + return conflict; 236 + } 237 + 238 + /** 222 239 * request_resource - request and reserve an I/O or memory resource 223 240 * @root: root resource descriptor 224 241 * @new: resource descriptor desired by caller ··· 246 229 { 247 230 struct resource *conflict; 248 231 249 - write_lock(&resource_lock); 250 - conflict = __request_resource(root, new); 251 - write_unlock(&resource_lock); 232 + conflict = request_resource_conflict(root, new); 252 233 return conflict ? -EBUSY : 0; 253 234 } 254 235 ··· 489 474 } 490 475 491 476 /** 492 - * insert_resource - Inserts a resource in the resource tree 477 + * insert_resource_conflict - Inserts resource in the resource tree 493 478 * @parent: parent of the new resource 494 479 * @new: new resource to insert 495 480 * 496 - * Returns 0 on success, -EBUSY if the resource can't be inserted. 481 + * Returns 0 on success, conflict resource if the resource can't be inserted. 497 482 * 498 - * This function is equivalent to request_resource when no conflict 483 + * This function is equivalent to request_resource_conflict when no conflict 499 484 * happens. If a conflict happens, and the conflicting resources 500 485 * entirely fit within the range of the new resource, then the new 501 486 * resource is inserted and the conflicting resources become children of 502 487 * the new resource. 503 488 */ 504 - int insert_resource(struct resource *parent, struct resource *new) 489 + struct resource *insert_resource_conflict(struct resource *parent, struct resource *new) 505 490 { 506 491 struct resource *conflict; 507 492 508 493 write_lock(&resource_lock); 509 494 conflict = __insert_resource(parent, new); 510 495 write_unlock(&resource_lock); 496 + return conflict; 497 + } 498 + 499 + /** 500 + * insert_resource - Inserts a resource in the resource tree 501 + * @parent: parent of the new resource 502 + * @new: new resource to insert 503 + * 504 + * Returns 0 on success, -EBUSY if the resource can't be inserted. 505 + */ 506 + int insert_resource(struct resource *parent, struct resource *new) 507 + { 508 + struct resource *conflict; 509 + 510 + conflict = insert_resource_conflict(parent, new); 511 511 return conflict ? -EBUSY : 0; 512 512 } 513 513