On Monday, June 11, 2012 11:25:38 am Andrey Zonov wrote: > On 6/11/12 6:19 PM, John Baldwin wrote: > > On Saturday, June 09, 2012 3:06:19 pm Andrey Zonov wrote: > >> On 6/9/12 9:35 PM, Marius Strobl wrote: > >>> On Sat, Jun 09, 2012 at 12:58:05PM +0400, Andrey Zonov wrote: > >>>> On 6/8/12 10:27 PM, John Baldwin wrote: > >>>>> On Friday, June 08, 2012 11:48:50 am Andrey Zonov wrote: > >>>>>> On Fri, Jun 8, 2012 at 7:19 PM, John Baldwin<j...@freebsd.org> > >>>>>> wrote: > >>>>>>> On Friday, June 08, 2012 3:14:19 am Andrey Zonov wrote: > >>>>>>>> On 6/7/12 10:02 PM, Andrey Zonov wrote: > >>>>>>>>> Hi, > >>>>>>>>> > >>>>>>>>> I just upgraded a few machines from 8.2-STABLE (r221983) to 9.0- > > STABLE > >>>>>>>>> (r234600) and now they can't find any disk because SAS controller > >>>>>>>>> cannot > >>>>>>>>> initialize with the following diagnostic: > >>>>>>>>> > >>>>>>>>> mpt0:<LSILogic SAS/SATA Adapter> port 0xd000-0xd0ff irq 26 at > > device > >>>>>>>>> 3.0 on pci6 > >>>>>>>>> mpt0: 0x4000 bytes of rid 0x14 res 3 failed (0, 0xffffffffffffffff). > >>>>>>>>> mpt0: Unable to memory map registers. > >>>>>>>>> mpt0: Giving Up. > >>>>>>>>> > >>>>>>>>> pciconf -lv: > >>>>>>>>> mpt0@pci0:6:3:0: class=0x010000 card=0x81dd1043 chip=0x00541000 > >>>>>>>>> rev=0x02 > >>>>>>>>> hdr=0x00 > >>>>>>>>> vendor = 'LSI Logic / Symbios Logic' > >>>>>>>>> device = 'SAS1068 PCI-X Fusion-MPT SAS' > >>>>>>>>> class = mass storage > >>>>>>>>> subclass = SCSI > >>>>>>>>> > >>>>>>>>> I tried to boot to latest HEAD and found the same problem. I also > > tried > >>>>>>>>> to build kernel with mpt driver from my 8.2. Controller didn't > >>>>>>>>> initialize with the same diagnostic. So it looks like the problem is > >>>>>>>>> not > >>>>>>>>> in mpt driver. > >>>>>>>>> > >>>>>>>>> Any help would be appreciated. > >>>>>>>>> > >>>>>>>> > >>>>>>>> +jhb@ > >>>>>>>> > >>>>>>>> Hi John, > >>>>>>>> > >>>>>>>> Could you please help me with the problem above? It looks like the > >>>>>>>> problem is in PCI code and you changed things there. > >>>>>>> > >>>>>>> Can you get a verbose dmesg? > >>>>>>> > >>>>>> > >>>>>> Yes, it's in attach. > >>>>> > >>>>> Can you get the output of 'devinfo -u' and 'devinfo -rv' from a broken > >>>>> kernel? > >>>>> > >>>> > >>>> Attached. > >>>> > >>>>> Can you also try setting 'debug.acpi.disable=sysres' in the loader? > >>>>> > >>>> > >>>> Didn't help. > >>>> > >>> > >>> That's probably due to a typo, the corret loader tunable is > >>> debug.acpi.disabled=sysres (note the 'd'). > >>> > >> > >> This helps, thanks! Please explain what this means. > > > > Well, it's working around a bug in your BIOS, but in this case FreeBSD > > should > > have coped fine and it didn't. Please try using this patch without that > > tunable and get a verbose dmesg please: > > Unfortunately didn't work.
Ah, it did work a bit, but it uncovered a larger bug. I didn't make the PCI-PCI bridge driver recursively grow windows. Try this: Index: sys/dev/pci/pci_pci.c =================================================================== --- pci_pci.c (revision 236888) +++ pci_pci.c (working copy) @@ -113,23 +113,27 @@ DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclas /* * Is a resource from a child device sub-allocated from one of our - * resource managers? + * resource managers? If so, return the associated window. */ -static int +static struct pcib_window * pcib_is_resource_managed(struct pcib_softc *sc, int type, struct resource *r) { switch (type) { case SYS_RES_IOPORT: - return (rman_is_region_manager(r, &sc->io.rman)); + if (rman_is_region_manager(r, &sc->io.rman)) + return (&sc->io); + break; case SYS_RES_MEMORY: /* Prefetchable resources may live in either memory rman. */ if (rman_get_flags(r) & RF_PREFETCHABLE && rman_is_region_manager(r, &sc->pmem.rman)) - return (1); - return (rman_is_region_manager(r, &sc->mem.rman)); + return (&sc->pmem); + if (rman_is_region_manager(r, &sc->mem.rman)) + return (&sc->mem); + break; } - return (0); + return (NULL); } static int @@ -871,6 +875,10 @@ pcib_grow_window(struct pcib_softc *sc, struct pci goto updatewin; } + /* Nothing to do if the request fits in the current window. */ + if (start >= rman_get_start(w->res) && end <= rman_get_end(w->res)) + return (ENOSPC); + /* * See if growing the window would help. Compute the minimum * amount of address space needed on both the front and back @@ -881,6 +889,10 @@ pcib_grow_window(struct pcib_softc *sc, struct pci * edge of the window, grow from the inner edge of the free * region. Otherwise grow from the window boundary. * + * As a special case, if the new region is an exact region + * that is a superset of the current window, align the ends + * and make a single adjust request to our parent. + * * XXX: Special case: if w->res is completely empty and the * request size is larger than w->res, we should find the * optimal aligned buffer containing w->res and allocate that. @@ -890,12 +902,22 @@ pcib_grow_window(struct pcib_softc *sc, struct pci "attempting to grow %s window for (%#lx-%#lx,%#lx)\n", w->name, start, end, count); align = 1ul << RF_ALIGNMENT(flags); + if (start + count - 1 == end && start <= rman_get_start(w->res) && + end >= rman_get_end(w->res)) { + start &= (1ul << w->step) - 1; + end = roundup2(end + 1, 1ul << w->step) - 1; + if (bootverbose) + printf("\twide candidate range: %#lx-%#lx\n", + start, end); + error = bus_adjust_resource(sc->dev, type, w->res, start, end); + goto adjusted; + } if (start < rman_get_start(w->res)) { if (rman_first_free_region(&w->rman, &start_free, &end_free) != 0 || start_free != rman_get_start(w->res)) - end_free = rman_get_start(w->res) - 1; + end_free = rman_get_start(w->res); if (end_free > end) - end_free = end; + end_free = end + 1; /* Move end_free down until it is properly aligned. */ end_free &= ~(align - 1); @@ -971,6 +993,7 @@ pcib_grow_window(struct pcib_softc *sc, struct pci } } +adjusted: if (error) return (error); if (bootverbose) @@ -1099,10 +1122,25 @@ pcib_adjust_resource(device_t bus, device_t child, u_long start, u_long end) { struct pcib_softc *sc; + struct pcib_window *w; + int error; sc = device_get_softc(bus); - if (pcib_is_resource_managed(sc, type, r)) - return (rman_adjust_resource(r, start, end)); + w = pcib_is_resource_managed(sc, type, r); + if (w != NULL) { + error = rman_adjust_resource(r, start, end); + if (error == 0) + return (error); + + /* + * If the initial adjustment fails, try to grow the + * window that backs this resource. + */ + if (pcib_grow_window(sc, w, type, start, end, end - start + 1, + rman_get_flags(r)) == 0) + error = rman_adjust_resource(r, start, end); + return (error); + } return (bus_generic_adjust_resource(bus, child, type, r, start, end)); } @@ -1114,7 +1152,7 @@ pcib_release_resource(device_t dev, device_t child int error; sc = device_get_softc(dev); - if (pcib_is_resource_managed(sc, type, r)) { + if (pcib_is_resource_managed(sc, type, r) != NULL) { if (rman_get_flags(r) & RF_ACTIVE) { error = bus_deactivate_resource(child, type, rid, r); if (error) -- John Baldwin _______________________________________________ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"