From njm at njm.me.uk Tue Sep 1 16:56:20 2009 From: njm at njm.me.uk (N.J. Mann) Date: Tue Sep 1 16:56:26 2009 Subject: svn commit: r196684 - stable/7 In-Reply-To: <200908310245.n7V2jliD013837@svn.freebsd.org> References: <200908310245.n7V2jliD013837@svn.freebsd.org> Message-ID: <20090901162939.GA2371@titania.njm.me.uk> In message <200908310245.n7V2jliD013837@svn.freebsd.org>, Edwin Groothuis (edwin@FreeBSD.org) wrote: > Author: edwin > Date: Mon Aug 31 02:45:47 2009 > New Revision: 196684 > URL: http://svn.freebsd.org/changeset/base/196684 > > Log: > MFC of r192625: > > Throw alert about the newly generated format of zic(8) and the > necessarity to run tzsetup(8). > > Modified: > stable/7/UPDATING (contents, props changed) > > Modified: stable/7/UPDATING > ============================================================================== > --- stable/7/UPDATING Mon Aug 31 02:22:18 2009 (r196683) > +++ stable/7/UPDATING Mon Aug 31 02:45:47 2009 (r196684) > @@ -8,6 +8,11 @@ Items affecting the ports and packages s > /usr/ports/UPDATING. Please read that file before running > portupgrade. > > +20090831: > + The newly imported zic(8) produces a new format in the > + output. Please run tzsetup(8) to install the newly created > + data to /etc/localtime. > + > 20090731: > The ABI of various structures related to the SYSV IPC API have > been changed. Bump __FreeBSD_version to 702105. I have just updated one of my machines that runs 7-STABLE and having done so I followed the above instructions. Having read the instructions I was expecting the new version of /etc/localtime to be different from the old one. However, the new one is identical to the old one. Is this to be expected? Cheers, Nick. -- From jhb at FreeBSD.org Thu Sep 3 13:56:19 2009 From: jhb at FreeBSD.org (John Baldwin) Date: Thu Sep 3 13:56:32 2009 Subject: svn commit: r196781 - in stable/7/sys: . amd64/amd64 amd64/include contrib/pf i386/i386 i386/include vm Message-ID: <200909031356.n83DuJ7P034506@svn.freebsd.org> Author: jhb Date: Thu Sep 3 13:56:18 2009 New Revision: 196781 URL: http://svn.freebsd.org/changeset/base/196781 Log: MFC 180430, 180483, 180485, 180601, 180845, 180871-180873, 181043, 181077, 181151, 181284, 181356, 181456, 189454, 194209, 195416, 195836, 196318, 196705, and 196707: Various fixes and enhancements to the amd64 and i386 pmaps to support PAT. - Extend pmap_demote_pde() to include the ability to instantiate a new page table page where none existed before. - Enhance pmap_change_attr() to fully support large (2/4MB) pages by breaking demoting them to 4KB page mappings when needed. - Enhance pmap_change_attr() to avoid page demotions, cache mode changes, and cache and TLB invalidation when some or all of the specified range is already mapped with the specified cache mode. - Enhance pmap_change_attr() to adjust the direct map automatically when changing the cache mode of a kernel virtual address range. - Fix pmap_object_init_pt() to not assume that the pages of a OBJT_DEVICE object are always physically contiguous. - Correct a critical accounting error in pmap_demote_pde(). Reviewed by: alc Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/amd64/pmap.c stable/7/sys/amd64/include/pmap.h stable/7/sys/contrib/pf/ (props changed) stable/7/sys/i386/i386/pmap.c stable/7/sys/i386/include/pmap.h stable/7/sys/vm/vm_object.c stable/7/sys/vm/vm_object.h Modified: stable/7/sys/amd64/amd64/pmap.c ============================================================================== --- stable/7/sys/amd64/amd64/pmap.c Thu Sep 3 13:54:58 2009 (r196780) +++ stable/7/sys/amd64/amd64/pmap.c Thu Sep 3 13:56:18 2009 (r196781) @@ -220,17 +220,22 @@ static void pmap_pvh_free(struct md_page static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); +static int pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode); static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot); static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); +static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); static boolean_t pmap_is_modified_pvh(struct md_page *pvh); +static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); +static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot); +static void pmap_pte_attr(pt_entry_t *pte, int cache_bits); static int pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, vm_page_t *free); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, @@ -461,11 +466,12 @@ create_pagetables(vm_paddr_t *firstaddr) ((pdp_entry_t *)KPDPphys)[i + KPDPI] |= PG_RW | PG_V | PG_U; } - /* Now set up the direct map space using 2MB pages */ + /* Preset PG_M and PG_A because demotion expects it */ for (i = 0; i < NPDEPG * ndmpdp; i++) { ((pd_entry_t *)DMPDphys)[i] = (vm_paddr_t)i << PDRSHIFT; - ((pd_entry_t *)DMPDphys)[i] |= PG_RW | PG_V | PG_PS | PG_G; + ((pd_entry_t *)DMPDphys)[i] |= PG_RW | PG_V | PG_PS | PG_G | + PG_M | PG_A; } /* And the direct map space's PDP */ @@ -1068,7 +1074,7 @@ pmap_kenter(vm_offset_t va, vm_paddr_t p pte_store(pte, pa | PG_RW | PG_V | PG_G); } -PMAP_INLINE void +static __inline void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode) { pt_entry_t *pte; @@ -2192,58 +2198,98 @@ pmap_pv_insert_pde(pmap_t pmap, vm_offse } /* - * Tries to demote a 2MB page mapping. + * Fills a page table page with mappings to consecutive physical pages. + */ +static void +pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte) +{ + pt_entry_t *pte; + + for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { + *pte = newpte; + newpte += PAGE_SIZE; + } +} + +/* + * Tries to demote a 2MB page mapping. If demotion fails, the 2MB page + * mapping is invalidated. */ static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) { pd_entry_t newpde, oldpde; - pt_entry_t *firstpte, newpte, *pte; + pt_entry_t *firstpte, newpte; vm_paddr_t mptepa; vm_page_t free, mpte; PMAP_LOCK_ASSERT(pmap, MA_OWNED); + oldpde = *pde; + KASSERT((oldpde & (PG_PS | PG_V)) == (PG_PS | PG_V), + ("pmap_demote_pde: oldpde is missing PG_PS and/or PG_V")); mpte = pmap_lookup_pt_page(pmap, va); if (mpte != NULL) pmap_remove_pt_page(pmap, mpte); else { - KASSERT((*pde & PG_W) == 0, + KASSERT((oldpde & PG_W) == 0, ("pmap_demote_pde: page table page for a wired mapping" " is missing")); - free = NULL; - pmap_remove_pde(pmap, pde, trunc_2mpage(va), &free); - pmap_invalidate_page(pmap, trunc_2mpage(va)); - pmap_free_zero_pages(free); - CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#lx" - " in pmap %p", va, pmap); - return (FALSE); + + /* + * Invalidate the 2MB page mapping and return "failure" if the + * mapping was never accessed or the allocation of the new + * page table page fails. If the 2MB page mapping belongs to + * the direct map region of the kernel's address space, then + * the page allocation request specifies the highest possible + * priority (VM_ALLOC_INTERRUPT). Otherwise, the priority is + * normal. Page table pages are preallocated for every other + * part of the kernel address space, so the direct map region + * is the only part of the kernel address space that must be + * handled here. + */ + if ((oldpde & PG_A) == 0 || (mpte = vm_page_alloc(NULL, + pmap_pde_pindex(va), (va >= DMAP_MIN_ADDRESS && va < + DMAP_MAX_ADDRESS ? VM_ALLOC_INTERRUPT : VM_ALLOC_NORMAL) | + VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) { + free = NULL; + pmap_remove_pde(pmap, pde, trunc_2mpage(va), &free); + pmap_invalidate_page(pmap, trunc_2mpage(va)); + pmap_free_zero_pages(free); + CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#lx" + " in pmap %p", va, pmap); + return (FALSE); + } + if (va < VM_MAXUSER_ADDRESS) + pmap->pm_stats.resident_count++; } mptepa = VM_PAGE_TO_PHYS(mpte); firstpte = (pt_entry_t *)PHYS_TO_DMAP(mptepa); - oldpde = *pde; newpde = mptepa | PG_M | PG_A | (oldpde & PG_U) | PG_RW | PG_V; - KASSERT((oldpde & (PG_A | PG_V)) == (PG_A | PG_V), - ("pmap_demote_pde: oldpde is missing PG_A and/or PG_V")); + KASSERT((oldpde & PG_A) != 0, + ("pmap_demote_pde: oldpde is missing PG_A")); KASSERT((oldpde & (PG_M | PG_RW)) != PG_RW, ("pmap_demote_pde: oldpde is missing PG_M")); - KASSERT((oldpde & PG_PS) != 0, - ("pmap_demote_pde: oldpde is missing PG_PS")); newpte = oldpde & ~PG_PS; if ((newpte & PG_PDE_PAT) != 0) newpte ^= PG_PDE_PAT | PG_PTE_PAT; /* - * If the mapping has changed attributes, update the page table - * entries. + * If the page table page is new, initialize it. */ + if (mpte->wire_count == 1) { + mpte->wire_count = NPTEPG; + pmap_fill_ptp(firstpte, newpte); + } KASSERT((*firstpte & PG_FRAME) == (newpte & PG_FRAME), ("pmap_demote_pde: firstpte and newpte map different physical" " addresses")); + + /* + * If the mapping has changed attributes, update the page table + * entries. + */ if ((*firstpte & PG_PTE_PROMOTE) != (newpte & PG_PTE_PROMOTE)) - for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { - *pte = newpte; - newpte += PAGE_SIZE; - } + pmap_fill_ptp(firstpte, newpte); /* * Demote the mapping. This pmap is locked. The old PDE has @@ -3310,78 +3356,74 @@ void pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size) { - vm_offset_t va; + pd_entry_t *pde; + vm_paddr_t pa, ptepa; vm_page_t p, pdpg; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); KASSERT(object->type == OBJT_DEVICE, ("pmap_object_init_pt: non-device object")); - if (((addr & (NBPDR - 1)) == 0) && ((size & (NBPDR - 1)) == 0)) { - vm_page_t m[1]; - pd_entry_t ptepa, *pde; - - PMAP_LOCK(pmap); - pde = pmap_pde(pmap, addr); - if (pde != 0 && (*pde & PG_V) != 0) - goto out; - PMAP_UNLOCK(pmap); -retry: + if ((addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) { + if (!vm_object_populate(object, pindex, pindex + atop(size))) + return; p = vm_page_lookup(object, pindex); - if (p != NULL) { - if (vm_page_sleep_if_busy(p, FALSE, "init4p")) - goto retry; - } else { - p = vm_page_alloc(object, pindex, VM_ALLOC_NORMAL); - if (p == NULL) - return; - m[0] = p; - - if (vm_pager_get_pages(object, m, 1, 0) != VM_PAGER_OK) { - vm_page_lock_queues(); - vm_page_free(p); - vm_page_unlock_queues(); - return; - } - - p = vm_page_lookup(object, pindex); - vm_page_wakeup(p); - } + KASSERT(p->valid == VM_PAGE_BITS_ALL, + ("pmap_object_init_pt: invalid page %p", p)); + /* + * Abort the mapping if the first page is not physically + * aligned to a 2MB page boundary. + */ ptepa = VM_PAGE_TO_PHYS(p); if (ptepa & (NBPDR - 1)) return; - p->valid = VM_PAGE_BITS_ALL; + /* + * Skip the first page. Abort the mapping if the rest of + * the pages are not physically contiguous. + */ + p = TAILQ_NEXT(p, listq); + for (pa = ptepa + PAGE_SIZE; pa < ptepa + size; + pa += PAGE_SIZE) { + KASSERT(p->valid == VM_PAGE_BITS_ALL, + ("pmap_object_init_pt: invalid page %p", p)); + if (pa != VM_PAGE_TO_PHYS(p)) + return; + p = TAILQ_NEXT(p, listq); + } + /* Map using 2MB pages. */ PMAP_LOCK(pmap); - for (va = addr; va < addr + size; va += NBPDR) { - while ((pdpg = - pmap_allocpde(pmap, va, M_NOWAIT)) == NULL) { - PMAP_UNLOCK(pmap); - vm_page_busy(p); - VM_OBJECT_UNLOCK(object); - VM_WAIT; - VM_OBJECT_LOCK(object); - vm_page_wakeup(p); - PMAP_LOCK(pmap); + for (pa = ptepa; pa < ptepa + size; pa += NBPDR) { + pdpg = pmap_allocpde(pmap, addr, M_NOWAIT); + if (pdpg == NULL) { + /* + * The creation of mappings below is only an + * optimization. If a page directory page + * cannot be allocated without blocking, + * continue on to the next mapping rather than + * blocking. + */ + addr += NBPDR; + continue; } pde = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg)); - pde = &pde[pmap_pde_index(va)]; + pde = &pde[pmap_pde_index(addr)]; if ((*pde & PG_V) == 0) { - pde_store(pde, ptepa | PG_PS | PG_M | PG_A | + pde_store(pde, pa | PG_PS | PG_M | PG_A | PG_U | PG_RW | PG_V); - pmap->pm_stats.resident_count += - NBPDR / PAGE_SIZE; + pmap->pm_stats.resident_count += NBPDR / + PAGE_SIZE; + pmap_pde_mappings++; } else { + /* Continue on if the PDE is already valid. */ pdpg->wire_count--; KASSERT(pdpg->wire_count > 0, ("pmap_object_init_pt: missing reference " - "to page directory page, va: 0x%lx", va)); + "to page directory page, va: 0x%lx", addr)); } - ptepa += NBPDR; + addr += NBPDR; } - pmap_invalidate_all(pmap); -out: PMAP_UNLOCK(pmap); } } @@ -3739,7 +3781,9 @@ pmap_remove_pages(pmap_t pmap) if ((tpte & PG_PS) != 0) pte = pde; else { - pte = vtopte(pv->pv_va); + pte = (pt_entry_t *)PHYS_TO_DMAP(tpte & + PG_FRAME); + pte = &pte[pmap_pte_index(pv->pv_va)]; tpte = *pte & ~PG_PTE_PAT; } @@ -4160,41 +4204,35 @@ pmap_clear_reference(vm_page_t m) /* Adjust the cache mode for a 4KB page mapped via a PTE. */ static __inline void -pmap_pte_attr(vm_offset_t va, int mode) +pmap_pte_attr(pt_entry_t *pte, int cache_bits) { - pt_entry_t *pte; u_int opte, npte; - pte = vtopte(va); - /* * The cache mode bits are all in the low 32-bits of the * PTE, so we can just spin on updating the low 32-bits. */ do { opte = *(u_int *)pte; - npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT); - npte |= pmap_cache_bits(mode, 0); + npte = opte & ~PG_PTE_CACHE; + npte |= cache_bits; } while (npte != opte && !atomic_cmpset_int((u_int *)pte, opte, npte)); } /* Adjust the cache mode for a 2MB page mapped via a PDE. */ static __inline void -pmap_pde_attr(vm_offset_t va, int mode) +pmap_pde_attr(pd_entry_t *pde, int cache_bits) { - pd_entry_t *pde; u_int opde, npde; - pde = pmap_pde(kernel_pmap, va); - /* * The cache mode bits are all in the low 32-bits of the * PDE, so we can just spin on updating the low 32-bits. */ do { opde = *(u_int *)pde; - npde = opde & ~(PG_PDE_PAT | PG_NC_PCD | PG_NC_PWT); - npde |= pmap_cache_bits(mode, 1); + npde = opde & ~PG_PDE_CACHE; + npde |= cache_bits; } while (npde != opde && !atomic_cmpset_int((u_int *)pde, opde, npde)); } @@ -4210,11 +4248,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_ vm_offset_t va, tmpva, offset; /* - * If this fits within the direct map window and use WB caching - * mode, use the direct map. + * If the specified range of physical addresses fits within the direct + * map window, use the direct map. */ - if (pa < dmaplimit && (pa + size) < dmaplimit && mode == PAT_WRITE_BACK) - return ((void *)PHYS_TO_DMAP(pa)); + if (pa < dmaplimit && pa + size < dmaplimit) { + va = PHYS_TO_DMAP(pa); + if (!pmap_change_attr(va, size, mode)) + return ((void *)va); + } offset = pa & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); va = kmem_alloc_nofault(kernel_map, size); @@ -4263,68 +4304,174 @@ pmap_unmapdev(vm_offset_t va, vm_size_t kmem_free(kernel_map, base, size); } +/* + * Changes the specified virtual address range's memory type to that given by + * the parameter "mode". The specified virtual address range must be + * completely contained within either the direct map or the kernel map. If + * the virtual address range is contained within the kernel map, then the + * memory type for each of the corresponding ranges of the direct map is also + * changed. (The corresponding ranges of the direct map are those ranges that + * map the same physical pages as the specified virtual address range.) These + * changes to the direct map are necessary because Intel describes the + * behavior of their processors as "undefined" if two or more mappings to the + * same physical page have different memory types. + * + * Returns zero if the change completed successfully, and either EINVAL or + * ENOMEM if the change failed. Specifically, EINVAL is returned if some part + * of the virtual address range was not mapped, and ENOMEM is returned if + * there was insufficient memory available to complete the change. In the + * latter case, the memory type may have been changed on some part of the + * virtual address range or the direct map. + */ int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) { + int error; + + PMAP_LOCK(kernel_pmap); + error = pmap_change_attr_locked(va, size, mode); + PMAP_UNLOCK(kernel_pmap); + return (error); +} + +static int +pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) +{ vm_offset_t base, offset, tmpva; + vm_paddr_t pa_start, pa_end; pd_entry_t *pde; pt_entry_t *pte; + int cache_bits_pte, cache_bits_pde, error; + boolean_t changed; + PMAP_LOCK_ASSERT(kernel_pmap, MA_OWNED); base = trunc_page(va); offset = va & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); - /* Only supported on kernel virtual addresses. */ - if (base <= VM_MAXUSER_ADDRESS) + /* + * Only supported on kernel virtual addresses, including the direct + * map but excluding the recursive map. + */ + if (base < DMAP_MIN_ADDRESS) return (EINVAL); + cache_bits_pde = pmap_cache_bits(mode, 1); + cache_bits_pte = pmap_cache_bits(mode, 0); + changed = FALSE; + /* - * XXX: We have to support tearing 2MB pages down into 4k pages if - * needed here. + * Pages that aren't mapped aren't supported. Also break down 2MB pages + * into 4KB pages if required. */ - /* Pages that aren't mapped aren't supported. */ - for (tmpva = base; tmpva < (base + size); ) { + for (tmpva = base; tmpva < base + size; ) { pde = pmap_pde(kernel_pmap, tmpva); if (*pde == 0) return (EINVAL); if (*pde & PG_PS) { - /* Handle 2MB pages that are completely contained. */ - if (size >= NBPDR) { + /* + * If the current 2MB page already has the required + * memory type, then we need not demote this page. Just + * increment tmpva to the next 2MB page frame. + */ + if ((*pde & PG_PDE_CACHE) == cache_bits_pde) { + tmpva = trunc_2mpage(tmpva) + NBPDR; + continue; + } + + /* + * If the current offset aligns with a 2MB page frame + * and there is at least 2MB left within the range, then + * we need not break down this page into 4KB pages. + */ + if ((tmpva & PDRMASK) == 0 && + tmpva + PDRMASK < base + size) { tmpva += NBPDR; continue; } - return (EINVAL); + if (!pmap_demote_pde(kernel_pmap, pde, tmpva)) + return (ENOMEM); } - pte = vtopte(va); + pte = pmap_pde_to_pte(pde, tmpva); if (*pte == 0) return (EINVAL); tmpva += PAGE_SIZE; } + error = 0; /* * Ok, all the pages exist, so run through them updating their - * cache mode. + * cache mode if required. */ - for (tmpva = base; size > 0; ) { + pa_start = pa_end = 0; + for (tmpva = base; tmpva < base + size; ) { pde = pmap_pde(kernel_pmap, tmpva); if (*pde & PG_PS) { - pmap_pde_attr(tmpva, mode); - tmpva += NBPDR; - size -= NBPDR; + if ((*pde & PG_PDE_CACHE) != cache_bits_pde) { + pmap_pde_attr(pde, cache_bits_pde); + changed = TRUE; + } + if (tmpva >= VM_MIN_KERNEL_ADDRESS) { + if (pa_start == pa_end) { + /* Start physical address run. */ + pa_start = *pde & PG_PS_FRAME; + pa_end = pa_start + NBPDR; + } else if (pa_end == (*pde & PG_PS_FRAME)) + pa_end += NBPDR; + else { + /* Run ended, update direct map. */ + error = pmap_change_attr_locked( + PHYS_TO_DMAP(pa_start), + pa_end - pa_start, mode); + if (error != 0) + break; + /* Start physical address run. */ + pa_start = *pde & PG_PS_FRAME; + pa_end = pa_start + NBPDR; + } + } + tmpva = trunc_2mpage(tmpva) + NBPDR; } else { - pmap_pte_attr(tmpva, mode); + pte = pmap_pde_to_pte(pde, tmpva); + if ((*pte & PG_PTE_CACHE) != cache_bits_pte) { + pmap_pte_attr(pte, cache_bits_pte); + changed = TRUE; + } + if (tmpva >= VM_MIN_KERNEL_ADDRESS) { + if (pa_start == pa_end) { + /* Start physical address run. */ + pa_start = *pte & PG_FRAME; + pa_end = pa_start + PAGE_SIZE; + } else if (pa_end == (*pte & PG_FRAME)) + pa_end += PAGE_SIZE; + else { + /* Run ended, update direct map. */ + error = pmap_change_attr_locked( + PHYS_TO_DMAP(pa_start), + pa_end - pa_start, mode); + if (error != 0) + break; + /* Start physical address run. */ + pa_start = *pte & PG_FRAME; + pa_end = pa_start + PAGE_SIZE; + } + } tmpva += PAGE_SIZE; - size -= PAGE_SIZE; } } + if (error == 0 && pa_start != pa_end) + error = pmap_change_attr_locked(PHYS_TO_DMAP(pa_start), + pa_end - pa_start, mode); /* - * Flush CPU caches to make sure any data isn't cached that shouldn't - * be, etc. - */ - pmap_invalidate_range(kernel_pmap, base, tmpva); - pmap_invalidate_cache(); - return (0); + * Flush CPU caches if required to make sure any data isn't cached that + * shouldn't be, etc. + */ + if (changed) { + pmap_invalidate_range(kernel_pmap, base, tmpva); + pmap_invalidate_cache(); + } + return (error); } /* Modified: stable/7/sys/amd64/include/pmap.h ============================================================================== --- stable/7/sys/amd64/include/pmap.h Thu Sep 3 13:54:58 2009 (r196780) +++ stable/7/sys/amd64/include/pmap.h Thu Sep 3 13:56:18 2009 (r196781) @@ -75,6 +75,10 @@ #define PG_PROT (PG_RW|PG_U) /* all protection bits . */ #define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */ +/* Page level cache control fields used to determine the PAT type */ +#define PG_PDE_CACHE (PG_PDE_PAT | PG_NC_PWT | PG_NC_PCD) +#define PG_PTE_CACHE (PG_PTE_PAT | PG_NC_PWT | PG_NC_PCD) + /* * Promotion to a 2MB (PDE) page mapping requires that the corresponding 4KB * (PTE) page mappings have identical settings for the following fields: @@ -308,7 +312,6 @@ void pmap_bootstrap(vm_paddr_t *); int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_init_pat(void); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); -void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); void *pmap_kenter_temporary(vm_paddr_t pa, int i); vm_paddr_t pmap_kextract(vm_offset_t); void pmap_kremove(vm_offset_t); Modified: stable/7/sys/i386/i386/pmap.c ============================================================================== --- stable/7/sys/i386/i386/pmap.c Thu Sep 3 13:54:58 2009 (r196780) +++ stable/7/sys/i386/i386/pmap.c Thu Sep 3 13:56:18 2009 (r196781) @@ -284,11 +284,15 @@ static boolean_t pmap_enter_pde(pmap_t p static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static boolean_t pmap_is_modified_pvh(struct md_page *pvh); +static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); +static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot); +static void pmap_pte_attr(pt_entry_t *pte, int cache_bits); static void pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, vm_page_t *free); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva, @@ -1132,7 +1136,7 @@ pmap_kenter(vm_offset_t va, vm_paddr_t p pte_store(pte, pa | PG_RW | PG_V | pgeflag); } -PMAP_INLINE void +static __inline void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode) { pt_entry_t *pte; @@ -2245,32 +2249,62 @@ pmap_pv_insert_pde(pmap_t pmap, vm_offse } /* - * Tries to demote a 2- or 4MB page mapping. + * Fills a page table page with mappings to consecutive physical pages. + */ +static void +pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte) +{ + pt_entry_t *pte; + + for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { + *pte = newpte; + newpte += PAGE_SIZE; + } +} + +/* + * Tries to demote a 2- or 4MB page mapping. If demotion fails, the + * 2- or 4MB page mapping is invalidated. */ static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) { pd_entry_t newpde, oldpde; pmap_t allpmaps_entry; - pt_entry_t *firstpte, newpte, *pte; + pt_entry_t *firstpte, newpte; vm_paddr_t mptepa; vm_page_t free, mpte; PMAP_LOCK_ASSERT(pmap, MA_OWNED); + oldpde = *pde; + KASSERT((oldpde & (PG_PS | PG_V)) == (PG_PS | PG_V), + ("pmap_demote_pde: oldpde is missing PG_PS and/or PG_V")); mpte = pmap_lookup_pt_page(pmap, va); if (mpte != NULL) pmap_remove_pt_page(pmap, mpte); else { - KASSERT((*pde & PG_W) == 0, + KASSERT((oldpde & PG_W) == 0, ("pmap_demote_pde: page table page for a wired mapping" " is missing")); - free = NULL; - pmap_remove_pde(pmap, pde, trunc_4mpage(va), &free); - pmap_invalidate_page(pmap, trunc_4mpage(va)); - pmap_free_zero_pages(free); - CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#x" - " in pmap %p", va, pmap); - return (FALSE); + + /* + * Invalidate the 2- or 4MB page mapping and return + * "failure" if the mapping was never accessed or the + * allocation of the new page table page fails. + */ + if ((oldpde & PG_A) == 0 || (mpte = vm_page_alloc(NULL, + va >> PDRSHIFT, VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL | + VM_ALLOC_WIRED)) == NULL) { + free = NULL; + pmap_remove_pde(pmap, pde, trunc_4mpage(va), &free); + pmap_invalidate_page(pmap, trunc_4mpage(va)); + pmap_free_zero_pages(free); + CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#x" + " in pmap %p", va, pmap); + return (FALSE); + } + if (va < VM_MAXUSER_ADDRESS) + pmap->pm_stats.resident_count++; } mptepa = VM_PAGE_TO_PHYS(mpte); @@ -2304,30 +2338,32 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t } firstpte = PADDR2; } - oldpde = *pde; newpde = mptepa | PG_M | PG_A | (oldpde & PG_U) | PG_RW | PG_V; - KASSERT((oldpde & (PG_A | PG_V)) == (PG_A | PG_V), - ("pmap_demote_pde: oldpde is missing PG_A and/or PG_V")); + KASSERT((oldpde & PG_A) != 0, + ("pmap_demote_pde: oldpde is missing PG_A")); KASSERT((oldpde & (PG_M | PG_RW)) != PG_RW, ("pmap_demote_pde: oldpde is missing PG_M")); - KASSERT((oldpde & PG_PS) != 0, - ("pmap_demote_pde: oldpde is missing PG_PS")); newpte = oldpde & ~PG_PS; if ((newpte & PG_PDE_PAT) != 0) newpte ^= PG_PDE_PAT | PG_PTE_PAT; /* - * If the mapping has changed attributes, update the page table - * entries. - */ + * If the page table page is new, initialize it. + */ + if (mpte->wire_count == 1) { + mpte->wire_count = NPTEPG; + pmap_fill_ptp(firstpte, newpte); + } KASSERT((*firstpte & PG_FRAME) == (newpte & PG_FRAME), ("pmap_demote_pde: firstpte and newpte map different physical" " addresses")); + + /* + * If the mapping has changed attributes, update the page table + * entries. + */ if ((*firstpte & PG_PTE_PROMOTE) != (newpte & PG_PTE_PROMOTE)) - for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { - *pte = newpte; - newpte += PAGE_SIZE; - } + pmap_fill_ptp(firstpte, newpte); /* * Demote the mapping. This pmap is locked. The old PDE has @@ -3432,62 +3468,57 @@ void pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size) { + pd_entry_t *pde; + vm_paddr_t pa, ptepa; vm_page_t p; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); KASSERT(object->type == OBJT_DEVICE, ("pmap_object_init_pt: non-device object")); if (pseflag && - ((addr & (NBPDR - 1)) == 0) && ((size & (NBPDR - 1)) == 0)) { - int i; - vm_page_t m[1]; - unsigned int ptepindex; - int npdes; - pd_entry_t ptepa; - - PMAP_LOCK(pmap); - if (pmap->pm_pdir[ptepindex = (addr >> PDRSHIFT)]) - goto out; - PMAP_UNLOCK(pmap); -retry: + (addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) { + if (!vm_object_populate(object, pindex, pindex + atop(size))) + return; p = vm_page_lookup(object, pindex); - if (p != NULL) { - if (vm_page_sleep_if_busy(p, FALSE, "init4p")) - goto retry; - } else { - p = vm_page_alloc(object, pindex, VM_ALLOC_NORMAL); - if (p == NULL) - return; - m[0] = p; - - if (vm_pager_get_pages(object, m, 1, 0) != VM_PAGER_OK) { - vm_page_lock_queues(); - vm_page_free(p); - vm_page_unlock_queues(); - return; - } - - p = vm_page_lookup(object, pindex); - vm_page_wakeup(p); - } + KASSERT(p->valid == VM_PAGE_BITS_ALL, + ("pmap_object_init_pt: invalid page %p", p)); + /* + * Abort the mapping if the first page is not physically + * aligned to a 2/4MB page boundary. + */ ptepa = VM_PAGE_TO_PHYS(p); if (ptepa & (NBPDR - 1)) return; - p->valid = VM_PAGE_BITS_ALL; + /* + * Skip the first page. Abort the mapping if the rest of + * the pages are not physically contiguous. + */ + p = TAILQ_NEXT(p, listq); + for (pa = ptepa + PAGE_SIZE; pa < ptepa + size; + pa += PAGE_SIZE) { + KASSERT(p->valid == VM_PAGE_BITS_ALL, + ("pmap_object_init_pt: invalid page %p", p)); + if (pa != VM_PAGE_TO_PHYS(p)) + return; + p = TAILQ_NEXT(p, listq); + } + /* Map using 2/4MB pages. */ PMAP_LOCK(pmap); - pmap->pm_stats.resident_count += size >> PAGE_SHIFT; - npdes = size >> PDRSHIFT; - for(i = 0; i < npdes; i++) { - pde_store(&pmap->pm_pdir[ptepindex], - ptepa | PG_U | PG_RW | PG_V | PG_PS); - ptepa += NBPDR; - ptepindex += 1; + for (pa = ptepa; pa < ptepa + size; pa += NBPDR) { + pde = pmap_pde(pmap, addr); + if (*pde == 0) { + pde_store(pde, pa | PG_PS | PG_M | PG_A | + PG_U | PG_RW | PG_V); + pmap->pm_stats.resident_count += NBPDR / + PAGE_SIZE; + pmap_pde_mappings++; + } + /* Else continue on if the PDE is already valid. */ + addr += NBPDR; } - pmap_invalidate_all(pmap); -out: PMAP_UNLOCK(pmap); } } @@ -4326,6 +4357,40 @@ pmap_clear_reference(vm_page_t m) * Miscellaneous support routines follow */ +/* Adjust the cache mode for a 4KB page mapped via a PTE. */ +static __inline void +pmap_pte_attr(pt_entry_t *pte, int cache_bits) +{ + u_int opte, npte; + + /* + * The cache mode bits are all in the low 32-bits of the + * PTE, so we can just spin on updating the low 32-bits. + */ + do { + opte = *(u_int *)pte; + npte = opte & ~PG_PTE_CACHE; + npte |= cache_bits; + } while (npte != opte && !atomic_cmpset_int((u_int *)pte, opte, npte)); +} + +/* Adjust the cache mode for a 2/4MB page mapped via a PDE. */ +static __inline void +pmap_pde_attr(pd_entry_t *pde, int cache_bits) +{ + u_int opde, npde; + + /* + * The cache mode bits are all in the low 32-bits of the + * PDE, so we can just spin on updating the low 32-bits. + */ + do { + opde = *(u_int *)pde; + npde = opde & ~PG_PDE_CACHE; + npde |= cache_bits; + } while (npde != opde && !atomic_cmpset_int((u_int *)pde, opde, npde)); +} + /* * Map a set of physical memory pages into the kernel virtual * address space. Return a pointer to where it is mapped. This @@ -4389,61 +4454,117 @@ pmap_unmapdev(vm_offset_t va, vm_size_t kmem_free(kernel_map, base, size); } +/* + * Changes the specified virtual address range's memory type to that given by + * the parameter "mode". The specified virtual address range must be + * completely contained within either the kernel map. + * + * Returns zero if the change completed successfully, and either EINVAL or + * ENOMEM if the change failed. Specifically, EINVAL is returned if some part + * of the virtual address range was not mapped, and ENOMEM is returned if + * there was insufficient memory available to complete the change. + */ int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) { vm_offset_t base, offset, tmpva; - pt_entry_t *pte; - u_int opte, npte; pd_entry_t *pde; + pt_entry_t *pte; + int cache_bits_pte, cache_bits_pde; + boolean_t changed; base = trunc_page(va); offset = va & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); - /* Only supported on kernel virtual addresses. */ - if (base <= VM_MAXUSER_ADDRESS) + /* + * Only supported on kernel virtual addresses above the recursive map. + */ + if (base < VM_MIN_KERNEL_ADDRESS) return (EINVAL); - /* 4MB pages and pages that aren't mapped aren't supported. */ - for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) { + cache_bits_pde = pmap_cache_bits(mode, 1); + cache_bits_pte = pmap_cache_bits(mode, 0); + changed = FALSE; + + /* + * Pages that aren't mapped aren't supported. Also break down + * 2/4MB pages into 4KB pages if required. + */ + PMAP_LOCK(kernel_pmap); + for (tmpva = base; tmpva < base + size; ) { pde = pmap_pde(kernel_pmap, tmpva); - if (*pde & PG_PS) - return (EINVAL); - if (*pde == 0) + if (*pde == 0) { + PMAP_UNLOCK(kernel_pmap); return (EINVAL); - pte = vtopte(va); - if (*pte == 0) + } + if (*pde & PG_PS) { + /* + * If the current 2/4MB page already has + * the required memory type, then we need not + * demote this page. Just increment tmpva to + * the next 2/4MB page frame. + */ + if ((*pde & PG_PDE_CACHE) == cache_bits_pde) { + tmpva = trunc_4mpage(tmpva) + NBPDR; + continue; + } + + /* + * If the current offset aligns with a 2/4MB + * page frame and there is at least 2/4MB left + * within the range, then we need not break + * down this page into 4KB pages. + */ + if ((tmpva & PDRMASK) == 0 && + tmpva + PDRMASK < base + size) { + tmpva += NBPDR; + continue; + } + if (!pmap_demote_pde(kernel_pmap, pde, tmpva)) { + PMAP_UNLOCK(kernel_pmap); + return (ENOMEM); + } + } + pte = vtopte(tmpva); + if (*pte == 0) { + PMAP_UNLOCK(kernel_pmap); return (EINVAL); + } + tmpva += PAGE_SIZE; } + PMAP_UNLOCK(kernel_pmap); /* - * Ok, all the pages exist and are 4k, so run through them updating - * their cache mode. + * Ok, all the pages exist, so run through them updating their + * cache mode if required. */ - for (tmpva = base; size > 0; ) { - pte = vtopte(tmpva); - - /* - * The cache mode bits are all in the low 32-bits of the - * PTE, so we can just spin on updating the low 32-bits. - */ - do { - opte = *(u_int *)pte; - npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT); - npte |= pmap_cache_bits(mode, 0); - } while (npte != opte && - !atomic_cmpset_int((u_int *)pte, opte, npte)); - tmpva += PAGE_SIZE; - size -= PAGE_SIZE; + for (tmpva = base; tmpva < base + size; ) { + pde = pmap_pde(kernel_pmap, tmpva); + if (*pde & PG_PS) { + if ((*pde & PG_PDE_CACHE) != cache_bits_pde) { + pmap_pde_attr(pde, cache_bits_pde); + changed = TRUE; + } + tmpva = trunc_4mpage(tmpva) + NBPDR; *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From jhb at FreeBSD.org Thu Sep 3 14:23:51 2009 From: jhb at FreeBSD.org (John Baldwin) Date: Thu Sep 3 14:23:58 2009 Subject: svn commit: r196782 - in stable/7/sys: . contrib/pf kern sys vm Message-ID: <200909031423.n83ENpUW035318@svn.freebsd.org> Author: jhb Date: Thu Sep 3 14:23:50 2009 New Revision: 196782 URL: http://svn.freebsd.org/changeset/base/196782 Log: MFC 193275 and 194989: Add an extension to the character device interface that allows character device drivers to use arbitrary VM objects to satisfy individual mmap() requests. - A new d_mmap_single(cdev, &foff, objsize, &object, prot) callback is added to cdevsw. This function is called for each mmap() request. If it returns ENODEV, then the mmap() request will fall back to using the device's device pager object and d_mmap(). Otherwise, the method can return a VM object to satisfy this entire mmap() request via *object. It can also modify the starting offset into this object via *foff. This allows device drivers to use the file offset as a cookie to identify specific VM objects. - vm_mmap_vnode() has been changed to call vm_mmap_cdev() directly when mapping V_CHR vnodes. This avoids duplicating all the cdev mmap handling code and simplifies some of vm_mmap_vnode(). - D_VERSION has been bumped to D_VERSION_02. Older device drivers using D_VERSION_01 are still supported. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/kern/kern_conf.c stable/7/sys/sys/conf.h stable/7/sys/vm/vm_mmap.c Modified: stable/7/sys/kern/kern_conf.c ============================================================================== --- stable/7/sys/kern/kern_conf.c Thu Sep 3 13:56:18 2009 (r196781) +++ stable/7/sys/kern/kern_conf.c Thu Sep 3 14:23:50 2009 (r196782) @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage"); @@ -276,6 +277,7 @@ dead_strategy(struct bio *bp) #define dead_dump (dumper_t *)enxio #define dead_kqfilter (d_kqfilter_t *)enxio +#define dead_mmap_single (d_mmap_single_t *)enodev static struct cdevsw dead_cdevsw = { .d_version = D_VERSION, @@ -290,7 +292,8 @@ static struct cdevsw dead_cdevsw = { .d_strategy = dead_strategy, .d_name = "dead", .d_dump = dead_dump, - .d_kqfilter = dead_kqfilter + .d_kqfilter = dead_kqfilter, + .d_mmap_single = dead_mmap_single }; /* Default methods if driver does not specify method */ @@ -302,6 +305,7 @@ static struct cdevsw dead_cdevsw = { #define no_ioctl (d_ioctl_t *)enodev #define no_mmap (d_mmap_t *)enodev #define no_kqfilter (d_kqfilter_t *)enodev +#define no_mmap_single (d_mmap_single_t *)enodev static void no_strategy(struct bio *bp) @@ -481,6 +485,23 @@ giant_mmap(struct cdev *dev, vm_offset_t return (retval); } +static int +giant_mmap_single(struct cdev *dev, vm_ooffset_t *offset, vm_size_t size, + vm_object_t *object, int nprot) +{ + struct cdevsw *dsw; + int retval; + + dsw = dev_refthread(dev); + if (dsw == NULL) + return (ENXIO); + mtx_lock(&Giant); + retval = dsw->d_gianttrick->d_mmap_single(dev, offset, size, object, + nprot); + mtx_unlock(&Giant); + dev_relthread(dev); + return (retval); +} /* * struct cdev * and u_dev_t primitives @@ -616,7 +637,8 @@ prep_cdevsw(struct cdevsw *devsw) return; } - if (devsw->d_version != D_VERSION_01) { + if (devsw->d_version != D_VERSION_01 && + devsw->d_version != D_VERSION_02) { printf( "WARNING: Device driver \"%s\" has wrong version %s\n", devsw->d_name == NULL ? "???" : devsw->d_name, @@ -632,6 +654,8 @@ prep_cdevsw(struct cdevsw *devsw) devsw->d_dump = dead_dump; devsw->d_kqfilter = dead_kqfilter; } + if (devsw->d_version == D_VERSION_01) + devsw->d_mmap_single = NULL; if (devsw->d_flags & D_TTY) { if (devsw->d_ioctl == NULL) devsw->d_ioctl = ttyioctl; @@ -668,6 +692,7 @@ prep_cdevsw(struct cdevsw *devsw) FIXUP(d_mmap, no_mmap, giant_mmap); FIXUP(d_strategy, no_strategy, giant_strategy); FIXUP(d_kqfilter, no_kqfilter, giant_kqfilter); + FIXUP(d_mmap_single, no_mmap_single, giant_mmap_single); if (devsw->d_dump == NULL) devsw->d_dump = no_dump; Modified: stable/7/sys/sys/conf.h ============================================================================== --- stable/7/sys/sys/conf.h Thu Sep 3 13:56:18 2009 (r196781) +++ stable/7/sys/sys/conf.h Thu Sep 3 14:23:50 2009 (r196782) @@ -106,6 +106,7 @@ struct thread; struct uio; struct knote; struct clonedevs; +struct vm_object; struct vnode; /* @@ -139,10 +140,10 @@ typedef int d_poll_t(struct cdev *dev, i typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn); typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot); +typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **object, int nprot); typedef void d_purge_t(struct cdev *dev); -typedef int d_spare2_t(struct cdev *dev); - typedef int dumper_t( void *priv, /* Private to the driver. */ void *virtual, /* Virtual (mapped) address. */ @@ -177,7 +178,8 @@ typedef int dumper_t( */ #define D_VERSION_00 0x20011966 #define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */ -#define D_VERSION D_VERSION_01 +#define D_VERSION_02 0x28042009 /* Add d_mmap_single */ +#define D_VERSION D_VERSION_02 /* * Flags used for internal housekeeping @@ -203,7 +205,7 @@ struct cdevsw { dumper_t *d_dump; d_kqfilter_t *d_kqfilter; d_purge_t *d_purge; - d_spare2_t *d_spare2; + d_mmap_single_t *d_mmap_single; uid_t d_uid; gid_t d_gid; mode_t d_mode; Modified: stable/7/sys/vm/vm_mmap.c ============================================================================== --- stable/7/sys/vm/vm_mmap.c Thu Sep 3 13:56:18 2009 (r196781) +++ stable/7/sys/vm/vm_mmap.c Thu Sep 3 14:23:50 2009 (r196782) @@ -116,9 +116,9 @@ vmmapentry_rsrc_init(dummy) } static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, - int *, struct vnode *, vm_ooffset_t, vm_object_t *); + int *, struct vnode *, vm_ooffset_t *, vm_object_t *); static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, - int *, struct cdev *, vm_ooffset_t, vm_object_t *); + int *, struct cdev *, vm_ooffset_t *, vm_object_t *); /* * MPSAFE @@ -1132,14 +1132,13 @@ munlock(td, uap) int vm_mmap_vnode(struct thread *td, vm_size_t objsize, vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, - struct vnode *vp, vm_ooffset_t foff, vm_object_t *objp) + struct vnode *vp, vm_ooffset_t *foffp, vm_object_t *objp) { struct vattr va; - void *handle; vm_object_t obj; + vm_offset_t foff; struct mount *mp; - struct cdevsw *dsw; - int error, flags, type; + int error, flags; int vfslocked; mp = vp->v_mount; @@ -1148,6 +1147,7 @@ vm_mmap_vnode(struct thread *td, vm_size VFS_UNLOCK_GIANT(vfslocked); return (error); } + foff = *foffp; flags = *flagsp; obj = vp->v_object; if (vp->v_type == VREG) { @@ -1163,41 +1163,12 @@ vm_mmap_vnode(struct thread *td, vm_size vp = (struct vnode*)obj->handle; vget(vp, LK_EXCLUSIVE, td); } - type = OBJT_VNODE; - handle = vp; } else if (vp->v_type == VCHR) { - type = OBJT_DEVICE; - handle = vp->v_rdev; - - dsw = dev_refthread(handle); - if (dsw == NULL) { - error = ENXIO; - goto done; - } - if (dsw->d_flags & D_MMAP_ANON) { - dev_relthread(handle); - *maxprotp = VM_PROT_ALL; - *flagsp |= MAP_ANON; - error = 0; - goto done; - } - dev_relthread(handle); - /* - * cdevs does not provide private mappings of any kind. - */ - if ((*maxprotp & VM_PROT_WRITE) == 0 && - (prot & PROT_WRITE) != 0) { - error = EACCES; - goto done; - } - if (flags & (MAP_PRIVATE|MAP_COPY)) { - error = EINVAL; - goto done; - } - /* - * Force device mappings to be shared. - */ - flags |= MAP_SHARED; + error = vm_mmap_cdev(td, objsize, prot, maxprotp, flagsp, + vp->v_rdev, foffp, objp); + if (error == 0) + goto mark_atime; + goto done; } else { error = EINVAL; goto done; @@ -1224,18 +1195,18 @@ vm_mmap_vnode(struct thread *td, vm_size * we do not need to sync it. * Adjust object size to be the size of actual file. */ - if (vp->v_type == VREG) { - objsize = round_page(va.va_size); - if (va.va_nlink == 0) - flags |= MAP_NOSYNC; - } - obj = vm_pager_allocate(type, handle, objsize, prot, foff); + objsize = round_page(va.va_size); + if (va.va_nlink == 0) + flags |= MAP_NOSYNC; + obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff); if (obj == NULL) { - error = (type == OBJT_DEVICE ? EINVAL : ENOMEM); + error = ENOMEM; goto done; } *objp = obj; *flagsp = flags; + +mark_atime: vfs_mark_atime(vp, td); done: @@ -1255,11 +1226,11 @@ done: int vm_mmap_cdev(struct thread *td, vm_size_t objsize, vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, - struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp) + struct cdev *cdev, vm_ooffset_t *foff, vm_object_t *objp) { vm_object_t obj; struct cdevsw *dsw; - int flags; + int error, flags; flags = *flagsp; @@ -1272,25 +1243,43 @@ vm_mmap_cdev(struct thread *td, vm_size_ *flagsp |= MAP_ANON; return (0); } - dev_relthread(cdev); /* - * cdevs does not provide private mappings of any kind. + * cdevs do not provide private mappings of any kind. */ if ((*maxprotp & VM_PROT_WRITE) == 0 && - (prot & PROT_WRITE) != 0) + (prot & PROT_WRITE) != 0) { + dev_relthread(cdev); return (EACCES); - if (flags & (MAP_PRIVATE|MAP_COPY)) + } + if (flags & (MAP_PRIVATE|MAP_COPY)) { + dev_relthread(cdev); return (EINVAL); + } /* * Force device mappings to be shared. */ flags |= MAP_SHARED; #ifdef MAC_XXX - error = mac_check_cdev_mmap(td->td_ucred, cdev, prot); - if (error != 0) + error = mac_cdev_check_mmap(td->td_ucred, cdev, prot); + if (error != 0) { + dev_relthread(cdev); return (error); + } #endif - obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff); + /* + * First, try d_mmap_single(). If that is not implemented + * (returns ENODEV), fall back to using the device pager. + * Note that d_mmap_single() must return a reference to the + * object (it needs to bump the reference count of the object + * it returns somehow). + * + * XXX assumes VM_PROT_* == PROT_* + */ + error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot); + dev_relthread(cdev); + if (error != ENODEV) + return (error); + obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff); if (obj == NULL) return (EINVAL); *objp = obj; @@ -1356,11 +1345,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, switch (handle_type) { case OBJT_DEVICE: error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, - handle, foff, &object); + handle, &foff, &object); break; case OBJT_VNODE: error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, - handle, foff, &object); + handle, &foff, &object); break; case OBJT_DEFAULT: if (handle == NULL) { From brian at FreeBSD.org Thu Sep 3 18:16:03 2009 From: brian at FreeBSD.org (Brian Somers) Date: Thu Sep 3 18:16:10 2009 Subject: svn commit: r196793 - stable/7/usr.sbin/ppp Message-ID: <200909031816.n83IG3jB041106@svn.freebsd.org> Author: brian Date: Thu Sep 3 18:16:03 2009 New Revision: 196793 URL: http://svn.freebsd.org/changeset/base/196793 Log: MFC r196530: Document that ppp handles pipe(2) descriptors specially in -direct mode. Modified: stable/7/usr.sbin/ppp/ (props changed) stable/7/usr.sbin/ppp/ppp.8.m4 Modified: stable/7/usr.sbin/ppp/ppp.8.m4 ============================================================================== --- stable/7/usr.sbin/ppp/ppp.8.m4 Thu Sep 3 17:37:23 2009 (r196792) +++ stable/7/usr.sbin/ppp/ppp.8.m4 Thu Sep 3 18:16:03 2009 (r196793) @@ -27,7 +27,7 @@ changecom(,)dnl .\" .\" $FreeBSD$ .\" -.Dd May 24, 2007 +.Dd August 25, 2009 .Dt PPP 8 .Os .Sh NAME @@ -171,6 +171,17 @@ If callback is configured, will use the .Dq set device information when dialing back. +.Pp +When run in +.Fl direct +mode, +.Nm +will behave slightly differently if descriptor 0 was created by +.Xr pipe 2 . +As pipes are not bi-directional, ppp will redirect all writes to descriptor +1 (standard output), leaving only reads acting on descriptor 0. +No special action is taken if descriptor 0 was created by +.Xr socketpair 2 . .It Fl dedicated This option is designed for machines connected with a dedicated wire. @@ -6070,6 +6081,8 @@ This socket is used to pass links betwee .Xr tcpdump 1 , .Xr telnet 1 , .Xr kldload 2 , +.Xr pipe 2 , +.Xr socketpair 2 , ifdef({LOCALNAT},{},{.Xr libalias 3 , })dnl ifdef({LOCALRAD},{},{.Xr libradius 3 , From alc at FreeBSD.org Fri Sep 4 04:48:12 2009 From: alc at FreeBSD.org (Alan Cox) Date: Fri Sep 4 04:48:23 2009 Subject: svn commit: r196807 - in stable/7/sys: . contrib/pf vm Message-ID: <200909040448.n844mCdq054063@svn.freebsd.org> Author: alc Date: Fri Sep 4 04:48:12 2009 New Revision: 196807 URL: http://svn.freebsd.org/changeset/base/196807 Log: MFC r190912 Previously, when vm_page_free_toq() was performed on a page belonging to a reservation, unless all of the reservation's pages were free, the reservation was moved to the head of the partially-populated reservations queue, where it would be the next reservation to be broken in case the free page queues were emptied. Now, instead, I am moving it to the tail. Very likely this reservation is in the process of being freed in its entirety, so placing it at the tail of the queue makes it more likely that the underlying physical memory will be returned to the free page queues as one contiguous chunk. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/vm/vm_reserv.c Modified: stable/7/sys/vm/vm_reserv.c ============================================================================== --- stable/7/sys/vm/vm_reserv.c Fri Sep 4 01:44:31 2009 (r196806) +++ stable/7/sys/vm/vm_reserv.c Fri Sep 4 04:48:12 2009 (r196807) @@ -138,8 +138,8 @@ static vm_reserv_t vm_reserv_array; * The partially-populated reservation queue * * This queue enables the fast recovery of an unused cached or free small page - * from a partially-populated reservation. The head of this queue is either - * the least-recently-populated or most-recently-depopulated reservation. + * from a partially-populated reservation. The reservation at the head of + * this queue is the least-recently-changed, partially-populated reservation. * * Access to this queue is synchronized by the free page queue lock. */ @@ -209,7 +209,7 @@ sysctl_vm_reserv_partpopq(SYSCTL_HANDLER /* * Reduces the given reservation's population count. If the population count * becomes zero, the reservation is destroyed. Additionally, moves the - * reservation to the head of the partially-populated reservations queue if the + * reservation to the tail of the partially-populated reservations queue if the * population count is non-zero. * * The free page queue lock must be held. @@ -235,7 +235,7 @@ vm_reserv_depopulate(vm_reserv_t rv) vm_reserv_freed++; } else { rv->inpartpopq = TRUE; - TAILQ_INSERT_HEAD(&vm_rvq_partpop, rv, partpopq); + TAILQ_INSERT_TAIL(&vm_rvq_partpop, rv, partpopq); } } From alc at FreeBSD.org Fri Sep 4 05:06:15 2009 From: alc at FreeBSD.org (Alan Cox) Date: Fri Sep 4 05:06:32 2009 Subject: svn commit: r196808 - in stable/7/sys: . amd64/include contrib/pf Message-ID: <200909040506.n8456FjI054462@svn.freebsd.org> Author: alc Date: Fri Sep 4 05:06:15 2009 New Revision: 196808 URL: http://svn.freebsd.org/changeset/base/196808 Log: MFC r193729 Now that amd64's kernel map is 512GB (r192469), there is no reason to cap its buffer map at 400MB. Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/include/param.h stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/amd64/include/param.h ============================================================================== --- stable/7/sys/amd64/include/param.h Fri Sep 4 04:48:12 2009 (r196807) +++ stable/7/sys/amd64/include/param.h Fri Sep 4 05:06:15 2009 (r196808) @@ -131,15 +131,6 @@ #endif /* - * Ceiling on size of buffer cache (really only effects write queueing, - * the VM page cache is not effected), can be changed via - * the kern.maxbcache /boot/loader.conf variable. - */ -#ifndef VM_BCACHE_SIZE_MAX -#define VM_BCACHE_SIZE_MAX (400 * 1024 * 1024) -#endif - -/* * Mach derived conversion macros */ #define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK)) From jhb at FreeBSD.org Fri Sep 4 19:59:33 2009 From: jhb at FreeBSD.org (John Baldwin) Date: Fri Sep 4 19:59:40 2009 Subject: svn commit: r196838 - in stable/7/sys: . amd64/amd64 amd64/include arm/include contrib/pf dev/iir i386/i386 i386/include ia64/include kern powerpc/include sparc64/include sun4v/include sun4v/sun4v vm Message-ID: <200909041959.n84JxWGA009848@svn.freebsd.org> Author: jhb Date: Fri Sep 4 19:59:32 2009 New Revision: 196838 URL: http://svn.freebsd.org/changeset/base/196838 Log: MFC 193396, 193521, 194331, 194337, 194376, 194454, 194562, 194642, 195033, 195385, 195649, 195660, 195749, and 195774: Add support to the virtual memory system for configuring machine- dependent memory attributes: - Refactor contigmalloc() into two functions: a simple front-end that deals with the malloc tag and calls a new back-end, kmem_alloc_contig(), that allocates the pages and maps them. - Use kmem_alloc_contig() to implement the UMA back-end allocator for jumbo frame zones. - Use kmem_alloc_contig() to allocate the top-level page tables for PAE. - Introduce vm_memattr_t to as a type to hold memory attributes. - Introduce vm_object_set_memattr() for setting the default memory attributes that will be given to an object's pages. - Introduce and use pmap_page_{get,set}_memattr() for getting and setting a page's machine-dependent memory attributes. Add full support for these functions on amd64 and i386 and stubs for them on the other architectures. The function pmap_page_set_memattr() is also responsible for any other machine-dependent aspects of changing a page's memory attributes, such as flushing the cache or updating the direct map. The uses include kmem_alloc_contig(), vm_page_alloc(), and the device pager: kmem_alloc_contig() can now be used to allocate kernel memory with non-default memory attributes on amd64 and i386. vm_page_alloc() and the device pager will set the memory attributes for the real or fictitious page according to the object's default memory attributes. - Update the various pmap functions on amd64 and i386 that map pages to incorporate each page's memory attributes in the mapping. Reviewed by: alc Added: stable/7/sys/amd64/include/vm.h - copied, changed from r195033, head/sys/amd64/include/vm.h stable/7/sys/arm/include/vm.h - copied, changed from r195033, head/sys/arm/include/vm.h stable/7/sys/i386/include/vm.h - copied, changed from r195033, head/sys/i386/include/vm.h stable/7/sys/ia64/include/vm.h - copied, changed from r195033, head/sys/ia64/include/vm.h stable/7/sys/powerpc/include/vm.h - copied, changed from r195033, head/sys/powerpc/include/vm.h stable/7/sys/sparc64/include/vm.h - copied, changed from r195033, head/sys/sparc64/include/vm.h stable/7/sys/sun4v/include/vm.h - copied, changed from r195033, head/sys/sun4v/include/vm.h Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/amd64/pmap.c stable/7/sys/amd64/include/pmap.h stable/7/sys/arm/include/pmap.h stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/iir/iir.c stable/7/sys/dev/iir/iir_ctrl.c stable/7/sys/i386/i386/pmap.c stable/7/sys/i386/include/pmap.h stable/7/sys/ia64/include/pmap.h stable/7/sys/kern/kern_mbuf.c stable/7/sys/powerpc/include/pmap.h stable/7/sys/sparc64/include/pmap.h stable/7/sys/sun4v/include/pmap.h stable/7/sys/sun4v/sun4v/pmap.c stable/7/sys/vm/device_pager.c stable/7/sys/vm/pmap.h stable/7/sys/vm/vm.h stable/7/sys/vm/vm_contig.c stable/7/sys/vm/vm_extern.h stable/7/sys/vm/vm_object.c stable/7/sys/vm/vm_object.h stable/7/sys/vm/vm_page.c stable/7/sys/vm/vm_phys.c Modified: stable/7/sys/amd64/amd64/pmap.c ============================================================================== --- stable/7/sys/amd64/amd64/pmap.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/amd64/amd64/pmap.c Fri Sep 4 19:59:32 2009 (r196838) @@ -618,6 +618,7 @@ pmap_page_init(vm_page_t m) { TAILQ_INIT(&m->md.pv_list); + m->md.pat_mode = PAT_WRITE_BACK; } /* @@ -748,21 +749,6 @@ pmap_cache_bits(int mode, boolean_t is_p /* The PAT bit is different for PTE's and PDE's. */ pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT; - /* If we don't support PAT, map extended modes to older ones. */ - if (!(cpu_feature & CPUID_PAT)) { - switch (mode) { - case PAT_UNCACHEABLE: - case PAT_WRITE_THROUGH: - case PAT_WRITE_BACK: - break; - case PAT_UNCACHED: - case PAT_WRITE_COMBINING: - case PAT_WRITE_PROTECTED: - mode = PAT_UNCACHEABLE; - break; - } - } - /* Map the caching mode to a PAT index. */ switch (mode) { #ifdef PAT_WORKS @@ -1134,7 +1120,8 @@ pmap_qenter(vm_offset_t sva, vm_page_t * endpte = pte + count; while (pte < endpte) { oldpte |= *pte; - pte_store(pte, VM_PAGE_TO_PHYS(*ma) | PG_G | PG_RW | PG_V); + pte_store(pte, VM_PAGE_TO_PHYS(*ma) | PG_G | + pmap_cache_bits((*ma)->md.pat_mode, 0) | PG_RW | PG_V); pte++; ma++; } @@ -3046,7 +3033,7 @@ validate: /* * Now validate mapping with desired protection/wiring. */ - newpte = (pt_entry_t)(pa | PG_V); + newpte = (pt_entry_t)(pa | pmap_cache_bits(m->md.pat_mode, 0) | PG_V); if ((prot & VM_PROT_WRITE) != 0) { newpte |= PG_RW; vm_page_flag_set(m, PG_WRITEABLE); @@ -3131,7 +3118,8 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t " in pmap %p", va, pmap); return (FALSE); } - newpde = VM_PAGE_TO_PHYS(m) | PG_PS | PG_V; + newpde = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 1) | + PG_PS | PG_V; if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) { newpde |= PG_MANAGED; @@ -3318,7 +3306,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_ */ pmap->pm_stats.resident_count++; - pa = VM_PAGE_TO_PHYS(m); + pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 0); if ((prot & VM_PROT_EXECUTE) == 0) pa |= pg_nx; @@ -3359,6 +3347,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs pd_entry_t *pde; vm_paddr_t pa, ptepa; vm_page_t p, pdpg; + int pat_mode; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); KASSERT(object->type == OBJT_DEVICE, @@ -3369,6 +3358,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs p = vm_page_lookup(object, pindex); KASSERT(p->valid == VM_PAGE_BITS_ALL, ("pmap_object_init_pt: invalid page %p", p)); + pat_mode = p->md.pat_mode; /* * Abort the mapping if the first page is not physically @@ -3380,21 +3370,28 @@ pmap_object_init_pt(pmap_t pmap, vm_offs /* * Skip the first page. Abort the mapping if the rest of - * the pages are not physically contiguous. + * the pages are not physically contiguous or have differing + * memory attributes. */ p = TAILQ_NEXT(p, listq); for (pa = ptepa + PAGE_SIZE; pa < ptepa + size; pa += PAGE_SIZE) { KASSERT(p->valid == VM_PAGE_BITS_ALL, ("pmap_object_init_pt: invalid page %p", p)); - if (pa != VM_PAGE_TO_PHYS(p)) + if (pa != VM_PAGE_TO_PHYS(p) || + pat_mode != p->md.pat_mode) return; p = TAILQ_NEXT(p, listq); } - /* Map using 2MB pages. */ + /* + * Map using 2MB pages. Since "ptepa" is 2M aligned and + * "size" is a multiple of 2M, adding the PAT setting to "pa" + * will not affect the termination of this loop. + */ PMAP_LOCK(pmap); - for (pa = ptepa; pa < ptepa + size; pa += NBPDR) { + for (pa = ptepa | pmap_cache_bits(pat_mode, 1); pa < ptepa + + size; pa += NBPDR) { pdpg = pmap_allocpde(pmap, addr, M_NOWAIT); if (pdpg == NULL) { /* @@ -4305,6 +4302,26 @@ pmap_unmapdev(vm_offset_t va, vm_size_t } /* + * Sets the memory attribute for the specified page. + */ +void +pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) +{ + + m->md.pat_mode = ma; + + /* + * If "m" is a normal page, update its direct mapping. This update + * can be relied upon to perform any cache operations that are + * required for data coherence. + */ + if ((m->flags & PG_FICTITIOUS) == 0 && + pmap_change_attr(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), PAGE_SIZE, + m->md.pat_mode)) + panic("memory attribute change on the direct map failed"); +} + +/* * Changes the specified virtual address range's memory type to that given by * the parameter "mode". The specified virtual address range must be * completely contained within either the direct map or the kernel map. If Modified: stable/7/sys/amd64/include/pmap.h ============================================================================== --- stable/7/sys/amd64/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/amd64/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -234,7 +234,7 @@ struct pv_entry; struct pv_chunk; struct md_page { - int pv_unused; + int pat_mode; TAILQ_HEAD(,pv_entry) pv_list; }; @@ -306,6 +306,7 @@ extern vm_paddr_t dump_avail[]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; +#define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode) #define pmap_unmapbios(va, sz) pmap_unmapdev((va), (sz)) void pmap_bootstrap(vm_paddr_t *); @@ -319,6 +320,7 @@ void *pmap_mapbios(vm_paddr_t, vm_size_t void *pmap_mapdev(vm_paddr_t, vm_size_t); void *pmap_mapdev_attr(vm_paddr_t, vm_size_t, int); boolean_t pmap_page_is_mapped(vm_page_t m); +void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma); void pmap_unmapdev(vm_offset_t, vm_size_t); void pmap_invalidate_page(pmap_t, vm_offset_t); void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); Copied and modified: stable/7/sys/amd64/include/vm.h (from r195033, head/sys/amd64/include/vm.h) ============================================================================== --- head/sys/amd64/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/amd64/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -32,14 +32,14 @@ #include -/* Cache control options. */ -#define VM_CACHE_UNCACHEABLE ((vm_cache_mode_t)PAT_UNCACHEABLE) -#define VM_CACHE_WRITE_COMBINING ((vm_cache_mode_t)PAT_WRITE_COMBINING) -#define VM_CACHE_WRITE_THROUGH ((vm_cache_mode_t)PAT_WRITE_THROUGH) -#define VM_CACHE_WRITE_PROTECTED ((vm_cache_mode_t)PAT_WRITE_PROTECTED) -#define VM_CACHE_WRITE_BACK ((vm_cache_mode_t)PAT_WRITE_BACK) -#define VM_CACHE_UNCACHED ((vm_cache_mode_t)PAT_UNCACHED) +/* Memory attributes. */ +#define VM_MEMATTR_UNCACHEABLE ((vm_memattr_t)PAT_UNCACHEABLE) +#define VM_MEMATTR_WRITE_COMBINING ((vm_memattr_t)PAT_WRITE_COMBINING) +#define VM_MEMATTR_WRITE_THROUGH ((vm_memattr_t)PAT_WRITE_THROUGH) +#define VM_MEMATTR_WRITE_PROTECTED ((vm_memattr_t)PAT_WRITE_PROTECTED) +#define VM_MEMATTR_WRITE_BACK ((vm_memattr_t)PAT_WRITE_BACK) +#define VM_MEMATTR_UNCACHED ((vm_memattr_t)PAT_UNCACHED) -#define VM_CACHE_DEFAULT VM_CACHE_WRITE_BACK +#define VM_MEMATTR_DEFAULT VM_MEMATTR_WRITE_BACK #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/arm/include/pmap.h ============================================================================== --- stable/7/sys/arm/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/arm/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -75,7 +75,10 @@ #endif +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) +#define pmap_page_set_memattr(m, ma) (void)0 + /* * Pmap stuff */ Copied and modified: stable/7/sys/arm/include/vm.h (from r195033, head/sys/arm/include/vm.h) ============================================================================== --- head/sys/arm/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/arm/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -29,7 +29,7 @@ #ifndef _MACHINE_VM_H_ #define _MACHINE_VM_H_ -/* Cache control is not (yet) implemented. */ -#define VM_CACHE_DEFAULT 0 +/* Memory attribute configuration is not (yet) implemented. */ +#define VM_MEMATTR_DEFAULT 0 #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/dev/iir/iir.c ============================================================================== --- stable/7/sys/dev/iir/iir.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/dev/iir/iir.c Fri Sep 4 19:59:32 2009 (r196838) @@ -67,9 +67,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include - #include MALLOC_DEFINE(M_GDTBUF, "iirbuf", "iir driver buffer"); Modified: stable/7/sys/dev/iir/iir_ctrl.c ============================================================================== --- stable/7/sys/dev/iir/iir_ctrl.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/dev/iir/iir_ctrl.c Fri Sep 4 19:59:32 2009 (r196838) @@ -52,10 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include -#include #include Modified: stable/7/sys/i386/i386/pmap.c ============================================================================== --- stable/7/sys/i386/i386/pmap.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/i386/i386/pmap.c Fri Sep 4 19:59:32 2009 (r196838) @@ -556,20 +556,18 @@ pmap_page_init(vm_page_t m) { TAILQ_INIT(&m->md.pv_list); + m->md.pat_mode = PAT_WRITE_BACK; } #ifdef PAE - -static MALLOC_DEFINE(M_PMAPPDPT, "pmap", "pmap pdpt"); - static void * pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) { /* Inform UMA that this allocator uses kernel_map/object. */ *flags = UMA_SLAB_KERNEL; - return (contigmalloc(PAGE_SIZE, M_PMAPPDPT, 0, 0x0ULL, 0xffffffffULL, - 1, 0)); + return ((void *)kmem_alloc_contig(kernel_map, bytes, wait, 0x0ULL, + 0xffffffffULL, 1, 0, VM_MEMATTR_DEFAULT)); } #endif @@ -1206,7 +1204,8 @@ pmap_qenter(vm_offset_t sva, vm_page_t * endpte = pte + count; while (pte < endpte) { oldpte |= *pte; - pte_store(pte, VM_PAGE_TO_PHYS(*ma) | pgeflag | PG_RW | PG_V); + pte_store(pte, VM_PAGE_TO_PHYS(*ma) | pgeflag | + pmap_cache_bits((*ma)->md.pat_mode, 0) | PG_RW | PG_V); pte++; ma++; } @@ -3161,7 +3160,7 @@ validate: /* * Now validate mapping with desired protection/wiring. */ - newpte = (pt_entry_t)(pa | PG_V); + newpte = (pt_entry_t)(pa | pmap_cache_bits(m->md.pat_mode, 0) | PG_V); if ((prot & VM_PROT_WRITE) != 0) { newpte |= PG_RW; vm_page_flag_set(m, PG_WRITEABLE); @@ -3243,7 +3242,8 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t " in pmap %p", va, pmap); return (FALSE); } - newpde = VM_PAGE_TO_PHYS(m) | PG_PS | PG_V; + newpde = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 1) | + PG_PS | PG_V; if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) { newpde |= PG_MANAGED; @@ -3428,7 +3428,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_ */ pmap->pm_stats.resident_count++; - pa = VM_PAGE_TO_PHYS(m); + pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 0); #ifdef PAE if ((prot & VM_PROT_EXECUTE) == 0) pa |= pg_nx; @@ -3471,6 +3471,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs pd_entry_t *pde; vm_paddr_t pa, ptepa; vm_page_t p; + int pat_mode; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); KASSERT(object->type == OBJT_DEVICE, @@ -3482,6 +3483,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs p = vm_page_lookup(object, pindex); KASSERT(p->valid == VM_PAGE_BITS_ALL, ("pmap_object_init_pt: invalid page %p", p)); + pat_mode = p->md.pat_mode; /* * Abort the mapping if the first page is not physically @@ -3493,21 +3495,28 @@ pmap_object_init_pt(pmap_t pmap, vm_offs /* * Skip the first page. Abort the mapping if the rest of - * the pages are not physically contiguous. + * the pages are not physically contiguous or have differing + * memory attributes. */ p = TAILQ_NEXT(p, listq); for (pa = ptepa + PAGE_SIZE; pa < ptepa + size; pa += PAGE_SIZE) { KASSERT(p->valid == VM_PAGE_BITS_ALL, ("pmap_object_init_pt: invalid page %p", p)); - if (pa != VM_PAGE_TO_PHYS(p)) + if (pa != VM_PAGE_TO_PHYS(p) || + pat_mode != p->md.pat_mode) return; p = TAILQ_NEXT(p, listq); } - /* Map using 2/4MB pages. */ + /* + * Map using 2/4MB pages. Since "ptepa" is 2/4M aligned and + * "size" is a multiple of 2/4M, adding the PAT setting to + * "pa" will not affect the termination of this loop. + */ PMAP_LOCK(pmap); - for (pa = ptepa; pa < ptepa + size; pa += NBPDR) { + for (pa = ptepa | pmap_cache_bits(pat_mode, 1); pa < ptepa + + size; pa += NBPDR) { pde = pmap_pde(pmap, addr); if (*pde == 0) { pde_store(pde, pa | PG_PS | PG_M | PG_A | @@ -3723,7 +3732,8 @@ pmap_zero_page(vm_page_t m) if (*sysmaps->CMAP2) panic("pmap_zero_page: CMAP2 busy"); sched_pin(); - *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M; + *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | + pmap_cache_bits(m->md.pat_mode, 0); invlcaddr(sysmaps->CADDR2); pagezero(sysmaps->CADDR2); *sysmaps->CMAP2 = 0; @@ -3745,9 +3755,10 @@ pmap_zero_page_area(vm_page_t m, int off sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; mtx_lock(&sysmaps->lock); if (*sysmaps->CMAP2) - panic("pmap_zero_page: CMAP2 busy"); + panic("pmap_zero_page_area: CMAP2 busy"); sched_pin(); - *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M; + *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | + pmap_cache_bits(m->md.pat_mode, 0); invlcaddr(sysmaps->CADDR2); if (off == 0 && size == PAGE_SIZE) pagezero(sysmaps->CADDR2); @@ -3769,9 +3780,10 @@ pmap_zero_page_idle(vm_page_t m) { if (*CMAP3) - panic("pmap_zero_page: CMAP3 busy"); + panic("pmap_zero_page_idle: CMAP3 busy"); sched_pin(); - *CMAP3 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M; + *CMAP3 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | + pmap_cache_bits(m->md.pat_mode, 0); invlcaddr(CADDR3); pagezero(CADDR3); *CMAP3 = 0; @@ -3798,8 +3810,10 @@ pmap_copy_page(vm_page_t src, vm_page_t sched_pin(); invlpg((u_int)sysmaps->CADDR1); invlpg((u_int)sysmaps->CADDR2); - *sysmaps->CMAP1 = PG_V | VM_PAGE_TO_PHYS(src) | PG_A; - *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M; + *sysmaps->CMAP1 = PG_V | VM_PAGE_TO_PHYS(src) | PG_A | + pmap_cache_bits(src->md.pat_mode, 0); + *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M | + pmap_cache_bits(dst->md.pat_mode, 0); bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE); *sysmaps->CMAP1 = 0; *sysmaps->CMAP2 = 0; @@ -4420,7 +4434,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_ pa += PAGE_SIZE; } pmap_invalidate_range(kernel_pmap, va, tmpva); - pmap_invalidate_cache(); + /* If "Self Snoop" is supported, do nothing. */ + if (!(cpu_feature & CPUID_SS)) + pmap_invalidate_cache(); return ((void *)(va + offset)); } @@ -4455,6 +4471,25 @@ pmap_unmapdev(vm_offset_t va, vm_size_t } /* + * Sets the memory attribute for the specified page. + */ +void +pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) +{ + + m->md.pat_mode = ma; + + /* + * If "m" is a normal page, flush it from the cache. + */ + if ((m->flags & PG_FICTITIOUS) == 0) { + /* If "Self Snoop" is supported, do nothing. */ + if (!(cpu_feature & CPUID_SS)) + pmap_invalidate_cache(); + } +} + +/* * Changes the specified virtual address range's memory type to that given by * the parameter "mode". The specified virtual address range must be * completely contained within either the kernel map. Modified: stable/7/sys/i386/include/pmap.h ============================================================================== --- stable/7/sys/i386/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/i386/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -332,7 +332,7 @@ struct pv_entry; struct pv_chunk; struct md_page { - int pv_unused; + int pat_mode; TAILQ_HEAD(,pv_entry) pv_list; }; @@ -411,6 +411,7 @@ extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; +#define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode) #define pmap_unmapbios(va, sz) pmap_unmapdev((va), (sz)) void pmap_bootstrap(vm_paddr_t); @@ -423,6 +424,7 @@ void *pmap_mapbios(vm_paddr_t, vm_size_t void *pmap_mapdev(vm_paddr_t, vm_size_t); void *pmap_mapdev_attr(vm_paddr_t, vm_size_t, int); boolean_t pmap_page_is_mapped(vm_page_t m); +void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma); void pmap_unmapdev(vm_offset_t, vm_size_t); pt_entry_t *pmap_pte(pmap_t, vm_offset_t) __pure2; void pmap_set_pg(void); Copied and modified: stable/7/sys/i386/include/vm.h (from r195033, head/sys/i386/include/vm.h) ============================================================================== --- head/sys/i386/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/i386/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -32,14 +32,14 @@ #include -/* Cache control options. */ -#define VM_CACHE_UNCACHEABLE ((vm_cache_mode_t)PAT_UNCACHEABLE) -#define VM_CACHE_WRITE_COMBINING ((vm_cache_mode_t)PAT_WRITE_COMBINING) -#define VM_CACHE_WRITE_THROUGH ((vm_cache_mode_t)PAT_WRITE_THROUGH) -#define VM_CACHE_WRITE_PROTECTED ((vm_cache_mode_t)PAT_WRITE_PROTECTED) -#define VM_CACHE_WRITE_BACK ((vm_cache_mode_t)PAT_WRITE_BACK) -#define VM_CACHE_UNCACHED ((vm_cache_mode_t)PAT_UNCACHED) +/* Memory attributes. */ +#define VM_MEMATTR_UNCACHEABLE ((vm_memattr_t)PAT_UNCACHEABLE) +#define VM_MEMATTR_WRITE_COMBINING ((vm_memattr_t)PAT_WRITE_COMBINING) +#define VM_MEMATTR_WRITE_THROUGH ((vm_memattr_t)PAT_WRITE_THROUGH) +#define VM_MEMATTR_WRITE_PROTECTED ((vm_memattr_t)PAT_WRITE_PROTECTED) +#define VM_MEMATTR_WRITE_BACK ((vm_memattr_t)PAT_WRITE_BACK) +#define VM_MEMATTR_UNCACHED ((vm_memattr_t)PAT_UNCACHED) -#define VM_CACHE_DEFAULT VM_CACHE_WRITE_BACK +#define VM_MEMATTR_DEFAULT VM_MEMATTR_WRITE_BACK #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/ia64/include/pmap.h ============================================================================== --- stable/7/sys/ia64/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/ia64/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -118,7 +118,9 @@ extern vm_offset_t virtual_end; extern uint64_t pmap_vhpt_base[]; extern int pmap_vhpt_log2size; +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) +#define pmap_page_set_memattr(m, ma) (void)0 #define pmap_mapbios(pa, sz) pmap_mapdev(pa, sz) #define pmap_unmapbios(va, sz) pmap_unmapdev(va, sz) Copied and modified: stable/7/sys/ia64/include/vm.h (from r195033, head/sys/ia64/include/vm.h) ============================================================================== --- head/sys/ia64/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/ia64/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -32,13 +32,13 @@ #include #include -/* Cache control options. */ -#define VM_CACHE_WRITE_BACK ((vm_cache_mode_t)PTE_MA_WB) -#define VM_CACHE_UNCACHEABLE ((vm_cache_mode_t)PTE_MA_UC) -#define VM_CACHE_UNCACHEABLE_EXPORTED ((vm_cache_mode_t)PTE_MA_UCE) -#define VM_CACHE_WRITE_COMBINING ((vm_cache_mode_t)PTE_MA_WC) -#define VM_CACHE_NATPAGE ((vm_cache_mode_t)PTE_MA_NATPAGE) +/* Memory attributes. */ +#define VM_MEMATTR_WRITE_BACK ((vm_memattr_t)PTE_MA_WB) +#define VM_MEMATTR_UNCACHEABLE ((vm_memattr_t)PTE_MA_UC) +#define VM_MEMATTR_UNCACHEABLE_EXPORTED ((vm_memattr_t)PTE_MA_UCE) +#define VM_MEMATTR_WRITE_COMBINING ((vm_memattr_t)PTE_MA_WC) +#define VM_MEMATTR_NATPAGE ((vm_memattr_t)PTE_MA_NATPAGE) -#define VM_CACHE_DEFAULT VM_CACHE_WRITE_BACK +#define VM_MEMATTR_DEFAULT VM_MEMATTR_WRITE_BACK #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/kern/kern_mbuf.c ============================================================================== --- stable/7/sys/kern/kern_mbuf.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/kern/kern_mbuf.c Fri Sep 4 19:59:32 2009 (r196838) @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -233,9 +235,6 @@ static void mb_zfini_pack(void *, int); static void mb_reclaim(void *); static void mbuf_init(void *); static void *mbuf_jumbo_alloc(uma_zone_t, int, u_int8_t *, int); -static void mbuf_jumbo_free(void *, int, u_int8_t); - -static MALLOC_DEFINE(M_JUMBOFRAME, "jumboframes", "mbuf jumbo frame buffers"); /* Ensure that MSIZE doesn't break dtom() - it must be a power of 2 */ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); @@ -297,7 +296,6 @@ mbuf_init(void *dummy) if (nmbjumbo9 > 0) uma_zone_set_max(zone_jumbo9, nmbjumbo9); uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc); - uma_zone_set_freef(zone_jumbo9, mbuf_jumbo_free); zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES, mb_ctor_clust, mb_dtor_clust, @@ -310,7 +308,6 @@ mbuf_init(void *dummy) if (nmbjumbo16 > 0) uma_zone_set_max(zone_jumbo16, nmbjumbo16); uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc); - uma_zone_set_freef(zone_jumbo16, mbuf_jumbo_free); zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), NULL, NULL, @@ -359,18 +356,8 @@ mbuf_jumbo_alloc(uma_zone_t zone, int by /* Inform UMA that this allocator uses kernel_map/object. */ *flags = UMA_SLAB_KERNEL; - return (contigmalloc(bytes, M_JUMBOFRAME, wait, (vm_paddr_t)0, - ~(vm_paddr_t)0, 1, 0)); -} - -/* - * UMA backend page deallocator for the jumbo frame zones. - */ -static void -mbuf_jumbo_free(void *mem, int size, u_int8_t flags) -{ - - contigfree(mem, size, M_JUMBOFRAME); + return ((void *)kmem_alloc_contig(kernel_map, bytes, wait, + (vm_paddr_t)0, ~(vm_paddr_t)0, 1, 0, VM_MEMATTR_DEFAULT)); } /* Modified: stable/7/sys/powerpc/include/pmap.h ============================================================================== --- stable/7/sys/powerpc/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/powerpc/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -72,7 +72,9 @@ struct md_page { extern struct pmap kernel_pmap_store; #define kernel_pmap (&kernel_pmap_store) +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!LIST_EMPTY(&(m)->md.mdpg_pvoh)) +#define pmap_page_set_memattr(m, ma) (void)0 #ifdef _KERNEL Copied and modified: stable/7/sys/powerpc/include/vm.h (from r195033, head/sys/powerpc/include/vm.h) ============================================================================== --- head/sys/powerpc/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/powerpc/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -31,10 +31,12 @@ #include -/* Cache control options. */ -#define VM_CACHE_INHIBIT ((vm_cache_mode_t)PTE_I) -#define VM_CACHE_WRITE_THROUGH ((vm_cache_mode_t)PTE_W) +/* Memory attributes. */ +#define VM_MEMATTR_CACHING_INHIBIT ((vm_memattr_t)PTE_I) +#define VM_MEMATTR_GUARD ((vm_memattr_t)PTE_G) +#define VM_MEMATTR_MEMORY_COHERENCE ((vm_memattr_t)PTE_M) +#define VM_MEMATTR_WRITE_THROUGH ((vm_memattr_t)PTE_W) -#define VM_CACHE_DEFAULT 0 +#define VM_MEMATTR_DEFAULT 0 #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/sparc64/include/pmap.h ============================================================================== --- stable/7/sys/sparc64/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/sparc64/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -77,6 +77,9 @@ struct pmap { #define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx) #define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx) +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT +#define pmap_page_set_memattr(m, ma) (void)0 + void pmap_bootstrap(vm_offset_t ekva); vm_paddr_t pmap_kextract(vm_offset_t va); void pmap_kenter(vm_offset_t va, vm_page_t m); Copied and modified: stable/7/sys/sparc64/include/vm.h (from r195033, head/sys/sparc64/include/vm.h) ============================================================================== --- head/sys/sparc64/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/sparc64/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -29,7 +29,7 @@ #ifndef _MACHINE_VM_H_ #define _MACHINE_VM_H_ -/* Cache control is not (yet) implemented. */ -#define VM_CACHE_DEFAULT 0 +/* Memory attribute configuration is not (yet) implemented. */ +#define VM_MEMATTR_DEFAULT 0 #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/sun4v/include/pmap.h ============================================================================== --- stable/7/sys/sun4v/include/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/sun4v/include/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -106,7 +106,9 @@ typedef struct pv_entry { TAILQ_ENTRY(pv_entry) pv_plist; } *pv_entry_t; +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) +#define pmap_page_set_memattr(m, ma) (void)0 void pmap_bootstrap(vm_offset_t ekva); vm_paddr_t pmap_kextract(vm_offset_t va); Copied and modified: stable/7/sys/sun4v/include/vm.h (from r195033, head/sys/sun4v/include/vm.h) ============================================================================== --- head/sys/sun4v/include/vm.h Fri Jun 26 04:47:43 2009 (r195033, copy source) +++ stable/7/sys/sun4v/include/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -29,7 +29,7 @@ #ifndef _MACHINE_VM_H_ #define _MACHINE_VM_H_ -/* Cache control is not (yet) implemented. */ -#define VM_CACHE_DEFAULT 0 +/* Memory attribute configuration is not (yet) implemented. */ +#define VM_MEMATTR_DEFAULT 0 #endif /* !_MACHINE_PMAP_H_ */ Modified: stable/7/sys/sun4v/sun4v/pmap.c ============================================================================== --- stable/7/sys/sun4v/sun4v/pmap.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/sun4v/sun4v/pmap.c Fri Sep 4 19:59:32 2009 (r196838) @@ -1298,7 +1298,7 @@ pmap_alloc_zeroed_contig_pages(int npage while (m == NULL) { for (i = 0; phys_avail[i + 1] != 0; i += 2) { m = vm_phys_alloc_contig(npages, phys_avail[i], - phys_avail[i + 1], alignment, (1UL<<34)); + phys_avail[i + 1], alignment, (1UL<<34)); if (m) goto found; } Modified: stable/7/sys/vm/device_pager.c ============================================================================== --- stable/7/sys/vm/device_pager.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/vm/device_pager.c Fri Sep 4 19:59:32 2009 (r196838) @@ -70,9 +70,9 @@ static struct mtx dev_pager_mtx; static uma_zone_t fakepg_zone; -static vm_page_t dev_pager_getfake(vm_paddr_t); +static vm_page_t dev_pager_getfake(vm_paddr_t, vm_memattr_t); static void dev_pager_putfake(vm_page_t); -static void dev_pager_updatefake(vm_page_t, vm_paddr_t); +static void dev_pager_updatefake(vm_page_t, vm_paddr_t, vm_memattr_t); struct pagerops devicepagerops = { .pgo_init = dev_pager_init, @@ -194,7 +194,7 @@ dev_pager_dealloc(object) /* * Free up our fake pages. */ - while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) != 0) { + while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) != NULL) { TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, pageq); dev_pager_putfake(m); } @@ -209,7 +209,8 @@ dev_pager_getpages(object, m, count, req { vm_pindex_t offset; vm_paddr_t paddr; - vm_page_t page; + vm_page_t m_paddr, page; + vm_memattr_t memattr; struct cdev *dev; int i, ret; int prot; @@ -219,7 +220,9 @@ dev_pager_getpages(object, m, count, req VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); dev = object->handle; - offset = m[reqpage]->pindex; + page = m[reqpage]; + offset = page->pindex; + memattr = object->memattr; VM_OBJECT_UNLOCK(object); csw = dev_refthread(dev); if (csw == NULL) @@ -233,14 +236,20 @@ dev_pager_getpages(object, m, count, req KASSERT(ret == 0, ("dev_pager_getpage: map function returns error")); td->td_fpop = fpop; dev_relthread(dev); - - if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) { + /* If "paddr" is a real page, perform a sanity check on "memattr". */ + if ((m_paddr = vm_phys_paddr_to_vm_page(paddr)) != NULL && + pmap_page_get_memattr(m_paddr) != memattr) { + memattr = pmap_page_get_memattr(m_paddr); + printf( + "WARNING: A device driver has set \"memattr\" inconsistently.\n"); + } + if ((page->flags & PG_FICTITIOUS) != 0) { /* * If the passed in reqpage page is a fake page, update it with * the new physical address. */ VM_OBJECT_LOCK(object); - dev_pager_updatefake(m[reqpage], paddr); + dev_pager_updatefake(page, paddr, memattr); if (count > 1) { vm_page_lock_queues(); for (i = 0; i < count; i++) { @@ -254,7 +263,7 @@ dev_pager_getpages(object, m, count, req * Replace the passed in reqpage page with our own fake page and * free up the all of the original pages. */ - page = dev_pager_getfake(paddr); + page = dev_pager_getfake(paddr, memattr); VM_OBJECT_LOCK(object); TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq); vm_page_lock_queues(); @@ -264,7 +273,7 @@ dev_pager_getpages(object, m, count, req vm_page_insert(page, object, offset); m[reqpage] = page; } - + page->valid = VM_PAGE_BITS_ALL; return (VM_PAGER_OK); } @@ -294,48 +303,48 @@ dev_pager_haspage(object, pindex, before } /* - * Instantiate a fictitious page. Unlike physical memory pages, only - * the machine-independent fields must be initialized. + * Create a fictitious page with the specified physical address and memory + * attribute. The memory attribute is the only the machine-dependent aspect + * of a fictitious page that must be initialized. */ static vm_page_t -dev_pager_getfake(paddr) - vm_paddr_t paddr; +dev_pager_getfake(vm_paddr_t paddr, vm_memattr_t memattr) { vm_page_t m; - m = uma_zalloc(fakepg_zone, M_WAITOK); - + m = uma_zalloc(fakepg_zone, M_WAITOK | M_ZERO); + m->phys_addr = paddr; + /* Fictitious pages don't use "segind". */ m->flags = PG_FICTITIOUS; + /* Fictitious pages don't use "order" or "pool". */ m->oflags = VPO_BUSY; - m->valid = VM_PAGE_BITS_ALL; - m->dirty = 0; - m->busy = 0; - m->queue = PQ_NONE; - m->object = NULL; - m->wire_count = 1; - m->hold_count = 0; - m->phys_addr = paddr; - + pmap_page_set_memattr(m, memattr); return (m); } +/* + * Release a fictitious page. + */ static void -dev_pager_putfake(m) - vm_page_t m; +dev_pager_putfake(vm_page_t m) { + if (!(m->flags & PG_FICTITIOUS)) panic("dev_pager_putfake: bad page"); uma_zfree(fakepg_zone, m); } +/* + * Update the given fictitious page to the specified physical address and + * memory attribute. + */ static void -dev_pager_updatefake(m, paddr) - vm_page_t m; - vm_paddr_t paddr; +dev_pager_updatefake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr) { + if (!(m->flags & PG_FICTITIOUS)) panic("dev_pager_updatefake: bad page"); m->phys_addr = paddr; - m->valid = VM_PAGE_BITS_ALL; + pmap_page_set_memattr(m, memattr); } Modified: stable/7/sys/vm/pmap.h ============================================================================== --- stable/7/sys/vm/pmap.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/vm/pmap.h Fri Sep 4 19:59:32 2009 (r196838) @@ -79,10 +79,16 @@ struct pmap_statistics { }; typedef struct pmap_statistics *pmap_statistics_t; +/* + * Each machine dependent implementation is expected to provide: + * + * vm_memattr_t pmap_page_get_memattr(vm_page_t); + * boolean_t pmap_page_is_mapped(vm_page_t); + * void pmap_page_set_memattr(vm_page_t, vm_memattr_t); + */ #include #ifdef _KERNEL -struct proc; struct thread; /* Modified: stable/7/sys/vm/vm.h ============================================================================== --- stable/7/sys/vm/vm.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/vm/vm.h Fri Sep 4 19:59:32 2009 (r196838) @@ -61,6 +61,14 @@ #ifndef VM_H #define VM_H +#include + +/* + * The exact set of memory attributes is machine dependent. However, every + * machine is required to define VM_MEMATTR_DEFAULT. + */ +typedef char vm_memattr_t; /* memory attribute codes */ + typedef char vm_inherit_t; /* inheritance codes */ #define VM_INHERIT_SHARE ((vm_inherit_t) 0) Modified: stable/7/sys/vm/vm_contig.c ============================================================================== --- stable/7/sys/vm/vm_contig.c Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/vm/vm_contig.c Fri Sep 4 19:59:32 2009 (r196838) @@ -193,37 +193,37 @@ vm_page_release_contig(vm_page_t m, vm_p * specified through the given flags, then the pages are zeroed * before they are mapped. */ -static void * -contigmapping(vm_page_t m, vm_pindex_t npages, int flags) +static vm_offset_t +contigmapping(vm_map_t map, vm_size_t size, vm_page_t m, vm_memattr_t memattr, + int flags) { vm_object_t object = kernel_object; - vm_map_t map = kernel_map; vm_offset_t addr, tmp_addr; - vm_pindex_t i; vm_map_lock(map); - if (vm_map_findspace(map, vm_map_min(map), npages << PAGE_SHIFT, &addr) - != KERN_SUCCESS) { + if (vm_map_findspace(map, vm_map_min(map), size, &addr)) { vm_map_unlock(map); - return (NULL); + return (0); } vm_object_reference(object); vm_map_insert(map, object, addr - VM_MIN_KERNEL_ADDRESS, - addr, addr + (npages << PAGE_SHIFT), VM_PROT_ALL, VM_PROT_ALL, 0); + addr, addr + size, VM_PROT_ALL, VM_PROT_ALL, 0); vm_map_unlock(map); - tmp_addr = addr; VM_OBJECT_LOCK(object); - for (i = 0; i < npages; i++) { - vm_page_insert(&m[i], object, + for (tmp_addr = addr; tmp_addr < addr + size; tmp_addr += PAGE_SIZE) { + if (memattr != VM_MEMATTR_DEFAULT) + pmap_page_set_memattr(m, memattr); + vm_page_insert(m, object, OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS)); - if ((flags & M_ZERO) && !(m[i].flags & PG_ZERO)) - pmap_zero_page(&m[i]); - tmp_addr += PAGE_SIZE; + if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0) + pmap_zero_page(m); + m->valid = VM_PAGE_BITS_ALL; + m++; } VM_OBJECT_UNLOCK(object); - vm_map_wire(map, addr, addr + (npages << PAGE_SHIFT), + vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); - return ((void *)addr); + return (addr); } void * @@ -237,11 +237,26 @@ contigmalloc( unsigned long boundary) { void *ret; + + ret = (void *)kmem_alloc_contig(kernel_map, size, flags, low, high, + alignment, boundary, VM_MEMATTR_DEFAULT); + if (ret != NULL) + malloc_type_allocated(type, round_page(size)); + return (ret); +} + +vm_offset_t +kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low, + vm_paddr_t high, unsigned long alignment, unsigned long boundary, + vm_memattr_t memattr) +{ + vm_offset_t ret; vm_page_t pages; unsigned long npgs; int actl, actmax, inactl, inactmax, tries; - npgs = round_page(size) >> PAGE_SHIFT; + size = round_page(size); + npgs = size >> PAGE_SHIFT; tries = 0; retry: pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary); @@ -267,13 +282,11 @@ again: tries++; goto retry; } - ret = NULL; + ret = 0; } else { - ret = contigmapping(pages, npgs, flags); - if (ret == NULL) + ret = contigmapping(map, size, pages, memattr, flags); + if (ret == 0) vm_page_release_contig(pages, npgs); - else - malloc_type_allocated(type, npgs << PAGE_SHIFT); } return (ret); } @@ -281,9 +294,7 @@ again: void contigfree(void *addr, unsigned long size, struct malloc_type *type) { - vm_pindex_t npgs; - npgs = round_page(size) >> PAGE_SHIFT; kmem_free(kernel_map, (vm_offset_t)addr, size); - malloc_type_freed(type, npgs << PAGE_SHIFT); + malloc_type_freed(type, round_page(size)); } Modified: stable/7/sys/vm/vm_extern.h ============================================================================== --- stable/7/sys/vm/vm_extern.h Fri Sep 4 19:20:46 2009 (r196837) +++ stable/7/sys/vm/vm_extern.h Fri Sep 4 19:59:32 2009 (r196838) @@ -57,6 +57,9 @@ int swapon(struct thread *, void *, int int kernacc(void *, int, int); vm_offset_t kmem_alloc(vm_map_t, vm_size_t); +vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, + vm_paddr_t low, vm_paddr_t high, unsigned long alignment, + unsigned long boundary, vm_memattr_t memattr); vm_offset_t kmem_alloc_nofault(vm_map_t, vm_size_t); vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t); void kmem_free(vm_map_t, vm_offset_t, vm_size_t); Modified: stable/7/sys/vm/vm_object.c ============================================================================== --- stable/7/sys/vm/vm_object.c Fri Sep 4 19:20:46 2009 (r196837) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From alc at FreeBSD.org Sat Sep 5 05:28:07 2009 From: alc at FreeBSD.org (Alan Cox) Date: Sat Sep 5 05:28:18 2009 Subject: svn commit: r196852 - in stable/7/sys: . contrib/pf pc98/include Message-ID: <200909050528.n855S7M0038174@svn.freebsd.org> Author: alc Date: Sat Sep 5 05:28:07 2009 New Revision: 196852 URL: http://svn.freebsd.org/changeset/base/196852 Log: MFC r195089 Add stub vm.h for pc98. Added: stable/7/sys/pc98/include/vm.h - copied unchanged from r195089, head/sys/pc98/include/vm.h Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) Copied: stable/7/sys/pc98/include/vm.h (from r195089, head/sys/pc98/include/vm.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/sys/pc98/include/vm.h Sat Sep 5 05:28:07 2009 (r196852, copy of r195089, head/sys/pc98/include/vm.h) @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#include From alc at FreeBSD.org Sat Sep 5 05:57:44 2009 From: alc at FreeBSD.org (Alan Cox) Date: Sat Sep 5 05:58:01 2009 Subject: svn commit: r196853 - in stable/7/sys: . contrib/pf i386/include Message-ID: <200909050557.n855viT4038786@svn.freebsd.org> Author: alc Date: Sat Sep 5 05:57:44 2009 New Revision: 196853 URL: http://svn.freebsd.org/changeset/base/196853 Log: MFC r194295 Move (read|write)_cyrix_reg() inlines from specialreg.h to cpufunc.h. specialreg.h now consists solely of register-related macros. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/i386/include/cpufunc.h stable/7/sys/i386/include/specialreg.h Modified: stable/7/sys/i386/include/cpufunc.h ============================================================================== --- stable/7/sys/i386/include/cpufunc.h Sat Sep 5 05:28:07 2009 (r196852) +++ stable/7/sys/i386/include/cpufunc.h Sat Sep 5 05:57:44 2009 (r196853) @@ -646,6 +646,20 @@ load_dr7(u_int dr7) __asm __volatile("movl %0,%%dr7" : : "r" (dr7)); } +static __inline u_char +read_cyrix_reg(u_char reg) +{ + outb(0x22, reg); + return inb(0x23); +} + +static __inline void +write_cyrix_reg(u_char reg, u_char data) +{ + outb(0x22, reg); + outb(0x23, data); +} + static __inline register_t intr_disable(void) { @@ -720,6 +734,7 @@ u_int rdr5(void); u_int rdr6(void); u_int rdr7(void); uint64_t rdtsc(void); +u_char read_cyrix_reg(u_char reg); u_int read_eflags(void); u_int rfs(void); uint64_t rgdt(void); @@ -728,6 +743,7 @@ uint64_t ridt(void); u_short rldt(void); u_short rtr(void); void wbinvd(void); +void write_cyrix_reg(u_char reg, u_char data); void write_eflags(u_int ef); void wrmsr(u_int msr, uint64_t newval); Modified: stable/7/sys/i386/include/specialreg.h ============================================================================== --- stable/7/sys/i386/include/specialreg.h Sat Sep 5 05:28:07 2009 (r196852) +++ stable/7/sys/i386/include/specialreg.h Sat Sep 5 05:57:44 2009 (r196853) @@ -540,20 +540,4 @@ #define VIA_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */ #define VIA_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */ -#ifndef LOCORE -static __inline u_char -read_cyrix_reg(u_char reg) -{ - outb(0x22, reg); - return inb(0x23); -} - -static __inline void -write_cyrix_reg(u_char reg, u_char data) -{ - outb(0x22, reg); - outb(0x23, data); -} -#endif - #endif /* !_MACHINE_SPECIALREG_H_ */ From kib at FreeBSD.org Sat Sep 5 13:31:16 2009 From: kib at FreeBSD.org (Konstantin Belousov) Date: Sat Sep 5 13:31:33 2009 Subject: svn commit: r196860 - in stable/7/sys: . contrib/pf fs/pseudofs Message-ID: <200909051331.n85DVGPb054244@svn.freebsd.org> Author: kib Date: Sat Sep 5 13:31:16 2009 New Revision: 196860 URL: http://svn.freebsd.org/changeset/base/196860 Log: MFC r196689: Remove spurious pfs_unlock(). Approved by: re (rwatson) Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/fs/pseudofs/pseudofs_vnops.c Modified: stable/7/sys/fs/pseudofs/pseudofs_vnops.c ============================================================================== --- stable/7/sys/fs/pseudofs/pseudofs_vnops.c Sat Sep 5 13:10:54 2009 (r196859) +++ stable/7/sys/fs/pseudofs/pseudofs_vnops.c Sat Sep 5 13:31:16 2009 (r196860) @@ -339,7 +339,6 @@ pfs_getextattr(struct vop_getextattr_arg if (proc != NULL) PROC_UNLOCK(proc); - pfs_unlock(pn); PFS_RETURN (error); } From rodrigc at FreeBSD.org Sat Sep 5 18:44:36 2009 From: rodrigc at FreeBSD.org (Craig Rodrigues) Date: Sat Sep 5 18:44:58 2009 Subject: svn commit: r196870 - stable/7/etc/rc.d Message-ID: <200909051844.n85IiaNs061373@svn.freebsd.org> Author: rodrigc Date: Sat Sep 5 18:44:36 2009 New Revision: 196870 URL: http://svn.freebsd.org/changeset/base/196870 Log: This set of MFC's brings savecore closer to the trunk version. Now, crashinfo will only be run if the following conditions are true: - savecore -C determines that a crash dump exists - crashinfo_enable="YES" MFC: 182460 Add the ability to run /usr/sbin/crashinfo on a new core dump automatically during boot. MFC: 180318 Remove the $DUMPDIR variable. It's redundant and the rest of the script uses $dumpdir directly. MFC: 180317 Make checking for the availability of core dumps work in the case that $dumpdev is not set to "AUTO". Modified: stable/7/etc/rc.d/savecore Modified: stable/7/etc/rc.d/savecore ============================================================================== --- stable/7/etc/rc.d/savecore Sat Sep 5 17:40:27 2009 (r196869) +++ stable/7/etc/rc.d/savecore Sat Sep 5 18:44:36 2009 (r196870) @@ -52,10 +52,25 @@ savecore_prestart() savecore_start() { + local dev + + case "${dumpdev}" in + [Aa][Uu][Tt][Oo]) + dev= + ;; + *) + dev="${dumpdev}" + ;; + esac + echo "Checking for core dump on ${dumpdev}..." - savecore ${savecore_flags} ${dumpdir} ${dumpdev} - if checkyesno crashinfo_enable; then - ${crashinfo_program} -d ${dumpdir} + if savecore -C "${dumpdir}" "${dev}" >/dev/null; then + savecore ${savecore_flags} ${dumpdir} ${dumpdev} + if checkyesno crashinfo_enable; then + ${crashinfo_program} -d ${dumpdir} + fi + else + [ -z "${rc_quiet}" ] && echo "No core dumps found" fi } From kib at FreeBSD.org Sun Sep 6 15:23:03 2009 From: kib at FreeBSD.org (Konstantin Belousov) Date: Sun Sep 6 15:23:09 2009 Subject: svn commit: r196894 - stable/7/sys/vm Message-ID: <200909061523.n86FN3QP087453@svn.freebsd.org> Author: kib Date: Sun Sep 6 15:23:03 2009 New Revision: 196894 URL: http://svn.freebsd.org/changeset/base/196894 Log: Partial MFC of r194459 by thompsa, without merge recording, to allow the vm_phys_paddr_to_vm_page(9) to return NULL instead of panicking when supplied physical address does not correspond to a vm page. This is needed for device pager (and not yet merged sg pager) to skip memattr checks on specific addresses. Reported by: Thierry Herbelot Modified: stable/7/sys/vm/vm_phys.c Modified: stable/7/sys/vm/vm_phys.c ============================================================================== --- stable/7/sys/vm/vm_phys.c Sun Sep 6 14:23:26 2009 (r196893) +++ stable/7/sys/vm/vm_phys.c Sun Sep 6 15:23:03 2009 (r196894) @@ -382,8 +382,7 @@ vm_phys_paddr_to_vm_page(vm_paddr_t pa) if (pa >= seg->start && pa < seg->end) return (&seg->first_page[atop(pa - seg->start)]); } - panic("vm_phys_paddr_to_vm_page: paddr %#jx is not in any segment", - (uintmax_t)pa); + return (NULL); } /* From attilio at FreeBSD.org Mon Sep 7 08:37:25 2009 From: attilio at FreeBSD.org (Attilio Rao) Date: Mon Sep 7 08:37:32 2009 Subject: svn commit: r196912 - in stable/7/sys: kern sys Message-ID: <200909070837.n878bP79008232@svn.freebsd.org> Author: attilio Date: Mon Sep 7 08:37:25 2009 New Revision: 196912 URL: http://svn.freebsd.org/changeset/base/196912 Log: MFC r196334: Add the macro ASSERT_ATOMIC_LOAD_PTR(), enabled through INVARIANTS, which asserts for the correct alignment of datas which need to be read atomically without locks. Use that macro in locking primitives. Modified: stable/7/sys/kern/kern_mutex.c stable/7/sys/kern/kern_rwlock.c stable/7/sys/kern/kern_sx.c stable/7/sys/sys/systm.h Modified: stable/7/sys/kern/kern_mutex.c ============================================================================== --- stable/7/sys/kern/kern_mutex.c Mon Sep 7 06:37:44 2009 (r196911) +++ stable/7/sys/kern/kern_mutex.c Mon Sep 7 08:37:25 2009 (r196912) @@ -724,6 +724,9 @@ mtx_init(struct mtx *m, const char *name MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE | MTX_NOWITNESS | MTX_DUPOK | MTX_NOPROFILE)) == 0); + ASSERT_ATOMIC_LOAD_PTR(m->mtx_lock, + ("%s: mtx_lock not aligned for %s:%p", __func__, name, + &m->mtx_lock)); #ifdef MUTEX_DEBUG /* Diagnostic and error correction */ Modified: stable/7/sys/kern/kern_rwlock.c ============================================================================== --- stable/7/sys/kern/kern_rwlock.c Mon Sep 7 06:37:44 2009 (r196911) +++ stable/7/sys/kern/kern_rwlock.c Mon Sep 7 08:37:25 2009 (r196912) @@ -137,6 +137,9 @@ rw_init_flags(struct rwlock *rw, const c MPASS((opts & ~(RW_DUPOK | RW_NOPROFILE | RW_NOWITNESS | RW_QUIET | RW_RECURSE)) == 0); + ASSERT_ATOMIC_LOAD_PTR(rw->rw_lock, + ("%s: rw_lock not aligned for %s:%p", __func__, name, + &rw->rw_lock)); flags = LO_UPGRADABLE | LO_RECURSABLE; if (opts & RW_DUPOK) Modified: stable/7/sys/kern/kern_sx.c ============================================================================== --- stable/7/sys/kern/kern_sx.c Mon Sep 7 06:37:44 2009 (r196911) +++ stable/7/sys/kern/kern_sx.c Mon Sep 7 08:37:25 2009 (r196912) @@ -166,6 +166,9 @@ sx_init_flags(struct sx *sx, const char MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK | SX_NOPROFILE | SX_ADAPTIVESPIN)) == 0); + ASSERT_ATOMIC_LOAD_PTR(sx->sx_lock, + ("%s: sx_lock not aligned for %s:%p", __func__, description, + &sx->sx_lock)); flags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE; if (opts & SX_DUPOK) Modified: stable/7/sys/sys/systm.h ============================================================================== --- stable/7/sys/sys/systm.h Mon Sep 7 06:37:44 2009 (r196911) +++ stable/7/sys/sys/systm.h Mon Sep 7 08:37:25 2009 (r196912) @@ -96,6 +96,17 @@ extern int maxusers; /* system tune hin #endif /* + * Assert that a pointer can be loaded from memory atomically. + * + * This assertion enforces stronger alignment than necessary. For example, + * on some architectures, atomicity for unaligned loads will depend on + * whether or not the load spans multiple cache lines. + */ +#define ASSERT_ATOMIC_LOAD_PTR(var, msg) \ + KASSERT(sizeof(var) == sizeof(void *) && \ + ((uintptr_t)&(var) & (sizeof(void *) - 1)) == 0, msg) + +/* * XXX the hints declarations are even more misplaced than most declarations * in this file, since they are needed in one file (per arch) and only used * in two files. From attilio at FreeBSD.org Mon Sep 7 08:41:15 2009 From: attilio at FreeBSD.org (Attilio Rao) Date: Mon Sep 7 08:41:26 2009 Subject: svn commit: r196913 - stable/7/lib/libthr/thread Message-ID: <200909070841.n878fE6M008345@svn.freebsd.org> Author: attilio Date: Mon Sep 7 08:41:14 2009 New Revision: 196913 URL: http://svn.freebsd.org/changeset/base/196913 Log: MFC r195403: Fix a bug in read lock acquisition for rwlocks by bumping rdlock_count when a successfull rwlock_rdlock_common() take place. Modified: stable/7/lib/libthr/thread/thr_rtld.c stable/7/lib/libthr/thread/thr_rwlock.c Modified: stable/7/lib/libthr/thread/thr_rtld.c ============================================================================== --- stable/7/lib/libthr/thread/thr_rtld.c Mon Sep 7 08:37:25 2009 (r196912) +++ stable/7/lib/libthr/thread/thr_rtld.c Mon Sep 7 08:41:14 2009 (r196913) @@ -116,6 +116,7 @@ _thr_rtld_rlock_acquire(void *lock) THR_CRITICAL_ENTER(curthread); while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0) ; + curthread->rdlock_count++; RESTORE_ERRNO(); } @@ -150,6 +151,7 @@ _thr_rtld_lock_release(void *lock) state = l->lock.rw_state; if (_thr_rwlock_unlock(&l->lock) == 0) { + curthread->rdlock_count--; if ((state & URWLOCK_WRITE_OWNER) == 0) { THR_CRITICAL_LEAVE(curthread); } else { Modified: stable/7/lib/libthr/thread/thr_rwlock.c ============================================================================== --- stable/7/lib/libthr/thread/thr_rwlock.c Mon Sep 7 08:37:25 2009 (r196912) +++ stable/7/lib/libthr/thread/thr_rwlock.c Mon Sep 7 08:41:14 2009 (r196913) @@ -177,10 +177,11 @@ rwlock_rdlock_common(pthread_rwlock_t *r /* if interrupted, try to lock it in userland again. */ if (_thr_rwlock_tryrdlock(&prwlock->lock, flags) == 0) { ret = 0; - curthread->rdlock_count++; break; } } + if (ret == 0) + curthread->rdlock_count++; return (ret); } From attilio at FreeBSD.org Mon Sep 7 08:46:27 2009 From: attilio at FreeBSD.org (Attilio Rao) Date: Mon Sep 7 08:46:44 2009 Subject: svn commit: r196914 - stable/7/usr.sbin/tzsetup Message-ID: <200909070846.n878kQLe008508@svn.freebsd.org> Author: attilio Date: Mon Sep 7 08:46:26 2009 New Revision: 196914 URL: http://svn.freebsd.org/changeset/base/196914 Log: MFC r195339: Add a new option (-s) that, when specified, skips the question about adjusting the clock to UTC. Sponsored by: Sandvine Incorporated Modified: stable/7/usr.sbin/tzsetup/tzsetup.8 stable/7/usr.sbin/tzsetup/tzsetup.c Modified: stable/7/usr.sbin/tzsetup/tzsetup.8 ============================================================================== --- stable/7/usr.sbin/tzsetup/tzsetup.8 Mon Sep 7 08:41:14 2009 (r196913) +++ stable/7/usr.sbin/tzsetup/tzsetup.8 Mon Sep 7 08:46:26 2009 (r196914) @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd January 24, 1996 +.Dd September 05, 2009 .Dt TZSETUP 8 .Os .Sh NAME @@ -31,7 +31,7 @@ .Nd set local timezone .Sh SYNOPSIS .Nm -.Op Fl n +.Op Fl ns .Op Ar default .Sh DESCRIPTION The @@ -51,6 +51,9 @@ The following option is available: .Bl -tag -offset indent -width Fl .It Fl n Do not create or copy files. +.It Fl s +Skip the initial question about adjusting the clock if not set to +.Tn UTC . .El .Pp It is possible to short-circuit the menu system by specifying a Modified: stable/7/usr.sbin/tzsetup/tzsetup.c ============================================================================== --- stable/7/usr.sbin/tzsetup/tzsetup.c Mon Sep 7 08:41:14 2009 (r196913) +++ stable/7/usr.sbin/tzsetup/tzsetup.c Mon Sep 7 08:46:26 2009 (r196914) @@ -648,11 +648,14 @@ main(int argc, char **argv) dialog_utc = dialog_noyes; #endif - while ((c = getopt(argc, argv, "n")) != -1) { + while ((c = getopt(argc, argv, "ns")) != -1) { switch(c) { case 'n': reallydoit = 0; break; + case 's': + dialog_utc = NULL; + break; default: usage(); @@ -671,22 +674,25 @@ main(int argc, char **argv) make_menus(); init_dialog(); - if (!dialog_utc("Select local or UTC (Greenwich Mean Time) clock", - "Is this machine's CMOS clock set to UTC? If it is set to local time,\n" - "or you don't know, please choose NO here!", 7, 72)) { - if (reallydoit) - unlink(_PATH_WALL_CMOS_CLOCK); - } else { - if (reallydoit) { - fd = open(_PATH_WALL_CMOS_CLOCK, - O_WRONLY|O_CREAT|O_TRUNC, - S_IRUSR|S_IRGRP|S_IROTH); - if (fd < 0) - err(1, "create %s", _PATH_WALL_CMOS_CLOCK); - close(fd); + if (dialog_utc != NULL) { + if (!dialog_utc("Select local or UTC (Greenwich Mean Time) clock", + "Is this machine's CMOS clock set to UTC? If it is set to local time,\n" + "or you don't know, please choose NO here!", 7, 72)) { + if (reallydoit) + unlink(_PATH_WALL_CMOS_CLOCK); + } else { + if (reallydoit) { + fd = open(_PATH_WALL_CMOS_CLOCK, + O_WRONLY|O_CREAT|O_TRUNC, + S_IRUSR|S_IRGRP|S_IROTH); + if (fd < 0) + err(1, "create %s", + _PATH_WALL_CMOS_CLOCK); + close(fd); + } } + dialog_clear_norefresh(); } - dialog_clear_norefresh(); if (optind == argc - 1) { char *msg; asprintf(&msg, "\nUse the default `%s' zone?", argv[optind]); From attilio at FreeBSD.org Mon Sep 7 08:52:16 2009 From: attilio at FreeBSD.org (Attilio Rao) Date: Mon Sep 7 08:52:32 2009 Subject: svn commit: r196915 - in stable/7/sys: dev/hwpmc kern Message-ID: <200909070852.n878qFds008667@svn.freebsd.org> Author: attilio Date: Mon Sep 7 08:52:15 2009 New Revision: 196915 URL: http://svn.freebsd.org/changeset/base/196915 Log: MFC r195159 and r195005: * Don't assume a fixed number of preloaded KLDs but calculate at runtime. This avoind ending up into an endless loop. * Fix a LOR between pmc_sx and allproc/proctree locks Sponsored by: Sandvine Incorporated Modified: stable/7/sys/dev/hwpmc/hwpmc_logging.c stable/7/sys/dev/hwpmc/hwpmc_mod.c stable/7/sys/kern/kern_linker.c Modified: stable/7/sys/dev/hwpmc/hwpmc_logging.c ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_logging.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/dev/hwpmc/hwpmc_logging.c Mon Sep 7 08:52:15 2009 (r196915) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -552,6 +553,12 @@ pmclog_configure_log(struct pmc_mdep *md int error; struct proc *p; + /* + * As long as it is possible to get a LOR between pmc_sx lock and + * proctree/allproc sx locks used for adding a new process, assure + * the former is not held here. + */ + sx_assert(&pmc_sx, SA_UNLOCKED); PMCDBG(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); p = po->po_owner; Modified: stable/7/sys/dev/hwpmc/hwpmc_mod.c ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_mod.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/dev/hwpmc/hwpmc_mod.c Mon Sep 7 08:52:15 2009 (r196915) @@ -2666,7 +2666,7 @@ static const char *pmc_op_to_name[] = { static int pmc_syscall_handler(struct thread *td, void *syscall_args) { - int error, is_sx_downgraded, op; + int error, is_sx_downgraded, is_sx_locked, op; struct pmc_syscall_args *c; void *arg; @@ -2675,6 +2675,7 @@ pmc_syscall_handler(struct thread *td, v DROP_GIANT(); is_sx_downgraded = 0; + is_sx_locked = 1; c = (struct pmc_syscall_args *) syscall_args; @@ -2723,9 +2724,11 @@ pmc_syscall_handler(struct thread *td, v * a log file configured, flush its buffers and * de-configure it. */ - if (cl.pm_logfd >= 0) + if (cl.pm_logfd >= 0) { + sx_xunlock(&pmc_sx); + is_sx_locked = 0; error = pmclog_configure_log(md, po, cl.pm_logfd); - else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { + } else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { pmclog_process_closelog(po); error = pmclog_flush(po); if (error == 0) { @@ -3776,10 +3779,12 @@ pmc_syscall_handler(struct thread *td, v break; } - if (is_sx_downgraded) - sx_sunlock(&pmc_sx); - else - sx_xunlock(&pmc_sx); + if (is_sx_locked != 0) { + if (is_sx_downgraded) + sx_sunlock(&pmc_sx); + else + sx_xunlock(&pmc_sx); + } if (error) atomic_add_int(&pmc_stats.pm_syscall_errors, 1); Modified: stable/7/sys/kern/kern_linker.c ============================================================================== --- stable/7/sys/kern/kern_linker.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/kern/kern_linker.c Mon Sep 7 08:52:15 2009 (r196915) @@ -1882,62 +1882,41 @@ linker_basename(const char *path) } #ifdef HWPMC_HOOKS - -struct hwpmc_context { - int nobjects; - int nmappings; - struct pmckern_map_in *kobase; -}; - -static int -linker_hwpmc_list_object(linker_file_t lf, void *arg) -{ - struct hwpmc_context *hc; - - hc = arg; - - /* If we run out of mappings, fail. */ - if (hc->nobjects >= hc->nmappings) - return (1); - - /* Save the info for this linker file. */ - hc->kobase[hc->nobjects].pm_file = lf->filename; - hc->kobase[hc->nobjects].pm_address = (uintptr_t)lf->address; - hc->nobjects++; - return (0); -} - /* * Inform hwpmc about the set of kernel modules currently loaded. */ void * linker_hwpmc_list_objects(void) { - struct hwpmc_context hc; + linker_file_t lf; + struct pmckern_map_in *kobase; + int i, nmappings; - hc.nmappings = 15; /* a reasonable default */ + nmappings = 0; + KLD_LOCK(); + TAILQ_FOREACH(lf, &linker_files, link) + nmappings++; - retry: - /* allocate nmappings+1 entries */ - MALLOC(hc.kobase, struct pmckern_map_in *, - (hc.nmappings + 1) * sizeof(struct pmckern_map_in), M_LINKER, - M_WAITOK | M_ZERO); - - hc.nobjects = 0; - if (linker_file_foreach(linker_hwpmc_list_object, &hc) != 0) { - hc.nmappings = hc.nobjects; - FREE(hc.kobase, M_LINKER); - goto retry; + /* Allocate nmappings + 1 entries. */ + kobase = malloc((nmappings + 1) * sizeof(struct pmckern_map_in), + M_LINKER, M_WAITOK | M_ZERO); + i = 0; + TAILQ_FOREACH(lf, &linker_files, link) { + + /* Save the info for this linker file. */ + kobase[i].pm_file = lf->filename; + kobase[i].pm_address = (uintptr_t)lf->address; + i++; } + KLD_UNLOCK(); - KASSERT(hc.nobjects > 0, ("linker_hpwmc_list_objects: no kernel " - "objects?")); + KASSERT(i > 0, ("linker_hwpmc_list_objects: no kernel objects?")); /* The last entry of the malloced area comprises of all zeros. */ - KASSERT(hc.kobase[hc.nobjects].pm_file == NULL, + KASSERT(kobase[i].pm_file == NULL, ("linker_hwpmc_list_objects: last object not NULL")); - return ((void *)hc.kobase); + return ((void *)kobase); } #endif From attilio at FreeBSD.org Mon Sep 7 09:51:24 2009 From: attilio at FreeBSD.org (Attilio Rao) Date: Mon Sep 7 09:51:41 2009 Subject: svn commit: r196917 - in stable/7: bin/ps sys/kern Message-ID: <200909070951.n879pNst010173@svn.freebsd.org> Author: attilio Date: Mon Sep 7 09:51:23 2009 New Revision: 196917 URL: http://svn.freebsd.org/changeset/base/196917 Log: MFC r189078: * Implement ucomm with a dynamic size function in order to print out the threads name also in the case they are not the last one shown. * On AMD64 pointers don't have enough space to be printed. Fix it. * Check a return value for malloc which wasn't checked before Sponsored by: Sandvine Incorporated Modified: stable/7/bin/ps/extern.h stable/7/bin/ps/keyword.c stable/7/bin/ps/print.c stable/7/bin/ps/ps.c stable/7/sys/kern/kern_proc.c Modified: stable/7/bin/ps/extern.h ============================================================================== --- stable/7/bin/ps/extern.h Mon Sep 7 09:30:37 2009 (r196916) +++ stable/7/bin/ps/extern.h Mon Sep 7 09:51:23 2009 (r196917) @@ -39,7 +39,7 @@ extern fixpt_t ccpu; extern int cflag, eval, fscale, nlistread, rawcpu; extern unsigned long mempages; extern time_t now; -extern int sumrusage, termwidth, totwidth; +extern int showthreads, sumrusage, termwidth, totwidth; extern STAILQ_HEAD(velisthead, varent) varlist; __BEGIN_DECLS @@ -71,6 +71,7 @@ void priorityr(KINFO *, VARENT *); void rgroupname(KINFO *, VARENT *); void runame(KINFO *, VARENT *); void rvar(KINFO *, VARENT *); +int s_comm(KINFO *); int s_label(KINFO *); int s_rgroupname(KINFO *); int s_runame(KINFO *); Modified: stable/7/bin/ps/keyword.c ============================================================================== --- stable/7/bin/ps/keyword.c Mon Sep 7 09:30:37 2009 (r196916) +++ stable/7/bin/ps/keyword.c Mon Sep 7 09:51:23 2009 (r196917) @@ -79,8 +79,8 @@ static VAR var[] = { CHAR, NULL, 0}, {"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, - {"comm", "COMMAND", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, - NULL, 0}, + {"comm", "COMMAND", NULL, LJUST|DSIZ, ucomm, s_comm, + COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0}, {"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0, CHAR, NULL, 0}, {"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d", @@ -135,12 +135,13 @@ static VAR var[] = { LONG, "ld", 0}, {"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "ld", 0}, - {"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, 8, 0, CHAR, NULL, 0}, + {"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, sizeof(void *) * 2, 0, + CHAR, NULL, 0}, {"oublk", "OUBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_oublock), LONG, "ld", 0}, {"oublock", "", "oublk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, - {"paddr", "PADDR", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR, - "lx", 0}, + {"paddr", "PADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2, + KOFF(ki_paddr), KPTR, "lx", 0}, {"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6, 0, CHAR, NULL, 0}, {"pcpu", "", "%cpu", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"pending", "", "sig", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, @@ -194,13 +195,13 @@ static VAR var[] = { {"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0}, {"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0}, {"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0}, - {"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, NULL, - 0}, + {"ucomm", "UCOMM", NULL, LJUST|DSIZ, ucomm, s_comm, + COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0}, {"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid), UINT, UIDFMT, 0}, {"upr", "UPR", NULL, 0, upr, NULL, 3, 0, CHAR, NULL, 0}, - {"uprocp", "UPROCP", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR, - "lx", 0}, + {"uprocp", "UPROCP", NULL, 0, kvar, NULL, sizeof(void *) * 2, + KOFF(ki_paddr), KPTR, "lx", 0}, {"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN, 0, CHAR, NULL, 0}, {"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, @@ -324,6 +325,8 @@ findvar(char *p, int user, char **header */ rflen = strlen(v->alias) + strlen(hp) + 2; realfmt = malloc(rflen); + if (realfmt == NULL) + errx(1, "malloc failed"); snprintf(realfmt, rflen, "%s=%s", v->alias, hp); parsefmt(realfmt, user); } Modified: stable/7/bin/ps/print.c ============================================================================== --- stable/7/bin/ps/print.c Mon Sep 7 09:30:37 2009 (r196916) +++ stable/7/bin/ps/print.c Mon Sep 7 09:51:23 2009 (r196917) @@ -186,6 +186,7 @@ command(KINFO *k, VARENT *ve) void ucomm(KINFO *k, VARENT *ve) { + char tmpbuff[COMMLEN + OCOMMLEN + 2]; VAR *v; v = ve->var; @@ -193,8 +194,15 @@ ucomm(KINFO *k, VARENT *ve) if (k->ki_d.prefix) (void)printf("%s", k->ki_d.prefix); (void)printf("%s", k->ki_p->ki_comm); - } else - (void)printf("%-*s", v->width, k->ki_p->ki_comm); + } else { + bzero(tmpbuff, sizeof(tmpbuff)); + if (showthreads && k->ki_p->ki_numthreads > 1) + sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm, + k->ki_p->ki_ocomm); + else + sprintf(tmpbuff, "%s", k->ki_p->ki_comm); + (void)printf("%-*s", v->width, tmpbuff); + } } void @@ -822,6 +830,20 @@ out: } int +s_comm(KINFO *k) +{ + char tmpbuff[COMMLEN + OCOMMLEN + 2]; + + bzero(tmpbuff, sizeof(tmpbuff)); + if (showthreads && k->ki_p->ki_numthreads > 1) + sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm, + k->ki_p->ki_ocomm); + else + sprintf(tmpbuff, "%s", k->ki_p->ki_comm); + return (strlen(tmpbuff)); +} + +int s_label(KINFO *k) { char *string = NULL; Modified: stable/7/bin/ps/ps.c ============================================================================== --- stable/7/bin/ps/ps.c Mon Sep 7 09:30:37 2009 (r196916) +++ stable/7/bin/ps/ps.c Mon Sep 7 09:51:23 2009 (r196917) @@ -100,6 +100,7 @@ int rawcpu; /* -C */ int sumrusage; /* -S */ int termwidth; /* Width of the screen (0 == infinity). */ int totwidth; /* Calculated-width of requested variables. */ +int showthreads; /* will threads be shown? */ struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist); @@ -178,7 +179,7 @@ main(int argc, char *argv[]) char *cols; int all, ch, elem, flag, _fmt, i, lineno; int descendancy, nentries, nkept, nselectors; - int prtheader, showthreads, wflag, what, xkeep, xkeep_implied; + int prtheader, wflag, what, xkeep, xkeep_implied; char errbuf[_POSIX2_LINE_MAX]; (void) setlocale(LC_ALL, ""); Modified: stable/7/sys/kern/kern_proc.c ============================================================================== --- stable/7/sys/kern/kern_proc.c Mon Sep 7 09:30:37 2009 (r196916) +++ stable/7/sys/kern/kern_proc.c Mon Sep 7 09:51:23 2009 (r196917) @@ -115,6 +115,7 @@ MALLOC_DEFINE(M_SUBPROC, "subproc", "Pro static void doenterpgrp(struct proc *, struct pgrp *); static void orphanpg(struct pgrp *pg); +static void fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp); static void fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp); static void fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread); @@ -670,6 +671,30 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump) #endif /* DDB */ /* + * Rework the kinfo_proc members which need to be aggregated in the + * case of process-ware informations. + * Must be called with the target spinlock process held. + */ +static void +fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp) +{ + struct thread *td; + + PROC_SLOCK_ASSERT(p, MA_OWNED); + + kp->ki_estcpu = 0; + kp->ki_pctcpu = 0; + kp->ki_runtime = 0; + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + kp->ki_pctcpu += sched_pctcpu(td); + kp->ki_runtime += cputick2usec(td->td_runtime); + kp->ki_estcpu += td->td_estcpu; + thread_unlock(td); + } +} + +/* * Clear kinfo_proc and fill in any information that is common * to all threads in the process. * Must be called with the target process locked. @@ -868,14 +893,15 @@ fill_kinfo_thread(struct thread *td, str kp->ki_numthreads = p->p_numthreads; kp->ki_pcb = td->td_pcb; kp->ki_kstack = (void *)td->td_kstack; - kp->ki_pctcpu = sched_pctcpu(td); - kp->ki_estcpu = td->td_estcpu; kp->ki_slptime = (ticks - td->td_slptick) / hz; kp->ki_pri.pri_class = td->td_pri_class; kp->ki_pri.pri_user = td->td_user_pri; - if (preferthread) + if (preferthread) { kp->ki_runtime = cputick2usec(td->td_runtime); + kp->ki_pctcpu = sched_pctcpu(td); + kp->ki_estcpu = td->td_estcpu; + } /* We can't get this anymore but ps etc never used it anyway. */ kp->ki_rqindex = 0; @@ -895,8 +921,9 @@ fill_kinfo_proc(struct proc *p, struct k fill_kinfo_proc_only(p, kp); PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0); + MPASS (FIRST_THREAD_IN_PROC(p) != NULL); + fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0); + fill_kinfo_aggregate(p, kp); PROC_SUNLOCK(p); } @@ -962,28 +989,20 @@ sysctl_out_proc(struct proc *p, struct s PROC_LOCK_ASSERT(p, MA_OWNED); - fill_kinfo_proc_only(p, &kinfo_proc); - if (flags & KERN_PROC_NOTHREADS) { - PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), - &kinfo_proc, 0); - PROC_SUNLOCK(p); + fill_kinfo_proc(p, &kinfo_proc); + if (flags & KERN_PROC_NOTHREADS) error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); - } else { + sizeof(kinfo_proc)); + else { PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - FOREACH_THREAD_IN_PROC(p, td) { - fill_kinfo_thread(td, &kinfo_proc, 1); - error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); - if (error) - break; - } - else + MPASS(FIRST_THREAD_IN_PROC(p) != NULL); + FOREACH_THREAD_IN_PROC(p, td) { + fill_kinfo_thread(td, &kinfo_proc, 1); error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); + sizeof(kinfo_proc)); + if (error) + break; + } PROC_SUNLOCK(p); } PROC_UNLOCK(p); From ume at FreeBSD.org Mon Sep 7 10:15:51 2009 From: ume at FreeBSD.org (Hajimu UMEMOTO) Date: Mon Sep 7 10:16:09 2009 Subject: svn commit: r196918 - in stable/7: sbin/ifconfig share/man/man4 sys/net sys/netinet sys/netinet6 sys/sys Message-ID: <200909071015.n87AFoDx011798@svn.freebsd.org> Author: ume Date: Mon Sep 7 10:15:50 2009 New Revision: 196918 URL: http://svn.freebsd.org/changeset/base/196918 Log: MFC r193664, r193796, r193815: Fix and add a workaround on an issue of EtherIP packet with reversed version field sent via gif(4)+if_bridge(4). The EtherIP implementation found on FreeBSD 6.1, 6.2, 6.3, 7.0, 7.1, and 7.2 had an interoperability issue because it sent the incorrect EtherIP packets and discarded the correct ones. Approved by: hrs Added: stable/7/sbin/ifconfig/ifgif.c - copied unchanged from r193664, head/sbin/ifconfig/ifgif.c Modified: stable/7/sbin/ifconfig/ (props changed) stable/7/sbin/ifconfig/Makefile stable/7/share/man/man4/ (props changed) stable/7/share/man/man4/gif.4 stable/7/share/man/man4/if_bridge.4 stable/7/sys/net/ (props changed) stable/7/sys/net/if_gif.c stable/7/sys/net/if_gif.h stable/7/sys/netinet/in_gif.c stable/7/sys/netinet6/in6_gif.c stable/7/sys/sys/priv.h Modified: stable/7/sbin/ifconfig/Makefile ============================================================================== --- stable/7/sbin/ifconfig/Makefile Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sbin/ifconfig/Makefile Mon Sep 7 10:15:50 2009 (r196918) @@ -25,6 +25,7 @@ SRCS+= ifmedia.c # SIOC[GS]IFMEDIA supp SRCS+= ifvlan.c # SIOC[GS]ETVLAN support SRCS+= ifieee80211.c # SIOC[GS]IEEE80211 support SRCS+= ifgre.c # GRE keys etc +SRCS+= ifgif.c # GIF reversed header workaround SRCS+= ifcarp.c # SIOC[GS]VH support SRCS+= ifgroup.c # ... Copied: stable/7/sbin/ifconfig/ifgif.c (from r193664, head/sbin/ifconfig/ifgif.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/sbin/ifconfig/ifgif.c Mon Sep 7 10:15:50 2009 (r196918, copy of r193664, head/sbin/ifconfig/ifgif.c) @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 2009 Hiroki Sato. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ifconfig.h" + +static void gif_status(int); + +static struct { + const char *label; + u_int mask; +} gif_opts[] = { + { "ACCEPT_REV_ETHIP_VER", GIF_ACCEPT_REVETHIP }, + { "SEND_REV_ETHIP_VER", GIF_SEND_REVETHIP }, +}; + +static void +gif_status(int s) +{ + int opts; + int nopts = 0; + int i; + + ifr.ifr_data = (caddr_t)&opts; + if (ioctl(s, GIFGOPTS, &ifr) == -1) + return; + + printf("\toptions=%d<", opts); + for (i=0; i < sizeof(gif_opts)/sizeof(gif_opts[0]); i++) { + if (opts & gif_opts[i].mask) { + if (nopts++) + printf(","); + printf("%s", gif_opts[i].label); + } + } + printf(">\n"); +} + +static void +setgifopts(const char *val, + int d, int s, const struct afswtch *afp) +{ + int opts; + + ifr.ifr_data = (caddr_t)&opts; + if (ioctl(s, GIFGOPTS, &ifr) == -1) { + warn("ioctl(GIFGOPTS)"); + return; + } + + if (d < 0) + opts &= ~(-d); + else + opts |= d; + + if (ioctl(s, GIFSOPTS, &ifr) == -1) { + warn("ioctl(GIFSOPTS)"); + return; + } +} + +static struct cmd gif_cmds[] = { + DEF_CMD("accept_rev_ethip_ver", GIF_ACCEPT_REVETHIP, setgifopts), + DEF_CMD("-accept_rev_ethip_ver",-GIF_ACCEPT_REVETHIP, setgifopts), + DEF_CMD("send_rev_ethip_ver", GIF_SEND_REVETHIP, setgifopts), + DEF_CMD("-send_rev_ethip_ver", -GIF_SEND_REVETHIP, setgifopts), +}; + +static struct afswtch af_gif = { + .af_name = "af_gif", + .af_af = AF_UNSPEC, + .af_other_status = gif_status, +}; + +static __constructor void +gif_ctor(void) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + int i; + + for (i = 0; i < N(gif_cmds); i++) + cmd_register(&gif_cmds[i]); + af_register(&af_gif); +#undef N +} Modified: stable/7/share/man/man4/gif.4 ============================================================================== --- stable/7/share/man/man4/gif.4 Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/share/man/man4/gif.4 Mon Sep 7 10:15:50 2009 (r196918) @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 10, 1999 +.Dd June 8, 2009 .Dt GIF 4 .Os .Sh NAME @@ -256,3 +256,32 @@ had a multi-destination behavior, config .Dv IFF_LINK0 flag. The behavior is obsolete and is no longer supported. +.Pp +On +.Fx +6.1, 6.2, 6.3, 7.0, 7.1, and 7.2 +the +.Nm +sends and receives incorrect EtherIP packets with reversed version +field when +.Xr if_bridge 4 +is used together. As a workaround on this interoperability issue, the +following two +.Xr ifconfig 8 +flags can be used: +.Bl -tag -width "accept_rev_ethip_ver" -offset indent +.It accept_rev_ethip_ver +accepts both correct EtherIP packets and ones with reversed version +field, if enabled. If disabled, the +.Nm +accepts the correct packets only. This flag is enabled by default. +.It send_rev_ethip_ver +sends EtherIP packets with reversed version field intentionally, if +enabled. If disabled, the +.Nm +sends the correct packets only. This flag is disabled by default. +.El +.Pp +If interoperability with the older +.Fx +machines is needed, both of these two flags must be enabled. Modified: stable/7/share/man/man4/if_bridge.4 ============================================================================== --- stable/7/share/man/man4/if_bridge.4 Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/share/man/man4/if_bridge.4 Mon Sep 7 10:15:50 2009 (r196918) @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 17, 2007 +.Dd June 8, 2009 .Dt IF_BRIDGE 4 .Os .Sh NAME @@ -389,6 +389,12 @@ ifconfig gif0 tunnel 1.2.3.4 5.6.7.8 up ifconfig bridge0 create ifconfig bridge0 addm fxp0 addm gif0 up .Ed +.Pp +Note that +.Fx +6.1, 6.2, 6.3, 7.0, 7.1, and 7.2 have a bug in the EtherIP protocol. +For more details and workaround, see +.Xr gif 4 manual page. .Sh SEE ALSO .Xr gif 4 , .Xr ipf 4 , Modified: stable/7/sys/net/if_gif.c ============================================================================== --- stable/7/sys/net/if_gif.c Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sys/net/if_gif.c Mon Sep 7 10:15:50 2009 (r196918) @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,7 @@ gif_clone_create(ifc, unit, params) if_initname(GIF2IFP(sc), ifc->ifc_name, unit); sc->encap_cookie4 = sc->encap_cookie6 = NULL; + sc->gif_options = GIF_ACCEPT_REVETHIP; GIF2IFP(sc)->if_addrlen = 0; GIF2IFP(sc)->if_mtu = GIF_MTU; @@ -479,6 +481,7 @@ gif_input(m, af, ifp) struct ifnet *ifp; { int isr, n; + struct gif_softc *sc = ifp->if_softc; struct etherip_header *eip; struct ether_header *eh; struct ifnet *oldifp; @@ -539,11 +542,25 @@ gif_input(m, af, ifp) } eip = mtod(m, struct etherip_header *); - if (eip->eip_ver != - (ETHERIP_VERSION & ETHERIP_VER_VERS_MASK)) { - /* discard unknown versions */ - m_freem(m); - return; + /* + * GIF_ACCEPT_REVETHIP (enabled by default) intentionally + * accepts an EtherIP packet with revered version field in + * the header. This is a knob for backward compatibility + * with FreeBSD 7.2R or prior. + */ + if (sc->gif_options & GIF_ACCEPT_REVETHIP) { + if (eip->eip_resvl != ETHERIP_VERSION + && eip->eip_ver != ETHERIP_VERSION) { + /* discard unknown versions */ + m_freem(m); + return; + } + } else { + if (eip->eip_ver != ETHERIP_VERSION) { + /* discard unknown versions */ + m_freem(m); + return; + } } m_adj(m, sizeof(struct etherip_header)); @@ -598,6 +615,7 @@ gif_ioctl(ifp, cmd, data) struct gif_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq*)data; int error = 0, size; + u_int options; struct sockaddr *dst, *src; #ifdef SIOCSIFMTU /* xxx */ u_long mtu; @@ -832,6 +850,24 @@ gif_ioctl(ifp, cmd, data) /* if_ioctl() takes care of it */ break; + case GIFGOPTS: + options = sc->gif_options; + error = copyout(&options, ifr->ifr_data, + sizeof(options)); + break; + + case GIFSOPTS: + if ((error = priv_check(curthread, PRIV_NET_GIF)) != 0) + break; + error = copyin(ifr->ifr_data, &options, sizeof(options)); + if (error) + break; + if (options & ~GIF_OPTMASK) + error = EINVAL; + else + sc->gif_options = options; + break; + default: error = EINVAL; break; Modified: stable/7/sys/net/if_gif.h ============================================================================== --- stable/7/sys/net/if_gif.h Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sys/net/if_gif.h Mon Sep 7 10:15:50 2009 (r196918) @@ -71,6 +71,7 @@ struct gif_softc { const struct encaptab *encap_cookie4; const struct encaptab *encap_cookie6; void *gif_netgraph; /* ng_gif(4) netgraph node info */ + u_int gif_options; LIST_ENTRY(gif_softc) gif_list; /* all gif's are linked */ }; #define GIF2IFP(sc) ((sc)->gif_ifp) @@ -94,12 +95,18 @@ struct gif_softc { #define MTAG_GIF_CALLED 0 struct etherip_header { - u_int8_t eip_ver; /* version/reserved */ - u_int8_t eip_pad; /* required padding byte */ -}; -#define ETHERIP_VER_VERS_MASK 0x0f -#define ETHERIP_VER_RSVD_MASK 0xf0 -#define ETHERIP_VERSION 0x03 +#if BYTE_ORDER == LITTLE_ENDIAN + u_int eip_resvl:4, /* reserved */ + eip_ver:4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_int eip_ver:4, /* version */ + eip_resvl:4; /* reserved */ +#endif + u_int8_t eip_resvh; /* reserved */ +} __packed; + +#define ETHERIP_VERSION 0x3 /* mbuf adjust factor to force 32-bit alignment of IP header */ #define ETHERIP_ALIGN 2 @@ -114,4 +121,11 @@ int gif_encapcheck(const struct mbuf *, #endif /* _KERNEL */ +#define GIFGOPTS _IOWR('i', 150, struct ifreq) +#define GIFSOPTS _IOW('i', 151, struct ifreq) + +#define GIF_ACCEPT_REVETHIP 0x0001 +#define GIF_SEND_REVETHIP 0x0010 +#define GIF_OPTMASK (GIF_ACCEPT_REVETHIP|GIF_SEND_REVETHIP) + #endif /* _NET_IF_GIF_H_ */ Modified: stable/7/sys/netinet/in_gif.c ============================================================================== --- stable/7/sys/netinet/in_gif.c Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sys/netinet/in_gif.c Mon Sep 7 10:15:50 2009 (r196918) @@ -144,8 +144,22 @@ in_gif_output(struct ifnet *ifp, int fam #endif /* INET6 */ case AF_LINK: proto = IPPROTO_ETHERIP; - eiphdr.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK; - eiphdr.eip_pad = 0; + + /* + * GIF_SEND_REVETHIP (disabled by default) intentionally + * sends an EtherIP packet with revered version field in + * the header. This is a knob for backward compatibility + * with FreeBSD 7.2R or prior. + */ + if ((sc->gif_options & GIF_SEND_REVETHIP)) { + eiphdr.eip_ver = 0; + eiphdr.eip_resvl = ETHERIP_VERSION; + eiphdr.eip_resvh = 0; + } else { + eiphdr.eip_ver = ETHERIP_VERSION; + eiphdr.eip_resvl = 0; + eiphdr.eip_resvh = 0; + } /* prepend Ethernet-in-IP header */ M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT); if (m && m->m_len < sizeof(struct etherip_header)) Modified: stable/7/sys/netinet6/in6_gif.c ============================================================================== --- stable/7/sys/netinet6/in6_gif.c Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sys/netinet6/in6_gif.c Mon Sep 7 10:15:50 2009 (r196918) @@ -142,8 +142,22 @@ in6_gif_output(struct ifnet *ifp, #endif case AF_LINK: proto = IPPROTO_ETHERIP; - eiphdr.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK; - eiphdr.eip_pad = 0; + + /* + * GIF_SEND_REVETHIP (disabled by default) intentionally + * sends an EtherIP packet with revered version field in + * the header. This is a knob for backward compatibility + * with FreeBSD 7.2R or prior. + */ + if ((sc->gif_options & GIF_SEND_REVETHIP)) { + eiphdr.eip_ver = 0; + eiphdr.eip_resvl = ETHERIP_VERSION; + eiphdr.eip_resvh = 0; + } else { + eiphdr.eip_ver = ETHERIP_VERSION; + eiphdr.eip_resvl = 0; + eiphdr.eip_resvh = 0; + } /* prepend Ethernet-in-IP header */ M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT); if (m && m->m_len < sizeof(struct etherip_header)) Modified: stable/7/sys/sys/priv.h ============================================================================== --- stable/7/sys/sys/priv.h Mon Sep 7 09:51:23 2009 (r196917) +++ stable/7/sys/sys/priv.h Mon Sep 7 10:15:50 2009 (r196918) @@ -327,6 +327,7 @@ #define PRIV_NET_ADDIFADDR 413 /* Add protocol addr to interface. */ #define PRIV_NET_DELIFADDR 414 /* Delete protocol addr on interface. */ #define PRIV_NET_LAGG 415 /* Administer lagg interface. */ +#define PRIV_NET_GIF 416 /* Administer gif interface. */ /* * 802.11-related privileges. From kib at FreeBSD.org Mon Sep 7 12:39:55 2009 From: kib at FreeBSD.org (Konstantin Belousov) Date: Mon Sep 7 12:40:01 2009 Subject: svn commit: r196922 - in stable/7/sys: . contrib/pf net ufs/ffs Message-ID: <200909071239.n87Cds3C014740@svn.freebsd.org> Author: kib Date: Mon Sep 7 12:39:54 2009 New Revision: 196922 URL: http://svn.freebsd.org/changeset/base/196922 Log: MFC r196206. Take the number of allocated freeblks into consideration for softdep_slowdown(). Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/net/ (props changed) stable/7/sys/ufs/ffs/ffs_softdep.c Modified: stable/7/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- stable/7/sys/ufs/ffs/ffs_softdep.c Mon Sep 7 12:10:41 2009 (r196921) +++ stable/7/sys/ufs/ffs/ffs_softdep.c Mon Sep 7 12:39:54 2009 (r196922) @@ -671,6 +671,8 @@ static int req_clear_inodedeps; /* synce static int req_clear_remove; /* syncer process flush some freeblks */ #define FLUSH_REMOVE 2 #define FLUSH_REMOVE_WAIT 3 +static long num_freeblkdep; /* number of freeblks workitems allocated */ + /* * runtime statistics */ @@ -2230,6 +2232,9 @@ softdep_setup_freeblocks(ip, length, fla freeblks->fb_uid = ip->i_uid; freeblks->fb_previousinum = ip->i_number; freeblks->fb_devvp = ip->i_devvp; + ACQUIRE_LOCK(&lk); + num_freeblkdep++; + FREE_LOCK(&lk); extblocks = 0; if (fs->fs_magic == FS_UFS2_MAGIC) extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); @@ -2821,6 +2826,7 @@ handle_workitem_freeblocks(freeblks, fla ACQUIRE_LOCK(&lk); WORKITEM_FREE(freeblks, D_FREEBLKS); + num_freeblkdep--; FREE_LOCK(&lk); } @@ -5748,7 +5754,8 @@ softdep_slowdown(vp) max_softdeps_hard = max_softdeps * 11 / 10; if (num_dirrem < max_softdeps_hard / 2 && num_inodedep < max_softdeps_hard && - VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps) { + VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps && + num_freeblkdep < max_softdeps_hard) { FREE_LOCK(&lk); return (0); } From bz at FreeBSD.org Mon Sep 7 13:37:04 2009 From: bz at FreeBSD.org (Bjoern A. Zeeb) Date: Mon Sep 7 13:37:22 2009 Subject: svn commit: r196924 - in stable/7/sys: . amd64/amd64 compat/ia32 contrib/pf i386/i386 kern sys Message-ID: <200909071337.n87Db4tN016089@svn.freebsd.org> Author: bz Date: Mon Sep 7 13:37:04 2009 New Revision: 196924 URL: http://svn.freebsd.org/changeset/base/196924 Log: MFC r196653: Make sure FreeBSD binaries without .note.ABI-tag section work correctly and do not match a colliding Debian GNU/kFreeBSD brandinfo statements. For this mark the Debian GNU/kFreeBSD brandinfo that it must have an .note.ABI-tag section and ignore the old EI_OSABI brandinfo when comparing a possibly colliding set of options. Due to SYSINIT we add the brandinfo in a non-deterministic order, so native FreeBSD is not always first. We may want to consider to force native FreeBSD to come first as well. The only way a problem could currently be noticed is when running an i386 binary without the .note.ABI-tag on amd64 and the Debian GNU/kFreeBSD brandinfo was matched first, as the fallback to ld-elf32.so.1 does not exist in that case. Reported and tested by: ticso In collaboration with: kib Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/amd64/elf_machdep.c stable/7/sys/compat/ia32/ia32_sysvec.c stable/7/sys/contrib/pf/ (props changed) stable/7/sys/i386/i386/elf_machdep.c stable/7/sys/kern/imgact_elf.c stable/7/sys/sys/imgact_elf.h Modified: stable/7/sys/amd64/amd64/elf_machdep.c ============================================================================== --- stable/7/sys/amd64/amd64/elf_machdep.c Mon Sep 7 12:41:19 2009 (r196923) +++ stable/7/sys/amd64/amd64/elf_machdep.c Mon Sep 7 13:37:04 2009 (r196924) @@ -117,7 +117,7 @@ static Elf64_Brandinfo kfreebsd_brand_in .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf64_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kelf64, SI_SUB_EXEC, SI_ORDER_ANY, Modified: stable/7/sys/compat/ia32/ia32_sysvec.c ============================================================================== --- stable/7/sys/compat/ia32/ia32_sysvec.c Mon Sep 7 12:41:19 2009 (r196923) +++ stable/7/sys/compat/ia32/ia32_sysvec.c Mon Sep 7 13:37:04 2009 (r196924) @@ -179,7 +179,7 @@ static Elf32_Brandinfo kia32_brand_info .interp_path = "/lib/ld.so.1", .sysvec = &ia32_freebsd_sysvec, .brand_note = &elf32_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kia32, SI_SUB_EXEC, SI_ORDER_ANY, Modified: stable/7/sys/i386/i386/elf_machdep.c ============================================================================== --- stable/7/sys/i386/i386/elf_machdep.c Mon Sep 7 12:41:19 2009 (r196923) +++ stable/7/sys/i386/i386/elf_machdep.c Mon Sep 7 13:37:04 2009 (r196924) @@ -116,7 +116,7 @@ static Elf32_Brandinfo kfreebsd_brand_in .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf32_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kelf32, SI_SUB_EXEC, SI_ORDER_ANY, Modified: stable/7/sys/kern/imgact_elf.c ============================================================================== --- stable/7/sys/kern/imgact_elf.c Mon Sep 7 12:41:19 2009 (r196923) +++ stable/7/sys/kern/imgact_elf.c Mon Sep 7 13:37:04 2009 (r196924) @@ -241,8 +241,10 @@ __elfN(get_brandinfo)(struct image_param /* Look for an ".note.ABI-tag" ELF section */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && - (bi->flags & BI_BRAND_NOTE) != 0) { + if (bi == NULL) + continue; + if (hdr->e_machine == bi->machine && (bi->flags & + (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) { ret = __elfN(check_note)(imgp, bi->brand_note, osrel); if (ret) return (bi); @@ -252,7 +254,9 @@ __elfN(get_brandinfo)(struct image_param /* If the executable has a brand, search for it in the brand list. */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && (hdr->e_ident[EI_OSABI] == bi->brand || strncmp((const char *)&hdr->e_ident[OLD_EI_BRAND], bi->compat_3_brand, strlen(bi->compat_3_brand)) == 0)) @@ -263,7 +267,9 @@ __elfN(get_brandinfo)(struct image_param if (interp != NULL) { for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && strcmp(interp, bi->interp_path) == 0) return (bi); } @@ -272,7 +278,9 @@ __elfN(get_brandinfo)(struct image_param /* Lacking a recognized interpreter, try the default brand */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && __elfN(fallback_brand) == bi->brand) return (bi); } Modified: stable/7/sys/sys/imgact_elf.h ============================================================================== --- stable/7/sys/sys/imgact_elf.h Mon Sep 7 12:41:19 2009 (r196923) +++ stable/7/sys/sys/imgact_elf.h Mon Sep 7 13:37:04 2009 (r196924) @@ -75,8 +75,9 @@ typedef struct { const char *interp_newpath; int flags; Elf_Brandnote *brand_note; -#define BI_CAN_EXEC_DYN 0x0001 -#define BI_BRAND_NOTE 0x0002 +#define BI_CAN_EXEC_DYN 0x0001 +#define BI_BRAND_NOTE 0x0002 /* May have note.ABI-tag section. */ +#define BI_BRAND_NOTE_MANDATORY 0x0004 /* Must have note.ABI-tag section. */ } __ElfN(Brandinfo); __ElfType(Auxargs); From edwin at FreeBSD.org Wed Sep 9 00:15:43 2009 From: edwin at FreeBSD.org (Edwin Groothuis) Date: Wed Sep 9 00:16:01 2009 Subject: svn commit: r197001 - stable/7/share/zoneinfo Message-ID: <200909090015.n890Fhnp066119@svn.freebsd.org> Author: edwin Date: Wed Sep 9 00:15:43 2009 New Revision: 197001 URL: http://svn.freebsd.org/changeset/base/197001 Log: MFC from 197000: Update to tzdata2008m: Samoa will go in DST on 4 October 2009 till 28 March 2010 Palestine will go back from DST on 4 September 2009 Modified: stable/7/share/zoneinfo/ (props changed) stable/7/share/zoneinfo/asia stable/7/share/zoneinfo/australasia Modified: stable/7/share/zoneinfo/asia ============================================================================== --- stable/7/share/zoneinfo/asia Wed Sep 9 00:07:05 2009 (r197000) +++ stable/7/share/zoneinfo/asia Wed Sep 9 00:15:43 2009 (r197001) @@ -1,5 +1,5 @@ #
-# @(#)asia	8.36
+# @(#)asia	8.40
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -1836,6 +1836,42 @@ Zone	Asia/Karachi	4:28:12 -	LMT	1907
 # http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
 # 
 
+# From Steffen Thorsen (2009-08-31):
+# Palestine's Council of Ministers announced that they will revert back to
+# winter time on Friday, 2009-09-04.
+#
+# One news source:
+# 
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
+# 
+# (Palestinian press agency, Arabic),
+# Google translate: "Decided that the Palestinian government in Ramallah
+# headed by Salam Fayyad, the start of work in time for the winter of
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
+# minutes per hour as of Friday morning."
+#
+# We are not sure if Gaza will do the same, last year they had a different
+# end date, we will keep this page updated:
+# 
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
+# 
+
+# From Alexander Krivenyshev (2009-09-02):
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
+#
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
+# to change time back to Standard time on September 4, 2009.
+#
+# "Winter time unite the West Bank and Gaza"
+# (from Palestinian National Authority):
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
+# 
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -1854,7 +1890,7 @@ Rule Palestine	2006	only	-	Sep	22	0:00	0
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
 Rule Palestine	2008	only	-	Aug	lastFri	2:00	0	-
 Rule Palestine	2009	max	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	max	-	Sep	lastMon	2:00	0	-
+Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct

Modified: stable/7/share/zoneinfo/australasia
==============================================================================
--- stable/7/share/zoneinfo/australasia	Wed Sep  9 00:07:05 2009	(r197000)
+++ stable/7/share/zoneinfo/australasia	Wed Sep  9 00:15:43 2009	(r197001)
@@ -1,5 +1,5 @@
 # 
-# @(#)australasia	8.12
+# @(#)australasia	8.13
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -443,10 +443,26 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1
 # http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
 # 
 
+# From Steffen Thorsen (2009-08-27):
+# Samoa's parliament passed the Daylight Saving Bill 2009, and will start 
+# daylight saving time on the first Sunday of October 2009 and end on the 
+# last Sunday of March 2010. We hope that the full text will be published 
+# soon, but we believe that the bill is only valid for 2009-2010. Samoa's 
+# Daylight Saving Act 2009 will be enforced as soon as the Head of State 
+# executes a proclamation publicizing this Act.
+#
+# Some background information here, which will be updated once we have 
+# more details:
+# 
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
+# 
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	WST			# Samoa Time
+			-11:00	-	WST	2009 Oct 4
+			-11:00	1:00	WSDT	2010 Mar 28
+			-11:00	-	WST
 
 # Solomon Is
 # excludes Bougainville, for which see Papua New Guinea
From attilio at FreeBSD.org  Thu Sep 10 11:44:51 2009
From: attilio at FreeBSD.org (Attilio Rao)
Date: Thu Sep 10 11:44:58 2009
Subject: svn commit: r197059 - stable/7/contrib/gdtoa
Message-ID: <200909101144.n8ABipTW018454@svn.freebsd.org>

Author: attilio
Date: Thu Sep 10 11:44:51 2009
New Revision: 197059
URL: http://svn.freebsd.org/changeset/base/197059

Log:
  MFC r196916:
  Fix a list overrun.
  
  Sponsored by: Sandvine Incorporated

Modified:
  stable/7/contrib/gdtoa/gdtoaimp.h
  stable/7/contrib/gdtoa/misc.c

Modified: stable/7/contrib/gdtoa/gdtoaimp.h
==============================================================================
--- stable/7/contrib/gdtoa/gdtoaimp.h	Thu Sep 10 11:27:07 2009	(r197058)
+++ stable/7/contrib/gdtoa/gdtoaimp.h	Thu Sep 10 11:44:51 2009	(r197059)
@@ -472,7 +472,7 @@ extern pthread_mutex_t __gdtoa_locks[2];
 		_pthread_mutex_unlock(&__gdtoa_locks[n]);	\
 } while(0)
 
-#define Kmax 15
+#define Kmax 9
 
  struct
 Bigint {

Modified: stable/7/contrib/gdtoa/misc.c
==============================================================================
--- stable/7/contrib/gdtoa/misc.c	Thu Sep 10 11:27:07 2009	(r197058)
+++ stable/7/contrib/gdtoa/misc.c	Thu Sep 10 11:44:51 2009	(r197059)
@@ -55,7 +55,9 @@ Balloc
 #endif
 
 	ACQUIRE_DTOA_LOCK(0);
-	if ( (rv = freelist[k]) !=0) {
+	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+	/* but this case seems very unlikely. */
+	if (k <= Kmax && (rv = freelist[k]) !=0) {
 		freelist[k] = rv->next;
 		}
 	else {
@@ -65,7 +67,7 @@ Balloc
 #else
 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
 			/sizeof(double);
-		if (pmem_next - private_mem + len <= PRIVATE_mem) {
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
 			rv = (Bigint*)pmem_next;
 			pmem_next += len;
 			}
@@ -89,10 +91,14 @@ Bfree
 #endif
 {
 	if (v) {
-		ACQUIRE_DTOA_LOCK(0);
-		v->next = freelist[v->k];
-		freelist[v->k] = v;
-		FREE_DTOA_LOCK(0);
+		if (v->k > Kmax)
+			free((void*)v);
+		else {
+			ACQUIRE_DTOA_LOCK(0);
+			v->next = freelist[v->k];
+			freelist[v->k] = v;
+			FREE_DTOA_LOCK(0);
+			}
 		}
 	}
 
From kib at FreeBSD.org  Thu Sep 10 13:01:23 2009
From: kib at FreeBSD.org (Konstantin Belousov)
Date: Thu Sep 10 13:01:40 2009
Subject: svn commit: r197063 - in stable/7/sys: . contrib/pf fs/pseudofs net
	ufs/ffs
Message-ID: <200909101301.n8AD1NDW020218@svn.freebsd.org>

Author: kib
Date: Thu Sep 10 13:01:23 2009
New Revision: 197063
URL: http://svn.freebsd.org/changeset/base/197063

Log:
  MFC r196920:
  insmntque_stddtr() clears vp->v_data and resets vp->v_op to
  dead_vnodeops before calling vgone(). Revert r189706 and corresponding
  part of the r186560.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/fs/pseudofs/pseudofs_vncache.c
  stable/7/sys/net/   (props changed)
  stable/7/sys/ufs/ffs/ffs_vfsops.c

Modified: stable/7/sys/fs/pseudofs/pseudofs_vncache.c
==============================================================================
--- stable/7/sys/fs/pseudofs/pseudofs_vncache.c	Thu Sep 10 12:58:37 2009	(r197062)
+++ stable/7/sys/fs/pseudofs/pseudofs_vncache.c	Thu Sep 10 13:01:23 2009	(r197063)
@@ -193,6 +193,7 @@ retry:
 	vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread);
 	error = insmntque(*vpp, mp);
 	if (error != 0) {
+		free(pvd, M_PFSVNCACHE);
 		*vpp = NULLVP;
 		return (error);
 	}

Modified: stable/7/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- stable/7/sys/ufs/ffs/ffs_vfsops.c	Thu Sep 10 12:58:37 2009	(r197062)
+++ stable/7/sys/ufs/ffs/ffs_vfsops.c	Thu Sep 10 13:01:23 2009	(r197063)
@@ -1466,6 +1466,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags
 		vp->v_vflag |= VV_FORCEINSMQ;
 	error = insmntque(vp, mp);
 	if (error != 0) {
+		uma_zfree(uma_inode, ip);
 		*vpp = NULL;
 		return (error);
 	}
From jhb at FreeBSD.org  Thu Sep 10 14:08:28 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Thu Sep 10 14:08:45 2009
Subject: svn commit: r197066 - stable/7/share/man/man7
Message-ID: <200909101408.n8AE8Skq021754@svn.freebsd.org>

Author: jhb
Date: Thu Sep 10 14:08:28 2009
New Revision: 197066
URL: http://svn.freebsd.org/changeset/base/197066

Log:
  MFC 196337 and 196356:
  Document SVN* and MAKE_DVD variables.

Modified:
  stable/7/share/man/man7/   (props changed)
  stable/7/share/man/man7/release.7

Modified: stable/7/share/man/man7/release.7
==============================================================================
--- stable/7/share/man/man7/release.7	Thu Sep 10 14:04:00 2009	(r197065)
+++ stable/7/share/man/man7/release.7	Thu Sep 10 14:08:28 2009	(r197066)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 12, 2006
+.Dd August 17, 2009
 .Dt RELEASE 7
 .Os
 .Sh NAME
@@ -332,6 +332,10 @@ patch file.
 A script that will be run in the
 .Xr chroot 8
 environment immediately after any local patches are applied.
+.It Va MAKE_DVD
+If defined, build a bootable ISO DVD image in the CD-ROM
+stage directory.
+This option may not be available for all architectures.
 .It Va MAKE_ISOS
 If defined, bootable ISO CD-ROM images will be created from the
 contents of the CD-ROM stage directory.
@@ -390,6 +394,35 @@ of the CVS tree
 .It Va SEPARATE_LIVEFS
 Store the live file system on its own CD-ROM image rather than placing it on
 the first disc.
+.It Va SVNCMDARGS
+Additional arguments for svn
+.Ic checkout
+and
+.Ic switch
+commands.
+.It Va SVNROOT
+The location of the FreeBSD SVN source repository.
+If this variable is set,
+then the source tree will be extracted using Subversion rather than
+CVS.
+.It Va SVNBRANCH
+The branch to check out from a SVN source repository.
+It is specified as a path such as
+.Pa head
+or
+.Pa stable/7 .
+If this variable is not set,
+then the branch that corresponds to the current value of
+.Va RELEASETAG
+will be used.
+If neither
+.Va SVNBRANCH
+nor
+.Va RELEASETAG
+are set,
+then the
+.Pa head
+branch will be used.
 .It Va TARGET_ARCH
 The target machine processor architecture.
 This is analogous to the
@@ -474,6 +507,7 @@ make release CHROOTDIR=/local3/release B
 .Xr install 1 ,
 .Xr make 1 ,
 .Xr patch 1 ,
+.Xr svn 1 Pq Pa ports/devel/subversion-freebsd ,
 .Xr uname 1 ,
 .Xr md 4 ,
 .Xr make.conf 5 ,
@@ -511,7 +545,7 @@ effort was spent getting
 into a shape where it could at least automate most of the tediousness
 of building a release in a sterile environment.
 .Pp
-With its almost 1000 revisions spread over multiple branches, the
+At near 1000 revisions spread over multiple branches, the
 .Xr cvs 1
 log of
 .Pa src/release/Makefile
From jhb at FreeBSD.org  Thu Sep 10 14:16:05 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Thu Sep 10 14:16:17 2009
Subject: svn commit: r197067 - stable/7/release
Message-ID: <200909101416.n8AEG5jf021981@svn.freebsd.org>

Author: jhb
Date: Thu Sep 10 14:16:05 2009
New Revision: 197067
URL: http://svn.freebsd.org/changeset/base/197067

Log:
  MFC 196221:
  Add the ability to build a release from an SVN checkout instead of a CVS
  checkout.  If SVNROOT is specified, then the source tree will be checked
  out from that SVN repository instead of using CVS.  ports and docs still
  use CVS.  If SVNROOT is not specified, then the source tree will be checked
  out using CVS.  An explicit SVN branch can be specified using SVNBRANCH
  (e.g. SVNBRANCH=stable/8).  If SVNBRANCH is not set but RELEASETAG is set
  to a CVS branch (such as RELENG_8) the appropriate SVN branch will be
  inferred from the CVS branch using svnbranch.awk.

Added:
  stable/7/release/svnbranch.awk
     - copied unchanged from r196221, head/release/svnbranch.awk
Modified:
  stable/7/release/   (props changed)
  stable/7/release/Makefile

Modified: stable/7/release/Makefile
==============================================================================
--- stable/7/release/Makefile	Thu Sep 10 14:08:28 2009	(r197066)
+++ stable/7/release/Makefile	Thu Sep 10 14:16:05 2009	(r197067)
@@ -1,7 +1,8 @@
 # $FreeBSD$
 #
 # make release [BUILDNAME=somename] CHROOTDIR=/some/dir CVSROOT=/cvs/dir \
-#     [RELEASETAG=tag]
+#     [RELEASETAG=tag] [SVNROOT=svn://svn.freebsd.org/base] \
+#     [SVNBRANCH=some/branch]
 #
 # Where "/some/dir" is the pathname of a directory on a some filesystem with
 # at least 1000MB of free space, "somename" is what you want the release to
@@ -9,6 +10,11 @@
 # which CVS "tag" name should be used when checking out the sources to build
 # the release (default is HEAD).
 #
+# Please note the support for building from SVN is preliminary and there
+# are still questions about things like how to handle updates of
+# /usr/src on production systems (csup(1) replacement).  It is a work
+# in progress and may change as the other issues get worked out.
+#
 # Please note: the md(4) driver must be present in the kernel
 # (either by being compiled in or available as a kld(4) module),
 # otherwise the target 'release.8' and possibly others will fail.
@@ -45,12 +51,25 @@ BUILDNAME?=${BASE}-${DATE}-SNAP
 # To add other options to the CVS command, set
 #CVSARGS="-lfq"
 #
-# To prefix the cvs command
+# To prefix the CVS command
 #CVSPREFIX="/usr/bin/time"
 #
 # Where the CVS repository is
 #CVSROOT="/home/ncvs"
 #
+# To add other options to the Subversion subcommands (co,up), set
+#SVNCMDARGS="-r '{ 01/01/2002 00:00:00 UTC }'"
+#
+# To prefix the Subversion command
+#SVNPREFIX="/usr/bin/time"
+#
+# Where the Subversion repository is
+#SVNROOT=svn://svn.freebsd.org/base
+#
+# Subversion branch to build for src.  If this is not set then it is
+# automatically computed from RELEASETAG.
+#SVNBRANCH=stable/7
+#
 # Non-zero if ${RELEASETAG} is in the form "RELENG_ver_RELEASE"; we
 # are building an official release.  Otherwise, we are building for
 # a branch.
@@ -64,6 +83,16 @@ PORTSRELEASETAG?=	${AUXRELEASETAG}
 .endif
 .endif
 
+# Determine the Subversion source branch that corresponds to the requested
+# RELEASETAG.
+.if !defined(SVNBRANCH)
+.if defined(RELEASETAG)
+SVNBRANCH!=	echo "${RELEASETAG}" | awk -f ${.CURDIR}/svnbranch.awk
+.else
+SVNBRANCH=	head
+.endif
+.endif
+
 # If you want to pass flags to the world build such as -j X, use
 # WORLD_FLAGS.  Similarly, you can specify make flags for kernel
 # builds via KERNEL_FLAGS.
@@ -342,8 +371,17 @@ CVS_PORTSARGS+=	-r ${PORTSRELEASETAG}
 WORLDDIR?=	${.CURDIR}/..
 
 release rerelease:
-.if !defined(CHROOTDIR) || !defined(BUILDNAME) || !defined(CVSROOT)
-	@echo "To make a release you must set CHROOTDIR, BUILDNAME and CVSROOT" && false
+.if !defined(CHROOTDIR) || !defined(BUILDNAME)
+	@echo "To make a release you must set CHROOTDIR and BUILDNAME" && false
+.endif
+.if !defined(NOPORTSATALL) && !defined(EXTPORTSDIR) && !defined(CVSROOT)
+	@echo "Building ports requires CVSROOT or EXTPORTSDIR" && false
+.endif
+.if !defined(NODOC) && !defined(EXTDOCDIR) && !defined(CVSROOT)
+	@echo "Building docs requires CVSROOT or EXTDOCDIR" && false
+.endif
+.if !defined(EXTSRCDIR) && !defined(CVSROOT) && !defined(SVNROOT)
+	@echo "The source tree requires SVNROOT, CVSROOT, or EXTSRCDIR" && false
 .endif
 .if defined(NOPORTSATALL) && !defined(NODOC)
 	@echo "Ports are required for building the docs.  Either set NODOC or"
@@ -388,6 +426,10 @@ release rerelease:
 .if defined(EXTSRCDIR)
 	cd ${CHROOTDIR}/usr && \
 	    cp -R -H ${EXTSRCDIR} src
+.elif defined(SVNROOT)
+	cd ${CHROOTDIR}/usr && \
+	    ${SVNPREFIX} svn co ${SVNCMDARGS} ${SVNROOT}/${SVNBRANCH} \
+	    ${RELEASESRCMODULE} 
 .else
 	cd ${CHROOTDIR}/usr && \
 	    ${CVSPREFIX} cvs -R ${CVSARGS} -d ${CVSROOT} \
@@ -433,7 +475,10 @@ release rerelease:
 .endif
 .if make(rerelease)
 .if !defined(RELEASENOUPDATE) && !defined(EXTSRCDIR)
-.if !defined(RELEASETAG)
+.if defined(SVNROOT)
+	cd ${CHROOTDIR}/usr/src && ${SVNPREFIX} svn switch ${SVNCMDARGS} \
+	    ${SVNROOT}/${SVNBRANCH}
+.elif !defined(RELEASETAG)
 	cd ${CHROOTDIR}/usr/src && ${CVSPREFIX} cvs -R ${CVSARGS} -q \
 	    update ${CVSCMDARGS} -P -d -A
 .else

Copied: stable/7/release/svnbranch.awk (from r196221, head/release/svnbranch.awk)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/release/svnbranch.awk	Thu Sep 10 14:16:05 2009	(r197067, copy of r196221, head/release/svnbranch.awk)
@@ -0,0 +1,28 @@
+# $FreeBSD$
+
+BEGIN {
+	FS = "_"
+}
+
+/RELENG_.*_RELEASE/ {
+	if (NF == 5) {
+		printf "release/%s.%s.%s", $2, $3, $4
+		exit
+	}
+}
+
+/RELENG_.*/ {
+	if (NF == 3) {
+		printf "releng/%s.%s", $2, $3
+		exit
+	}
+
+	if (NF == 2) {
+		printf "stable/%s", $2
+		exit
+	}
+}
+
+// {
+	printf "unknown_branch"
+}
From jhb at FreeBSD.org  Thu Sep 10 16:03:12 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Thu Sep 10 16:03:33 2009
Subject: svn commit: r197069 - in stable/7/sys: . contrib/pf net
Message-ID: <200909101603.n8AG3CTS024372@svn.freebsd.org>

Author: jhb
Date: Thu Sep 10 16:03:11 2009
New Revision: 197069
URL: http://svn.freebsd.org/changeset/base/197069

Log:
  Hoist some mergeinfo up from sys/net to sys/.
  
  Reported by:	kib

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/net/   (props changed)
From avg at freebsd.org  Thu Sep 10 16:10:12 2009
From: avg at freebsd.org (Andriy Gapon)
Date: Thu Sep 10 16:10:18 2009
Subject: svn commit: r197069 - in stable/7/sys: . contrib/pf net
In-Reply-To: <200909101603.n8AG3CTS024372@svn.freebsd.org>
References: <200909101603.n8AG3CTS024372@svn.freebsd.org>
Message-ID: <4AA924DF.7080009@freebsd.org>

on 10/09/2009 19:03 John Baldwin said the following:
> Author: jhb
> Date: Thu Sep 10 16:03:11 2009
> New Revision: 197069
> URL: http://svn.freebsd.org/changeset/base/197069
> 
> Log:
>   Hoist some mergeinfo up from sys/net to sys/.
>   
>   Reported by:	kib

Perhaps it's possible to develop a commit hook that would reject mergeinfo being
set on some entities? E.g. individual files, or directories under sys.

-- 
Andriy Gapon
From jhb at freebsd.org  Thu Sep 10 17:58:00 2009
From: jhb at freebsd.org (John Baldwin)
Date: Thu Sep 10 17:58:06 2009
Subject: svn commit: r197069 - in stable/7/sys: . contrib/pf net
In-Reply-To: <4AA924DF.7080009@freebsd.org>
References: <200909101603.n8AG3CTS024372@svn.freebsd.org>
	<4AA924DF.7080009@freebsd.org>
Message-ID: <200909101327.23113.jhb@freebsd.org>

On Thursday 10 September 2009 12:10:07 pm Andriy Gapon wrote:
> on 10/09/2009 19:03 John Baldwin said the following:
> > Author: jhb
> > Date: Thu Sep 10 16:03:11 2009
> > New Revision: 197069
> > URL: http://svn.freebsd.org/changeset/base/197069
> > 
> > Log:
> >   Hoist some mergeinfo up from sys/net to sys/.
> >   
> >   Reported by:	kib
> 
> Perhaps it's possible to develop a commit hook that would reject mergeinfo being
> set on some entities? E.g. individual files, or directories under sys.

In some cases it is valid to add the mergeinfo, though that is probably
restricted to certain subdirectories (contrib, cddl, crypto).  I don't know
enough of the SVN internals to look at doing that.

-- 
John Baldwin
From yongari at FreeBSD.org  Fri Sep 11 17:12:44 2009
From: yongari at FreeBSD.org (Pyun YongHyeon)
Date: Fri Sep 11 17:12:56 2009
Subject: svn commit: r197094 - in stable/7/sys: . contrib/pf dev/mii
Message-ID: <200909111712.n8BHCikr058172@svn.freebsd.org>

Author: yongari
Date: Fri Sep 11 17:12:43 2009
New Revision: 197094
URL: http://svn.freebsd.org/changeset/base/197094

Log:
  MFC r196366:
    Backout r193289. r193289 restored page select bits to previous
    value instead of blindly resetting it to 0. However, it seems page
    select bits of some 88E1116 PHY is initialized to invalid one such
    that restoring page select bits after programming broke MII
    register access. The correct solution would be reset page select
    bits to 0 in PHY attach stage but it would require more testing.
    Since we're in BETA stage such a change would be dangerous so just
    back it out.
    This change should fix nfe(4) breakage on NVIDIA MCP55.
  
    Reported by:	Ryan Rogers < webmaster <> doghouserepair dot com >
  		Sam Fourman Jr. < sfourman <> gmail dot com >
    Tested by:	Ryan Rogers < webmaster <> doghouserepair dot com >
  		Sam Fourman Jr. < sfourman <> gmail dot com >

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/mii/e1000phy.c

Modified: stable/7/sys/dev/mii/e1000phy.c
==============================================================================
--- stable/7/sys/dev/mii/e1000phy.c	Fri Sep 11 16:53:12 2009	(r197093)
+++ stable/7/sys/dev/mii/e1000phy.c	Fri Sep 11 17:12:43 2009	(r197094)
@@ -239,13 +239,11 @@ e1000phy_reset(struct mii_softc *sc)
 
 		if (esc->mii_model == MII_MODEL_MARVELL_E1116 ||
 		    esc->mii_model == MII_MODEL_MARVELL_E1149) {
-			page = PHY_READ(sc, E1000_EADR);
-			/* Select page 2, MAC specific control register. */
 			PHY_WRITE(sc, E1000_EADR, 2);
 			reg = PHY_READ(sc, E1000_SCR);
 			reg |= E1000_SCR_RGMII_POWER_UP;
 			PHY_WRITE(sc, E1000_SCR, reg);
-			PHY_WRITE(sc, E1000_EADR, page);
+			PHY_WRITE(sc, E1000_EADR, 0);
 		}
 	}
 
From yongari at FreeBSD.org  Fri Sep 11 17:15:19 2009
From: yongari at FreeBSD.org (Pyun YongHyeon)
Date: Fri Sep 11 17:15:30 2009
Subject: svn commit: r197095 - in stable/7/sys: . contrib/pf dev/re pci
Message-ID: <200909111715.n8BHFIgW058282@svn.freebsd.org>

Author: yongari
Date: Fri Sep 11 17:15:18 2009
New Revision: 197095
URL: http://svn.freebsd.org/changeset/base/197095

Log:
  MFC r196516:
    Add RTL8168DP/RTL8111DP device id. While I'm here append "8111D" to
    the description of RTL8168D as RL_HWREV_8168D can be either
    RTL8168D or RTL8111D.
  
    PR:	kern/137672

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/re/if_re.c
  stable/7/sys/pci/if_rlreg.h

Modified: stable/7/sys/dev/re/if_re.c
==============================================================================
--- stable/7/sys/dev/re/if_re.c	Fri Sep 11 17:12:43 2009	(r197094)
+++ stable/7/sys/dev/re/if_re.c	Fri Sep 11 17:15:18 2009	(r197095)
@@ -174,8 +174,8 @@ static struct rl_type re_devs[] = {
 	{ RT_VENDORID, RT_DEVICEID_8101E, 0,
 	    "RealTek 8101E/8102E/8102EL PCIe 10/100baseTX" },
 	{ RT_VENDORID, RT_DEVICEID_8168, 0,
-	    "RealTek 8168/8168B/8168C/8168CP/8168D/8111B/8111C/8111CP PCIe "
-	    "Gigabit Ethernet" },
+	    "RealTek 8168/8168B/8168C/8168CP/8168D/8168DP/"
+	    "8111B/8111C/8111CP/8111DP PCIe Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169, 0,
 	    "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
@@ -216,7 +216,8 @@ static struct rl_hwrev re_hwrevs[] = {
 	{ RL_HWREV_8168C, RL_8169, "8168C/8111C"},
 	{ RL_HWREV_8168C_SPIN2, RL_8169, "8168C/8111C"},
 	{ RL_HWREV_8168CP, RL_8169, "8168CP/8111CP"},
-	{ RL_HWREV_8168D, RL_8169, "8168D"},
+	{ RL_HWREV_8168D, RL_8169, "8168D/8111D"},
+	{ RL_HWREV_8168DP, RL_8169, "8168DP/8111DP"},
 	{ 0, 0, NULL }
 };
 
@@ -1280,6 +1281,7 @@ re_attach(device_t dev)
 		/* FALLTHROUGH */
 	case RL_HWREV_8168CP:
 	case RL_HWREV_8168D:
+	case RL_HWREV_8168DP:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP;
 		/*

Modified: stable/7/sys/pci/if_rlreg.h
==============================================================================
--- stable/7/sys/pci/if_rlreg.h	Fri Sep 11 17:12:43 2009	(r197094)
+++ stable/7/sys/pci/if_rlreg.h	Fri Sep 11 17:15:18 2009	(r197095)
@@ -160,6 +160,7 @@
 #define RL_HWREV_8169_8110SC	0x18000000
 #define RL_HWREV_8102EL		0x24800000
 #define RL_HWREV_8168D		0x28000000
+#define RL_HWREV_8168DP		0x28800000
 #define RL_HWREV_8168_SPIN1	0x30000000
 #define RL_HWREV_8100E		0x30800000
 #define RL_HWREV_8101E		0x34000000
From yongari at FreeBSD.org  Fri Sep 11 17:18:08 2009
From: yongari at FreeBSD.org (Pyun YongHyeon)
Date: Fri Sep 11 17:18:15 2009
Subject: svn commit: r197096 - in stable/7/sys: . contrib/pf dev/alc
Message-ID: <200909111718.n8BHI83b058382@svn.freebsd.org>

Author: yongari
Date: Fri Sep 11 17:18:08 2009
New Revision: 197096
URL: http://svn.freebsd.org/changeset/base/197096

Log:
  MFC r195989:
    Free allocated Rx ring dma memory/tags.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/alc/if_alc.c

Modified: stable/7/sys/dev/alc/if_alc.c
==============================================================================
--- stable/7/sys/dev/alc/if_alc.c	Fri Sep 11 17:15:18 2009	(r197095)
+++ stable/7/sys/dev/alc/if_alc.c	Fri Sep 11 17:18:08 2009	(r197096)
@@ -1501,6 +1501,21 @@ alc_dma_free(struct alc_softc *sc)
 		bus_dma_tag_destroy(sc->alc_cdata.alc_tx_ring_tag);
 		sc->alc_cdata.alc_tx_ring_tag = NULL;
 	}
+	/* Rx ring. */
+	if (sc->alc_cdata.alc_rx_ring_tag != NULL) {
+		if (sc->alc_cdata.alc_rx_ring_map != NULL)
+			bus_dmamap_unload(sc->alc_cdata.alc_rx_ring_tag,
+			    sc->alc_cdata.alc_rx_ring_map);
+		if (sc->alc_cdata.alc_rx_ring_map != NULL &&
+		    sc->alc_rdata.alc_rx_ring != NULL)
+			bus_dmamem_free(sc->alc_cdata.alc_rx_ring_tag,
+			    sc->alc_rdata.alc_rx_ring,
+			    sc->alc_cdata.alc_rx_ring_map);
+		sc->alc_rdata.alc_rx_ring = NULL;
+		sc->alc_cdata.alc_rx_ring_map = NULL;
+		bus_dma_tag_destroy(sc->alc_cdata.alc_rx_ring_tag);
+		sc->alc_cdata.alc_rx_ring_tag = NULL;
+	}
 	/* Rx return ring. */
 	if (sc->alc_cdata.alc_rr_ring_tag != NULL) {
 		if (sc->alc_cdata.alc_rr_ring_map != NULL)
From yongari at FreeBSD.org  Fri Sep 11 17:20:12 2009
From: yongari at FreeBSD.org (Pyun YongHyeon)
Date: Fri Sep 11 17:20:30 2009
Subject: svn commit: r197097 - in stable/7/sys: . contrib/pf dev/alc
Message-ID: <200909111720.n8BHKBCn058476@svn.freebsd.org>

Author: yongari
Date: Fri Sep 11 17:20:11 2009
New Revision: 197097
URL: http://svn.freebsd.org/changeset/base/197097

Log:
  MFC r196517:
    Don't try to power down PHY when alc(4) failed to map the device.
    This fixes system crash when mapping alc(4) device failed in device
    attach.
  
    Reported by:	Jim < stapleton.41 <> gmail DOT com >

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/alc/if_alc.c

Modified: stable/7/sys/dev/alc/if_alc.c
==============================================================================
--- stable/7/sys/dev/alc/if_alc.c	Fri Sep 11 17:18:08 2009	(r197096)
+++ stable/7/sys/dev/alc/if_alc.c	Fri Sep 11 17:20:11 2009	(r197097)
@@ -858,7 +858,8 @@ alc_detach(device_t dev)
 			sc->alc_intrhand[i] = NULL;
 		}
 	}
-	alc_phy_down(sc);
+	if (sc->alc_res[0] != NULL)
+		alc_phy_down(sc);
 	bus_release_resources(dev, sc->alc_irq_spec, sc->alc_irq);
 	if ((sc->alc_flags & (ALC_FLAG_MSI | ALC_FLAG_MSIX)) != 0)
 		pci_release_msi(dev);
From yongari at FreeBSD.org  Fri Sep 11 17:25:25 2009
From: yongari at FreeBSD.org (Pyun YongHyeon)
Date: Fri Sep 11 17:25:41 2009
Subject: svn commit: r197098 - in stable/7/sys: . contrib/pf dev/txp
Message-ID: <200909111725.n8BHPOQt058643@svn.freebsd.org>

Author: yongari
Date: Fri Sep 11 17:25:24 2009
New Revision: 197098
URL: http://svn.freebsd.org/changeset/base/197098

Log:
  MFC r196721:
    Make sure rx descriptor ring align on 16 bytes. I guess the
    alignment requirement could be multiple of 4 bytes but I think
    using descriptor size would make intention clearer.
    Previously the size of rx descriptor was not power of 2 so it
    caused panic in bus_dmamem_alloc(9).
  
    Reported by:	Jeff Blank (jb000003 <> mr-happy dot com)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/txp/if_txp.c

Modified: stable/7/sys/dev/txp/if_txp.c
==============================================================================
--- stable/7/sys/dev/txp/if_txp.c	Fri Sep 11 17:20:11 2009	(r197097)
+++ stable/7/sys/dev/txp/if_txp.c	Fri Sep 11 17:25:24 2009	(r197098)
@@ -1389,7 +1389,8 @@ txp_alloc_rings(struct txp_softc *sc)
 
 	/* High priority rx ring. */
 	error = txp_dma_alloc(sc, "hi priority rx ring",
-	    &sc->sc_cdata.txp_rxhiring_tag, sizeof(struct txp_rx_desc), 0,
+	    &sc->sc_cdata.txp_rxhiring_tag,
+	    roundup(sizeof(struct txp_rx_desc), 16), 0,
 	    &sc->sc_cdata.txp_rxhiring_map, (void **)&sc->sc_ldata.txp_rxhiring,
 	    sizeof(struct txp_rx_desc) * RX_ENTRIES,
 	    &sc->sc_ldata.txp_rxhiring_paddr);
@@ -1409,7 +1410,8 @@ txp_alloc_rings(struct txp_softc *sc)
 
 	/* Low priority rx ring. */
 	error = txp_dma_alloc(sc, "low priority rx ring",
-	    &sc->sc_cdata.txp_rxloring_tag, sizeof(struct txp_rx_desc), 0,
+	    &sc->sc_cdata.txp_rxloring_tag,
+	    roundup(sizeof(struct txp_rx_desc), 16), 0,
 	    &sc->sc_cdata.txp_rxloring_map, (void **)&sc->sc_ldata.txp_rxloring,
 	    sizeof(struct txp_rx_desc) * RX_ENTRIES,
 	    &sc->sc_ldata.txp_rxloring_paddr);
From jhb at FreeBSD.org  Fri Sep 11 21:09:59 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Fri Sep 11 21:10:16 2009
Subject: svn commit: r197101 - stable/7/release
Message-ID: <200909112109.n8BL9xbb063582@svn.freebsd.org>

Author: jhb
Date: Fri Sep 11 21:09:59 2009
New Revision: 197101
URL: http://svn.freebsd.org/changeset/base/197101

Log:
  MFC part of 180012:
  Changes to exclude .svn directories when building tarballs during release
  builds (not documented in the original commit to HEAD).

Modified:
  stable/7/release/   (props changed)
  stable/7/release/Makefile

Modified: stable/7/release/Makefile
==============================================================================
--- stable/7/release/Makefile	Fri Sep 11 19:23:11 2009	(r197100)
+++ stable/7/release/Makefile	Fri Sep 11 21:09:59 2009	(r197101)
@@ -731,7 +731,7 @@ release.6:
 	@rm -rf ${RD}/dists/ports/ports*
 	@mkdir -p ${RD}/dists/ports
 	@echo rolling ports/ports tarball
-	@tar --exclude CVS --exclude 'ports/distfiles/*' \
+	@tar --exclude CVS --exclude .svn --exclude 'ports/distfiles/*' \
 	  -czf ${RD}/dists/ports/ports.tgz -C /usr ports
 	@cp ${.CURDIR}/scripts/ports-install.sh ${RD}/dists/ports/install.sh
 	@(cd ${RD}/dists/ports; \
@@ -834,7 +834,8 @@ release.8:
 .if ${TARGET} == "i386" || ${TARGET_ARCH} == "amd64"
 	@cp ${RD}/trees/base/boot/mbr ${RD}/mfsfd/boot
 .endif
-	@tar --exclude CVS -cf - -C ${.CURDIR}/../usr.sbin/sysinstall help | \
+	@tar --exclude CVS --exclude .svn -cf - \
+		-C ${.CURDIR}/../usr.sbin/sysinstall help | \
 		tar xf - -C ${RD}/mfsfd/stand
 	@mkdir -p ${RD}/mfsroot
 	sh -e ${DOFS_SH} ${RD}/mfsroot/mfsroot ${RD} ${MNT} \
@@ -1232,7 +1233,7 @@ doTARBALL:
 	@( cd ${SD} && \
 		tn=`echo ${TN} | tr 'A-Z' 'a-z'` && \
 		echo rolling ${TD}/$$tn tarball &&\
-		tar --exclude CVS --exclude obj --exclude BOOTMFS -cf - ${ARG} | \
+		tar --exclude CVS --exclude .svn --exclude obj --exclude BOOTMFS -cf - ${ARG} | \
 		${ZIPNSPLIT} ${RD}/dists/${TD}/$$tn. && \
 		sh ${.CURDIR}/scripts/info.sh ${RD}/dists/${TD}/$$tn \
 		    > ${RD}/dists/${TD}/$$tn.inf && \
From ume at FreeBSD.org  Sun Sep 13 11:45:32 2009
From: ume at FreeBSD.org (Hajimu UMEMOTO)
Date: Sun Sep 13 11:45:39 2009
Subject: svn commit: r197159 - stable/7/sbin/ifconfig
Message-ID: <200909131145.n8DBjVkw020148@svn.freebsd.org>

Author: ume
Date: Sun Sep 13 11:45:31 2009
New Revision: 197159
URL: http://svn.freebsd.org/changeset/base/197159

Log:
  MFC r196929: Suppress an options line when no bit is on.

Modified:
  stable/7/sbin/ifconfig/   (props changed)
  stable/7/sbin/ifconfig/ifgif.c

Modified: stable/7/sbin/ifconfig/ifgif.c
==============================================================================
--- stable/7/sbin/ifconfig/ifgif.c	Sun Sep 13 11:34:33 2009	(r197158)
+++ stable/7/sbin/ifconfig/ifgif.c	Sun Sep 13 11:45:31 2009	(r197159)
@@ -71,6 +71,8 @@ gif_status(int s)
 	ifr.ifr_data = (caddr_t)&opts;
 	if (ioctl(s, GIFGOPTS, &ifr) == -1)
 		return;
+	if (opts == 0)
+		return;
 
 	printf("\toptions=%d<", opts);
 	for (i=0; i < sizeof(gif_opts)/sizeof(gif_opts[0]); i++) {
From ume at FreeBSD.org  Sun Sep 13 11:52:18 2009
From: ume at FreeBSD.org (Hajimu UMEMOTO)
Date: Sun Sep 13 11:52:36 2009
Subject: svn commit: r197162 - in stable/7: contrib/traceroute
	usr.sbin/traceroute6
Message-ID: <200909131152.n8DBqHAk020421@svn.freebsd.org>

Author: ume
Date: Sun Sep 13 11:52:17 2009
New Revision: 197162
URL: http://svn.freebsd.org/changeset/base/197162

Log:
  MFC r196475:
   - Add AS lookup functionality to traceroute6(8) as well.
   - Support for IPv6 transport for AS lookup.
   - Introduce $RA_SERVER to set whois server.
   - Support for 4 byte ASN.
   - ANSIfy function declaration in as.c.

Modified:
  stable/7/contrib/traceroute/   (props changed)
  stable/7/contrib/traceroute/as.c
  stable/7/contrib/traceroute/as.h
  stable/7/contrib/traceroute/traceroute.c
  stable/7/usr.sbin/traceroute6/   (props changed)
  stable/7/usr.sbin/traceroute6/Makefile
  stable/7/usr.sbin/traceroute6/traceroute6.8
  stable/7/usr.sbin/traceroute6/traceroute6.c

Modified: stable/7/contrib/traceroute/as.c
==============================================================================
--- stable/7/contrib/traceroute/as.c	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/contrib/traceroute/as.c	Sun Sep 13 11:52:17 2009	(r197162)
@@ -63,55 +63,42 @@ struct aslookup {
 };
 
 void *
-as_setup(server)
-	char *server;
+as_setup(char *server)
 {
 	struct aslookup *asn;
-	struct hostent *he = NULL;
-	struct servent *se;
-	struct sockaddr_in in;
+	struct addrinfo hints, *res0, *res;
 	FILE *f;
-	int s;
+	int s, error;
 
 	if (server == NULL)
+		server = getenv("RA_SERVER");
+	if (server == NULL)
 		server = DEFAULT_AS_SERVER;
 
-	(void)memset(&in, 0, sizeof(in));
-	in.sin_family = AF_INET;
-	in.sin_len = sizeof(in);
-	if ((se = getservbyname("whois", "tcp")) == NULL) {
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	error = getaddrinfo(server, "whois", &hints, &res0);
+	if (error == EAI_SERVICE) {
 		warnx("warning: whois/tcp service not found");
-		in.sin_port = ntohs(43);
-	} else
-		in.sin_port = se->s_port;
-
-	if (inet_aton(server, &in.sin_addr) == 0 && 
-	    ((he = gethostbyname(server)) == NULL ||
-	    he->h_addr == NULL)) {
-		warnx("%s: %s", server, hstrerror(h_errno));
-		return (NULL);
+		error = getaddrinfo(server, "43", &hints, &res0);
 	}
-
-	if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-		warn("socket");
+	if (error != 0) {
+		warnx("%s: %s", server, gai_strerror(error));
 		return (NULL);
 	}
 
-	do {
-		if (he != NULL) {
-			memcpy(&in.sin_addr, he->h_addr, he->h_length);
-			he->h_addr_list++;
-		}
-		if (connect(s, (struct sockaddr *)&in, sizeof(in)) == 0)
+	for (res = res0; res; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (s < 0)
+			continue;
+		if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
 			break;
-		if (he == NULL || he->h_addr == NULL) {
-			close(s);
-			s = -1;
-			break;
-		}
-	} while (1);
-
-	if (s == -1) {
+		close(s);
+		s = -1;
+	}
+	freeaddrinfo(res0);
+	if (s < 0) {
 		warn("connect");
 		return (NULL);
 	}
@@ -137,23 +124,23 @@ as_setup(server)
 	return (asn);
 }
 
-int
-as_lookup(_asn, addr)
-	void *_asn;
-	struct in_addr *addr;
+unsigned int
+as_lookup(void *_asn, char *addr, sa_family_t family)
 {
 	struct aslookup *asn = _asn;
 	char buf[1024];
-	int as, rc, dlen;
+	unsigned int as;
+	int rc, dlen, plen;
 
-	as = rc = dlen = 0;
-	(void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr));
+	as = 0;
+	rc = dlen = 0;
+	plen = (family == AF_INET6) ? 128 : 32;
+	(void)fprintf(asn->as_f, "!r%s/%d,l\n", addr, plen);
 	(void)fflush(asn->as_f);
 
 #ifdef AS_DEBUG_FILE
 	if (asn->as_debug) {
-		(void)fprintf(asn->as_debug, ">> !r%s/32,l\n",
-		     inet_ntoa(*addr));
+		(void)fprintf(asn->as_debug, ">> !r%s/%d,l\n", addr, plen);
 		(void)fflush(asn->as_debug);
 	}
 #endif /* AS_DEBUG_FILE */
@@ -182,7 +169,7 @@ as_lookup(_asn, addr)
 				}
 #endif /* AS_DEBUG_FILE */
 				break;
-			    case 'C':	
+			    case 'C':
 			    case 'D':
 			    case 'E':
 			    case 'F':
@@ -209,7 +196,7 @@ as_lookup(_asn, addr)
 
 		/* origin line is the interesting bit */
 		if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) {
-			sscanf(buf + 7, " AS%d", &as);
+			sscanf(buf + 7, " AS%u", &as);
 #ifdef AS_DEBUG_FILE
 			if (asn->as_debug) {
 				(void)fprintf(asn->as_debug, "as: %d\n", as);
@@ -223,8 +210,7 @@ as_lookup(_asn, addr)
 }
 
 void
-as_shutdown(_asn)
-	void *_asn;
+as_shutdown(void *_asn)
 {
 	struct aslookup *asn = _asn;
 

Modified: stable/7/contrib/traceroute/as.h
==============================================================================
--- stable/7/contrib/traceroute/as.h	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/contrib/traceroute/as.h	Sun Sep 13 11:52:17 2009	(r197162)
@@ -37,6 +37,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-void	*as_setup __P((char *));
-int	as_lookup __P((void *, struct in_addr *));
-void	as_shutdown __P((void *));
+void *as_setup(char *);
+unsigned int as_lookup(void *, char *, sa_family_t);
+void as_shutdown(void *);

Modified: stable/7/contrib/traceroute/traceroute.c
==============================================================================
--- stable/7/contrib/traceroute/traceroute.c	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/contrib/traceroute/traceroute.c	Sun Sep 13 11:52:17 2009	(r197162)
@@ -1477,19 +1477,21 @@ print(register u_char *buf, register int
 {
 	register struct ip *ip;
 	register int hlen;
+	char addr[INET_ADDRSTRLEN];
 
 	ip = (struct ip *) buf;
 	hlen = ip->ip_hl << 2;
 	cc -= hlen;
 
+	strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
+
 	if (as_path)
-		Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
+		Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
 
 	if (nflag)
-		Printf(" %s", inet_ntoa(from->sin_addr));
+		Printf(" %s", addr);
 	else
-		Printf(" %s (%s)", inetname(from->sin_addr),
-		    inet_ntoa(from->sin_addr));
+		Printf(" %s (%s)", inetname(from->sin_addr), addr);
 
 	if (verbose)
 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));

Modified: stable/7/usr.sbin/traceroute6/Makefile
==============================================================================
--- stable/7/usr.sbin/traceroute6/Makefile	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/usr.sbin/traceroute6/Makefile	Sun Sep 13 11:52:17 2009	(r197162)
@@ -13,12 +13,17 @@
 # A PARTICULAR PURPOSE.
 # $FreeBSD$
 
+TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
+.PATH: ${TRACEROUTE_DISTDIR}
+
 PROG=	traceroute6
 MAN=	traceroute6.8
+SRCS=	as.c traceroute6.c
 BINOWN=	root
 BINMODE= 4555
 
 CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
+CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
 
 DPADD=	${LIBIPSEC}
 LDADD=	-lipsec

Modified: stable/7/usr.sbin/traceroute6/traceroute6.8
==============================================================================
--- stable/7/usr.sbin/traceroute6/traceroute6.8	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/usr.sbin/traceroute6/traceroute6.8	Sun Sep 13 11:52:17 2009	(r197162)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 17, 1998
+.Dd August 24, 2009
 .Dt TRACEROUTE6 8
 .Os
 .\"
@@ -40,7 +40,7 @@
 .Sh SYNOPSIS
 .Nm
 .Bk -words
-.Op Fl dIlnNrvU
+.Op Fl adIlnNrvU
 .Ek
 .Bk -words
 .Op Fl f Ar firsthop
@@ -64,6 +64,9 @@
 .Op Fl w Ar waittime
 .Ek
 .Bk -words
+.Op Fl A Ar as_server
+.Ek
+.Bk -words
 .Ar target
 .Op Ar datalen
 .Ek
@@ -84,6 +87,10 @@ after the destination host name.
 .Pp
 Other options are:
 .Bl -tag -width Ds
+.It Fl a
+Turn on AS# lookups for each hop encountered.
+.It Fl A Ar as_server
+Turn on AS# lookups and use the given server instead of the default.
 .It Fl d
 Debug mode.
 .It Fl f Ar firsthop

Modified: stable/7/usr.sbin/traceroute6/traceroute6.c
==============================================================================
--- stable/7/usr.sbin/traceroute6/traceroute6.c	Sun Sep 13 11:52:15 2009	(r197161)
+++ stable/7/usr.sbin/traceroute6/traceroute6.c	Sun Sep 13 11:52:17 2009	(r197162)
@@ -282,6 +282,8 @@ static const char rcsid[] =
 #include 
 #endif
 
+#include "as.h"
+
 #define DUMMY_PORT 10010
 
 #define	MAXPACKET	65535	/* max ip packet size */
@@ -359,6 +361,9 @@ int waittime = 5;		/* time to wait for r
 int nflag;			/* print addresses numerically */
 int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
 int lflag;			/* print both numerical address & hostname */
+int as_path;			/* print as numbers for each hop */
+char *as_server = NULL;
+void *asn;
 
 int
 main(argc, argv)
@@ -411,8 +416,15 @@ main(argc, argv)
 
 	seq = 0;
 
-	while ((ch = getopt(argc, argv, "df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
+	while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
 		switch (ch) {
+		case 'a':
+			as_path = 1;
+			break;
+		case 'A':
+			as_path = 1;
+			as_server = optarg;
+			break;
 		case 'd':
 			options |= SO_DEBUG;
 			break;
@@ -867,6 +879,17 @@ main(argc, argv)
 		srcport = ntohs(Src.sin6_port);
 	}
 
+	if (as_path) {
+		asn = as_setup(as_server);
+		if (asn == NULL) {
+			fprintf(stderr,
+			    "traceroute6: as_setup failed, AS# lookups"
+			    " disabled\n");
+			(void)fflush(stderr);
+			as_path = 0;
+		}
+	}
+
 	/*
 	 * Message to users
 	 */
@@ -948,6 +971,8 @@ main(argc, argv)
 			exit(0);
 		}
 	}
+	if (as_path)
+		as_shutdown(asn);
 
 	exit(0);
 }
@@ -1361,6 +1386,8 @@ print(mhdr, cc)
 	if (getnameinfo((struct sockaddr *)from, from->sin6_len,
 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
 		strlcpy(hbuf, "invalid", sizeof(hbuf));
+	if (as_path)
+		printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
 	if (nflag)
 		printf(" %s", hbuf);
 	else if (lflag)
From ume at FreeBSD.org  Sun Sep 13 17:05:56 2009
From: ume at FreeBSD.org (Hajimu UMEMOTO)
Date: Sun Sep 13 17:06:08 2009
Subject: svn commit: r197170 - stable/7/share/timedef
Message-ID: <200909131705.n8DH5uLn026723@svn.freebsd.org>

Author: ume
Date: Sun Sep 13 17:05:56 2009
New Revision: 197170
URL: http://svn.freebsd.org/changeset/base/197170

Log:
  MFC r196651: AM/PM date format for ja_JP.eucJP and ja_JP.SJIS were
  localized by r193869.  However, ja_JP.UTF-8 wasn't.  So, reflect it
  to ja_JP.UTF-8 as well.

Modified:
  stable/7/share/timedef/   (props changed)
  stable/7/share/timedef/ja_JP.UTF-8.src

Modified: stable/7/share/timedef/ja_JP.UTF-8.src
==============================================================================
--- stable/7/share/timedef/ja_JP.UTF-8.src	Sun Sep 13 17:01:34 2009	(r197169)
+++ stable/7/share/timedef/ja_JP.UTF-8.src	Sun Sep 13 17:05:56 2009	(r197170)
@@ -68,13 +68,11 @@
 #
 # am
 #
-#??
-AM
+??
 #
 # pm
 #
-#??
-PM
+??
 #
 # date_fmt
 #
From ume at FreeBSD.org  Sun Sep 13 17:08:59 2009
From: ume at FreeBSD.org (Hajimu UMEMOTO)
Date: Sun Sep 13 17:09:10 2009
Subject: svn commit: r197171 - stable/7/usr.bin/w
Message-ID: <200909131708.n8DH8wlY026818@svn.freebsd.org>

Author: ume
Date: Sun Sep 13 17:08:58 2009
New Revision: 197171
URL: http://svn.freebsd.org/changeset/base/197171

Log:
  MFC r196652: Fix the problem that the entry broke into two lines
  with multi-byte AM/PM date format.

Modified:
  stable/7/usr.bin/w/   (props changed)
  stable/7/usr.bin/w/extern.h
  stable/7/usr.bin/w/pr_time.c
  stable/7/usr.bin/w/w.c

Modified: stable/7/usr.bin/w/extern.h
==============================================================================
--- stable/7/usr.bin/w/extern.h	Sun Sep 13 17:05:56 2009	(r197170)
+++ stable/7/usr.bin/w/extern.h	Sun Sep 13 17:08:58 2009	(r197171)
@@ -38,6 +38,6 @@
 extern	int use_ampm;
 
 struct kinfo_proc;
-void	pr_attime(time_t *, time_t *);
+int	pr_attime(time_t *, time_t *);
 int	pr_idle(time_t);
 int	proc_compare(struct kinfo_proc *, struct kinfo_proc *);

Modified: stable/7/usr.bin/w/pr_time.c
==============================================================================
--- stable/7/usr.bin/w/pr_time.c	Sun Sep 13 17:05:56 2009	(r197170)
+++ stable/7/usr.bin/w/pr_time.c	Sun Sep 13 17:08:58 2009	(r197171)
@@ -52,13 +52,14 @@ static const char sccsid[] = "@(#)pr_tim
  * pr_attime --
  *	Print the time since the user logged in.
  */
-void
+int
 pr_attime(time_t *started, time_t *now)
 {
-	static char buf[256];
+	static wchar_t buf[256];
 	struct tm tp, tm;
 	time_t diff;
-	char fmt[20];
+	wchar_t *fmt;
+	int len, width, offset = 0;
 
 	tp = *localtime(started);
 	tm = *localtime(now);
@@ -66,7 +67,7 @@ pr_attime(time_t *started, time_t *now)
 
 	/* If more than a week, use day-month-year. */
 	if (diff > 86400 * 7)
-		(void)strcpy(fmt, "%d%b%y");
+		fmt = L"%d%b%y";
 
 	/* If not today, use day-hour-am/pm. */
 	else if (tm.tm_mday != tp.tm_mday ||
@@ -74,16 +75,26 @@ pr_attime(time_t *started, time_t *now)
 		 tm.tm_year != tp.tm_year) {
 	/* The line below does not take DST into consideration */
 	/* else if (*now / 86400 != *started / 86400) { */
-		(void)strcpy(fmt, use_ampm ? "%a%I%p" : "%a%H");
+		fmt = use_ampm ? L"%a%I%p" : L"%a%H";
 	}
 
 	/* Default is hh:mm{am,pm}. */
 	else {
-		(void)strcpy(fmt, use_ampm ? "%l:%M%p" : "%k:%M");
+		fmt = use_ampm ? L"%l:%M%p" : L"%k:%M";
 	}
 
-	(void)strftime(buf, sizeof(buf), fmt, &tp);
-	(void)wprintf(L"%-7.7s", buf);
+	(void)wcsftime(buf, sizeof(buf), fmt, &tp);
+	len = wcslen(buf);
+	width = wcswidth(buf, len);
+	if (len == width)
+		(void)wprintf(L"%-7.7ls", buf);
+	else if (width < 7)
+		(void)wprintf(L"%ls%.*s", buf, 7 - width, "      ");
+	else {
+		(void)wprintf(L"%ls", buf);
+		offset = width - 7;
+	}
+	return (offset);
 }
 
 /*

Modified: stable/7/usr.bin/w/w.c
==============================================================================
--- stable/7/usr.bin/w/w.c	Sun Sep 13 17:05:56 2009	(r197170)
+++ stable/7/usr.bin/w/w.c	Sun Sep 13 17:08:58 2009	(r197171)
@@ -137,7 +137,7 @@ main(int argc, char *argv[])
 	struct stat *stp;
 	FILE *ut;
 	time_t touched;
-	int ch, i, nentries, nusers, wcmd, longidle, dropgid;
+	int ch, i, nentries, nusers, wcmd, longidle, longattime, dropgid;
 	const char *memf, *nlistf, *p;
 	char *x_suffix;
 	char buf[MAXHOSTNAMELEN], errbuf[_POSIX2_LINE_MAX];
@@ -406,9 +406,10 @@ main(int argc, char *argv[])
 		    ep->utmp.ut_line : ep->utmp.ut_line + 3,
 		    W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-");
 		t = _time_to_time32(ep->utmp.ut_time);
-		pr_attime(&t, &now);
+		longattime = pr_attime(&t, &now);
 		longidle = pr_idle(ep->idle);
-		(void)printf("%.*s\n", argwidth - longidle, ep->args);
+		(void)printf("%.*s\n", argwidth - longidle - longattime,
+		    ep->args);
 	}
 	(void)kvm_close(kd);
 	exit(0);
From jhb at FreeBSD.org  Mon Sep 14 17:34:50 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Mon Sep 14 17:34:58 2009
Subject: svn commit: r197197 - in stable/7: sys sys/amd64/amd64 sys/arm/arm
	sys/conf sys/contrib/pf sys/fs/procfs sys/i386/i386
	sys/ia64/ia64 sys/kern sys/sparc64/sparc64 sys/sys sys/vm
	usr.bin/procstat
Message-ID: <200909141734.n8EHYng3061392@svn.freebsd.org>

Author: jhb
Date: Mon Sep 14 17:34:49 2009
New Revision: 197197
URL: http://svn.freebsd.org/changeset/base/197197

Log:
  MFC 195840, 195844, and 196637:
  Add a new type of VM object: OBJT_SG.  An OBJT_SG object is very similar to
  a device pager (OBJT_DEVICE) object in that it uses fictitious pages to
  provide aliases to other memory addresses.  The primary difference is that
  it uses an sglist(9) to determine the physical addresses for a given offset
  into the object instead of invoking the d_mmap() method in a device driver.

Added:
  stable/7/sys/vm/sg_pager.c
     - copied, changed from r195840, head/sys/vm/sg_pager.c
Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/pmap.c
  stable/7/sys/arm/arm/pmap.c
  stable/7/sys/conf/files
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/fs/procfs/procfs_map.c
  stable/7/sys/i386/i386/pmap.c
  stable/7/sys/ia64/ia64/pmap.c
  stable/7/sys/kern/kern_proc.c
  stable/7/sys/sparc64/sparc64/pmap.c
  stable/7/sys/sys/user.h
  stable/7/sys/vm/vm.h
  stable/7/sys/vm/vm_fault.c
  stable/7/sys/vm/vm_map.c
  stable/7/sys/vm/vm_meter.c
  stable/7/sys/vm/vm_object.c
  stable/7/sys/vm/vm_object.h
  stable/7/sys/vm/vm_page.c
  stable/7/sys/vm/vm_pageout.c
  stable/7/sys/vm/vm_pager.c
  stable/7/sys/vm/vm_pager.h
  stable/7/usr.bin/procstat/   (props changed)
  stable/7/usr.bin/procstat/procstat_vm.c

Modified: stable/7/sys/amd64/amd64/pmap.c
==============================================================================
--- stable/7/sys/amd64/amd64/pmap.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/amd64/amd64/pmap.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -3350,7 +3350,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs
 	int pat_mode;
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	KASSERT(object->type == OBJT_DEVICE,
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
 	    ("pmap_object_init_pt: non-device object"));
 	if ((addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) {
 		if (!vm_object_populate(object, pindex, pindex + atop(size)))
@@ -4592,7 +4592,8 @@ vm_offset_t
 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
 {
 
-	if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
+	if ((obj == NULL) || (size < NBPDR) ||
+	    (obj->type != OBJT_DEVICE && obj->type != OBJT_SG)) {
 		return addr;
 	}
 

Modified: stable/7/sys/arm/arm/pmap.c
==============================================================================
--- stable/7/sys/arm/arm/pmap.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/arm/arm/pmap.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -3071,7 +3071,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs
 {
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	KASSERT(object->type == OBJT_DEVICE,
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
 	    ("pmap_object_init_pt: non-device object"));
 }
 

Modified: stable/7/sys/conf/files
==============================================================================
--- stable/7/sys/conf/files	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/conf/files	Mon Sep 14 17:34:49 2009	(r197197)
@@ -2210,6 +2210,7 @@ vm/default_pager.c		standard
 vm/device_pager.c		standard
 vm/phys_pager.c			standard
 vm/redzone.c			optional DEBUG_REDZONE
+vm/sg_pager.c			standard
 vm/swap_pager.c			standard
 vm/uma_core.c			standard
 vm/uma_dbg.c			standard

Modified: stable/7/sys/fs/procfs/procfs_map.c
==============================================================================
--- stable/7/sys/fs/procfs/procfs_map.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/fs/procfs/procfs_map.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -177,6 +177,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
 				type = "swap";
 				vp = NULL;
 				break;
+			case OBJT_SG:
 			case OBJT_DEVICE:
 				type = "device";
 				vp = NULL;

Modified: stable/7/sys/i386/i386/pmap.c
==============================================================================
--- stable/7/sys/i386/i386/pmap.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/i386/i386/pmap.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -3474,7 +3474,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs
 	int pat_mode;
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	KASSERT(object->type == OBJT_DEVICE,
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
 	    ("pmap_object_init_pt: non-device object"));
 	if (pseflag && 
 	    (addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) {
@@ -4712,7 +4712,8 @@ vm_offset_t
 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
 {
 
-	if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
+	if ((obj == NULL) || (size < NBPDR) ||
+	    (obj->type != OBJT_DEVICE && obj->type != OBJT_SG)) {
 		return addr;
 	}
 

Modified: stable/7/sys/ia64/ia64/pmap.c
==============================================================================
--- stable/7/sys/ia64/ia64/pmap.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/ia64/ia64/pmap.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -1737,7 +1737,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offs
 {
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	KASSERT(object->type == OBJT_DEVICE,
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
 	    ("pmap_object_init_pt: non-device object"));
 }
 

Modified: stable/7/sys/kern/kern_proc.c
==============================================================================
--- stable/7/sys/kern/kern_proc.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/kern/kern_proc.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -1488,6 +1488,9 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_A
 			case OBJT_DEAD:
 				kve->kve_type = KVME_TYPE_DEAD;
 				break;
+			case OBJT_SG:
+				kve->kve_type = KVME_TYPE_SG;
+				break;
 			default:
 				kve->kve_type = KVME_TYPE_UNKNOWN;
 				break;
@@ -1659,6 +1662,9 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
 			case OBJT_DEAD:
 				kve->kve_type = KVME_TYPE_DEAD;
 				break;
+			case OBJT_SG:
+				kve->kve_type = KVME_TYPE_SG;
+				break;
 			default:
 				kve->kve_type = KVME_TYPE_UNKNOWN;
 				break;

Modified: stable/7/sys/sparc64/sparc64/pmap.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/pmap.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/sparc64/sparc64/pmap.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -1495,7 +1495,7 @@ pmap_object_init_pt(pmap_t pm, vm_offset
 {
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	KASSERT(object->type == OBJT_DEVICE,
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
 	    ("pmap_object_init_pt: non-device object"));
 }
 

Modified: stable/7/sys/sys/user.h
==============================================================================
--- stable/7/sys/sys/user.h	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/sys/user.h	Mon Sep 14 17:34:49 2009	(r197197)
@@ -334,6 +334,7 @@ struct kinfo_file {
 #define	KVME_TYPE_DEVICE	4
 #define	KVME_TYPE_PHYS		5
 #define	KVME_TYPE_DEAD		6
+#define	KVME_TYPE_SG		7
 #define	KVME_TYPE_UNKNOWN	255
 
 #define	KVME_PROT_READ		0x00000001

Copied and modified: stable/7/sys/vm/sg_pager.c (from r195840, head/sys/vm/sg_pager.c)
==============================================================================
--- head/sys/vm/sg_pager.c	Fri Jul 24 13:50:29 2009	(r195840, copy source)
+++ stable/7/sys/vm/sg_pager.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -45,7 +46,7 @@ __FBSDID("$FreeBSD$");
 
 static void sg_pager_init(void);
 static vm_object_t sg_pager_alloc(void *, vm_ooffset_t, vm_prot_t,
-    vm_ooffset_t, struct ucred *);
+    vm_ooffset_t);
 static void sg_pager_dealloc(vm_object_t);
 static int sg_pager_getpages(vm_object_t, vm_page_t *, int, int);
 static void sg_pager_putpages(vm_object_t, vm_page_t *, int, 
@@ -78,7 +79,7 @@ sg_pager_init(void)
 
 static vm_object_t
 sg_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
-    vm_ooffset_t foff, struct ucred *cred)
+    vm_ooffset_t foff)
 {
 	struct sglist *sg;
 	vm_object_t object;
@@ -193,21 +194,18 @@ sg_pager_getpages(vm_object_t object, vm
 	    ("backing page for SG is fake"));
 
 	/* Construct a new fake page. */
-	printf("SG: getting fake page for paddr %lx\n", paddr);
 	page = sg_pager_getfake(paddr, memattr);
 	VM_OBJECT_LOCK(object);
 	TAILQ_INSERT_TAIL(&object->un_pager.sgp.sgp_pglist, page, pageq);
 
 	/* Free the original pages and insert this fake page into the object. */
 	vm_page_lock_queues();
-	for (i = 0; i < count; i++) {
-		printf("SG: freeing VM page %p\n", m[i]);
+	for (i = 0; i < count; i++)
 		vm_page_free(m[i]);
-	}
 	vm_page_unlock_queues();
-	printf("SG: Inserting new fake page\n");
 	vm_page_insert(page, object, offset);
 	m[reqpage] = page;
+	page->valid = VM_PAGE_BITS_ALL;
 
 	return (VM_PAGER_OK);
 }

Modified: stable/7/sys/vm/vm.h
==============================================================================
--- stable/7/sys/vm/vm.h	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm.h	Mon Sep 14 17:34:49 2009	(r197197)
@@ -89,7 +89,7 @@ typedef u_char vm_prot_t;	/* protection 
 #define	VM_PROT_DEFAULT		VM_PROT_ALL
 
 enum obj_type { OBJT_DEFAULT, OBJT_SWAP, OBJT_VNODE, OBJT_DEVICE, OBJT_PHYS,
-		OBJT_DEAD };
+		OBJT_DEAD, OBJT_SG };
 typedef u_char objtype_t;
 
 union vm_map_object;

Modified: stable/7/sys/vm/vm_fault.c
==============================================================================
--- stable/7/sys/vm/vm_fault.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_fault.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -485,7 +485,8 @@ readrest:
 			    (fs.first_object == fs.object ||
 			     (is_first_object_locked = VM_OBJECT_TRYLOCK(fs.first_object))) &&
 			    fs.first_object->type != OBJT_DEVICE &&
-			    fs.first_object->type != OBJT_PHYS) {
+			    fs.first_object->type != OBJT_PHYS &&
+			    fs.first_object->type != OBJT_SG) {
 				vm_pindex_t firstpindex, tmppindex;
 
 				if (fs.first_pindex < 2 * VM_FAULT_READ)

Modified: stable/7/sys/vm/vm_map.c
==============================================================================
--- stable/7/sys/vm/vm_map.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_map.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -1478,7 +1478,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offse
 	if ((prot & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0 || object == NULL)
 		return;
 	VM_OBJECT_LOCK(object);
-	if (object->type == OBJT_DEVICE) {
+	if (object->type == OBJT_DEVICE || object->type == OBJT_SG) {
 		pmap_object_init_pt(map->pmap, addr, object, pindex, size);
 		goto unlock_return;
 	}
@@ -1954,7 +1954,8 @@ done:
 				 */
 				vm_fault_unwire(map, entry->start, entry->end,
 				    entry->object.vm_object != NULL &&
-				    entry->object.vm_object->type == OBJT_DEVICE);
+				    (entry->object.vm_object->type == OBJT_DEVICE ||
+				    entry->object.vm_object->type == OBJT_SG));
 			}
 		}
 		KASSERT(entry->eflags & MAP_ENTRY_IN_TRANSITION,
@@ -2073,7 +2074,8 @@ vm_map_wire(vm_map_t map, vm_offset_t st
 			saved_start = entry->start;
 			saved_end = entry->end;
 			fictitious = entry->object.vm_object != NULL &&
-			    entry->object.vm_object->type == OBJT_DEVICE;
+			    (entry->object.vm_object->type == OBJT_DEVICE ||
+			    entry->object.vm_object->type == OBJT_SG);
 			/*
 			 * Release the map lock, relying on the in-transition
 			 * mark.
@@ -2169,7 +2171,8 @@ done:
 				 */
 				vm_fault_unwire(map, entry->start, entry->end,
 				    entry->object.vm_object != NULL &&
-				    entry->object.vm_object->type == OBJT_DEVICE);
+				    (entry->object.vm_object->type == OBJT_DEVICE ||
+				    entry->object.vm_object->type == OBJT_SG));
 			}
 		}
 	next_entry_done:
@@ -2294,7 +2297,8 @@ vm_map_entry_unwire(vm_map_t map, vm_map
 {
 	vm_fault_unwire(map, entry->start, entry->end,
 	    entry->object.vm_object != NULL &&
-	    entry->object.vm_object->type == OBJT_DEVICE);
+	    (entry->object.vm_object->type == OBJT_DEVICE ||
+	    entry->object.vm_object->type == OBJT_SG));
 	entry->wired_count = 0;
 }
 

Modified: stable/7/sys/vm/vm_meter.c
==============================================================================
--- stable/7/sys/vm/vm_meter.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_meter.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -211,7 +211,7 @@ vmtotal(SYSCTL_HANDLER_ARGS)
 		 * synchronization should not impair the accuracy of
 		 * the reported statistics. 
 		 */
-		if (object->type == OBJT_DEVICE) {
+		if (object->type == OBJT_DEVICE || object->type == OBJT_SG) {
 			/*
 			 * Devices, like /dev/mem, will badly skew our totals.
 			 */

Modified: stable/7/sys/vm/vm_object.c
==============================================================================
--- stable/7/sys/vm/vm_object.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_object.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -306,6 +306,7 @@ vm_object_set_memattr(vm_object_t object
 	case OBJT_DEFAULT:
 	case OBJT_DEVICE:
 	case OBJT_PHYS:
+	case OBJT_SG:
 	case OBJT_SWAP:
 	case OBJT_VNODE:
 		if (!TAILQ_EMPTY(&object->memq))

Modified: stable/7/sys/vm/vm_object.h
==============================================================================
--- stable/7/sys/vm/vm_object.h	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_object.h	Mon Sep 14 17:34:49 2009	(r197197)
@@ -124,6 +124,15 @@ struct vm_object {
 		} devp;
 
 		/*
+		 * SG pager
+		 *
+		 *	sgp_pglist - list of allocated pages
+		 */
+		struct {
+			TAILQ_HEAD(, vm_page) sgp_pglist;
+		} sgp;
+
+		/*
 		 * Swap pager
 		 *
 		 *	swp_bcount - number of swap 'swblock' metablocks, each

Modified: stable/7/sys/vm/vm_page.c
==============================================================================
--- stable/7/sys/vm/vm_page.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_page.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -1149,7 +1149,7 @@ vm_page_alloc(vm_object_t object, vm_pin
 	if (object != NULL) {
 		/* Ignore device objects; the pager sets "memattr" for them. */
 		if (object->memattr != VM_MEMATTR_DEFAULT &&
-		    object->type != OBJT_DEVICE)
+		    object->type != OBJT_DEVICE && object->type != OBJT_SG)
 			pmap_page_set_memattr(m, object->memattr);
 		vm_page_insert(m, object, pindex);
 	} else

Modified: stable/7/sys/vm/vm_pageout.c
==============================================================================
--- stable/7/sys/vm/vm_pageout.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_pageout.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -516,7 +516,9 @@ vm_pageout_object_deactivate_pages(pmap,
 	int actcount, rcount, remove_mode;
 
 	VM_OBJECT_LOCK_ASSERT(first_object, MA_OWNED);
-	if (first_object->type == OBJT_DEVICE || first_object->type == OBJT_PHYS)
+	if (first_object->type == OBJT_DEVICE ||
+	    first_object->type == OBJT_SG ||
+	    first_object->type == OBJT_PHYS)
 		return;
 	for (object = first_object;; object = backing_object) {
 		if (pmap_resident_count(pmap) <= desired)

Modified: stable/7/sys/vm/vm_pager.c
==============================================================================
--- stable/7/sys/vm/vm_pager.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_pager.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -160,7 +160,8 @@ struct pagerops *pagertab[] = {
 	&vnodepagerops,		/* OBJT_VNODE */
 	&devicepagerops,	/* OBJT_DEVICE */
 	&physpagerops,		/* OBJT_PHYS */
-	&deadpagerops		/* OBJT_DEAD */
+	&deadpagerops,		/* OBJT_DEAD */
+	&sgpagerops		/* OBJT_SG */
 };
 
 static const int npagers = sizeof(pagertab) / sizeof(pagertab[0]);

Modified: stable/7/sys/vm/vm_pager.h
==============================================================================
--- stable/7/sys/vm/vm_pager.h	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/sys/vm/vm_pager.h	Mon Sep 14 17:34:49 2009	(r197197)
@@ -71,6 +71,7 @@ extern struct pagerops swappagerops;
 extern struct pagerops vnodepagerops;
 extern struct pagerops devicepagerops;
 extern struct pagerops physpagerops;
+extern struct pagerops sgpagerops;
 
 /*
  * get/put return values

Modified: stable/7/usr.bin/procstat/procstat_vm.c
==============================================================================
--- stable/7/usr.bin/procstat/procstat_vm.c	Mon Sep 14 16:52:38 2009	(r197196)
+++ stable/7/usr.bin/procstat/procstat_vm.c	Mon Sep 14 17:34:49 2009	(r197197)
@@ -93,6 +93,9 @@ procstat_vm(pid_t pid, struct kinfo_proc
 		case KVME_TYPE_DEAD:
 			str = "dd";
 			break;
+		case KVME_TYPE_SG:
+			str = "sg";
+			break;
 		case KVME_TYPE_UNKNOWN:
 		default:
 			str = "??";
From jhb at FreeBSD.org  Mon Sep 14 17:45:59 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Mon Sep 14 17:46:05 2009
Subject: svn commit: r197198 - stable/7/sys/sys
Message-ID: <200909141745.n8EHjwOT061684@svn.freebsd.org>

Author: jhb
Date: Mon Sep 14 17:45:58 2009
New Revision: 197198
URL: http://svn.freebsd.org/changeset/base/197198

Log:
  Bump __FreeBSD_version to 702106 for the recent PAT, d_mmap_single(), and
  OBJT_SG changes.

Modified:
  stable/7/sys/sys/param.h

Modified: stable/7/sys/sys/param.h
==============================================================================
--- stable/7/sys/sys/param.h	Mon Sep 14 17:34:49 2009	(r197197)
+++ stable/7/sys/sys/param.h	Mon Sep 14 17:45:58 2009	(r197198)
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 702105	/* Master, propagated to newvers */
+#define __FreeBSD_version 702106	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include 
From emaste at FreeBSD.org  Tue Sep 15 02:23:17 2009
From: emaste at FreeBSD.org (Ed Maste)
Date: Tue Sep 15 02:23:38 2009
Subject: svn commit: r197213 - stable/7/sys/cam
Message-ID: <200909150223.n8F2NGeu073047@svn.freebsd.org>

Author: emaste
Date: Tue Sep 15 02:23:16 2009
New Revision: 197213
URL: http://svn.freebsd.org/changeset/base/197213

Log:
  MFC r195685:
  
  Fix leaks in probestart, probedone, and scsi_scan_bus.  Also free
  page_list using the matching malloc type for the allocation.
  
  (In HEAD these functions have moved to scsi_xpt.c)
  
  Reviewed by:	scottl

Modified:
  stable/7/sys/cam/cam_xpt.c

Modified: stable/7/sys/cam/cam_xpt.c
==============================================================================
--- stable/7/sys/cam/cam_xpt.c	Tue Sep 15 02:22:57 2009	(r197212)
+++ stable/7/sys/cam/cam_xpt.c	Tue Sep 15 02:23:16 2009	(r197213)
@@ -5240,6 +5240,7 @@ xpt_scan_bus(struct cam_periph *periph, 
 			}
 			work_ccb = xpt_alloc_ccb_nowait();
 			if (work_ccb == NULL) {
+				xpt_free_ccb((union ccb *)scan_info->cpi);
 				free(scan_info, M_CAMXPT);
 				xpt_free_path(path);
 				request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
@@ -5360,6 +5361,7 @@ xpt_scan_bus(struct cam_periph *periph, 
 			}
 
 			if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) {
+				xpt_free_ccb(request_ccb);
 				break;
 			}
 			status = xpt_create_path(&path, xpt_periph,
@@ -5828,8 +5830,11 @@ probestart(struct cam_periph *periph, un
 
 		serial_buf = NULL;
 		device = periph->path->device;
-		device->serial_num = NULL;
-		device->serial_num_len = 0;
+		if (device->serial_num != NULL) {
+			free(device->serial_num, M_CAMXPT);
+			device->serial_num = NULL;
+			device->serial_num_len = 0;
+		}
 
 		serial_buf = (struct scsi_vpd_unit_serial_number *)
 			malloc(sizeof(*serial_buf), M_CAMXPT, M_NOWAIT|M_ZERO);
@@ -6168,7 +6173,7 @@ probedone(struct cam_periph *periph, uni
 		}
 
 		if (page_list != NULL)
-			free(page_list, M_DEVBUF);
+			free(page_list, M_CAMXPT);
 
 		if (serialnum_supported) {
 			xpt_release_ccb(done_ccb);
From avg at FreeBSD.org  Thu Sep 17 12:44:59 2009
From: avg at FreeBSD.org (Andriy Gapon)
Date: Thu Sep 17 12:45:16 2009
Subject: svn commit: r197271 - in stable/7/sys: . contrib/pf dev/pci
Message-ID: <200909171244.n8HCix5Y056991@svn.freebsd.org>

Author: avg
Date: Thu Sep 17 12:44:58 2009
New Revision: 197271
URL: http://svn.freebsd.org/changeset/base/197271

Log:
  MFC r197077: pci: remove definitions of duplicate constants
  
  Suggested by:	jhb
  Reviewed by:	jhb

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/pci/pcireg.h
  stable/7/sys/dev/pci/pcivar.h

Modified: stable/7/sys/dev/pci/pcireg.h
==============================================================================
--- stable/7/sys/dev/pci/pcireg.h	Thu Sep 17 12:41:27 2009	(r197270)
+++ stable/7/sys/dev/pci/pcireg.h	Thu Sep 17 12:44:58 2009	(r197271)
@@ -39,11 +39,11 @@
  */
 
 /* some PCI bus constants */
-
-#define	PCI_BUSMAX	255
-#define	PCI_SLOTMAX	31
-#define	PCI_FUNCMAX	7
-#define	PCI_REGMAX	255
+#define	PCI_DOMAINMAX	65535	/* highest supported domain number */
+#define	PCI_BUSMAX	255	/* highest supported bus number */
+#define	PCI_SLOTMAX	31	/* highest supported slot number */
+#define	PCI_FUNCMAX	7	/* highest supported function number */
+#define	PCI_REGMAX	255	/* highest supported config register addr. */
 #define	PCI_MAXHDRTYPE	2
 
 /* PCI config header registers for all devices */

Modified: stable/7/sys/dev/pci/pcivar.h
==============================================================================
--- stable/7/sys/dev/pci/pcivar.h	Thu Sep 17 12:41:27 2009	(r197270)
+++ stable/7/sys/dev/pci/pcivar.h	Thu Sep 17 12:44:58 2009	(r197271)
@@ -33,13 +33,6 @@
 #include 
 
 /* some PCI bus constants */
-
-#define	PCI_DOMAINMAX	65535	/* highest supported domain number */
-#define	PCI_BUSMAX	255	/* highest supported bus number */
-#define	PCI_SLOTMAX	31	/* highest supported slot number */
-#define	PCI_FUNCMAX	7	/* highest supported function number */
-#define	PCI_REGMAX	255	/* highest supported config register addr. */
-
 #define	PCI_MAXMAPS_0	6	/* max. no. of memory/port maps */
 #define	PCI_MAXMAPS_1	2	/* max. no. of maps for PCI to PCI bridge */
 #define	PCI_MAXMAPS_2	1	/* max. no. of maps for CardBus bridge */
From nyan at FreeBSD.org  Thu Sep 17 14:23:51 2009
From: nyan at FreeBSD.org (Takahashi Yoshihiro)
Date: Thu Sep 17 14:24:03 2009
Subject: svn commit: r197283 - in stable/7/sys: . boot/pc98 contrib/pf
Message-ID: <200909171423.n8HENpJt060084@svn.freebsd.org>

Author: nyan
Date: Thu Sep 17 14:23:51 2009
New Revision: 197283
URL: http://svn.freebsd.org/changeset/base/197283

Log:
  MFC: r197156
  
    MFi386:
  
    Move the loader's entry point to 0x200000.  This change is also needed
    for pc98.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/boot/pc98/Makefile.inc
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/boot/pc98/Makefile.inc
==============================================================================
--- stable/7/sys/boot/pc98/Makefile.inc	Thu Sep 17 14:12:21 2009	(r197282)
+++ stable/7/sys/boot/pc98/Makefile.inc	Thu Sep 17 14:23:51 2009	(r197283)
@@ -4,7 +4,7 @@
 
 BINDIR?=	/boot
 
-LOADER_ADDRESS?=0x100000
+LOADER_ADDRESS?=0x200000
 CFLAGS+=	-ffreestanding -mpreferred-stack-boundary=2 \
 		-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
 		-Os
From avg at FreeBSD.org  Fri Sep 18 14:12:40 2009
From: avg at FreeBSD.org (Andriy Gapon)
Date: Fri Sep 18 14:12:57 2009
Subject: svn commit: r197311 - in stable/7/sys: . contrib/pf dev/pci
Message-ID: <200909181412.n8IECecw093023@svn.freebsd.org>

Author: avg
Date: Fri Sep 18 14:12:40 2009
New Revision: 197311
URL: http://svn.freebsd.org/changeset/base/197311

Log:
  MFC r197099: pci(4): don't perform maximum register number check
  
  Different sub-kinds of PCI buses may have different rules and
  thus it is up for the bus backends to do proper input checks.
  For example, PCIe allows configuration register numbers < 0x1000,
  while for PCI proper the limit is 0x100.
  And, in fact, the buses already do the checks.
  
  Reviewed by:	jhb

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/pci/pci_user.c

Modified: stable/7/sys/dev/pci/pci_user.c
==============================================================================
--- stable/7/sys/dev/pci/pci_user.c	Fri Sep 18 14:05:56 2009	(r197310)
+++ stable/7/sys/dev/pci/pci_user.c	Fri Sep 18 14:12:40 2009	(r197311)
@@ -605,9 +605,8 @@ getconfexit:
 		case 4:
 		case 2:
 		case 1:
-			/* Make sure register is in bounds and aligned. */
+			/* Make sure register is not negative and aligned. */
 			if (io->pi_reg < 0 ||
-			    io->pi_reg + io->pi_width > PCI_REGMAX + 1 ||
 			    io->pi_reg & (io->pi_width - 1)) {
 				error = EINVAL;
 				break;
From marius at FreeBSD.org  Sun Sep 20 00:15:53 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 00:16:05 2009
Subject: svn commit: r197335 - in stable/7/sys: . contrib/pf sparc64/sparc64
Message-ID: <200909200015.n8K0Fr7o038903@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 00:15:52 2009
New Revision: 197335
URL: http://svn.freebsd.org/changeset/base/197335

Log:
  MFC: r191980
  
  - Fix style.
  - Use __FBSDID.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/sparc64/sparc64/vm_machdep.c

Modified: stable/7/sys/sparc64/sparc64/vm_machdep.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/vm_machdep.c	Sat Sep 19 21:46:12 2009	(r197334)
+++ stable/7/sys/sparc64/sparc64/vm_machdep.c	Sun Sep 20 00:15:52 2009	(r197335)
@@ -39,23 +39,26 @@
  *
  *	from: @(#)vm_machdep.c	7.3 (Berkeley) 5/13/91
  *	Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * 	from: FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.167 2001/07/12
- * $FreeBSD$
+ *	from: FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.167 2001/07/12
  */
 
+#include 
+__FBSDID("$FreeBSD$");
+
 #include "opt_pmap.h"
 
 #include 
 #include 
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,12 +76,12 @@
 #include 
 #include 
 
-#include 
 #include 
+#include 
 #include 
 #include 
-#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -94,7 +97,7 @@ static void	sf_buf_init(void *arg);
 SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
 
 /*
- * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the
+ * Expanded sf_freelist head.  Really an SLIST_HEAD() in disguise, with the
  * sf_freelist head with the sf_lock mutex.
  */
 static struct {
@@ -124,11 +127,13 @@ cpu_exit(struct thread *td)
 void
 cpu_thread_exit(struct thread *td)
 {
+
 }
 
 void
 cpu_thread_clean(struct thread *td)
 {
+
 }
 
 void
@@ -146,16 +151,19 @@ cpu_thread_alloc(struct thread *td)
 void
 cpu_thread_free(struct thread *td)
 {
+
 }
- 
+
 void
 cpu_thread_swapin(struct thread *td)
 {
+
 }
 
 void
 cpu_thread_swapout(struct thread *td)
 {
+
 }
 
 void
@@ -328,6 +336,7 @@ cpu_reset(void)
 		0,
 		(cell_t)bspec
 	};
+
 	if ((chosen = OF_finddevice("/chosen")) != 0) {
 		if (OF_getprop(chosen, "bootpath", bspec, sizeof(bspec)) == -1)
 			bspec[0] = '\0';
@@ -392,7 +401,7 @@ sf_buf_init(void *arg)
 }
 
 /*
- * Get an sf_buf from the freelist. Will block if none are available.
+ * Get an sf_buf from the freelist.  Will block if none are available.
  */
 struct sf_buf *
 sf_buf_alloc(struct vm_page *m, int flags)
@@ -411,7 +420,7 @@ sf_buf_alloc(struct vm_page *m, int flag
 		sf_buf_alloc_want--;
 
 		/*
-		 * If we got a signal, don't risk going back to sleep. 
+		 * If we got a signal, don't risk going back to sleep.
 		 */
 		if (error)
 			break;
From marius at FreeBSD.org  Sun Sep 20 00:51:49 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 00:52:00 2009
Subject: svn commit: r197336 - in stable/7/sys: . contrib/pf sparc64/sparc64
Message-ID: <200909200051.n8K0pmG6039592@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 00:51:48 2009
New Revision: 197336
URL: http://svn.freebsd.org/changeset/base/197336

Log:
  MFC: r191981
  
  Just like in cpu_halt(), use cpu_shutdown() rather than ofw_exit()
  directly in cpu_reset() in order to idle the APs before exiting
  the kernel and letting the BSP enter the firmware so that processes
  like init(8) which still might be running on an AP at that point
  don't cause a panic there when it crashes due to the fact it no
  longer can be supported by the kernel.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/sparc64/sparc64/vm_machdep.c

Modified: stable/7/sys/sparc64/sparc64/vm_machdep.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/vm_machdep.c	Sun Sep 20 00:15:52 2009	(r197335)
+++ stable/7/sys/sparc64/sparc64/vm_machdep.c	Sun Sep 20 00:51:48 2009	(r197336)
@@ -343,7 +343,7 @@ cpu_reset(void)
 		bspec[sizeof(bspec) - 1] = '\0';
 	}
 
-	openfirmware_exit(&args);
+	cpu_shutdown(&args);
 }
 
 /*
From marius at FreeBSD.org  Sun Sep 20 00:54:52 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 00:55:09 2009
Subject: svn commit: r197337 - in stable/7/sys: . contrib/pf dev/mii
Message-ID: <200909200054.n8K0spCi039701@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 00:54:51 2009
New Revision: 197337
URL: http://svn.freebsd.org/changeset/base/197337

Log:
  MFC: r194134
  
  - Also probe DP83865, which is an is an ultra low power version
    of the DP83861 and DP83891.
  - Reset the PHY during attach so it's in a known state.
  - Add a comment describing why we hardwire 10baseT support in
    the BMSR.
  - Always explicitly set IFM_HDX for half-duplex. [1]
  
  Obtained from:	OpenBSD [1]

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/mii/miidevs
  stable/7/sys/dev/mii/nsgphy.c

Modified: stable/7/sys/dev/mii/miidevs
==============================================================================
--- stable/7/sys/dev/mii/miidevs	Sun Sep 20 00:51:48 2009	(r197336)
+++ stable/7/sys/dev/mii/miidevs	Sun Sep 20 00:54:51 2009	(r197337)
@@ -197,6 +197,7 @@ model NATSEMI DP83815		0x0002 DP83815 10
 model NATSEMI DP83847		0x0003 DP83847 10/100 media interface
 model NATSEMI DP83891		0x0005 DP83891 10/100/1000 media interface
 model NATSEMI DP83861		0x0006 DP83861 10/100/1000 media interface
+model NATSEMI DP83865		0x0007 DP83865 10/100/1000 media interface
 
 /* Quality Semiconductor PHYs */
 model QUALSEMI QS6612		0x0000 QS6612 10/100 media interface

Modified: stable/7/sys/dev/mii/nsgphy.c
==============================================================================
--- stable/7/sys/dev/mii/nsgphy.c	Sun Sep 20 00:51:48 2009	(r197336)
+++ stable/7/sys/dev/mii/nsgphy.c	Sun Sep 20 00:54:51 2009	(r197337)
@@ -41,17 +41,19 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * Driver for the National Semiconductor DP83891 and DP83861
+ * Driver for the National Semiconductor DP83861, DP83865 and DP83891
  * 10/100/1000 PHYs.
  * Datasheet available at: http://www.national.com/ds/DP/DP83861.pdf
+ * and at: http://www.national.com/ds/DP/DP83865.pdf
  *
- * The DP83891 is the older NatSemi gigE PHY which isn't being sold
- * anymore. The DP83861 is its replacement, which is an 'enhanced'
- * firmware driven component. The major difference between the
- * two is that the 83891 can't generate interrupts, while the
- * 83861 can. (I think it wasn't originally designed to do this, but
- * it can now thanks to firmware updates.) The 83861 also allows
- * access to its internal RAM via indirect register access.
+ * The DP83891 is the older NS GigE PHY which isn't being sold
+ * anymore.  The DP83861 is its replacement, which is an 'enhanced'
+ * firmware driven component.  The major difference between the
+ * two is that the DP83891 can't generate interrupts, while the
+ * 83861 can (probably it wasn't originally designed to do this, but
+ * it can now thanks to firmware updates).  The DP83861 also allows
+ * access to its internal RAM via indirect register access.  The
+ * DP83865 is an ultra low power version of the DP83861 and DP83891.
  */
 
 #include 
@@ -99,6 +101,7 @@ static void	nsgphy_status(struct mii_sof
 
 static const struct mii_phydesc nsgphys[] = {
 	MII_PHY_DESC(NATSEMI, DP83861),
+	MII_PHY_DESC(NATSEMI, DP83865),
 	MII_PHY_DESC(NATSEMI, DP83891),
 	MII_PHY_END
 };
@@ -133,8 +136,14 @@ nsgphy_attach(device_t dev)
 
 	mii->mii_instance++;
 
+	mii_phy_reset(sc);
+
+	/*
+	 * NB: the PHY has the 10baseT BMSR bits hard-wired to 0,
+	 * even though it supports 10baseT.
+	 */
 	sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) |
-	    (BMSR_10TFDX|BMSR_10THDX)) & ma->mii_capmask;
+	    (BMSR_10TFDX | BMSR_10THDX)) & ma->mii_capmask;
 	if (sc->mii_capabilities & BMSR_EXTSTAT)
 		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
 
@@ -238,7 +247,7 @@ nsgphy_status(struct mii_softc *sc)
 			return;
 		}
 
-		switch (physup & (PHY_SUP_SPEED1|PHY_SUP_SPEED0)) {
+		switch (physup & (PHY_SUP_SPEED1 | PHY_SUP_SPEED0)) {
 		case PHY_SUP_SPEED1:
 			mii->mii_media_active |= IFM_1000_T;
 			gtsr = PHY_READ(sc, MII_100T2SR);
@@ -257,9 +266,13 @@ nsgphy_status(struct mii_softc *sc)
 		default:
 			mii->mii_media_active |= IFM_NONE;
 			mii->mii_media_status = 0;
+			return;
 		}
+
 		if (physup & PHY_SUP_DUPLEX)
 			mii->mii_media_active |= IFM_FDX;
+		else
+			mii->mii_media_active |= IFM_HDX;
 	} else
 		mii->mii_media_active = ife->ifm_media;
 }
From marius at FreeBSD.org  Sun Sep 20 12:08:30 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:08:49 2009
Subject: svn commit: r197343 - in stable/7/sys: . boot/forth conf contrib/pf
	dev/cas modules modules/cas sparc64/conf
Message-ID: <200909201208.n8KC8U0i055798@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:08:29 2009
New Revision: 197343
URL: http://svn.freebsd.org/changeset/base/197343

Log:
  MFC: 194246, 194904, 194973
  
  Add cas(4), a driver for Sun Cassini/Cassini+ and National Semiconductor
  DP83065 Saturn Gigabit Ethernet controllers. These are the successors
  of the Sun GEM controllers and still have a similar but extended transmit
  logic. As such this driver is based on gem(4).
  Thanks to marcel@ for providing a Sun Quad GigaSwift Ethernet UTP (QGE)
  card which was vital for getting this driver to work on architectures
  not using Open Firmware.

Added:
  stable/7/sys/dev/cas/
     - copied from r194246, head/sys/dev/cas/
  stable/7/sys/modules/cas/
     - copied from r194246, head/sys/modules/cas/
Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/boot/forth/loader.conf
  stable/7/sys/conf/NOTES
  stable/7/sys/conf/files
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/cas/if_cas.c
  stable/7/sys/dev/cas/if_casvar.h
  stable/7/sys/modules/Makefile
  stable/7/sys/sparc64/conf/GENERIC

Modified: stable/7/sys/boot/forth/loader.conf
==============================================================================
--- stable/7/sys/boot/forth/loader.conf	Sun Sep 20 11:33:39 2009	(r197342)
+++ stable/7/sys/boot/forth/loader.conf	Sun Sep 20 12:08:29 2009	(r197343)
@@ -220,6 +220,7 @@ if_axe_load="NO"		# ASIX Electronics AX8
 if_bce_load="NO"		# Broadcom NetXtreme II Gigabit Ethernet
 if_bfe_load="NO"		# Broadcom BCM4401
 if_bge_load="NO"		# Broadcom BCM570x PCI Gigabit Ethernet
+if_cas_load="NO"		# Sun Cassini/Cassini+ and NS DP83065 Saturn
 if_cm_load="NO"			# SMC (90c26, 90c56, 90c66)
 if_cs_load="NO"			# Crystal Semiconductor CS8920
 if_cue_load="NO"		# CATC USB-EL1210A USB Ethernet

Modified: stable/7/sys/conf/NOTES
==============================================================================
--- stable/7/sys/conf/NOTES	Sun Sep 20 11:33:39 2009	(r197342)
+++ stable/7/sys/conf/NOTES	Sun Sep 20 12:08:29 2009	(r197343)
@@ -1733,6 +1733,7 @@ device		miibus
 #	BCM570x family of controllers, including the 3Com 3c996-T,
 #	the Netgear GA302T, the SysKonnect SK-9D21 and SK-9D41, and
 #	the embedded gigE NICs on Dell PowerEdge 2550 servers.
+# cas:	Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn
 # cm:	Arcnet SMC COM90c26 / SMC COM90c56
 #	(and SMC COM90c66 in '56 compatibility mode) adapters.
 # cnw:  Xircom CNW/Netware Airsurfer PC Card adapter
@@ -1875,6 +1876,7 @@ device		ale		# Atheros AR8121/AR8113/AR8
 device		bce		# Broadcom BCM5706/BCM5708 Gigabit Ethernet
 device		bfe		# Broadcom BCM440x 10/100 Ethernet
 device		bge		# Broadcom BCM570xx Gigabit Ethernet
+device		cas		# Sun Cassini/Cassini+ and NS DP83065 Saturn
 device		cxgb		# Chelsio T3 10 Gigabit Ethernet
 device		dc		# DEC/Intel 21143 and various workalikes
 device		et		# Agere ET1310 10/100/Gigabit Ethernet

Modified: stable/7/sys/conf/files
==============================================================================
--- stable/7/sys/conf/files	Sun Sep 20 11:33:39 2009	(r197342)
+++ stable/7/sys/conf/files	Sun Sep 20 12:08:29 2009	(r197343)
@@ -671,6 +671,7 @@ dev/buslogic/bt_pci.c		optional bt pci
 dev/cardbus/cardbus.c		optional cardbus
 dev/cardbus/cardbus_cis.c	optional cardbus
 dev/cardbus/cardbus_device.c	optional cardbus
+dev/cas/if_cas.c		optional cas
 dev/ciss/ciss.c			optional ciss
 dev/cm/smc90cx6.c		optional cm
 dev/cmx/cmx.c			optional cmx

Modified: stable/7/sys/dev/cas/if_cas.c
==============================================================================
--- head/sys/dev/cas/if_cas.c	Mon Jun 15 18:22:41 2009	(r194246)
+++ stable/7/sys/dev/cas/if_cas.c	Sun Sep 20 12:08:29 2009	(r197343)
@@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 #include 
@@ -135,7 +135,8 @@ static void	cas_free(void *arg1, void* a
 static void	cas_init(void *xsc);
 static void	cas_init_locked(struct cas_softc *sc);
 static void	cas_init_regs(struct cas_softc *sc);
-static void	cas_intr(void *v);
+static int	cas_intr(void *v);
+static void	cas_intr_task(void *arg, int pending __unused);
 static int	cas_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static int	cas_load_txmbuf(struct cas_softc *sc, struct mbuf **m_head);
 static int	cas_mediachange(struct ifnet *ifp);
@@ -159,13 +160,13 @@ static void	cas_rxdma_callback(void *xsc
 		    int nsegs, int error);
 static void	cas_setladrf(struct cas_softc *sc);
 static void	cas_start(struct ifnet *ifp);
-static void	cas_start_locked(struct ifnet *ifp);
 static void	cas_stop(struct ifnet *ifp);
 static void	cas_suspend(struct cas_softc *sc);
 static void	cas_tick(void *arg);
 static void	cas_tint(struct cas_softc *sc);
+static void	cas_tx_task(void *arg, int pending __unused);
 static inline void cas_txkick(struct cas_softc *sc);
-static int	cas_watchdog(struct cas_softc *sc);
+static void	cas_watchdog(struct cas_softc *sc);
 
 static devclass_t cas_devclass;
 
@@ -201,7 +202,19 @@ cas_attach(struct cas_softc *sc)
 	IFQ_SET_READY(&ifp->if_snd);
 
 	callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
-	callout_init_mtx(&sc->sc_rx_ch, &sc->sc_mtx, 0);
+	callout_init(&sc->sc_rx_ch, 1);
+	/* Create local taskq. */
+	TASK_INIT(&sc->sc_intr_task, 0, cas_intr_task, sc);
+	TASK_INIT(&sc->sc_tx_task, 1, cas_tx_task, ifp);
+	sc->sc_tq = taskqueue_create_fast("cas_taskq", M_WAITOK,
+	    taskqueue_thread_enqueue, &sc->sc_tq);
+	if (sc->sc_tq == NULL) {
+		device_printf(sc->sc_dev, "could not create taskqueue\n");
+		error = ENXIO;
+		goto fail_ifnet;
+	}
+	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+	    device_get_nameunit(sc->sc_dev));
 
 	/* Make sure the chip is stopped. */
 	cas_reset(sc);
@@ -211,7 +224,7 @@ cas_attach(struct cas_softc *sc)
 	    BUS_SPACE_MAXSIZE, 0, BUS_SPACE_MAXSIZE, 0, NULL, NULL,
 	    &sc->sc_pdmatag);
 	if (error != 0)
-		goto fail_ifnet;
+		goto fail_taskq;
 
 	error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
@@ -422,6 +435,8 @@ cas_attach(struct cas_softc *sc)
 	bus_dma_tag_destroy(sc->sc_rdmatag);
  fail_ptag:
 	bus_dma_tag_destroy(sc->sc_pdmatag);
+ fail_taskq:
+	taskqueue_free(sc->sc_tq);
  fail_ifnet:
 	if_free(ifp);
 	return (error);
@@ -433,13 +448,16 @@ cas_detach(struct cas_softc *sc)
 	struct ifnet *ifp = sc->sc_ifp;
 	int i;
 
+	ether_ifdetach(ifp);
 	CAS_LOCK(sc);
 	cas_stop(ifp);
 	CAS_UNLOCK(sc);
 	callout_drain(&sc->sc_tick_ch);
 	callout_drain(&sc->sc_rx_ch);
-	ether_ifdetach(ifp);
+	taskqueue_drain(sc->sc_tq, &sc->sc_intr_task);
+	taskqueue_drain(sc->sc_tq, &sc->sc_tx_task);
 	if_free(ifp);
+	taskqueue_free(sc->sc_tq);
 	device_delete_child(sc->sc_dev, sc->sc_miibus);
 
 	for (i = 0; i < CAS_NRXDESC; i++)
@@ -586,12 +604,11 @@ static void
 cas_tick(void *arg)
 {
 	struct cas_softc *sc = arg;
-	struct ifnet *ifp;
+	struct ifnet *ifp = sc->sc_ifp;
 	uint32_t v;
 
 	CAS_LOCK_ASSERT(sc, MA_OWNED);
 
-	ifp = sc->sc_ifp;
 	/*
 	 * Unload collision and error counters.
 	 */
@@ -622,8 +639,10 @@ cas_tick(void *arg)
 
 	mii_tick(sc->sc_mii);
 
-	if (cas_watchdog(sc) == EJUSTRETURN)
-		return;
+	if (sc->sc_txfree != CAS_MAXTXFREE)
+		cas_tint(sc);
+
+	cas_watchdog(sc);
 
 	callout_reset(&sc->sc_tick_ch, hz, cas_tick, sc);
 }
@@ -915,6 +934,9 @@ cas_init_locked(struct cas_softc *sc)
 
 	CAS_LOCK_ASSERT(sc, MA_OWNED);
 
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
 #ifdef CAS_DEBUG
 	CTR2(KTR_CAS, "%s: %s: calling stop", device_get_name(sc->sc_dev),
 	    __func__);
@@ -994,7 +1016,7 @@ cas_init_locked(struct cas_softc *sc)
 
 	/* Set up interrupts. */
 	CAS_WRITE_4(sc, CAS_INTMASK,
-	    ~(CAS_INTR_TX_INT_ME | CAS_INTR_TX_ALL | CAS_INTR_TX_TAG_ERR |
+	    ~(CAS_INTR_TX_INT_ME | CAS_INTR_TX_TAG_ERR |
 	    CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_TAG_ERR |
 	    CAS_INTR_RX_COMP_FULL | CAS_INTR_RX_BUF_AEMPTY |
 	    CAS_INTR_RX_COMP_AFULL | CAS_INTR_RX_LEN_MMATCH |
@@ -1003,6 +1025,8 @@ cas_init_locked(struct cas_softc *sc)
 	    | CAS_INTR_PCS_INT | CAS_INTR_MIF
 #endif
 	    ));
+	/* Don't clear top level interrupts when CAS_STATUS_ALIAS is read. */
+	CAS_WRITE_4(sc, CAS_CLEAR_ALIAS, 0);
 	CAS_WRITE_4(sc, CAS_MAC_RX_MASK, ~CAS_MAC_RX_OVERFLOW);
 	CAS_WRITE_4(sc, CAS_MAC_TX_MASK,
 	    ~(CAS_MAC_TX_UNDERRUN | CAS_MAC_TX_MAX_PKT_ERR));
@@ -1240,7 +1264,7 @@ cas_load_txmbuf(struct cas_softc *sc, st
 	CTR3(KTR_CAS, "%s: start of frame at segment %d, TX %d",
 	    __func__, seg, nexttx);
 #endif
-	if (sc->sc_txwin += nsegs > CAS_NTXSEGS * 2 / 3) {
+	if (sc->sc_txwin += nsegs > CAS_MAXTXFREE * 2 / 3) {
 		sc->sc_txwin = 0;
 		sc->sc_txdescs[txs->txs_firstdesc].cd_flags |=
 		    htole64(cflags | CAS_TD_START_OF_FRAME | CAS_TD_INT_ME);
@@ -1351,13 +1375,12 @@ cas_init_regs(struct cas_softc *sc)
 }
 
 static void
-cas_start(struct ifnet *ifp)
+cas_tx_task(void *arg, int pending __unused)
 {
-	struct cas_softc *sc = ifp->if_softc;
+	struct ifnet *ifp;
 
-	CAS_LOCK(sc);
-	cas_start_locked(ifp);
-	CAS_UNLOCK(sc);
+	ifp = (struct ifnet *)arg;
+	cas_start(ifp);
 }
 
 static inline void
@@ -1379,17 +1402,22 @@ cas_txkick(struct cas_softc *sc)
 }
 
 static void
-cas_start_locked(struct ifnet *ifp)
+cas_start(struct ifnet *ifp)
 {
 	struct cas_softc *sc = ifp->if_softc;
 	struct mbuf *m;
 	int kicked, ntx;
 
-	CAS_LOCK_ASSERT(sc, MA_OWNED);
+	CAS_LOCK(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->sc_flags & CAS_LINK) == 0)
+	    IFF_DRV_RUNNING || (sc->sc_flags & CAS_LINK) == 0) {
+		CAS_UNLOCK(sc);
 		return;
+	}
+
+	if (sc->sc_txfree < CAS_MAXTXFREE / 4)
+		cas_tint(sc);
 
 #ifdef CAS_DEBUG
 	CTR4(KTR_CAS, "%s: %s: txfree %d, txnext %d",
@@ -1434,6 +1462,8 @@ cas_start_locked(struct ifnet *ifp)
 		    sc->sc_wdog_timer);
 #endif
 	}
+
+	CAS_UNLOCK(sc);
 }
 
 static void
@@ -1530,17 +1560,10 @@ cas_tint(struct cas_softc *sc)
 #endif
 
 	if (progress) {
-		if (sc->sc_txfree == CAS_NTXDESC - 1)
-			sc->sc_txwin = 0;
-
-		/*
-		 * We freed some descriptors, so reset IFF_DRV_OACTIVE
-		 * and restart.
-		 */
+		/* We freed some descriptors, so reset IFF_DRV_OACTIVE. */
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 		if (STAILQ_EMPTY(&sc->sc_txdirtyq))
 			sc->sc_wdog_timer = 0;
-		cas_start_locked(ifp);
 	}
 
 #ifdef CAS_DEBUG
@@ -1554,7 +1577,7 @@ cas_rint_timeout(void *arg)
 {
 	struct cas_softc *sc = arg;
 
-	CAS_LOCK_ASSERT(sc, MA_OWNED);
+	CAS_LOCK_ASSERT(sc, MA_NOTOWNED);
 
 	cas_rint(sc);
 }
@@ -1569,7 +1592,7 @@ cas_rint(struct cas_softc *sc)
 	uint32_t rxhead;
 	u_int idx, idx2, len, off, skip;
 
-	CAS_LOCK_ASSERT(sc, MA_OWNED);
+	CAS_LOCK_ASSERT(sc, MA_NOTOWNED);
 
 	callout_stop(&sc->sc_rx_ch);
 
@@ -1674,14 +1697,16 @@ cas_rint(struct cas_softc *sc)
 				refcount_acquire(&rxds->rxds_refcount);
 				bus_dmamap_sync(sc->sc_rdmatag,
 				    rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD);
+#if __FreeBSD_version < 800016
 				MEXTADD(m, (caddr_t)rxds->rxds_buf +
 				    off * 256 + ETHER_ALIGN, len, cas_free,
-#if __FreeBSD_version < 800016
-				    rxds,
+				    rxds, M_RDONLY, EXT_NET_DRV);
 #else
+				MEXTADD(m, (caddr_t)rxds->rxds_buf +
+				    off * 256 + ETHER_ALIGN, len, cas_free,
 				    sc, (void *)(uintptr_t)idx,
-#endif
 				    M_RDONLY, EXT_NET_DRV);
+#endif
 				if ((m->m_flags & M_EXT) == 0) {
 					m_freem(m);
 					m = NULL;
@@ -1695,9 +1720,7 @@ cas_rint(struct cas_softc *sc)
 					cas_rxcksum(m, CAS_GET(word4,
 					    CAS_RC4_TCP_CSUM));
 				/* Pass it on. */
-				CAS_UNLOCK(sc);
 				(*ifp->if_input)(ifp, m);
-				CAS_LOCK(sc);
 			} else
 				ifp->if_ierrors++;
 
@@ -1719,14 +1742,16 @@ cas_rint(struct cas_softc *sc)
 				m->m_len = min(CAS_PAGE_SIZE - off, len);
 				bus_dmamap_sync(sc->sc_rdmatag,
 				    rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD);
-				MEXTADD(m, (caddr_t)rxds->rxds_buf + off,
-				    m->m_len, cas_free,
 #if __FreeBSD_version < 800016
-				    rxds,
+				MEXTADD(m, (caddr_t)rxds->rxds_buf + off,
+				    m->m_len, cas_free, rxds, M_RDONLY,
+				    EXT_NET_DRV);
 #else
-				    sc, (void *)(uintptr_t)idx,
+				MEXTADD(m, (caddr_t)rxds->rxds_buf + off,
+				    m->m_len, cas_free, sc,
+				    (void *)(uintptr_t)idx, M_RDONLY,
+				    EXT_NET_DRV);
 #endif
-				    M_RDONLY, EXT_NET_DRV);
 				if ((m->m_flags & M_EXT) == 0) {
 					m_freem(m);
 					m = NULL;
@@ -1753,14 +1778,16 @@ cas_rint(struct cas_softc *sc)
 					bus_dmamap_sync(sc->sc_rdmatag,
 					    rxds2->rxds_dmamap,
 					    BUS_DMASYNC_POSTREAD);
-					MEXTADD(m2, (caddr_t)rxds2->rxds_buf,
-					    m2->m_len, cas_free,
 #if __FreeBSD_version < 800016
-					    rxds2,
+					MEXTADD(m2, (caddr_t)rxds2->rxds_buf,
+					    m2->m_len, cas_free, rxds2,
+					    M_RDONLY, EXT_NET_DRV);
 #else
+					MEXTADD(m2, (caddr_t)rxds2->rxds_buf,
+					    m2->m_len, cas_free,
 					    sc, (void *)(uintptr_t)idx2,
-#endif
 					    M_RDONLY, EXT_NET_DRV);
+#endif
 					if ((m2->m_flags & M_EXT) == 0) {
 						m_freem(m2);
 						m2 = NULL;
@@ -1781,9 +1808,7 @@ cas_rint(struct cas_softc *sc)
 					cas_rxcksum(m, CAS_GET(word4,
 					    CAS_RC4_TCP_CSUM));
 				/* Pass it on. */
-				CAS_UNLOCK(sc);
 				(*ifp->if_input)(ifp, m);
-				CAS_LOCK(sc);
 			} else
 				ifp->if_ierrors++;
 
@@ -1799,6 +1824,8 @@ cas_rint(struct cas_softc *sc)
 
  skip:
 		cas_rxcompinit(&sc->sc_rxcomps[sc->sc_rxcptr]);
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+			break;
 	}
 	CAS_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	CAS_WRITE_4(sc, CAS_RX_COMP_TAIL, sc->sc_rxcptr);
@@ -1819,7 +1846,7 @@ cas_free(void *arg1, void *arg2)
 {
 	struct cas_rxdsoft *rxds;
 	struct cas_softc *sc;
-	u_int idx, locked;
+	u_int idx;
 
 #if __FreeBSD_version < 800016
 	rxds = arg2;
@@ -1837,18 +1864,17 @@ cas_free(void *arg1, void *arg2)
 	 * NB: this function can be called via m_freem(9) within
 	 * this driver!
 	 */
-	if ((locked = CAS_LOCK_OWNED(sc)) == 0)
-		CAS_LOCK(sc);
+
 	cas_add_rxdesc(sc, idx);
-	if (locked == 0)
-		CAS_UNLOCK(sc);
 }
 
 static inline void
 cas_add_rxdesc(struct cas_softc *sc, u_int idx)
 {
+	u_int locked;
 
-	CAS_LOCK_ASSERT(sc, MA_OWNED);
+	if ((locked = CAS_LOCK_OWNED(sc)) == 0)
+		CAS_LOCK(sc);
 
 	bus_dmamap_sync(sc->sc_rdmatag, sc->sc_rxdsoft[idx].rxds_dmamap,
 	    BUS_DMASYNC_PREREAD);
@@ -1866,13 +1892,19 @@ cas_add_rxdesc(struct cas_softc *sc, u_i
 		CAS_WRITE_4(sc, CAS_RX_KICK,
 		    (sc->sc_rxdptr + CAS_NRXDESC - 4) & CAS_NRXDESC_MASK);
 	}
+
+	if (locked == 0)
+		CAS_UNLOCK(sc);
 }
 
 static void
 cas_eint(struct cas_softc *sc, u_int status)
 {
+	struct ifnet *ifp = sc->sc_ifp;
+
+	CAS_LOCK_ASSERT(sc, MA_NOTOWNED);
 
-	sc->sc_ifp->if_ierrors++;
+	ifp->if_ierrors++;
 
 	device_printf(sc->sc_dev, "%s: status 0x%x", __func__, status);
 	if ((status & CAS_INTR_PCI_ERROR_INT) != 0) {
@@ -1886,21 +1918,43 @@ cas_eint(struct cas_softc *sc, u_int sta
 	}
 	printf("\n");
 
-	cas_init_locked(sc);
-	cas_start_locked(sc->sc_ifp);
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	cas_init(sc);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
 }
 
-static void
+static int
 cas_intr(void *v)
 {
 	struct cas_softc *sc = v;
+
+	if (__predict_false((CAS_READ_4(sc, CAS_STATUS_ALIAS) &
+	    CAS_INTR_SUMMARY) == 0))
+		return (FILTER_STRAY);
+
+	/* Disable interrupts. */
+	CAS_WRITE_4(sc, CAS_INTMASK, 0xffffffff);
+	taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
+
+	return (FILTER_HANDLED);
+}
+
+static void
+cas_intr_task(void *arg, int pending __unused)
+{
+	struct cas_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
 	uint32_t status, status2;
 
-	status = CAS_READ_4(sc, CAS_STATUS);
-	if (__predict_false((status & CAS_INTR_SUMMARY) == 0))
+	CAS_LOCK_ASSERT(sc, MA_NOTOWNED);
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 		return;
 
-	CAS_LOCK(sc);
+	status = CAS_READ_4(sc, CAS_STATUS);
+	if (__predict_false((status & CAS_INTR_SUMMARY) == 0))
+		goto done;
 
 #ifdef CAS_DEBUG
 	CTR4(KTR_CAS, "%s: %s: cplt %x, status %x",
@@ -1941,7 +1995,6 @@ cas_intr(void *v)
 	    (CAS_INTR_TX_TAG_ERR | CAS_INTR_RX_TAG_ERR |
 	    CAS_INTR_RX_LEN_MMATCH | CAS_INTR_PCI_ERROR_INT)) != 0)) {
 		cas_eint(sc, status);
-		CAS_UNLOCK(sc);
 		return;
 	}
 
@@ -1968,21 +2021,48 @@ cas_intr(void *v)
 	    (CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_COMP_FULL |
 	    CAS_INTR_RX_BUF_AEMPTY | CAS_INTR_RX_COMP_AFULL)) != 0) {
 		cas_rint(sc);
+#ifdef CAS_DEBUG
 		if (__predict_false((status &
 		    (CAS_INTR_RX_BUF_NA | CAS_INTR_RX_COMP_FULL |
 		    CAS_INTR_RX_BUF_AEMPTY | CAS_INTR_RX_COMP_AFULL)) != 0))
 			device_printf(sc->sc_dev,
 			    "RX fault, status %x\n", status);
+#endif
 	}
 
 	if ((status &
-	    (CAS_INTR_TX_INT_ME | CAS_INTR_TX_ALL | CAS_INTR_TX_DONE)) != 0)
+	    (CAS_INTR_TX_INT_ME | CAS_INTR_TX_ALL | CAS_INTR_TX_DONE)) != 0) {
+		CAS_LOCK(sc);
 		cas_tint(sc);
+		CAS_UNLOCK(sc);
+	}
 
-	CAS_UNLOCK(sc);
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+	else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
+
+	status = CAS_READ_4(sc, CAS_STATUS_ALIAS);
+	if (__predict_false((status & CAS_INTR_SUMMARY) != 0)) {
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
+		return;
+	}
+
+ done:
+	/* Re-enable interrupts. */
+	CAS_WRITE_4(sc, CAS_INTMASK,
+	    ~(CAS_INTR_TX_INT_ME | CAS_INTR_TX_TAG_ERR |
+	    CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_TAG_ERR |
+	    CAS_INTR_RX_COMP_FULL | CAS_INTR_RX_BUF_AEMPTY |
+	    CAS_INTR_RX_COMP_AFULL | CAS_INTR_RX_LEN_MMATCH |
+	    CAS_INTR_PCI_ERROR_INT
+#ifdef CAS_DEBUG
+	    | CAS_INTR_PCS_INT | CAS_INTR_MIF
+#endif
+	));
 }
 
-static int
+static void
 cas_watchdog(struct cas_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_ifp;
@@ -2003,7 +2083,7 @@ cas_watchdog(struct cas_softc *sc)
 #endif
 
 	if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
-		return (0);
+		return;
 
 	if ((sc->sc_flags & CAS_LINK) != 0)
 		device_printf(sc->sc_dev, "device timeout\n");
@@ -2012,9 +2092,10 @@ cas_watchdog(struct cas_softc *sc)
 	++ifp->if_oerrors;
 
 	/* Try to get more packets going. */
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	cas_init_locked(sc);
-	cas_start_locked(ifp);
-	return (EJUSTRETURN);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
 }
 
 static void
@@ -2378,7 +2459,8 @@ cas_ioctl(struct ifnet *ifp, u_long cmd,
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		CAS_LOCK(sc);
-		cas_setladrf(sc);
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+			cas_setladrf(sc);
 		CAS_UNLOCK(sc);
 		break;
 	case SIOCSIFMTU:
@@ -2729,7 +2811,7 @@ cas_pci_attach(device_t dev)
 	}
 
 	if (bus_setup_intr(dev, sc->sc_res[CAS_RES_INTR], INTR_TYPE_NET |
-	    INTR_MPSAFE, NULL, cas_intr, sc, &sc->sc_ih) != 0) {
+	    INTR_MPSAFE, cas_intr, NULL, sc, &sc->sc_ih) != 0) {
 		device_printf(dev, "failed to set up interrupt\n");
 		cas_detach(sc);
 		goto fail;

Modified: stable/7/sys/dev/cas/if_casvar.h
==============================================================================
--- head/sys/dev/cas/if_casvar.h	Mon Jun 15 18:22:41 2009	(r194246)
+++ stable/7/sys/dev/cas/if_casvar.h	Sun Sep 20 12:08:29 2009	(r197343)
@@ -138,6 +138,9 @@ struct cas_softc {
 	u_char		sc_enaddr[ETHER_ADDR_LEN];
 	struct callout	sc_tick_ch;	/* tick callout */
 	struct callout	sc_rx_ch;	/* delayed RX callout */
+	struct task	sc_intr_task;
+	struct task	sc_tx_task;
+	struct taskqueue	*sc_tq;
 	u_int		sc_wdog_timer;	/* watchdog timer */
 
 	void		*sc_ih;

Modified: stable/7/sys/modules/Makefile
==============================================================================
--- stable/7/sys/modules/Makefile	Sun Sep 20 11:33:39 2009	(r197342)
+++ stable/7/sys/modules/Makefile	Sun Sep 20 12:08:29 2009	(r197343)
@@ -46,6 +46,7 @@ SUBDIR=	${_3dfx} \
 	${_canbepm} \
 	${_canbus} \
 	${_cardbus} \
+	cas \
 	${_cbb} \
 	cd9660 \
 	cd9660_iconv \

Modified: stable/7/sys/sparc64/conf/GENERIC
==============================================================================
--- stable/7/sys/sparc64/conf/GENERIC	Sun Sep 20 11:33:39 2009	(r197342)
+++ stable/7/sys/sparc64/conf/GENERIC	Sun Sep 20 12:08:29 2009	(r197343)
@@ -164,6 +164,7 @@ device		txp		# 3Com 3cR990 (``Typhoon'')
 device		miibus		# MII bus support
 #device		bfe		# Broadcom BCM440x 10/100 Ethernet
 device		bge		# Broadcom BCM570xx Gigabit Ethernet
+device		cas		# Sun Cassini/Cassini+ and NS DP83065 Saturn
 device		dc		# DEC/Intel 21143 and various workalikes
 device		fxp		# Intel EtherExpress PRO/100B (82557, 82558)
 device		gem		# Sun GEM/Sun ERI/Apple GMAC
From marius at FreeBSD.org  Sun Sep 20 12:12:36 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:12:42 2009
Subject: svn commit: r197344 - in stable/7/sys: . contrib/pf dev/mpt
Message-ID: <200909201212.n8KCCauu055933@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:12:36 2009
New Revision: 197344
URL: http://svn.freebsd.org/changeset/base/197344

Log:
  - Remove unused variables. [1]
  - Remove redundant zeroing of tmf_req which Coverity Prevent(tm) complains
    about. [2]
  
  Submitted by:	Christoph Mallon [1]
  Found with:	Coverity Prevent(tm) [2]
  CID:		2496 [2]

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/mpt/mpt_cam.c

Modified: stable/7/sys/dev/mpt/mpt_cam.c
==============================================================================
--- stable/7/sys/dev/mpt/mpt_cam.c	Sun Sep 20 12:08:29 2009	(r197343)
+++ stable/7/sys/dev/mpt/mpt_cam.c	Sun Sep 20 12:12:36 2009	(r197344)
@@ -884,11 +884,6 @@ mpt_sata_pass_reply_handler(struct mpt_s
 	if (req != NULL) {
 
 		if (reply_frame != NULL) {
-			MSG_SATA_PASSTHROUGH_REQUEST *pass;
-			MSG_SATA_PASSTHROUGH_REPLY *reply;
-
-			pass = (MSG_SATA_PASSTHROUGH_REQUEST *)req->req_vbuf;
-			reply = (MSG_SATA_PASSTHROUGH_REPLY *)reply_frame;
 			req->IOCStatus = le16toh(reply_frame->IOCStatus);
 		}
 		req->state &= ~REQ_STATE_QUEUED;
@@ -1063,7 +1058,7 @@ mpt_read_config_info_spi(struct mpt_soft
 static int
 mpt_set_initial_config_spi(struct mpt_softc *mpt)
 {
-	int i, j, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
+	int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
 	int error;
 
 	mpt->mpt_disc_enable = 0xff;
@@ -1101,15 +1096,11 @@ mpt_set_initial_config_spi(struct mpt_so
 	 * all targets back to async/narrow.
 	 *
 	 * We skip this step if the BIOS has already negotiated
-	 * speeds with the targets and does not require us to
-	 * do Domain Validation.
+	 * speeds with the targets.
 	 */
 	i = mpt->mpt_port_page2.PortSettings &
 	    MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS;
-	j = mpt->mpt_port_page2.PortFlags &
-	    MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
-	if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS /* &&
-	    j == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV */) {
+	if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS) {
 		mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
 		    "honoring BIOS transfer negotiations\n");
 	} else {
@@ -2602,7 +2593,6 @@ mpt_scsi_reply_handler(struct mpt_softc 
 {
 	MSG_SCSI_IO_REQUEST *scsi_req;
 	union ccb *ccb;
-	target_id_t tgt;
 
 	if (req->state == REQ_STATE_FREE) {
 		mpt_prt(mpt, "mpt_scsi_reply_handler: req already free\n");
@@ -2617,7 +2607,6 @@ mpt_scsi_reply_handler(struct mpt_softc 
 		return (TRUE);
 	}
 
-	tgt = scsi_req->TargetID;
 	mpt_req_untimeout(req, mpt_timeout, ccb);
 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 
@@ -2971,13 +2960,9 @@ mpt_fc_els_reply_handler(struct mpt_soft
 		}
 		if (tgt_req) {
 			mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, tgt_req);
-			uint8_t *vbuf;
 			union ccb *ccb = tgt->ccb;
 			uint32_t ct_id;
 
-			vbuf = tgt_req->req_vbuf;
-			vbuf += MPT_RQSL(mpt);
-
 			/*
 			 * Check to make sure we have the correct command
 			 * The reply descriptor in the target state should
@@ -3079,7 +3064,6 @@ mpt_scsi_reply_frame_handler(struct mpt_
 	MSG_SCSI_IO_REPLY *scsi_io_reply;
 	u_int ioc_status;
 	u_int sstate;
-	u_int loginfo;
 
 	MPT_DUMP_REPLY_FRAME(mpt, reply_frame);
 	KASSERT(reply_frame->Function == MPI_FUNCTION_SCSI_IO_REQUEST
@@ -3090,7 +3074,6 @@ mpt_scsi_reply_frame_handler(struct mpt_
 
 	scsi_io_reply = (MSG_SCSI_IO_REPLY *)reply_frame;
 	ioc_status = le16toh(scsi_io_reply->IOCStatus);
-	loginfo = ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE;
 	ioc_status &= MPI_IOCSTATUS_MASK;
 	sstate = scsi_io_reply->SCSIState;
 
@@ -4040,16 +4023,11 @@ mpt_scsi_send_tmf(struct mpt_softc *mpt,
 	memset(tmf_req, 0, sizeof(*tmf_req));
 	tmf_req->TargetID = target;
 	tmf_req->Bus = channel;
-	tmf_req->ChainOffset = 0;
 	tmf_req->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
-	tmf_req->Reserved = 0;
 	tmf_req->TaskType = type;
-	tmf_req->Reserved1 = 0;
 	tmf_req->MsgFlags = flags;
 	tmf_req->MsgContext =
 	    htole32(mpt->tmf_req->index | scsi_tmf_handler_id);
-	memset(&tmf_req->LUN, 0,
-	    sizeof(tmf_req->LUN) + sizeof(tmf_req->Reserved2));
 	if (lun > 256) {
 		tmf_req->LUN[0] = 0x40 | ((lun >> 8) & 0x3f);
 		tmf_req->LUN[1] = lun & 0xff;
From marius at FreeBSD.org  Sun Sep 20 12:14:43 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:14:54 2009
Subject: svn commit: r197345 - stable/7/share/man/man4
Message-ID: <200909201214.n8KCEg7E056020@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:14:42 2009
New Revision: 197345
URL: http://svn.freebsd.org/changeset/base/197345

Log:
  MFC: r194247
  
  Add a man page for cas(4) and reference it as appropriate.

Added:
  stable/7/share/man/man4/cas.4
     - copied unchanged from r194247, head/share/man/man4/cas.4
Modified:
  stable/7/share/man/man4/   (props changed)
  stable/7/share/man/man4/Makefile
  stable/7/share/man/man4/altq.4
  stable/7/share/man/man4/miibus.4
  stable/7/share/man/man4/vlan.4

Modified: stable/7/share/man/man4/Makefile
==============================================================================
--- stable/7/share/man/man4/Makefile	Sun Sep 20 12:12:36 2009	(r197344)
+++ stable/7/share/man/man4/Makefile	Sun Sep 20 12:14:42 2009	(r197345)
@@ -46,6 +46,7 @@ MAN=	aac.4 \
 	bt.4 \
 	cardbus.4 \
 	carp.4 \
+	cas.4 \
 	ccd.4 \
 	cd.4 \
 	cdce.4 \
@@ -448,6 +449,7 @@ MLINKS+=bfe.4 if_bfe.4
 MLINKS+=bge.4 if_bge.4
 MLINKS+=bktr.4 brooktree.4
 MLINKS+=cnw.4 if_cnw.4
+MLINKS+=cas.4 if_cas.4
 MLINKS+=crypto.4 cryptodev.4
 MLINKS+=cue.4 if_cue.4
 MLINKS+=dc.4 if_dc.4

Modified: stable/7/share/man/man4/altq.4
==============================================================================
--- stable/7/share/man/man4/altq.4	Sun Sep 20 12:12:36 2009	(r197344)
+++ stable/7/share/man/man4/altq.4	Sun Sep 20 12:14:42 2009	(r197345)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 10, 2009
+.Dd June 14, 2009
 .Dt ALTQ 4
 .Os
 .Sh NAME
@@ -126,6 +126,7 @@ They have been applied to the following 
 .Xr bce 4 ,
 .Xr bfe 4 ,
 .Xr bge 4 ,
+.Xr cas 4 ,
 .Xr dc 4 ,
 .Xr de 4 ,
 .Xr ed 4 ,

Copied: stable/7/share/man/man4/cas.4 (from r194247, head/share/man/man4/cas.4)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/share/man/man4/cas.4	Sun Sep 20 12:14:42 2009	(r197345, copy of r194247, head/share/man/man4/cas.4)
@@ -0,0 +1,154 @@
+.\"
+.\" Copyright (c) 2009 Marius Strobl 
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 15, 2009
+.Dt CAS 4
+.Os
+.Sh NAME
+.Nm cas
+.Nd Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn Gigabit Ethernet driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device miibus"
+.Cd "device cas"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+if_cas="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the Sun Cassini/Cassini+ and National
+Semiconductor DP83065 Saturn Gigabit Ethernet controllers found
+on-board in Sun UltraSPARC machines and as add-on cards.
+.Pp
+All controllers supported by the
+.Nm
+driver have TCP/UDP checksum offload capability for both receive and
+transmit, support for the reception and transmission of extended frames
+for
+.Xr vlan 4
+and an interrupt coalescing/moderation mechanism as well as a 512-bit
+multicast hash filter.
+.Pp
+The
+.Nm
+driver also supports Jumbo Frames (up to 9022 bytes), which can be
+configured via the interface MTU setting.
+Selecting an MTU larger than 1500 bytes with the
+.Xr ifconfig 8
+utility configures the adapter to receive and transmit Jumbo Frames.
+.Sh HARDWARE
+.Pp
+The chips supported by the
+.Nm
+driver are:
+.Pp
+.Bl -bullet -compact
+.It
+National Semiconductor DP83065 Saturn Gigabit Ethernet
+.It
+Sun Cassini Gigabit Ethernet
+.It
+Sun Cassini+ Gigabit Ethernet
+.El
+.Pp
+The
+following add-on cards are known to work with the
+.Nm
+driver at this time:
+.Pp
+.Bl -bullet -compact
+.It
+Sun GigaSwift Ethernet 1.0 UTP (Cassini)
+(part no.\& 501-5902)
+.It
+Sun GigaSwift Ethernet UTP (GCS)
+(part no.\& 501-6719)
+.It
+Sun Quad GigaSwift Ethernet UTP (QGE)
+(part no.\& 501-6522)
+.El
+.Sh NOTES
+On sparc64 the
+.Nm
+driver respects the
+.Va local-mac-address?
+system configuration variable which can be set in the Open Firmware boot
+monitor using the
+.Ic setenv
+command or by
+.Xr eeprom 8 .
+If set to
+.Dq Li false
+(the default), the
+.Nm
+driver will use the system's default MAC address for all of its devices.
+If set to
+.Dq Li true ,
+the unique MAC address of each interface is used if present rather than
+the system's default MAC address.
+.Pp
+Supported interfaces having their own MAC address include on-board
+versions on boards equipped with more than one Ethernet interface and
+all add-on cards.
+.Sh SEE ALSO
+.Xr altq 4 ,
+.Xr miibus 4 ,
+.Xr netintro 4 ,
+.Xr vlan 4 ,
+.Xr eeprom 8 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Nm
+device driver appeared in
+.Fx 8.0
+and
+.Fx 7.3 .
+It is named after the
+.Nm
+driver which first appeared in
+.Ox 4.1
+and supports the same set of controllers but is otherwise unrelated.
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Marius Strobl
+.Aq marius@FreeBSD.org
+based on the
+.Xr gem 4
+driver.

Modified: stable/7/share/man/man4/miibus.4
==============================================================================
--- stable/7/share/man/man4/miibus.4	Sun Sep 20 12:12:36 2009	(r197344)
+++ stable/7/share/man/man4/miibus.4	Sun Sep 20 12:14:42 2009	(r197345)
@@ -8,7 +8,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 10, 2009
+.Dd June 14, 2009
 .Dt MIIBUS 4
 .Os
 .Sh NAME
@@ -61,6 +61,8 @@ Broadcom NetXtreme II Gigabit Ethernet
 Broadcom BCM4401 Ethernet
 .It Xr bge 4
 Broadcom BCM570xx Gigabit Ethernet
+.It Xr cas 4
+Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn
 .It Xr dc 4
 DEC/Intel 21143 and various workalikes
 .It Xr ed 4
@@ -137,6 +139,7 @@ but as a result are not well behaved new
 .Xr bce 4 ,
 .Xr bfe 4 ,
 .Xr bge 4 ,
+.Xr cas 4 ,
 .Xr dc 4 ,
 .Xr ed 4 ,
 .Xr et 4 ,

Modified: stable/7/share/man/man4/vlan.4
==============================================================================
--- stable/7/share/man/man4/vlan.4	Sun Sep 20 12:12:36 2009	(r197344)
+++ stable/7/share/man/man4/vlan.4	Sun Sep 20 12:14:42 2009	(r197345)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 10, 2009
+.Dd June 14, 2009
 .Dt VLAN 4
 .Os
 .Sh NAME
@@ -161,6 +161,7 @@ The following interfaces support long fr
 .Nm
 natively:
 .Xr bfe 4 ,
+.Xr cas 4 ,
 .Xr dc 4 ,
 .Xr fwe 4 ,
 .Xr fxp 4 ,
From marius at FreeBSD.org  Sun Sep 20 12:19:22 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:19:38 2009
Subject: svn commit: r197346 - stable/7/release/doc/en_US.ISO8859-1/hardware
Message-ID: <200909201219.n8KCJMwO056156@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:19:21 2009
New Revision: 197346
URL: http://svn.freebsd.org/changeset/base/197346

Log:
  MFC: r194248
  
  Add cas(4).

Modified:
  stable/7/release/doc/en_US.ISO8859-1/hardware/article.sgml   (contents, props changed)

Modified: stable/7/release/doc/en_US.ISO8859-1/hardware/article.sgml
==============================================================================
--- stable/7/release/doc/en_US.ISO8859-1/hardware/article.sgml	Sun Sep 20 12:14:42 2009	(r197345)
+++ stable/7/release/doc/en_US.ISO8859-1/hardware/article.sgml	Sun Sep 20 12:19:21 2009	(r197346)
@@ -699,6 +699,8 @@
 
     &hwlist.bge;
 
+    &hwlist.cas;
+
     &hwlist.cdce;
 
     [&arch.amd64;, &arch.i386;] Crystal Semiconductor CS89x0-based NICs 
From marius at FreeBSD.org  Sun Sep 20 12:24:55 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:25:11 2009
Subject: svn commit: r197347 - stable/7/usr.sbin/sysinstall
Message-ID: <200909201224.n8KCOt9K056309@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:24:55 2009
New Revision: 197347
URL: http://svn.freebsd.org/changeset/base/197347

Log:
  MFC: r194249
  
  Add cas(4).

Modified:
  stable/7/usr.sbin/sysinstall/   (props changed)
  stable/7/usr.sbin/sysinstall/devices.c

Modified: stable/7/usr.sbin/sysinstall/devices.c
==============================================================================
--- stable/7/usr.sbin/sysinstall/devices.c	Sun Sep 20 12:19:21 2009	(r197346)
+++ stable/7/usr.sbin/sysinstall/devices.c	Sun Sep 20 12:24:55 2009	(r197347)
@@ -104,6 +104,7 @@ static struct _devname {
     NETWORK("bce",	"Broadcom NetXtreme II Gigabit Ethernet card"),
     NETWORK("bfe",	"Broadcom BCM440x PCI Ethernet card"),
     NETWORK("bge",	"Broadcom BCM570x PCI Gigabit Ethernet card"),
+    NETWORK("cas",	"Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"),
     NETWORK("cue",	"CATC USB Ethernet adapter"),
     NETWORK("cxgb",	"Chelsio T3 10Gb Ethernet card"),
     NETWORK("fpa",	"DEC DEFPA PCI FDDI card"),
From marius at FreeBSD.org  Sun Sep 20 12:56:51 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 12:57:04 2009
Subject: svn commit: r197349 - in stable/7/sys: . conf contrib/pf dev/gem
	modules/gem
Message-ID: <200909201256.n8KCuofu057064@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 12:56:50 2009
New Revision: 197349
URL: http://svn.freebsd.org/changeset/base/197349

Log:
  MFC: r194763, r194886
  
  - Initialize the ifnet structure, especially if_dname, before probing
    the PHYs as some PHY drivers use it (but probably shouldn't). How
    gem(4) has worked with brgphy(4) on powerpc without this so far is
    unclear to me.
  - Call ether_ifdetach(9) before stopping the controller and the
    callouts. The consensus is that the latter is now safe to do and
    should also solve the problem of active BPF listeners clearing
    promiscuous mode can result in the tick callout being restarted
    which in turn will trigger a panic once it's actually gone.
  - Introduce a dying flag which is set during detach and checked in
    gem_ioctl() in order to prevent active BPF listeners to clear
    promiscuous mode which may lead to the tick callout being restarted
    which will trigger a panic once it's actually gone.
  - In gem_stop() reset rather than just disable the transmitter and
    receiver in order to ensure we're not unloading DMA maps still in
    use by the hardware. [1]
  - The blanking time is specified in PCI clocks so we should use twice
    the value when operating at 66MHz.
  - Spell some 2 as ETHER_ALIGN and a 19 as GEM_STATUS_TX_COMPLETION_SHFT
    to make the actual intentions clear.
  - As we don't unload the peak attempts counter ignore its overflow
    interrupts.
  - Remove a stale setting of a variable to GEM_TD_INTERRUPT_ME which
    isn't used afterwards.
  - For optimum performance increment the TX kick register in multiples
    of 4 if possible as suggested by the documentation.
  - Partially revert r164931; drivers should only clear the watchdog
    timer if all outstanding TX descriptors are done.
  - Fix some debugging strings.
  - Add a missing BUS_DMASYNC_POSTWRITE in gem_rint().
  - As the error paths in the interrupt handler are generally unlikely
    predict them as false.
  - Add support for the SBus version of the GEM controller. [2]
  - Add some lock assertions.
  - Improve some comments.
  - Fix some more or less cosmetic issues in the code of the PCI front-end.
  - Change some softc members to be unsigned where more appropriate and
    remove unused ones.
  
  Obtained from:	NetBSD (partially) [2], OpenBSD [1]

Added:
  stable/7/sys/dev/gem/if_gem_sbus.c
     - copied unchanged from r194763, head/sys/dev/gem/if_gem_sbus.c
Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/conf/files
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/gem/if_gem.c
  stable/7/sys/dev/gem/if_gem_pci.c
  stable/7/sys/dev/gem/if_gemreg.h
  stable/7/sys/dev/gem/if_gemvar.h
  stable/7/sys/modules/gem/Makefile

Modified: stable/7/sys/conf/files
==============================================================================
--- stable/7/sys/conf/files	Sun Sep 20 12:40:56 2009	(r197348)
+++ stable/7/sys/conf/files	Sun Sep 20 12:56:50 2009	(r197349)
@@ -841,6 +841,7 @@ dev/flash/at45d.c		optional at45d
 dev/fxp/if_fxp.c		optional fxp
 dev/gem/if_gem.c		optional gem
 dev/gem/if_gem_pci.c		optional gem pci
+dev/gem/if_gem_sbus.c		optional gem sbus
 dev/hatm/if_hatm.c		optional hatm pci
 dev/hatm/if_hatm_intr.c		optional hatm pci
 dev/hatm/if_hatm_ioctl.c	optional hatm pci

Modified: stable/7/sys/dev/gem/if_gem.c
==============================================================================
--- stable/7/sys/dev/gem/if_gem.c	Sun Sep 20 12:40:56 2009	(r197348)
+++ stable/7/sys/dev/gem/if_gem.c	Sun Sep 20 12:56:50 2009	(r197349)
@@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$");
 CTASSERT(powerof2(GEM_NRXDESC) && GEM_NRXDESC >= 32 && GEM_NRXDESC <= 8192);
 CTASSERT(powerof2(GEM_NTXDESC) && GEM_NTXDESC >= 32 && GEM_NTXDESC <= 8192);
 
-#define	TRIES	10000
+#define	GEM_TRIES	10000
 
 /*
  * The hardware supports basic TCP/UDP checksum offloading.  However,
@@ -119,7 +119,7 @@ static void	gem_rint(struct gem_softc *s
 #ifdef GEM_RINT_TIMEOUT
 static void	gem_rint_timeout(void *arg);
 #endif
-static __inline void gem_rxcksum(struct mbuf *m, uint64_t flags);
+static inline void gem_rxcksum(struct mbuf *m, uint64_t flags);
 static void	gem_rxdrain(struct gem_softc *sc);
 static void	gem_setladrf(struct gem_softc *sc);
 static void	gem_start(struct ifnet *ifp);
@@ -127,6 +127,7 @@ static void	gem_start_locked(struct ifne
 static void	gem_stop(struct ifnet *ifp, int disable);
 static void	gem_tick(void *arg);
 static void	gem_tint(struct gem_softc *sc);
+static inline void gem_txkick(struct gem_softc *sc);
 static int	gem_watchdog(struct gem_softc *sc);
 
 devclass_t gem_devclass;
@@ -151,9 +152,24 @@ gem_attach(struct gem_softc *sc)
 	int error, i;
 	uint32_t v;
 
+	if (bootverbose)
+		device_printf(sc->sc_dev, "flags=0x%x\n", sc->sc_flags);
+
+	/* Set up ifnet structure. */
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL)
 		return (ENOSPC);
+	sc->sc_csum_features = GEM_CSUM_FEATURES;
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(sc->sc_dev),
+	    device_get_unit(sc->sc_dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_start = gem_start;
+	ifp->if_ioctl = gem_ioctl;
+	ifp->if_init = gem_init;
+	IFQ_SET_MAXLEN(&ifp->if_snd, GEM_TXQUEUELEN);
+	ifp->if_snd.ifq_drv_maxlen = GEM_TXQUEUELEN;
+	IFQ_SET_READY(&ifp->if_snd);
 
 	callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
 #ifdef GEM_RINT_TIMEOUT
@@ -161,27 +177,26 @@ gem_attach(struct gem_softc *sc)
 #endif
 
 	/* Make sure the chip is stopped. */
-	ifp->if_softc = sc;
 	gem_reset(sc);
 
 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
 	    BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL,
 	    NULL, &sc->sc_pdmatag);
-	if (error)
+	if (error != 0)
 		goto fail_ifnet;
 
 	error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
 	    1, MCLBYTES, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_rdmatag);
-	if (error)
+	if (error != 0)
 		goto fail_ptag;
 
 	error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
 	    MCLBYTES * GEM_NTXSEGS, GEM_NTXSEGS, MCLBYTES,
 	    BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag);
-	if (error)
+	if (error != 0)
 		goto fail_rtag;
 
 	error = bus_dma_tag_create(sc->sc_pdmatag, PAGE_SIZE, 0,
@@ -189,7 +204,7 @@ gem_attach(struct gem_softc *sc)
 	    sizeof(struct gem_control_data), 1,
 	    sizeof(struct gem_control_data), 0,
 	    NULL, NULL, &sc->sc_cdmatag);
-	if (error)
+	if (error != 0)
 		goto fail_ttag;
 
 	/*
@@ -199,7 +214,7 @@ gem_attach(struct gem_softc *sc)
 	if ((error = bus_dmamem_alloc(sc->sc_cdmatag,
 	    (void **)&sc->sc_control_data,
 	    BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
-	    &sc->sc_cddmamap))) {
+	    &sc->sc_cddmamap)) != 0) {
 		device_printf(sc->sc_dev,
 		    "unable to allocate control data, error = %d\n", error);
 		goto fail_ctag;
@@ -338,19 +353,6 @@ gem_attach(struct gem_softc *sc)
 	device_printf(sc->sc_dev, "%ukB RX FIFO, %ukB TX FIFO\n",
 	    sc->sc_rxfifosize / 1024, v / 16);
 
-	sc->sc_csum_features = GEM_CSUM_FEATURES;
-	/* Initialize ifnet structure. */
-	ifp->if_softc = sc;
-	if_initname(ifp, device_get_name(sc->sc_dev),
-	    device_get_unit(sc->sc_dev));
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-	ifp->if_start = gem_start;
-	ifp->if_ioctl = gem_ioctl;
-	ifp->if_init = gem_init;
-	IFQ_SET_MAXLEN(&ifp->if_snd, GEM_TXQUEUELEN);
-	ifp->if_snd.ifq_drv_maxlen = GEM_TXQUEUELEN;
-	IFQ_SET_READY(&ifp->if_snd);
-
 	/* Attach the interface. */
 	ether_ifattach(ifp, sc->sc_enaddr);
 
@@ -401,6 +403,7 @@ gem_detach(struct gem_softc *sc)
 	struct ifnet *ifp = sc->sc_ifp;
 	int i;
 
+	ether_ifdetach(ifp);
 	GEM_LOCK(sc);
 	gem_stop(ifp, 1);
 	GEM_UNLOCK(sc);
@@ -408,7 +411,6 @@ gem_detach(struct gem_softc *sc)
 #ifdef GEM_RINT_TIMEOUT
 	callout_drain(&sc->sc_rx_ch);
 #endif
-	ether_ifdetach(ifp);
 	if_free(ifp);
 	device_delete_child(sc->sc_dev, sc->sc_miibus);
 
@@ -456,7 +458,7 @@ gem_resume(struct gem_softc *sc)
 	GEM_UNLOCK(sc);
 }
 
-static __inline void
+static inline void
 gem_rxcksum(struct mbuf *m, uint64_t flags)
 {
 	struct ether_header *eh;
@@ -535,12 +537,11 @@ static void
 gem_tick(void *arg)
 {
 	struct gem_softc *sc = arg;
-	struct ifnet *ifp;
+	struct ifnet *ifp = sc->sc_ifp;
 	uint32_t v;
 
 	GEM_LOCK_ASSERT(sc, MA_OWNED);
 
-	ifp = sc->sc_ifp;
 	/*
 	 * Unload collision and error counters.
 	 */
@@ -584,7 +585,7 @@ gem_bitwait(struct gem_softc *sc, u_int 
 	int i;
 	uint32_t reg;
 
-	for (i = TRIES; i--; DELAY(100)) {
+	for (i = GEM_TRIES; i--; DELAY(100)) {
 		reg = GEM_BANKN_READ_M(bank, 4, sc, r);
 		if ((reg & clr) == 0 && (reg & set) == set)
 			return (1);
@@ -593,8 +594,7 @@ gem_bitwait(struct gem_softc *sc, u_int 
 }
 
 static void
-gem_reset(sc)
-	struct gem_softc *sc;
+gem_reset(struct gem_softc *sc)
 {
 
 #ifdef GEM_DEBUG
@@ -644,9 +644,8 @@ gem_stop(struct ifnet *ifp, int disable)
 	callout_stop(&sc->sc_rx_ch);
 #endif
 
-	/* XXX should we reset these instead? */
-	gem_disable_tx(sc);
-	gem_disable_rx(sc);
+	gem_reset_tx(sc);
+	gem_reset_rx(sc);
 
 	/*
 	 * Release any queued transmit buffers.
@@ -721,7 +720,7 @@ gem_reset_rxdma(struct gem_softc *sc)
 		if (sc->sc_rxsoft[i].rxs_mbuf != NULL)
 			GEM_UPDATE_RXDESC(sc, i);
 	sc->sc_rxptr = 0;
-	GEM_CDSYNC(sc, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
+	GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	/* NOTE: we use only 32-bit DMA addresses here. */
 	GEM_BANK1_WRITE_4(sc, GEM_RX_RING_PTR_HI, 0);
@@ -732,9 +731,11 @@ gem_reset_rxdma(struct gem_softc *sc)
 	    ((ETHER_HDR_LEN + sizeof(struct ip)) <<
 	    GEM_RX_CONFIG_CXM_START_SHFT) |
 	    (GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
-	    (2 << GEM_RX_CONFIG_FBOFF_SHFT));
+	    (ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT));
+	/* Adjust for the SBus clock probably isn't worth the fuzz. */
 	GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
-	    (6 << GEM_RX_BLANKING_TIME_SHIFT) | 6);
+	    ((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
+	    GEM_RX_BLANKING_TIME_SHIFT) | 6);
 	GEM_BANK1_WRITE_4(sc, GEM_RX_PAUSE_THRESH,
 	    (3 * sc->sc_rxfifosize / 256) |
 	    ((sc->sc_rxfifosize / 256) << 12));
@@ -798,12 +799,13 @@ gem_disable_tx(struct gem_softc *sc)
 }
 
 static int
-gem_meminit(sc)
-	struct gem_softc *sc;
+gem_meminit(struct gem_softc *sc)
 {
 	struct gem_rxsoft *rxs;
 	int error, i;
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	/*
 	 * Initialize the transmit descriptor ring.
 	 */
@@ -837,7 +839,8 @@ gem_meminit(sc)
 			GEM_INIT_RXDESC(sc, i);
 	}
 	sc->sc_rxptr = 0;
-	GEM_CDSYNC(sc, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
+
+	GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	return (0);
 }
@@ -938,6 +941,20 @@ gem_init_locked(struct gem_softc *sc)
 #endif
 
 	/* step 8.  Global Configuration & Interrupt Mask */
+
+	/*
+	 * Set the internal arbitration to "infinite" bursts of the
+	 * maximum length of 31 * 64 bytes so DMA transfers aren't
+	 * split up in cache line size chunks.  This greatly improves
+	 * RX performance.
+	 * Enable silicon bug workarounds for the Apple variants.
+	 */
+	GEM_BANK1_WRITE_4(sc, GEM_CONFIG,
+	    GEM_CONFIG_TXDMA_LIMIT | GEM_CONFIG_RXDMA_LIMIT |
+	    ((sc->sc_flags & GEM_PCI) != 0 ? GEM_CONFIG_BURST_INF :
+	    GEM_CONFIG_BURST_64) | (GEM_IS_APPLE(sc) ?
+	    GEM_CONFIG_RONPAULBIT | GEM_CONFIG_BUG2FIX : 0));
+
 	GEM_BANK1_WRITE_4(sc, GEM_INTMASK,
 	    ~(GEM_INTR_TX_INTME | GEM_INTR_TX_EMPTY | GEM_INTR_RX_DONE |
 	    GEM_INTR_RX_NOBUF | GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR |
@@ -949,7 +966,8 @@ gem_init_locked(struct gem_softc *sc)
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_MASK,
 	    GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT);
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_MASK,
-	    GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP);
+	    GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP |
+	    GEM_MAC_TX_PEAK_EXP);
 #ifdef GEM_DEBUG
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_MASK,
 	    ~(GEM_MAC_PAUSED | GEM_MAC_PAUSE | GEM_MAC_RESUME));
@@ -961,7 +979,8 @@ gem_init_locked(struct gem_softc *sc)
 	/* step 9.  ETX Configuration: use mostly default values. */
 
 	/* Enable DMA. */
-	v = gem_ringsize(GEM_NTXDESC /* XXX */);
+	v = gem_ringsize(GEM_NTXDESC);
+	/* Set TX FIFO threshold and enable DMA. */
 	v |= ((sc->sc_variant == GEM_SUN_ERI ? 0x100 : 0x4ff) << 10) &
 	    GEM_TX_CONFIG_TXFIFO_TH;
 	GEM_BANK1_WRITE_4(sc, GEM_TX_CONFIG, v | GEM_TX_CONFIG_TXDMA_EN);
@@ -973,14 +992,16 @@ gem_init_locked(struct gem_softc *sc)
 	/* RX TCP/UDP checksum offset */
 	v |= ((ETHER_HDR_LEN + sizeof(struct ip)) <<
 	    GEM_RX_CONFIG_CXM_START_SHFT);
-
-	/* Enable DMA. */
+	/* Set RX FIFO threshold, set first byte offset and enable DMA. */
 	GEM_BANK1_WRITE_4(sc, GEM_RX_CONFIG,
 	    v | (GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
-	    (2 << GEM_RX_CONFIG_FBOFF_SHFT) | GEM_RX_CONFIG_RXDMA_EN);
+	    (ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT) |
+	    GEM_RX_CONFIG_RXDMA_EN);
 
+	/* Adjust for the SBus clock probably isn't worth the fuzz. */
 	GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
-	    (6 << GEM_RX_BLANKING_TIME_SHIFT) | 6);
+	    ((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
+	    GEM_RX_BLANKING_TIME_SHIFT) | 6);
 
 	/*
 	 * The following value is for an OFF Threshold of about 3/4 full
@@ -1002,7 +1023,7 @@ gem_init_locked(struct gem_softc *sc)
 		device_printf(sc->sc_dev, "cannot configure RX MAC\n");
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
 
-	/* step 13. TX_MAC Configuration Register */
+	/* step 13.  TX_MAC Configuration Register */
 	v = GEM_BANK1_READ_4(sc, GEM_MAC_TX_CONFIG);
 	v |= GEM_MAC_TX_ENABLE;
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, 0);
@@ -1037,6 +1058,8 @@ gem_load_txmbuf(struct gem_softc *sc, st
 	uint64_t cflags, flags;
 	int error, nexttx, nsegs, offset, seg;
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	/* Get a work queue entry. */
 	if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) {
 		/* Ran out of descriptors. */
@@ -1143,7 +1166,6 @@ gem_load_txmbuf(struct gem_softc *sc, st
 #endif
 	if (++sc->sc_txwin > GEM_NTXSEGS * 2 / 3) {
 		sc->sc_txwin = 0;
-		flags |= GEM_TD_INTERRUPT_ME;
 		sc->sc_txdescs[txs->txs_firstdesc].gd_flags |=
 		    GEM_DMA_WRITE(sc, GEM_TD_INTERRUPT_ME |
 		    GEM_TD_START_OF_PACKET);
@@ -1175,6 +1197,8 @@ gem_init_regs(struct gem_softc *sc)
 {
 	const u_char *laddr = IF_LLADDR(sc->sc_ifp);
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	/* These registers are not cleared on reset. */
 	if ((sc->sc_flags & GEM_INITED) == 0) {
 		/* magic values */
@@ -1182,16 +1206,19 @@ gem_init_regs(struct gem_softc *sc)
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG1, 8);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG2, 4);
 
+		/* min frame length */
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
-		/* max frame and max burst size */
+		/* max frame length and max burst size */
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MAX_FRAME,
 		    (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) | (0x2000 << 16));
 
+		/* more magic values */
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_PREAMBLE_LEN, 0x7);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_JAM_SIZE, 0x4);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ATTEMPT_LIMIT, 0x10);
-		/* dunno... */
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_TYPE, 0x8088);
+
+		/* random number seed */
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_RANDOM_SEED,
 		    ((laddr[5] << 8) | laddr[4]) & 0x3ff);
 
@@ -1209,7 +1236,6 @@ gem_init_regs(struct gem_softc *sc)
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER0, 0);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER1, 0);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER2, 0);
-
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK1_2, 0);
 		GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK0, 0);
 
@@ -1232,18 +1258,6 @@ gem_init_regs(struct gem_softc *sc)
 	/* Set XOFF PAUSE time. */
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_SEND_PAUSE_CMD, 0x1BF0);
 
-	/*
-	 * Set the internal arbitration to "infinite" bursts of the
-	 * maximum length of 31 * 64 bytes so DMA transfers aren't
-	 * split up in cache line size chunks.  This greatly improves
-	 * especially RX performance.
-	 * Enable silicon bug workarounds for the Apple variants.
-	 */
-	GEM_BANK1_WRITE_4(sc, GEM_CONFIG,
-	    GEM_CONFIG_TXDMA_LIMIT | GEM_CONFIG_RXDMA_LIMIT |
-	    GEM_CONFIG_BURST_INF | (GEM_IS_APPLE(sc) ?
-	    GEM_CONFIG_RONPAULBIT | GEM_CONFIG_BUG2FIX : 0));
-
 	/* Set the station address. */
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR0, (laddr[4] << 8) | laddr[5]);
 	GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR1, (laddr[2] << 8) | laddr[3]);
@@ -1263,12 +1277,32 @@ gem_start(struct ifnet *ifp)
 	GEM_UNLOCK(sc);
 }
 
+static inline void
+gem_txkick(struct gem_softc *sc)
+{
+
+	/*
+	 * Update the TX kick register.  This register has to point to the
+	 * descriptor after the last valid one and for optimum performance
+	 * should be incremented in multiples of 4 (the DMA engine fetches/
+	 * updates descriptors in batches of 4).
+	 */
+#ifdef GEM_DEBUG
+	CTR3(KTR_GEM, "%s: %s: kicking TX %d",
+	    device_get_name(sc->sc_dev), __func__, sc->sc_txnext);
+#endif
+	GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	GEM_BANK1_WRITE_4(sc, GEM_TX_KICK, sc->sc_txnext);
+}
+
 static void
 gem_start_locked(struct ifnet *ifp)
 {
 	struct gem_softc *sc = ifp->if_softc;
 	struct mbuf *m;
-	int ntx;
+	int kicked, ntx;
+
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 	    IFF_DRV_RUNNING || (sc->sc_flags & GEM_LINK) == 0)
@@ -1280,6 +1314,7 @@ gem_start_locked(struct ifnet *ifp)
 	    sc->sc_txnext);
 #endif
 	ntx = 0;
+	kicked = 0;
 	for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && sc->sc_txfree > 1;) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
@@ -1291,19 +1326,18 @@ gem_start_locked(struct ifnet *ifp)
 			IFQ_DRV_PREPEND(&ifp->if_snd, m);
 			break;
 		}
+		if ((sc->sc_txnext % 4) == 0) {
+			gem_txkick(sc);
+			kicked = 1;
+		} else
+			kicked = 0;
 		ntx++;
-		/* Kick the transmitter. */
-#ifdef GEM_DEBUG
-		CTR3(KTR_GEM, "%s: %s: kicking TX %d",
-		    device_get_name(sc->sc_dev), __func__, sc->sc_txnext);
-#endif
-		GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-		GEM_BANK1_WRITE_4(sc, GEM_TX_KICK, sc->sc_txnext);
-
 		BPF_MTAP(ifp, m);
 	}
 
 	if (ntx > 0) {
+		if (kicked == 0)
+			gem_txkick(sc);
 #ifdef GEM_DEBUG
 		CTR2(KTR_GEM, "%s: packets enqueued, OWN on %d",
 		    device_get_name(sc->sc_dev), sc->sc_txnext);
@@ -1324,10 +1358,13 @@ gem_tint(struct gem_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct gem_txsoft *txs;
-	int txlast, progress;
+	int progress;
+	uint32_t txlast;
 #ifdef GEM_DEBUG
 	int i;
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	CTR2(KTR_GEM, "%s: %s", device_get_name(sc->sc_dev), __func__);
 #endif
 
@@ -1338,7 +1375,6 @@ gem_tint(struct gem_softc *sc)
 	progress = 0;
 	GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
 	while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
-
 #ifdef GEM_DEBUG
 		if ((ifp->if_flags & IFF_DEBUG) != 0) {
 			printf("    txsoft %p transmit chain:\n", txs);
@@ -1419,8 +1455,8 @@ gem_tint(struct gem_softc *sc)
 		 * and restart.
 		 */
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		sc->sc_wdog_timer = STAILQ_EMPTY(&sc->sc_txdirtyq) ? 0 : 5;
-
+		if (STAILQ_EMPTY(&sc->sc_txdirtyq))
+		    sc->sc_wdog_timer = 0;
 		gem_start_locked(ifp);
 	}
 
@@ -1437,6 +1473,7 @@ gem_rint_timeout(void *arg)
 	struct gem_softc *sc = arg;
 
 	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	gem_rint(sc);
 }
 #endif
@@ -1449,6 +1486,8 @@ gem_rint(struct gem_softc *sc)
 	uint64_t rxstat;
 	uint32_t rxcomp;
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 #ifdef GEM_RINT_TIMEOUT
 	callout_stop(&sc->sc_rx_ch);
 #endif
@@ -1461,12 +1500,11 @@ gem_rint(struct gem_softc *sc)
 	 * how long the following loop can execute.
 	 */
 	rxcomp = GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION);
-
 #ifdef GEM_DEBUG
-	CTR3(KTR_GEM, "%s: sc->rxptr %d, complete %d",
+	CTR3(KTR_GEM, "%s: sc->sc_rxptr %d, complete %d",
 	    __func__, sc->sc_rxptr, rxcomp);
 #endif
-	GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
+	GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 	for (; sc->sc_rxptr != rxcomp;) {
 		m = sc->sc_rxsoft[sc->sc_rxptr].rxs_mbuf;
 		rxstat = GEM_DMA_READ(sc,
@@ -1525,9 +1563,9 @@ gem_rint(struct gem_softc *sc)
 		/*
 		 * Update the RX kick register.  This register has to point
 		 * to the descriptor after the last valid one (before the
-		 * current batch) and must be incremented in multiples of
-		 * 4 (because the DMA engine fetches/updates descriptors
-		 * in batches of 4).
+		 * current batch) and for optimum performance should be
+		 * incremented in multiples of 4 (the DMA engine fetches/
+		 * updates descriptors in batches of 4).
 		 */
 		sc->sc_rxptr = GEM_NEXTRX(sc->sc_rxptr);
 		if ((sc->sc_rxptr % 4) == 0) {
@@ -1545,7 +1583,7 @@ gem_rint(struct gem_softc *sc)
 		}
 
 		ifp->if_ipackets++;
-		m->m_data += 2; /* We're already off by two */
+		m->m_data += ETHER_ALIGN; /* first byte offset */
 		m->m_pkthdr.rcvif = ifp;
 		m->m_pkthdr.len = m->m_len = GEM_RD_BUFLEN(rxstat);
 
@@ -1559,7 +1597,7 @@ gem_rint(struct gem_softc *sc)
 	}
 
 #ifdef GEM_DEBUG
-	CTR3(KTR_GEM, "%s: done sc->rxptr %d, complete %d", __func__,
+	CTR3(KTR_GEM, "%s: done sc->sc_rxptr %d, complete %d", __func__,
 	    sc->sc_rxptr, GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION));
 #endif
 }
@@ -1572,6 +1610,8 @@ gem_add_rxbuf(struct gem_softc *sc, int 
 	bus_dma_segment_t segs[1];
 	int error, nsegs;
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 	if (m == NULL)
 		return (ENOBUFS);
@@ -1620,7 +1660,15 @@ gem_eint(struct gem_softc *sc, u_int sta
 		return;
 	}
 
-	device_printf(sc->sc_dev, "%s: status=%x\n", __func__, status);
+	device_printf(sc->sc_dev, "%s: status 0x%x", __func__, status);
+	if ((status & GEM_INTR_BERR) != 0) {
+		if ((sc->sc_flags & GEM_PCI) != 0)
+			printf(", PCI bus error 0x%x\n",
+			    GEM_BANK1_READ_4(sc, GEM_PCI_ERROR_STATUS));
+		else
+			printf(", SBus error 0x%x\n",
+			    GEM_BANK1_READ_4(sc, GEM_SBUS_STATUS));
+	}
 }
 
 void
@@ -1634,8 +1682,8 @@ gem_intr(void *v)
 
 #ifdef GEM_DEBUG
 	CTR4(KTR_GEM, "%s: %s: cplt %x, status %x",
-	    device_get_name(sc->sc_dev), __func__, (status >> 19),
-	    (u_int)status);
+	    device_get_name(sc->sc_dev), __func__,
+	    (status >> GEM_STATUS_TX_COMPLETION_SHFT), (u_int)status);
 
 	/*
 	 * PCS interrupts must be cleared, otherwise no traffic is passed!
@@ -1665,7 +1713,7 @@ gem_intr(void *v)
 		device_printf(sc->sc_dev, "%s: MIF interrupt\n", __func__);
 #endif
 
-	if ((status &
+	if (__predict_false(status &
 	    (GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR | GEM_INTR_BERR)) != 0)
 		gem_eint(sc, status);
 
@@ -1675,17 +1723,20 @@ gem_intr(void *v)
 	if ((status & (GEM_INTR_TX_EMPTY | GEM_INTR_TX_INTME)) != 0)
 		gem_tint(sc);
 
-	if (status & GEM_INTR_TX_MAC) {
+	if (__predict_false((status & GEM_INTR_TX_MAC) != 0)) {
 		status2 = GEM_BANK1_READ_4(sc, GEM_MAC_TX_STATUS);
 		if ((status2 &
-		    ~(GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP)) != 0)
+		    ~(GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP |
+		    GEM_MAC_TX_PEAK_EXP)) != 0)
 			device_printf(sc->sc_dev,
 			    "MAC TX fault, status %x\n", status2);
 		if ((status2 &
-		    (GEM_MAC_TX_UNDERRUN | GEM_MAC_TX_PKT_TOO_LONG)) != 0)
+		    (GEM_MAC_TX_UNDERRUN | GEM_MAC_TX_PKT_TOO_LONG)) != 0) {
+			sc->sc_ifp->if_oerrors++;
 			gem_init_locked(sc);
+		}
 	}
-	if (status & GEM_INTR_RX_MAC) {
+	if (__predict_false((status & GEM_INTR_RX_MAC) != 0)) {
 		status2 = GEM_BANK1_READ_4(sc, GEM_MAC_RX_STATUS);
 		/*
 		 * At least with GEM_SUN_GEM and some GEM_SUN_ERI
@@ -1906,6 +1957,8 @@ gem_mii_statchg(device_t dev)
 
 	sc = device_get_softc(dev);
 
+	GEM_LOCK_ASSERT(sc, MA_OWNED);
+
 #ifdef GEM_DEBUG
 	if ((sc->sc_ifp->if_flags & IFF_DEBUG) != 0)
 		device_printf(sc->sc_dev, "%s: status change: PHY = %d\n",
@@ -1985,7 +2038,7 @@ gem_mii_statchg(device_t dev)
 		if ((GEM_BANK1_READ_4(sc, GEM_MIF_CONFIG) &
 		    GEM_MIF_CONFIG_PHY_SEL) != 0) {
 			/* External MII needs echo disable if half duplex. */
-		    	if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
+			if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
 			    IFM_FDX) == 0)
 				v |= GEM_MAC_XIF_ECHO_DISABL;
 		} else

Modified: stable/7/sys/dev/gem/if_gem_pci.c
==============================================================================
--- stable/7/sys/dev/gem/if_gem_pci.c	Sun Sep 20 12:40:56 2009	(r197348)
+++ stable/7/sys/dev/gem/if_gem_pci.c	Sun Sep 20 12:56:50 2009	(r197349)
@@ -90,7 +90,7 @@ static device_method_t gem_pci_methods[]
 	DEVMETHOD(miibus_writereg,	gem_mii_writereg),
 	DEVMETHOD(miibus_statchg,	gem_mii_statchg),
 
-	{ 0, 0 }
+	KOBJMETHOD_END
 };
 
 static driver_t gem_pci_driver = {
@@ -107,7 +107,7 @@ static const struct gem_pci_dev {
 	uint32_t	gpd_devid;
 	int		gpd_variant;
 	const char	*gpd_desc;
-} gem_pci_devlist[] = {
+} const gem_pci_devlist[] = {
 	{ 0x1101108e, GEM_SUN_ERI,	"Sun ERI 10/100 Ethernet" },
 	{ 0x2bad108e, GEM_SUN_GEM,	"Sun GEM Gigabit Ethernet" },
 	{ 0x0021106b, GEM_APPLE_GMAC,	"Apple UniNorth GMAC Ethernet" },
@@ -200,13 +200,18 @@ gem_pci_attach(device_t dev)
 	    GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE,
 	    &sc->sc_res[GEM_RES_BANK2]->r_bushandle);
 
+	/* Determine whether we're running at 66MHz. */
+	if ((GEM_BANK2_READ_4(sc, GEM_PCI_BIF_CONFIG) &
+	   GEM_PCI_BIF_CNF_M66EN) != 0)
+		sc->sc_flags |= GEM_PCI66;
+
 #if defined(__powerpc__) || defined(__sparc64__)
 	OF_getetheraddr(dev, sc->sc_enaddr);
 #else
 	/*
 	 * Dig out VPD (vital product data) and read NA (network address).
-	 * The VPD of GEM resides in the PCI Expansion ROM (PCI FCode) and
-	 * can't be accessed via the PCI capability pointer.
+	 * The VPD resides in the PCI Expansion ROM (PCI FCode) and can't
+	 * be accessed via the PCI capability pointer.
 	 * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
 	 * chapter 2 describes the data structure.
 	 */
@@ -225,22 +230,21 @@ gem_pci_attach(device_t dev)
 #define	PCI_VPDRES_BYTE0		0x00
 #define	PCI_VPDRES_ISLARGE(x)		((x) & 0x80)
 #define	PCI_VPDRES_LARGE_NAME(x)	((x) & 0x7f)
-#define	PCI_VPDRES_TYPE_VPD		0x10		/* large */
 #define	PCI_VPDRES_LARGE_LEN_LSB	0x01
 #define	PCI_VPDRES_LARGE_LEN_MSB	0x02
-#define	PCI_VPDRES_LARGE_DATA		0x03
-#define	PCI_VPD_SIZE			0x03
+#define	PCI_VPDRES_LARGE_SIZE		0x03
+#define	PCI_VPDRES_TYPE_VPD		0x10		/* large */
 #define	PCI_VPD_KEY0			0x00
 #define	PCI_VPD_KEY1			0x01
 #define	PCI_VPD_LEN			0x02
-#define	PCI_VPD_DATA			0x03
+#define	PCI_VPD_SIZE			0x03
 
 #define	GEM_ROM_READ_1(sc, offs)					\
-    GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs))
+	GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs))
 #define	GEM_ROM_READ_2(sc, offs)					\
-    GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs))
+	GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs))
 #define	GEM_ROM_READ_4(sc, offs)					\
-    GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs))
+	GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs))
 
 	/* Read PCI Expansion ROM header. */
 	if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
@@ -273,22 +277,22 @@ gem_pci_attach(device_t dev)
 	    j + PCI_VPDRES_BYTE0)) == 0 ||
 	    PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc,
 	    j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD ||
-	    (GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8 |
+	    ((GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8) |
 	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB)) !=
 	    PCI_VPD_SIZE + ETHER_ADDR_LEN ||
-	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) !=
+	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY0) !=
 	    0x4e /* N */ ||
-	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) !=
+	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY1) !=
 	    0x41 /* A */ ||
-	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) !=
+	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_LEN) !=
 	    ETHER_ADDR_LEN ||
-	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA +
+	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE +
 	    ETHER_ADDR_LEN) != 0x79) {
 		device_printf(dev, "unexpected PCI VPD\n");
 		goto fail;
 	}
 	bus_read_region_1(sc->sc_res[GEM_RES_BANK1],
-	    GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA,
+	    GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE,
 	    sc->sc_enaddr, ETHER_ADDR_LEN);
 #endif
 
@@ -330,19 +334,15 @@ gem_pci_detach(device_t dev)
 static int
 gem_pci_suspend(device_t dev)
 {
-	struct gem_softc *sc;
 
-	sc = device_get_softc(dev);
-	gem_suspend(sc);
+	gem_suspend(device_get_softc(dev));
 	return (0);
 }
 
 static int
 gem_pci_resume(device_t dev)
 {
-	struct gem_softc *sc;
 
-	sc = device_get_softc(dev);
-	gem_resume(sc);
+	gem_resume(device_get_softc(dev));
 	return (0);
 }

Copied: stable/7/sys/dev/gem/if_gem_sbus.c (from r194763, head/sys/dev/gem/if_gem_sbus.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/sys/dev/gem/if_gem_sbus.c	Sun Sep 20 12:56:50 2009	(r197349, copy of r194763, head/sys/dev/gem/if_gem_sbus.c)
@@ -0,0 +1,210 @@
+/*-
+ * Copyright (C) 2001 Eduardo Horvath.
+ * Copyright (c) 2007 Marius Strobl 
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: if_gem_pci.c,v 1.7 2001/10/18 15:09:15 thorpej Exp
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+/*
+ * SBus bindings for Sun GEM Ethernet controllers
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include "miibus_if.h"
+
+static device_probe_t gem_sbus_probe;
+static device_attach_t gem_sbus_attach;
+static device_detach_t gem_sbus_detach;
+static device_suspend_t gem_sbus_suspend;
+static device_resume_t gem_sbus_resume;
+
+static device_method_t gem_sbus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		gem_sbus_probe),
+	DEVMETHOD(device_attach,	gem_sbus_attach),
+	DEVMETHOD(device_detach,	gem_sbus_detach),
+	DEVMETHOD(device_suspend,	gem_sbus_suspend),
+	DEVMETHOD(device_resume,	gem_sbus_resume),
+	/* Use the suspend handler here, it is all that is required. */
+	DEVMETHOD(device_shutdown,	gem_sbus_suspend),
+
+	/* bus interface */
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	gem_mii_readreg),
+	DEVMETHOD(miibus_writereg,	gem_mii_writereg),
+	DEVMETHOD(miibus_statchg,	gem_mii_statchg),
+
+	KOBJMETHOD_END
+};
+
+static driver_t gem_sbus_driver = {
+	"gem",
+	gem_sbus_methods,
+	sizeof(struct gem_softc)
+};
+
+DRIVER_MODULE(gem, sbus, gem_sbus_driver, gem_devclass, 0, 0);
+MODULE_DEPEND(gem, sbus, 1, 1, 1);
+MODULE_DEPEND(gem, ether, 1, 1, 1);
+
+static int
+gem_sbus_probe(device_t dev)
+{
+
+	if (strcmp(ofw_bus_get_name(dev), "network") == 0 &&
+	    ofw_bus_get_compat(dev) != NULL &&
+	    strcmp(ofw_bus_get_compat(dev), "SUNW,sbus-gem") == 0) {
+		device_set_desc(dev, "Sun GEM Gigabit Ethernet");
+		return (0);
+	}
+
+	return (ENXIO);
+}
+
+static struct resource_spec gem_sbus_res_spec[] = {
+	{ SYS_RES_IRQ, 0, RF_SHAREABLE | RF_ACTIVE },	/* GEM_RES_INTR */
+	{ SYS_RES_MEMORY, 1, RF_ACTIVE },		/* GEM_RES_BANK1 */
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },		/* GEM_RES_BANK2 */
+	{ -1, 0 }
+};
+
+static int
+gem_sbus_attach(device_t dev)
+{
+	struct gem_softc *sc;
+	int burst;
+	uint32_t val;
+
+	sc = device_get_softc(dev);
+	sc->sc_variant = GEM_SUN_GEM;
+	sc->sc_dev = dev;
+
+	if (bus_alloc_resources(dev, gem_sbus_res_spec, sc->sc_res)) {
+		device_printf(dev, "failed to allocate resources\n");
+		bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
+		return (ENXIO);
+	}
+
+	GEM_LOCK_INIT(sc, device_get_nameunit(dev));
+
+	OF_getetheraddr(dev, sc->sc_enaddr);
+
+	burst = sbus_get_burstsz(dev);
+	val = GEM_SBUS_CFG_PARITY;
+	if ((burst & SBUS_BURST64_MASK) != 0) {
+		val |= GEM_SBUS_CFG_64BIT;
+		burst >>= SBUS_BURST64_SHIFT;
+	}
+	if ((burst & SBUS_BURST_64) != 0)
+		val |= GEM_SBUS_CFG_BURST_64;
+	else if ((burst & SBUS_BURST_32) != 0)
+		val |= GEM_SBUS_CFG_BURST_32;
+	else {
+		device_printf(dev, "unsupported burst size\n");
+		goto fail;
+	}
+	/* Reset the SBus interface only. */
+	(void)GEM_BANK2_READ_4(sc, GEM_SBUS_BIF_RESET);
+	DELAY(100);
+	GEM_BANK2_WRITE_4(sc, GEM_SBUS_CONFIG, val);
+
+	if (gem_attach(sc) != 0) {
+		device_printf(dev, "could not be attached\n");
+		goto fail;
+	}
+
+	if (bus_setup_intr(dev, sc->sc_res[GEM_RES_INTR], INTR_TYPE_NET |
+	    INTR_MPSAFE, NULL, gem_intr, sc, &sc->sc_ih) != 0) {
+		device_printf(dev, "failed to set up interrupt\n");
+		gem_detach(sc);
+		goto fail;
+	}
+	return (0);
+
+ fail:
+	GEM_LOCK_DESTROY(sc);
+	bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
+	return (ENXIO);
+}
+
+static int
+gem_sbus_detach(device_t dev)
+{
+	struct gem_softc *sc;
+
+	sc = device_get_softc(dev);
+	bus_teardown_intr(dev, sc->sc_res[GEM_RES_INTR], sc->sc_ih);
+	gem_detach(sc);
+	GEM_LOCK_DESTROY(sc);
+	bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
+	return (0);
+}
+
+static int
+gem_sbus_suspend(device_t dev)
+{
+
+	gem_suspend(device_get_softc(dev));
+	return (0);
+}
+
+static int
+gem_sbus_resume(device_t dev)
+{
+
+	gem_resume(device_get_softc(dev));
+	return (0);
+}

Modified: stable/7/sys/dev/gem/if_gemreg.h
==============================================================================
--- stable/7/sys/dev/gem/if_gemreg.h	Sun Sep 20 12:40:56 2009	(r197348)
+++ stable/7/sys/dev/gem/if_gemreg.h	Sun Sep 20 12:56:50 2009	(r197349)
@@ -32,7 +32,7 @@
 #ifndef	_IF_GEMREG_H
 #define	_IF_GEMREG_H
 
-/* Register definitions for Sun GEM gigabit ethernet */
+/* register definitions for Apple GMAC, Sun ERI and Sun GEM */
 
 /*
  * First bank: this registers live at the start of the PCI
@@ -47,97 +47,110 @@
 #define	GEM_INTACK		0x0014	/* Interrupt acknowledge, W/O */
 #define	GEM_STATUS_ALIAS	0x001c

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
From marius at FreeBSD.org  Sun Sep 20 13:47:56 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 13:48:02 2009
Subject: svn commit: r197353 - stable/7/release/doc/en_US.ISO8859-1/hardware
Message-ID: <200909201347.n8KDltC5058378@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 13:47:55 2009
New Revision: 197353
URL: http://svn.freebsd.org/changeset/base/197353

Log:
  Move mergeinfo for r194248 from article.sgml up to its directory.

Modified:
  stable/7/release/doc/en_US.ISO8859-1/hardware/   (props changed)
From marius at FreeBSD.org  Sun Sep 20 14:26:18 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 14:26:24 2009
Subject: svn commit: r197358 - stable/7/share/man/man4
Message-ID: <200909201426.n8KEQHUC059278@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 14:26:17 2009
New Revision: 197358
URL: http://svn.freebsd.org/changeset/base/197358

Log:
  MFC: r194764
  
  - Update regarding the support for SBus GEM added in r194763 (MFC'ed
    in r197349).
  - Improve the description a bit and add a reference to vlan(4).

Modified:
  stable/7/share/man/man4/   (props changed)
  stable/7/share/man/man4/gem.4

Modified: stable/7/share/man/man4/gem.4
==============================================================================
--- stable/7/share/man/man4/gem.4	Sun Sep 20 14:20:00 2009	(r197357)
+++ stable/7/share/man/man4/gem.4	Sun Sep 20 14:26:17 2009	(r197358)
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 15, 2009
+.Dd June 14, 2009
 .Dt GEM 4
 .Os
 .Sh NAME
@@ -57,9 +57,16 @@ if_gem_load="YES"
 .Sh DESCRIPTION
 The
 .Nm
-driver provides support for the GMac Ethernet hardware found mostly in
+driver provides support for the GMAC Ethernet hardware found mostly in
 the last Apple PowerBooks G3s and most G4-based Apple hardware, as
-well as many Sun UltraSPARCs.
+well as Sun UltraSPARC machines.
+.Pp                                                                            
+All controllers supported by the                                               
+.Nm                                                                            
+driver have TCP checksum offload capability for both receive and transmit,     
+support for the reception and transmission of extended frames for              
+.Xr vlan 4                                                                     
+and a 512-bit multicast hash filter.                                           
 .Sh HARDWARE
 .Pp
 Chips supported by the
@@ -84,6 +91,9 @@ driver at this time:
 .It
 Sun Gigabit Ethernet PCI 2.0/3.0 (GBE/P)
 (part no.\& 501-4373)
+.It
+Sun Gigabit Ethernet SBus 2.0/3.0 (GBE/S)
+(part no.\& 501-4375)
 .El
 .Sh NOTES
 On sparc64 the
@@ -108,15 +118,11 @@ the system's default MAC address.
 Supported interfaces having their own MAC address include the on-board
 Sun ERI 10/100 Mbps on boards equipped with more than one Ethernet interface
 and the Sun Gigabit Ethernet 2.0/3.0 GBE add-on cards.
-.Sh CAVEATS
-Currently the
-.Nm
-driver fails to attach to Sun Gigabit Ethernet SBus 2.0/3.0 (GBE/S) cards,
-as no SBus front-end has been written so far.
 .Sh SEE ALSO
 .Xr altq 4 ,
 .Xr miibus 4 ,
 .Xr netintro 4 ,
+.Xr vlan 4 ,
 .Xr eeprom 8 ,
 .Xr ifconfig 8
 .Sh HISTORY
@@ -132,9 +138,19 @@ version to include it was
 .An -nosplit
 The
 .Nm
-driver was written by
+driver was written for
+.Nx
+by
 .An Eduardo Horvath
 .Aq eeh@NetBSD.org .
+It was ported to
+.Fx
+by
+.An Thomas Moestl
+.Aq tmm@FreeBSD.org
+and later on improved by
+.An Marius Strobl
+.Aq marus@FreeBSD.org .
 The man page was written by
 .An Thomas Klausner
 .Aq wiz@NetBSD.org .
From marius at FreeBSD.org  Sun Sep 20 18:53:41 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 18:53:47 2009
Subject: svn commit: r197366 - in stable/7/sys: . contrib/pf sparc64/include
	sparc64/sparc64
Message-ID: <200909201853.n8KIreu6064995@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 18:53:40 2009
New Revision: 197366
URL: http://svn.freebsd.org/changeset/base/197366

Log:
  MFC: r195149 (partial)
  
  - Work around the broken loader behavior of not demapping no longer
    used kernel TLB slots when unloading the kernel or modules, which
    results in havoc when loading a kernel and modules which take up
    less TLB slots afterwards as the unused but locked ones aren't
    accounted for in virtual_avail. Eventually this should be fixed
    in the loader which isn't straight forward though and the kernel
    should be robust against this anyway. [1]
  - Remove the no longer used global msgbuf_phys.
  - Remove the redundant ekva parameter of pmap_bootstrap_alloc().
  - Correct some outdated function names in ktr(9) invocations.
  
  Requested by:	jhb [1]

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/sparc64/include/pmap.h
  stable/7/sys/sparc64/sparc64/machdep.c
  stable/7/sys/sparc64/sparc64/pmap.c

Modified: stable/7/sys/sparc64/include/pmap.h
==============================================================================
--- stable/7/sys/sparc64/include/pmap.h	Sun Sep 20 17:46:56 2009	(r197365)
+++ stable/7/sys/sparc64/include/pmap.h	Sun Sep 20 18:53:40 2009	(r197366)
@@ -80,7 +80,7 @@ struct pmap {
 #define	pmap_page_get_memattr(m)	VM_MEMATTR_DEFAULT
 #define	pmap_page_set_memattr(m, ma)	(void)0
 
-void	pmap_bootstrap(vm_offset_t ekva);
+void	pmap_bootstrap(void);
 vm_paddr_t pmap_kextract(vm_offset_t va);
 void	pmap_kenter(vm_offset_t va, vm_page_t m);
 void	pmap_kremove(vm_offset_t);
@@ -106,8 +106,6 @@ extern	vm_paddr_t phys_avail[];
 extern	vm_offset_t virtual_avail;
 extern	vm_offset_t virtual_end;
 
-extern	vm_paddr_t msgbuf_phys;
-
 #ifdef PMAP_STATS
 
 SYSCTL_DECL(_debug_pmap_stats);

Modified: stable/7/sys/sparc64/sparc64/machdep.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/machdep.c	Sun Sep 20 17:46:56 2009	(r197365)
+++ stable/7/sys/sparc64/sparc64/machdep.c	Sun Sep 20 18:53:40 2009	(r197366)
@@ -242,6 +242,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_l
 	char *env;
 	struct pcpu *pc;
 	vm_offset_t end;
+	vm_offset_t va;
 	caddr_t kmdp;
 	phandle_t child;
 	phandle_t root;
@@ -360,19 +361,28 @@ sparc64_init(caddr_t mdp, u_long o1, u_l
 	 * Panic if there is no metadata.  Most likely the kernel was booted
 	 * directly, instead of through loader(8).
 	 */
-	if (mdp == NULL || kmdp == NULL) {
-		printf("sparc64_init: no loader metadata.\n"
+	if (mdp == NULL || kmdp == NULL || end == 0 ||
+	    kernel_tlb_slots == 0 || kernel_tlbs == NULL) {
+		printf("sparc64_init: missing loader metadata.\n"
 		    "This probably means you are not using loader(8).\n");
 		panic("sparc64_init");
 	}
 
 	/*
-	 * Sanity check the kernel end, which is important.
-	 */
-	if (end == 0) {
-		printf("sparc64_init: warning, kernel end not specified.\n"
-		    "Attempting to continue anyway.\n");
-		end = (vm_offset_t)_end;
+	 * Work around the broken loader behavior of not demapping no
+	 * longer used kernel TLB slots when unloading the kernel or
+	 * modules.
+	 */
+	for (va = KERNBASE + (kernel_tlb_slots - 1) * PAGE_SIZE_4M;
+	    va >= roundup2(end, PAGE_SIZE_4M); va -= PAGE_SIZE_4M) {
+		printf("demapping unused kernel TLB slot (va %#lx - %#lx)\n",
+		    va, va + PAGE_SIZE_4M - 1);
+		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
+		    ASI_DMMU_DEMAP, 0);
+		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
+		    ASI_IMMU_DEMAP, 0);
+		flush(KERNBASE);
+		kernel_tlb_slots--;
 	}
 
 	/*
@@ -421,7 +431,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_l
 	/*
 	 * Initialize virtual memory and calculate physmem.
 	 */
-	pmap_bootstrap(end);
+	pmap_bootstrap();
 
 	/*
 	 * Initialize tunables.

Modified: stable/7/sys/sparc64/sparc64/pmap.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/pmap.c	Sun Sep 20 17:46:56 2009	(r197365)
+++ stable/7/sys/sparc64/sparc64/pmap.c	Sun Sep 20 18:53:40 2009	(r197366)
@@ -119,10 +119,9 @@ __FBSDID("$FreeBSD$");
 extern struct mtx sched_lock;
 
 /*
- * Virtual and physical address of message buffer
+ * Virtual address of message buffer
  */
 struct msgbuf *msgbufp;
-vm_paddr_t msgbuf_phys;
 
 /*
  * Map of physical memory reagions
@@ -277,7 +276,7 @@ om_cmp(const void *a, const void *b)
  * Bootstrap the system enough to run with virtual memory.
  */
 void
-pmap_bootstrap(vm_offset_t ekva)
+pmap_bootstrap(void)
 {
 	struct pmap *pm;
 	struct tte *tp;
@@ -365,8 +364,8 @@ pmap_bootstrap(vm_offset_t ekva)
 	/*
 	 * Allocate and map the message buffer.
 	 */
-	msgbuf_phys = pmap_bootstrap_alloc(MSGBUF_SIZE);
-	msgbufp = (struct msgbuf *)TLB_PHYS_TO_DIRECT(msgbuf_phys);
+	pa = pmap_bootstrap_alloc(MSGBUF_SIZE);
+	msgbufp = (struct msgbuf *)TLB_PHYS_TO_DIRECT(pa);
 
 	/*
 	 * Patch the virtual address and the tsb mask into the trap table.
@@ -415,10 +414,11 @@ pmap_bootstrap(vm_offset_t ekva)
 	}
 
 	/*
-	 * Set the start and end of KVA.  The kernel is loaded at the first
-	 * available 4MB super page, so round up to the end of the page.
+	 * Set the start and end of KVA.  The kernel is loaded starting
+	 * at the first available 4MB super page, so we advance to the
+	 * end of the last one used for it.
 	 */
-	virtual_avail = roundup2(ekva, PAGE_SIZE_4M);
+	virtual_avail = KERNBASE + kernel_tlb_slots * PAGE_SIZE_4M;
 	virtual_end = vm_max_kernel_address;
 	kernel_vm_end = vm_max_kernel_address;
 
@@ -438,8 +438,7 @@ pmap_bootstrap(vm_offset_t ekva)
 	 * coloured properly, since we're allocating from phys_avail so the
 	 * memory won't have an associated vm_page_t.
 	 */
-	pa = pmap_bootstrap_alloc(roundup(KSTACK_PAGES, DCACHE_COLORS) *
-	    PAGE_SIZE);
+	pa = pmap_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE);
 	kstack0_phys = pa;
 	virtual_avail += roundup(KSTACK_GUARD_PAGES, DCACHE_COLORS) *
 	    PAGE_SIZE;
@@ -582,7 +581,7 @@ pmap_bootstrap_alloc(vm_size_t size)
 	vm_paddr_t pa;
 	int i;
 
-	size = round_page(size);
+	size = roundup(size, PAGE_SIZE * DCACHE_COLORS);
 	for (i = 0; phys_avail[i + 1] != 0; i += 2) {
 		if (phys_avail[i + 1] - phys_avail[i] < size)
 			continue;
@@ -942,7 +941,7 @@ pmap_kremove_flags(vm_offset_t va)
 	struct tte *tp;
 
 	tp = tsb_kvtotte(va);
-	CTR3(KTR_PMAP, "pmap_kremove: va=%#lx tp=%p data=%#lx", va, tp,
+	CTR3(KTR_PMAP, "pmap_kremove_flags: va=%#lx tp=%p data=%#lx", va, tp,
 	    tp->tte_data);
 	TTE_ZERO(tp);
 }
@@ -1345,7 +1344,7 @@ pmap_enter_locked(pmap_t pm, vm_offset_t
 	}
 
 	CTR6(KTR_PMAP,
-	    "pmap_enter: ctx=%p m=%p va=%#lx pa=%#lx prot=%#x wired=%d",
+	    "pmap_enter_locked: ctx=%p m=%p va=%#lx pa=%#lx prot=%#x wired=%d",
 	    pm->pm_context[curcpu], m, va, pa, prot, wired);
 
 	/*
@@ -1353,7 +1352,7 @@ pmap_enter_locked(pmap_t pm, vm_offset_t
 	 * changed, must be protection or wiring change.
 	 */
 	if ((tp = tsb_tte_lookup(pm, va)) != NULL && TTE_GET_PA(tp) == pa) {
-		CTR0(KTR_PMAP, "pmap_enter: update");
+		CTR0(KTR_PMAP, "pmap_enter_locked: update");
 		PMAP_STATS_INC(pmap_nenter_update);
 
 		/*
@@ -1410,12 +1409,12 @@ pmap_enter_locked(pmap_t pm, vm_offset_t
 		 * phsyical address, delete the old mapping.
 		 */
 		if (tp != NULL) {
-			CTR0(KTR_PMAP, "pmap_enter: replace");
+			CTR0(KTR_PMAP, "pmap_enter_locked: replace");
 			PMAP_STATS_INC(pmap_nenter_replace);
 			pmap_remove_tte(pm, NULL, tp, va);
 			tlb_page_demap(pm, va);
 		} else {
-			CTR0(KTR_PMAP, "pmap_enter: new");
+			CTR0(KTR_PMAP, "pmap_enter_locked: new");
 			PMAP_STATS_INC(pmap_nenter_new);
 		}
 
From marius at FreeBSD.org  Sun Sep 20 18:59:30 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Sun Sep 20 18:59:37 2009
Subject: svn commit: r197367 - in stable/7/sys: . contrib/pf dev/pci
	sparc64/include
Message-ID: <200909201859.n8KIxUq2065155@svn.freebsd.org>

Author: marius
Date: Sun Sep 20 18:59:30 2009
New Revision: 197367
URL: http://svn.freebsd.org/changeset/base/197367

Log:
  MFC: r195808
  
  Add a MD __PCI_BAR_ZERO_VALID which denotes that BARs containing 0
  actually specify valid bases that should be treated just as normal.
  The PCI specifications have no indication that 0 would be a magic value
  indicating a disabled BAR as commonly used on at least amd64 and i386
  but not sparc64. It's unclear what to do in pci_delete_resource()
  instead of writing 0 to a BAR though as there's no (other) way do
  disable individual BARs so its decoding is left enabled in case of
  __PCI_BAR_ZERO_VALID for now.
  
  Approved by:	jhb

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/pci/pci.c
  stable/7/sys/sparc64/include/param.h

Modified: stable/7/sys/dev/pci/pci.c
==============================================================================
--- stable/7/sys/dev/pci/pci.c	Sun Sep 20 18:53:40 2009	(r197366)
+++ stable/7/sys/dev/pci/pci.c	Sun Sep 20 18:59:30 2009	(r197367)
@@ -2337,7 +2337,7 @@ pci_add_map(device_t bus, device_t dev, 
 {
 	pci_addr_t base, map, testval;
 	pci_addr_t start, end, count;
-	int barlen, maprange, mapsize, type;
+	int barlen, basezero, maprange, mapsize, type;
 	uint16_t cmd;
 	struct resource *res;
 
@@ -2350,6 +2350,11 @@ pci_add_map(device_t bus, device_t dev, 
 		type = SYS_RES_IOPORT;
 	mapsize = pci_mapsize(testval);
 	base = pci_mapbase(map);
+#ifdef __PCI_BAR_ZERO_VALID
+	basezero = 0;
+#else
+	basezero = base == 0;
+#endif
 	maprange = pci_maprange(map);
 	barlen = maprange == 64 ? 2 : 1;
 
@@ -2378,17 +2383,17 @@ pci_add_map(device_t bus, device_t dev, 
 	}
 
 	/*
-	 * If base is 0, then we have problems.  It is best to ignore
-	 * such entries for the moment.  These will be allocated later if
-	 * the driver specifically requests them.  However, some
-	 * removable busses look better when all resources are allocated,
-	 * so allow '0' to be overriden.
+	 * If base is 0, then we have problems if this architecture does
+	 * not allow that.  It is best to ignore such entries for the
+	 * moment.  These will be allocated later if the driver specifically
+	 * requests them.  However, some removable busses look better when
+	 * all resources are allocated, so allow '0' to be overriden.
 	 *
 	 * Similarly treat maps whose values is the same as the test value
 	 * read back.  These maps have had all f's written to them by the
 	 * BIOS in an attempt to disable the resources.
 	 */
-	if (!force && (base == 0 || map == testval))
+	if (!force && (basezero || map == testval))
 		return (barlen);
 	if ((u_long)base != base) {
 		device_printf(bus,
@@ -2425,7 +2430,7 @@ pci_add_map(device_t bus, device_t dev, 
 	}
 
 	count = 1 << mapsize;
-	if (base == 0 || base == pci_mapbase(testval)) {
+	if (basezero || base == pci_mapbase(testval)) {
 		start = 0;	/* Let the parent decide. */
 		end = ~0ULL;
 	} else {
@@ -3669,6 +3674,7 @@ pci_delete_resource(device_t dev, device
 			return;
 		}
 
+#ifndef __PCI_BAR_ZERO_VALID
 		/*
 		 * If this is a BAR, clear the BAR so it stops
 		 * decoding before releasing the resource.
@@ -3679,6 +3685,7 @@ pci_delete_resource(device_t dev, device
 			pci_write_bar(child, rid, 0);
 			break;
 		}
+#endif
 		bus_release_resource(dev, type, rid, rle->res);
 	}
 	resource_list_delete(rl, type, rid);

Modified: stable/7/sys/sparc64/include/param.h
==============================================================================
--- stable/7/sys/sparc64/include/param.h	Sun Sep 20 18:53:40 2009	(r197366)
+++ stable/7/sys/sparc64/include/param.h	Sun Sep 20 18:59:30 2009	(r197367)
@@ -48,6 +48,8 @@
 
 #ifndef _NO_NAMESPACE_POLLUTION
 
+#define __PCI_BAR_ZERO_VALID
+
 #ifndef _MACHINE_PARAM_H_
 #define	_MACHINE_PARAM_H_
 
From emaste at FreeBSD.org  Tue Sep 22 23:11:24 2009
From: emaste at FreeBSD.org (Ed Maste)
Date: Tue Sep 22 23:11:30 2009
Subject: svn commit: r197422 - in stable/7/sys: . contrib/pf kern sys
Message-ID: <200909222311.n8MNBN5A035351@svn.freebsd.org>

Author: emaste
Date: Tue Sep 22 23:11:23 2009
New Revision: 197422
URL: http://svn.freebsd.org/changeset/base/197422

Log:
  MFC r195134, r195135, r195191
  
  r195134, r195134:
    Add a complement to FIONREAD, called FIONWRITE, which returns the
    number of bytes not yet properly disposed of.  Implement it for
    all sockets.
  
  r195191:
    Add FIONSPACE from NetBSD.  FIONSPACE is provided so that programs
    may easily determine how much space is left in the send queue;
    they do not need to know the send queue size.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/kern/sys_socket.c
  stable/7/sys/sys/filio.h

Modified: stable/7/sys/kern/sys_socket.c
==============================================================================
--- stable/7/sys/kern/sys_socket.c	Tue Sep 22 22:23:52 2009	(r197421)
+++ stable/7/sys/kern/sys_socket.c	Tue Sep 22 23:11:23 2009	(r197422)
@@ -161,6 +161,19 @@ soo_ioctl(struct file *fp, u_long cmd, v
 		*(int *)data = so->so_rcv.sb_cc;
 		break;
 
+	case FIONWRITE:
+		/* Unlocked read. */
+		*(int *)data = so->so_snd.sb_cc;
+		break;
+
+	case FIONSPACE:
+		if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc) ||
+		    (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
+			*(int *)data = 0;
+		else
+			*(int *)data = sbspace(&so->so_snd);
+		break;
+
 	case FIOSETOWN:
 		error = fsetown(*(int *)data, &so->so_sigio);
 		break;

Modified: stable/7/sys/sys/filio.h
==============================================================================
--- stable/7/sys/sys/filio.h	Tue Sep 22 22:23:52 2009	(r197421)
+++ stable/7/sys/sys/filio.h	Tue Sep 22 23:11:23 2009	(r197422)
@@ -55,6 +55,8 @@ struct fiodgname_arg {
 	void	*buf;
 };
 #define	FIODGNAME	_IOW('f', 120, struct fiodgname_arg) /* get dev. name */
+#define	FIONWRITE	_IOR('f', 119, int)	/* get # bytes (yet) to write */
+#define	FIONSPACE	_IOR('f', 118, int)	/* get space in send queue */
 /* Handle lseek SEEK_DATA and SEEK_HOLE for holey file knowledge. */
 #define	FIOSEEKDATA	_IOWR('f', 97, off_t)	/* SEEK_DATA */
 #define	FIOSEEKHOLE	_IOWR('f', 98, off_t)	/* SEEK_HOLE */
From emaste at FreeBSD.org  Wed Sep 23 00:31:09 2009
From: emaste at FreeBSD.org (Ed Maste)
Date: Wed Sep 23 00:31:49 2009
Subject: svn commit: r197423 - stable/7/usr.bin/gcore
Message-ID: <200909230031.n8N0V8bF036913@svn.freebsd.org>

Author: emaste
Date: Wed Sep 23 00:31:08 2009
New Revision: 197423
URL: http://svn.freebsd.org/changeset/base/197423

Log:
  MFC r180603:
  
    Use %zd for size_t.  With this gcore(1) is WARNS=6 clean.

Modified:
  stable/7/usr.bin/gcore/   (props changed)
  stable/7/usr.bin/gcore/elfcore.c

Modified: stable/7/usr.bin/gcore/elfcore.c
==============================================================================
--- stable/7/usr.bin/gcore/elfcore.c	Tue Sep 22 23:11:23 2009	(r197422)
+++ stable/7/usr.bin/gcore/elfcore.c	Wed Sep 23 00:31:08 2009	(r197423)
@@ -158,7 +158,7 @@ elf_coredump(int efd __unused, int fd, p
 				err(1, "read from %s", memname);
 			if ((size_t)ngot < nwant)
 				errx(1, "short read from %s:"
-				    " wanted %d, got %d", memname,
+				    " wanted %zd, got %zd", memname,
 				    nwant, ngot);
 			ngot = write(fd, buf, nwant);
 			if (ngot == -1)
@@ -414,7 +414,7 @@ readhdrinfo(pid_t pid, prstatus_t *statu
 	if ((n = read(fd, &status->pr_reg, sizeof status->pr_reg)) == -1)
 		err(1, "read error from %s", name);
 	if ((size_t)n < sizeof(status->pr_reg))
-		errx(1, "short read from %s: wanted %u, got %d", name,
+		errx(1, "short read from %s: wanted %zd, got %d", name,
 		    sizeof status->pr_reg, n);
 	close(fd);
 
@@ -425,7 +425,7 @@ readhdrinfo(pid_t pid, prstatus_t *statu
 	if ((n = read(fd, fpregset, sizeof *fpregset)) == -1)
 		err(1, "read error from %s", name);
 	if ((size_t)n < sizeof(*fpregset))
-		errx(1, "short read from %s: wanted %u, got %d", name,
+		errx(1, "short read from %s: wanted %zd, got %d", name,
 		    sizeof *fpregset, n);
 	close(fd);
 
From attilio at FreeBSD.org  Thu Sep 24 09:08:23 2009
From: attilio at FreeBSD.org (Attilio Rao)
Date: Thu Sep 24 09:08:39 2009
Subject: svn commit: r197453 - in stable/7/sys: . contrib/pf kern
Message-ID: <200909240908.n8O98Ncg091256@svn.freebsd.org>

Author: attilio
Date: Thu Sep 24 09:08:22 2009
New Revision: 197453
URL: http://svn.freebsd.org/changeset/base/197453

Log:
  MFC r197223:
  Fix a deadlock in sched_switch_migrate given by the runqueues being not
  locked at once together when doing the switch.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/kern/sched_ule.c

Modified: stable/7/sys/kern/sched_ule.c
==============================================================================
--- stable/7/sys/kern/sched_ule.c	Thu Sep 24 08:35:17 2009	(r197452)
+++ stable/7/sys/kern/sched_ule.c	Thu Sep 24 09:08:22 2009	(r197453)
@@ -1822,18 +1822,24 @@ sched_switch_migrate(struct tdq *tdq, st
 	 */
 	spinlock_enter();
 	thread_block_switch(td);	/* This releases the lock on tdq. */
-	TDQ_LOCK(tdn);
-	tdq_add(tdn, td, flags);
-	tdq_notify(td->td_sched);
-	/*
-	 * After we unlock tdn the new cpu still can't switch into this
-	 * thread until we've unblocked it in cpu_switch().  The lock
-	 * pointers may match in the case of HTT cores.  Don't unlock here
-	 * or we can deadlock when the other CPU runs the IPI handler.
+
+	/*
+	 * Acquire both run-queue locks before placing the thread on the new
+	 * run-queue to avoid deadlocks created by placing a thread with a
+	 * blocked lock on the run-queue of a remote processor.  The deadlock
+	 * occurs when a third processor attempts to lock the two queues in
+	 * question while the target processor is spinning with its own
+	 * run-queue lock held while waiting for the blocked lock to clear.
 	 */
-	if (TDQ_LOCKPTR(tdn) != TDQ_LOCKPTR(tdq)) {
-		TDQ_UNLOCK(tdn);
+	if (TDQ_LOCKPTR(tdn) == TDQ_LOCKPTR(tdq)) {
 		TDQ_LOCK(tdq);
+		tdq_add(tdn, td, flags);
+		tdq_notify(td->td_sched);
+	} else {
+		tdq_lock_pair(tdn, tdq);
+		tdq_add(tdn, td, flags);
+		tdq_notify(td->td_sched);
+		TDQ_UNLOCK(tdn);
 	}
 	spinlock_exit();
 #endif
From jhb at FreeBSD.org  Thu Sep 24 14:30:17 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Thu Sep 24 14:30:29 2009
Subject: svn commit: r197456 - stable/7/release/doc/en_US.ISO8859-1/hardware
Message-ID: <200909241430.n8OEUHDl099333@svn.freebsd.org>

Author: jhb
Date: Thu Sep 24 14:30:17 2009
New Revision: 197456
URL: http://svn.freebsd.org/changeset/base/197456

Log:
  Manually remove mergeinfo from this file.  For some reason svn didn't elide
  this automatically as it should have during the previous revision.

Modified:
  stable/7/release/doc/en_US.ISO8859-1/hardware/article.sgml   (props changed)
From marck at FreeBSD.org  Fri Sep 25 07:57:29 2009
From: marck at FreeBSD.org (Dmitry Morozovsky)
Date: Fri Sep 25 07:57:36 2009
Subject: svn commit: r197479 - in stable/7/sys: .
	cddl/contrib/opensolaris/uts/common/fs/zfs contrib/pf
Message-ID: <200909250757.n8P7vTih021746@svn.freebsd.org>

Author: marck (doc committer)
Date: Fri Sep 25 07:57:28 2009
New Revision: 197479
URL: http://svn.freebsd.org/changeset/base/197479

Log:
  MFC r197150:
  
    There is a bug where mze_insert() can trigger an assert() of inserting
    the same entry twice. This bug is not fixed yet, but leads to situation
    where when try to access corrupted directory the kernel will panic.
    Until the bug is properly fixed, try to recover from it and log that it
    happened.
  
    OpenSolaris bug:	6709336
  
  Approved by:	pjd

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c	Fri Sep 25 02:19:57 2009	(r197478)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c	Fri Sep 25 07:57:28 2009	(r197479)
@@ -181,10 +181,11 @@ mze_compare(const void *arg1, const void
 	return (0);
 }
 
-static void
+static int
 mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
 {
 	mzap_ent_t *mze;
+	avl_index_t idx;
 
 	ASSERT(zap->zap_ismicro);
 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
@@ -194,7 +195,12 @@ mze_insert(zap_t *zap, int chunkid, uint
 	mze->mze_chunkid = chunkid;
 	mze->mze_hash = hash;
 	mze->mze_phys = *mzep;
-	avl_add(&zap->zap_m.zap_avl, mze);
+	if (avl_find(&zap->zap_m.zap_avl, mze, &idx) != NULL) {
+		kmem_free(mze, sizeof (mzap_ent_t));
+		return (EEXIST);
+	}
+	avl_insert(&zap->zap_m.zap_avl, mze, idx);
+	return (0);
 }
 
 static mzap_ent_t *
@@ -329,10 +335,15 @@ mzap_open(objset_t *os, uint64_t obj, dm
 			if (mze->mze_name[0]) {
 				zap_name_t *zn;
 
-				zap->zap_m.zap_num_entries++;
 				zn = zap_name_alloc(zap, mze->mze_name,
 				    MT_EXACT);
-				mze_insert(zap, i, zn->zn_hash, mze);
+				if (mze_insert(zap, i, zn->zn_hash, mze) == 0)
+					zap->zap_m.zap_num_entries++;
+				else {
+					printf("ZFS WARNING: Duplicated ZAP "
+					    "entry detected (%s).",
+					    mze->mze_name);
+				}
 				zap_name_free(zn);
 			}
 		}
@@ -771,7 +782,7 @@ again:
 			if (zap->zap_m.zap_alloc_next ==
 			    zap->zap_m.zap_num_chunks)
 				zap->zap_m.zap_alloc_next = 0;
-			mze_insert(zap, i, zn->zn_hash, mze);
+			VERIFY(0 == mze_insert(zap, i, zn->zn_hash, mze));
 			return;
 		}
 	}
From jhb at FreeBSD.org  Fri Sep 25 14:58:31 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Fri Sep 25 14:59:41 2009
Subject: svn commit: r197483 - in stable/7/sys: . contrib/pf dev/pci
Message-ID: <200909251458.n8PEwURd031715@svn.freebsd.org>

Author: jhb
Date: Fri Sep 25 14:58:30 2009
New Revision: 197483
URL: http://svn.freebsd.org/changeset/base/197483

Log:
  MFC 197406:
  Don't reread the command register to see if enabling I/O or memory
  decoding "took".  Other OS's that I checked do not do this and it breaks
  some amdpm(4) devices.  Prior to 7.2 we did not honor the error returned
  when this failed anyway, so this in effect restores previous behavior.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/pci/pci.c

Modified: stable/7/sys/dev/pci/pci.c
==============================================================================
--- stable/7/sys/dev/pci/pci.c	Fri Sep 25 14:58:00 2009	(r197482)
+++ stable/7/sys/dev/pci/pci.c	Fri Sep 25 14:58:30 2009	(r197483)
@@ -2134,62 +2134,38 @@ pci_disable_busmaster_method(device_t de
 int
 pci_enable_io_method(device_t dev, device_t child, int space)
 {
-	uint16_t command;
 	uint16_t bit;
-	char *error;
-
-	bit = 0;
-	error = NULL;
 
 	switch(space) {
 	case SYS_RES_IOPORT:
 		bit = PCIM_CMD_PORTEN;
-		error = "port";
 		break;
 	case SYS_RES_MEMORY:
 		bit = PCIM_CMD_MEMEN;
-		error = "memory";
 		break;
 	default:
 		return (EINVAL);
 	}
 	pci_set_command_bit(dev, child, bit);
-	/* Some devices seem to need a brief stall here, what do to? */
-	command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
-	if (command & bit)
-		return (0);
-	device_printf(child, "failed to enable %s mapping!\n", error);
-	return (ENXIO);
+	return (0);
 }
 
 int
 pci_disable_io_method(device_t dev, device_t child, int space)
 {
-	uint16_t command;
 	uint16_t bit;
-	char *error;
-
-	bit = 0;
-	error = NULL;
 
 	switch(space) {
 	case SYS_RES_IOPORT:
 		bit = PCIM_CMD_PORTEN;
-		error = "port";
 		break;
 	case SYS_RES_MEMORY:
 		bit = PCIM_CMD_MEMEN;
-		error = "memory";
 		break;
 	default:
 		return (EINVAL);
 	}
 	pci_clear_command_bit(dev, child, bit);
-	command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
-	if (command & bit) {
-		device_printf(child, "failed to disable %s mapping!\n", error);
-		return (ENXIO);
-	}
 	return (0);
 }
 
From jhb at FreeBSD.org  Fri Sep 25 15:08:52 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Fri Sep 25 15:09:09 2009
Subject: svn commit: r197485 - in stable/7/sys: . amd64/amd64 contrib/pf
	i386/i386
Message-ID: <200909251508.n8PF8p0G032024@svn.freebsd.org>

Author: jhb
Date: Fri Sep 25 15:08:51 2009
New Revision: 197485
URL: http://svn.freebsd.org/changeset/base/197485

Log:
  MFC 197410:
  - Split the logic to parse an SMAP entry out into a separate function on
    amd64 similar to i386.  This fixes a bug on amd64 where overlapping
    entries would not cause the SMAP parsing to stop.
  - Change the SMAP parsing code to do a sorted insertion into physmap[]
    instead of an append to support systems with out-of-order SMAP entries.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/machdep.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/i386/i386/machdep.c

Modified: stable/7/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/machdep.c	Fri Sep 25 15:08:26 2009	(r197484)
+++ stable/7/sys/amd64/amd64/machdep.c	Fri Sep 25 15:08:51 2009	(r197485)
@@ -862,6 +862,77 @@ isa_irq_pending(void)
 
 u_int basemem;
 
+static int
+add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
+{
+	int i, insert_idx, physmap_idx;
+
+	physmap_idx = *physmap_idxp;
+
+	if (boothowto & RB_VERBOSE)
+		printf("SMAP type=%02x base=%016lx len=%016lx\n",
+		    smap->type, smap->base, smap->length);
+
+	if (smap->type != SMAP_TYPE_MEMORY)
+		return (1);
+
+	if (smap->length == 0)
+		return (0);
+
+	/*
+	 * Find insertion point while checking for overlap.  Start off by
+	 * assuming the new entry will be added to the end.
+	 */
+	insert_idx = physmap_idx + 2;
+	for (i = 0; i <= physmap_idx; i += 2) {
+		if (smap->base < physmap[i + 1]) {
+			if (smap->base + smap->length <= physmap[i]) {
+				insert_idx = i;
+				break;
+			}
+			if (boothowto & RB_VERBOSE)
+				printf(
+		    "Overlapping memory regions, ignoring second region\n");
+			return (1);
+		}
+	}
+
+	/* See if we can prepend to the next entry. */
+	if (insert_idx <= physmap_idx &&
+	    smap->base + smap->length == physmap[insert_idx]) {
+		physmap[insert_idx] = smap->base;
+		return (1);
+	}
+
+	/* See if we can append to the previous entry. */
+	if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+		physmap[insert_idx - 1] += smap->length;
+		return (1);
+	}
+
+	physmap_idx += 2;
+	*physmap_idxp = physmap_idx;
+	if (physmap_idx == PHYSMAP_SIZE) {
+		printf(
+		"Too many segments in the physical address map, giving up\n");
+		return (0);
+	}
+
+	/*
+	 * Move the last 'N' entries down to make room for the new
+	 * entry if needed.
+	 */
+	for (i = physmap_idx; i > insert_idx; i -= 2) {
+		physmap[i] = physmap[i - 2];
+		physmap[i + 1] = physmap[i - 1];
+	}
+
+	/* Insert the new entry. */
+	physmap[insert_idx] = smap->base;
+	physmap[insert_idx + 1] = smap->base + smap->length;
+	return (1);
+}
+
 /*
  * Populate the (physmap) array with base/bound pairs describing the
  * available physical memory in the system, then test this memory and
@@ -905,40 +976,9 @@ getmemsize(caddr_t kmdp, u_int64_t first
 	smapsize = *((u_int32_t *)smapbase - 1);
 	smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
 
-	for (smap = smapbase; smap < smapend; smap++) {
-		if (boothowto & RB_VERBOSE)
-			printf("SMAP type=%02x base=%016lx len=%016lx\n",
-			    smap->type, smap->base, smap->length);
-
-		if (smap->type != SMAP_TYPE_MEMORY)
-			continue;
-
-		if (smap->length == 0)
-			continue;
-
-		for (i = 0; i <= physmap_idx; i += 2) {
-			if (smap->base < physmap[i + 1]) {
-				if (boothowto & RB_VERBOSE)
-					printf(
-	"Overlapping or non-monotonic memory region, ignoring second region\n");
-				continue;
-			}
-		}
-
-		if (smap->base == physmap[physmap_idx + 1]) {
-			physmap[physmap_idx + 1] += smap->length;
-			continue;
-		}
-
-		physmap_idx += 2;
-		if (physmap_idx == PHYSMAP_SIZE) {
-			printf(
-		"Too many segments in the physical address map, giving up\n");
+	for (smap = smapbase; smap < smapend; smap++)
+		if (!add_smap_entry(smap, physmap, &physmap_idx))
 			break;
-		}
-		physmap[physmap_idx] = smap->base;
-		physmap[physmap_idx + 1] = smap->base + smap->length;
-	}
 
 	/*
 	 * Find the 'base memory' segment for SMP

Modified: stable/7/sys/i386/i386/machdep.c
==============================================================================
--- stable/7/sys/i386/i386/machdep.c	Fri Sep 25 15:08:26 2009	(r197484)
+++ stable/7/sys/i386/i386/machdep.c	Fri Sep 25 15:08:51 2009	(r197485)
@@ -1653,7 +1653,7 @@ sdtossd(sd, ssd)
 static int
 add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
 {
-	int i, physmap_idx;
+	int i, insert_idx, physmap_idx;
 
 	physmap_idx = *physmap_idxp;
 	
@@ -1675,17 +1675,34 @@ add_smap_entry(struct bios_smap *smap, v
 	}
 #endif
 
+	/*
+	 * Find insertion point while checking for overlap.  Start off by
+	 * assuming the new entry will be added to the end.
+	 */
+	insert_idx = physmap_idx + 2;
 	for (i = 0; i <= physmap_idx; i += 2) {
 		if (smap->base < physmap[i + 1]) {
+			if (smap->base + smap->length <= physmap[i]) {
+				insert_idx = i;
+				break;
+			}
 			if (boothowto & RB_VERBOSE)
 				printf(
-	"Overlapping or non-monotonic memory region, ignoring second region\n");
+		    "Overlapping memory regions, ignoring second region\n");
 			return (1);
 		}
 	}
 
-	if (smap->base == physmap[physmap_idx + 1]) {
-		physmap[physmap_idx + 1] += smap->length;
+	/* See if we can prepend to the next entry. */
+	if (insert_idx <= physmap_idx &&
+	    smap->base + smap->length == physmap[insert_idx]) {
+		physmap[insert_idx] = smap->base;
+		return (1);
+	}
+
+	/* See if we can append to the previous entry. */
+	if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+		physmap[insert_idx - 1] += smap->length;
 		return (1);
 	}
 
@@ -1696,8 +1713,19 @@ add_smap_entry(struct bios_smap *smap, v
 		"Too many segments in the physical address map, giving up\n");
 		return (0);
 	}
-	physmap[physmap_idx] = smap->base;
-	physmap[physmap_idx + 1] = smap->base + smap->length;
+
+	/*
+	 * Move the last 'N' entries down to make room for the new
+	 * entry if needed.
+	 */
+	for (i = physmap_idx; i > insert_idx; i -= 2) {
+		physmap[i] = physmap[i - 2];
+		physmap[i + 1] = physmap[i - 1];
+	}
+
+	/* Insert the new entry. */
+	physmap[insert_idx] = smap->base;
+	physmap[insert_idx + 1] = smap->base + smap->length;
 	return (1);
 }
 
From jhb at FreeBSD.org  Fri Sep 25 15:14:33 2009
From: jhb at FreeBSD.org (John Baldwin)
Date: Fri Sep 25 15:14:50 2009
Subject: svn commit: r197487 - in stable/7/sys: . contrib/pf dev/acpi_support
Message-ID: <200909251514.n8PFEXRK032225@svn.freebsd.org>

Author: jhb
Date: Fri Sep 25 15:14:33 2009
New Revision: 197487
URL: http://svn.freebsd.org/changeset/base/197487

Log:
  MFC 197415:
  The elements in the component arrays may be direct Package objects rather
  than references to objects.  In that case, simply use the Package directly.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/acpi_support/acpi_aiboost.c

Modified: stable/7/sys/dev/acpi_support/acpi_aiboost.c
==============================================================================
--- stable/7/sys/dev/acpi_support/acpi_aiboost.c	Fri Sep 25 15:14:11 2009	(r197486)
+++ stable/7/sys/dev/acpi_support/acpi_aiboost.c	Fri Sep 25 15:14:33 2009	(r197487)
@@ -44,7 +44,6 @@ ACPI_MODULE_NAME("AIBOOST")
 
 #define DESCSTRLEN 32
 struct acpi_aiboost_element{
-	ACPI_HANDLE h;
 	uint32_t id;
 	char desc[DESCSTRLEN];
 };
@@ -125,22 +124,23 @@ static ACPI_STATUS acpi_aiboost_getcompo
 	
 	for(i = 1 ; i < o->Package.Count; i++){
 		elem = &o->Package.Elements[i];
-		if(elem->Type != ACPI_TYPE_ANY){
-			printf("NOREF\n");
-			goto error;
-		}
-		c->elem[ i - 1].h = elem->Reference.Handle;
-
-		buf2.Pointer = NULL;
-		buf2.Length = ACPI_ALLOCATE_BUFFER;
-		
-		status = AcpiEvaluateObject(c->elem[i - 1].h, NULL, NULL,
-					    &buf2);
-		if(ACPI_FAILURE(status)){
-			printf("FETCH OBJECT\n");
+		if (elem->Type == ACPI_TYPE_ANY) {
+			buf2.Pointer = NULL;
+			buf2.Length = ACPI_ALLOCATE_BUFFER;
+
+			status = AcpiEvaluateObject(elem->Reference.Handle,
+			    NULL, NULL, &buf2);
+			if (ACPI_FAILURE(status)){
+				printf("FETCH OBJECT\n");
+				goto error;
+			}
+			subobj = buf2.Pointer;
+		} else if (elem->Type == ACPI_TYPE_PACKAGE)
+			subobj = elem;
+		else {
+			printf("NO PACKAGE\n");
 			goto error;
 		}
-		subobj = buf2.Pointer;
 		if(ACPI_FAILURE(acpi_PkgInt32(subobj,0, &c->elem[i -1].id))){
 			printf("ID FAILED\n");
 			goto error;
@@ -149,15 +149,17 @@ static ACPI_STATUS acpi_aiboost_getcompo
 				     sizeof(c->elem[i - 1].desc));
 		if(ACPI_FAILURE(status)){
 			if(status == E2BIG){
-				c->elem[i-1].desc[DESCSTRLEN-1] = 0;
+				c->elem[i - 1].desc[DESCSTRLEN-1] = 0;
 			}else{
 				printf("DESC FAILED %d\n", i-1);
 				goto error;
 			}
 		}
 		
-		if(buf2.Pointer)
-		  AcpiOsFree(buf2.Pointer);
+		if (buf2.Pointer) {
+			AcpiOsFree(buf2.Pointer);
+			buf2.Pointer = NULL;
+		}
 	}
 
 	if(buf.Pointer)
From marius at FreeBSD.org  Fri Sep 25 17:07:44 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Fri Sep 25 17:07:56 2009
Subject: svn commit: r197489 - in stable/7/sys: . contrib/pf dev/ata
Message-ID: <200909251707.n8PH7iJu034475@svn.freebsd.org>

Author: marius
Date: Fri Sep 25 17:07:43 2009
New Revision: 197489
URL: http://svn.freebsd.org/changeset/base/197489

Log:
  MFC: 197402
  
  - Add missing bus_dmamap_sync(9) calls for the work DMA map. Previously
    the work area was totally unsynchronized which means this driver only
    had a chance of working on x86 when no bounce buffers were involved,
    which isn't that likely given that support for 64-bit DMA is currently
    broken throughout ata(4).
  - Add necessary little-endian conversion of accesses to the work area,
    making this driver work on big-endian hosts. While at it, use the
    alignment-agnostic byte order encoders in order to be on the safe side.
  - Clear the reserved member of the SG list entries in order to be on the
    safe side. [1]
  
  Submitted by:	yongari [1]
  Reviewed by:	yongari

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ata/ata-chipset.c

Modified: stable/7/sys/dev/ata/ata-chipset.c
==============================================================================
--- stable/7/sys/dev/ata/ata-chipset.c	Fri Sep 25 16:45:27 2009	(r197488)
+++ stable/7/sys/dev/ata/ata-chipset.c	Fri Sep 25 17:07:43 2009	(r197489)
@@ -2690,6 +2690,8 @@ ata_marvell_edma_allocate(device_t dev)
 
     /* clear work area */
     bzero(ch->dma->work, 1024+256);
+    bus_dmamap_sync(ch->dma->work_tag, ch->dma->work_map,
+	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
     /* set legacy ATA resources */
     for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
@@ -2799,8 +2801,6 @@ ata_marvell_edma_begin_transaction(struc
     struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
     u_int32_t req_in;
     u_int8_t *bytep;
-    u_int16_t *wordp;
-    u_int32_t *quadp;
     int i, tag = 0x07;
     int dummy, error, slot;
 
@@ -2831,13 +2831,14 @@ ata_marvell_edma_begin_transaction(struc
     slot = (((req_in & ~0xfffffc00) >> 5) + 0) & 0x1f;
     bytep = (u_int8_t *)(ch->dma->work);
     bytep += (slot << 5);
-    wordp = (u_int16_t *)bytep;
-    quadp = (u_int32_t *)bytep;
 
     /* fill in this request */
-    quadp[0] = (long)ch->dma->sg_bus & 0xffffffff;
-    quadp[1] = (u_int64_t)ch->dma->sg_bus >> 32;
-    wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag<<1);
+    le32enc(bytep + 0 * sizeof(u_int32_t),
+	ch->dma->sg_bus & 0xffffffff);
+    le32enc(bytep + 1 * sizeof(u_int32_t),
+	(u_int64_t)ch->dma->sg_bus >> 32);
+    le16enc(bytep + 4 * sizeof(u_int16_t),
+	(request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag << 1));
 
     i = 10;
     bytep[i++] = (request->u.ata.count >> 8) & 0xff;
@@ -2866,6 +2867,9 @@ ata_marvell_edma_begin_transaction(struc
     bytep[i++] = request->u.ata.command;
     bytep[i++] = 0x90 | ATA_COMMAND;
 
+    bus_dmamap_sync(ch->dma->work_tag, ch->dma->work_map,
+	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
     /* enable EDMA machinery if needed */
     if (!(ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001)) {
 	ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000001);
@@ -2908,6 +2912,8 @@ ata_marvell_edma_end_transaction(struct 
 	slot = (((rsp_in & ~0xffffff00) >> 3)) & 0x1f;
 	rsp_out &= 0xffffff00;
 	rsp_out += (slot << 3);
+	bus_dmamap_sync(ch->dma->work_tag, ch->dma->work_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 	response = (struct ata_marvell_response *)
 		   (ch->dma->work + 1024 + (slot << 3));
 
@@ -2982,6 +2988,7 @@ ata_marvell_edma_dmasetprd(void *xsc, bu
 	prd[i].addrlo = htole32(segs[i].ds_addr);
 	prd[i].count = htole32(segs[i].ds_len);
 	prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32);
+	prd[i].reserved = 0;
     }
     prd[i - 1].count |= htole32(ATA_DMA_EOT);
     KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));
From marius at FreeBSD.org  Fri Sep 25 19:59:48 2009
From: marius at FreeBSD.org (Marius Strobl)
Date: Fri Sep 25 20:00:06 2009
Subject: svn commit: r197503 - in stable/7/sys: . contrib/pf dev/sound/pci
Message-ID: <200909251959.n8PJxm4v038447@svn.freebsd.org>

Author: marius
Date: Fri Sep 25 19:59:48 2009
New Revision: 197503
URL: http://svn.freebsd.org/changeset/base/197503

Log:
  MFC: r197401
  
  - According to Linux, the ALi M5451 can do 31-bit DMA instead of just
    30-bit like the reset of the controllers supported by this driver.
    Actually ALi M5451 can be setup up to generate 32-bit addresses by
    setting the 31st bit via the accompanying ISA bridge, which allows
    it to work in sparc64 machines whose IOMMU require at least 32-bit
    DMA. Even though other architectures would also benefit from 32-bit
    DMA, enabling this bit is limited to sparc64 as bus_dma(9) doesn't
    generally guarantee that a low address of BUS_SPACE_MAXADDR_32BIT
    results in a buffer in the 32-bit range.
  - According to Tatsuo YOKOGAWA's ali(4), the the DMA transfer size of
    ALi M5451 is fixed to 64k and in fact using the default size of 4k
    causes the chip to overrun the mapping, triggering uncorrectable
    DMA errors on sparc64.
  - The 4DWAVE DX and NX require the recording buffer to be 8-byte
    aligned so adjust the bus_dma_tag_create(9) accordingly.
  - Unlike the rest of the controllers supported by this driver, the
    ALi M5451 only has 32 hardware channels instead of 64 so limit the
    loop in tr_intr() accordingly. [1]
  
  Submitted by:	yongari [1]
  Reviewed by:	yongari (superset of what is committed)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/sound/pci/t4dwave.c

Modified: stable/7/sys/dev/sound/pci/t4dwave.c
==============================================================================
--- stable/7/sys/dev/sound/pci/t4dwave.c	Fri Sep 25 19:59:18 2009	(r197502)
+++ stable/7/sys/dev/sound/pci/t4dwave.c	Fri Sep 25 19:59:48 2009	(r197503)
@@ -41,18 +41,22 @@ SND_DECLARE_FILE("$FreeBSD$");
 #define SPA_PCI_ID	0x70181039
 
 #define TR_DEFAULT_BUFSZ 	0x1000
+/* For ALi M5451 the DMA transfer size appears to be fixed to 64k. */
+#define ALI_BUFSZ	0x10000
+#define TR_BUFALGN	0x8
 #define TR_TIMEOUT_CDC	0xffff
+#define TR_MAXHWCH	64
+#define ALI_MAXHWCH	32
 #define TR_MAXPLAYCH	4
+#define ALI_MAXPLAYCH	1
 /*
- * Though, it's not clearly documented in trident datasheet, trident
- * audio cards can't handle DMA addresses located above 1GB. The LBA
- * (loop begin address) register which holds DMA base address is 32bits
- * register.
- * But the MSB 2bits are used for other purposes(I guess it is really
- * bad idea). This effectivly limits the DMA address space up to 1GB.
+ * Though, it's not clearly documented in the 4DWAVE datasheet, the
+ * DX and NX chips can't handle DMA addresses located above 1GB as the
+ * LBA (loop begin address) register which holds the DMA base address
+ * is 32-bit, but the two MSBs are used for other purposes.
  */
-#define TR_MAXADDR	((1 << 30) - 1)
-
+#define TR_MAXADDR	((1U << 30) - 1)
+#define ALI_MAXADDR	((1U << 31) - 1)
 
 struct tr_info;
 
@@ -93,6 +97,7 @@ struct tr_info {
 
 	struct mtx *lock;
 
+	u_int32_t hwchns;
 	u_int32_t playchns;
 	unsigned int bufsz;
 
@@ -394,7 +399,10 @@ tr_wrch(struct tr_chinfo *ch)
 	ch->ec		&= 0x00000fff;
 	ch->alpha	&= 0x00000fff;
 	ch->delta	&= 0x0000ffff;
-	ch->lba		&= 0x3fffffff;
+	if (tr->type == ALI_PCI_ID)
+		ch->lba &= ALI_MAXADDR;
+	else
+		ch->lba &= TR_MAXADDR;
 
 	cr[1]=ch->lba;
 	cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol);
@@ -437,7 +445,10 @@ tr_rdch(struct tr_chinfo *ch)
 	snd_mtxunlock(tr->lock);
 
 
-	ch->lba=	(cr[1] & 0x3fffffff);
+	if (tr->type == ALI_PCI_ID)
+		ch->lba=(cr[1] & ALI_MAXADDR);
+	else
+		ch->lba=(cr[1] & TR_MAXADDR);
 	ch->fmc=	(cr[3] & 0x0000c000) >> 14;
 	ch->rvol=	(cr[3] & 0x00003f80) >> 7;
 	ch->cvol=	(cr[3] & 0x0000007f);
@@ -624,7 +635,6 @@ trrchan_setformat(kobj_t obj, void *data
 	tr_wr(tr, TR_REG_SBCTRL, i, 1);
 
 	return 0;
-
 }
 
 static int
@@ -725,7 +735,7 @@ tr_intr(void *p)
 	intsrc = tr_rd(tr, TR_REG_MISCINT, 4);
 	if (intsrc & TR_INT_ADDR) {
 		chnum = 0;
-		while (chnum < 64) {
+		while (chnum < tr->hwchns) {
 			mask = 0x00000001;
 			active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4);
 			bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4);
@@ -811,8 +821,13 @@ tr_pci_attach(device_t dev)
 	u_int32_t	data;
 	struct tr_info *tr;
 	struct ac97_info *codec = 0;
+	bus_addr_t	lowaddr;
 	int		i, dacn;
 	char 		status[SND_STATUSLEN];
+#ifdef __sparc64__
+	device_t	*children;
+	int		nchildren;
+#endif
 
 	tr = malloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO);
 	tr->type = pci_get_devid(dev);
@@ -830,7 +845,7 @@ tr_pci_attach(device_t dev)
 	} else {
 		switch (tr->type) {
 		case ALI_PCI_ID:
-			dacn = 1;
+			dacn = ALI_MAXPLAYCH;
 			break;
 		default:
 			dacn = TR_MAXPLAYCH;
@@ -855,8 +870,6 @@ tr_pci_attach(device_t dev)
 		goto bad;
 	}
 
-	tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ, 65536);
-
 	if (tr_init(tr) == -1) {
 		device_printf(dev, "unable to initialize the card\n");
 		goto bad;
@@ -875,12 +888,59 @@ tr_pci_attach(device_t dev)
 		goto bad;
 	}
 
-	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
+	if (tr->type == ALI_PCI_ID) {
+		/*
+		 * The M5451 generates 31 bit of DMA and in order to do
+		 * 32-bit DMA, the 31st bit can be set via its accompanying
+		 * ISA bridge.  Note that we can't predict whether bus_dma(9)
+		 * will actually supply us with a 32-bit buffer and even when
+		 * using a low address of BUS_SPACE_MAXADDR_32BIT for both
+		 * we might end up with the play buffer being in the 32-bit
+		 * range while the record buffer isn't or vice versa. So we
+		 * limit enabling the 31st bit to sparc64, where the IOMMU
+		 * guarantees that we're using a 32-bit address (and in turn
+		 * requires it).
+		 */
+		lowaddr = ALI_MAXADDR;
+#ifdef __sparc64__
+		if (device_get_children(device_get_parent(dev), &children,
+		    &nchildren) == 0) {
+			for (i = 0; i < nchildren; i++) {
+				if (pci_get_devid(children[i]) == 0x153310b9) {
+					lowaddr = BUS_SPACE_MAXADDR_32BIT;
+					data = pci_read_config(children[i],
+					    0x7e, 1);
+					if (bootverbose)
+						device_printf(dev,
+						    "M1533 0x7e: 0x%x -> ",
+						    data);
+					data |= 0x1;
+					if (bootverbose)
+						printf("0x%x\n", data);
+					pci_write_config(children[i], 0x7e,
+					    data, 1);
+					break;
+				}
+			}
+		}
+		free(children, M_TEMP);
+#endif
+		tr->hwchns = ALI_MAXHWCH;
+		tr->bufsz = ALI_BUFSZ;
+	} else {
+		lowaddr = TR_MAXADDR;
+		tr->hwchns = TR_MAXHWCH;
+		tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ,
+		    65536);
+	}
+
+	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev),
+		/*alignment*/TR_BUFALGN,
 		/*boundary*/0,
-		/*lowaddr*/TR_MAXADDR,
+		/*lowaddr*/lowaddr,
 		/*highaddr*/BUS_SPACE_MAXADDR,
 		/*filter*/NULL, /*filterarg*/NULL,
-		/*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
+		/*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/tr->bufsz,
 		/*flags*/0, /*lockfunc*/busdma_lock_mutex,
 		/*lockarg*/&Giant, &tr->parent_dmat) != 0) {
 		device_printf(dev, "unable to create dma tag\n");
From mlaier at FreeBSD.org  Sat Sep 26 11:31:25 2009
From: mlaier at FreeBSD.org (Max Laier)
Date: Sat Sep 26 11:31:32 2009
Subject: svn commit: r197516 - in stable/7/sys: . conf contrib/pf
Message-ID: <200909261131.n8QBVPhU057955@svn.freebsd.org>

Author: mlaier
Date: Sat Sep 26 11:31:25 2009
New Revision: 197516
URL: http://svn.freebsd.org/changeset/base/197516

Log:
  MFC r197334,r197433:
      Extract svn and git version info from git-svn repos.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/conf/newvers.sh
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/conf/newvers.sh
==============================================================================
--- stable/7/sys/conf/newvers.sh	Sat Sep 26 00:10:45 2009	(r197515)
+++ stable/7/sys/conf/newvers.sh	Sat Sep 26 11:31:25 2009	(r197516)
@@ -89,28 +89,54 @@ i=`${MAKE:-make} -V KERN_IDENT`
 
 case "$d" in
 */sys/*)
+	SRCDIR=${d##*obj}
+	if [ -n "$MACHINE" ]; then
+		SRCDIR=${SRCDIR##/$MACHINE}
+	fi
+	SRCDIR=${SRCDIR%%/sys/*}
+
 	for dir in /bin /usr/bin /usr/local/bin; do
-		if [ -x "${dir}/svnversion" ]; then
+		if [ -d "${SRCDIR}/sys/.svn" -a -x "${dir}/svnversion" ] ; then
 			svnversion=${dir}/svnversion
-			SRCDIR=${d##*obj}
-			if [ -n "$MACHINE" ]; then
-				SRCDIR=${SRCDIR##/$MACHINE}
-			fi
-			SRCDIR=${SRCDIR%%/sys/*}
+			break
+		fi
+		if [ -d "${SRCDIR}/.git" -a -x "${dir}/git" ] ; then
+			git_cmd="${dir}/git --git-dir=${SRCDIR}/.git"
 			break
 		fi
 	done
 
-	if [ -n "$svnversion" -a -d "${SRCDIR}/sys/.svn" ] ; then
+	if [ -n "$svnversion" ] ; then
 		svn=" r`cd ${SRCDIR}/sys && $svnversion`"
 	fi
+	if [ -n "$git_cmd" ] ; then
+		git=`$git_cmd rev-parse --verify --short HEAD 2>/dev/null`
+		svn=`$git_cmd svn find-rev $git 2>/dev/null`
+		if [ -n "$svn" ] ; then
+			svn=" r${svn}"
+			git="=${git}"
+		else
+			svn=`$git_cmd log | fgrep 'git-svn-id:' | head -1 | \
+			     sed -n 's/^.*@\([0-9][0-9]*\).*$/\1/p'`
+			if [ -n $svn ] ; then
+				svn=" r${svn}"
+				git="+${git}"
+			else
+				git=" ${git}"
+			fi
+		fi
+		if $git_cmd --work-tree=${SRCDIR} diff-index \
+		    --name-only HEAD | read dummy; then
+			git="${git}-dirty"
+		fi
+	fi
 	;;
 esac
 
 cat << EOF > vers.c
 $COPYRIGHT
-#define SCCSSTR "@(#)${VERSION} #${v}${svn}: ${t}"
-#define VERSTR "${VERSION} #${v}${svn}: ${t}\\n    ${u}@${h}:${d}\\n"
+#define SCCSSTR "@(#)${VERSION} #${v}${svn}${git}: ${t}"
+#define VERSTR "${VERSION} #${v}${svn}${git}: ${t}\\n    ${u}@${h}:${d}\\n"
 #define RELSTR "${RELEASE}"
 
 char sccs[sizeof(SCCSSTR) > 128 ? sizeof(SCCSSTR) : 128] = SCCSSTR;
From stas at FreeBSD.org  Sat Sep 26 20:07:49 2009
From: stas at FreeBSD.org (Stanislav Sedov)
Date: Sat Sep 26 20:08:09 2009
Subject: svn commit: r197529 - in stable/7/sys: . contrib/pf netinet
Message-ID: <200909262007.n8QK7nDa069706@svn.freebsd.org>

Author: stas
Date: Sat Sep 26 20:07:48 2009
New Revision: 197529
URL: http://svn.freebsd.org/changeset/base/197529

Log:
  - MFC r196410 by peter@:
     Fix signed comparison bug when ticks goes negative after 24 days of
     uptime.  This causes the tcp time_wait state code to fail to expire
     sockets in timewait state.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/netinet/tcp_timewait.c

Modified: stable/7/sys/netinet/tcp_timewait.c
==============================================================================
--- stable/7/sys/netinet/tcp_timewait.c	Sat Sep 26 19:00:47 2009	(r197528)
+++ stable/7/sys/netinet/tcp_timewait.c	Sat Sep 26 20:07:48 2009	(r197529)
@@ -587,7 +587,7 @@ tcp_tw_2msl_scan(int reuse)
 	INP_INFO_WLOCK_ASSERT(&tcbinfo);
 	for (;;) {
 		tw = TAILQ_FIRST(&twq_2msl);
-		if (tw == NULL || (!reuse && tw->tw_time > ticks))
+		if (tw == NULL || (!reuse && (tw->tw_time - ticks) > 0))
 			break;
 		INP_WLOCK(tw->tw_inpcb);
 		tcp_twclose(tw, reuse);
From gallatin at FreeBSD.org  Mon Sep 28 15:10:09 2009
From: gallatin at FreeBSD.org (Andrew Gallatin)
Date: Mon Sep 28 15:10:21 2009
Subject: svn commit: r197577 - in stable/7/sys: . contrib/pf dev/mxge
Message-ID: <200909281510.n8SFA9sx058132@svn.freebsd.org>

Author: gallatin
Date: Mon Sep 28 15:10:08 2009
New Revision: 197577
URL: http://svn.freebsd.org/changeset/base/197577

Log:
  MFC 197395: Improve mxge watchdog routine's ability to reliably reset a failed NIC

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/mxge/if_mxge.c

Modified: stable/7/sys/dev/mxge/if_mxge.c
==============================================================================
--- stable/7/sys/dev/mxge/if_mxge.c	Mon Sep 28 11:31:21 2009	(r197576)
+++ stable/7/sys/dev/mxge/if_mxge.c	Mon Sep 28 15:10:08 2009	(r197577)
@@ -135,7 +135,7 @@ MODULE_DEPEND(mxge, zlib, 1, 1, 1);
 
 static int mxge_load_firmware(mxge_softc_t *sc, int adopt);
 static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
-static int mxge_close(mxge_softc_t *sc);
+static int mxge_close(mxge_softc_t *sc, int down);
 static int mxge_open(mxge_softc_t *sc);
 static void mxge_tick(void *arg);
 
@@ -1291,8 +1291,7 @@ mxge_reset(mxge_softc_t *sc, int interru
 		ss->lro_queued = 0;
 		ss->lro_flushed = 0;
 		if (ss->fw_stats != NULL) {
-			ss->fw_stats->valid = 0;
-			ss->fw_stats->send_done_count = 0;
+			bzero(ss->fw_stats, sizeof *ss->fw_stats);
 		}
 	}
 	sc->rdma_tags_available = 15;
@@ -1365,7 +1364,7 @@ mxge_change_lro_locked(mxge_softc_t *sc,
 		ifp->if_capenable |= IFCAP_LRO;
 	sc->lro_cnt = lro_cnt;
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		mxge_close(sc);
+		mxge_close(sc, 0);
 		err = mxge_open(sc);
 	}
 	return err;
@@ -1481,6 +1480,10 @@ mxge_add_sysctls(mxge_softc_t *sc)
 		       "read_write_dma_MBs",
 		       CTLFLAG_RD, &sc->read_write_dma,
 		       0, "DMA concurrent Read/Write speed in MB/s");
+	SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
+		       "watchdog_resets",
+		       CTLFLAG_RD, &sc->watchdog_resets,
+		       0, "Number of times NIC was reset");
 
 
 	/* performance related tunables */
@@ -3377,28 +3380,29 @@ abort:
 }
 
 static int
-mxge_close(mxge_softc_t *sc)
+mxge_close(mxge_softc_t *sc, int down)
 {
 	mxge_cmd_t cmd;
 	int err, old_down_cnt;
 
 	callout_stop(&sc->co_hdl);
 	sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-	old_down_cnt = sc->down_cnt;
-	mb();
-	err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
-	if (err) {
-		device_printf(sc->dev, "Couldn't bring down link\n");
-	}
-	if (old_down_cnt == sc->down_cnt) {
-		/* wait for down irq */
-		DELAY(10 * sc->intr_coal_delay);
-	}
-	mb();
-	if (old_down_cnt == sc->down_cnt) {
-		device_printf(sc->dev, "never got down irq\n");
+	if (!down) {
+		old_down_cnt = sc->down_cnt;
+		mb();
+		err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
+		if (err) {
+			device_printf(sc->dev, "Couldn't bring down link\n");
+		}
+		if (old_down_cnt == sc->down_cnt) {
+			/* wait for down irq */
+			DELAY(10 * sc->intr_coal_delay);
+		}
+		mb();
+		if (old_down_cnt == sc->down_cnt) {
+			device_printf(sc->dev, "never got down irq\n");
+		}
 	}
-
 	mxge_free_mbufs(sc);
 
 	return 0;
@@ -3451,7 +3455,8 @@ static int
 mxge_watchdog_reset(mxge_softc_t *sc)
 {
 	struct pci_devinfo *dinfo;
-	int err;
+	struct mxge_slice_state *ss;
+	int err, running, s, num_tx_slices = 1;
 	uint32_t reboot;
 	uint16_t cmd;
 
@@ -3485,6 +3490,30 @@ mxge_watchdog_reset(mxge_softc_t *sc)
 		reboot = mxge_read_reboot(sc);
 		device_printf(sc->dev, "NIC rebooted, status = 0x%x\n",
 			      reboot);
+		running = sc->ifp->if_drv_flags & IFF_DRV_RUNNING;
+		if (running) {
+
+			/* 
+			 * quiesce NIC so that TX routines will not try to
+			 * xmit after restoration of BAR
+			 */
+
+			/* Mark the link as down */
+			if (sc->link_state) {
+				sc->link_state = 0;
+				if_link_state_change(sc->ifp,
+						     LINK_STATE_DOWN);
+			}
+#ifdef IFNET_BUF_RING
+			num_tx_slices = sc->num_slices;
+#endif
+			/* grab all TX locks to ensure no tx  */
+			for (s = 0; s < num_tx_slices; s++) {
+				ss = &sc->ss[s];
+				mtx_lock(&ss->tx.mtx);
+			}
+			mxge_close(sc, 1);
+		}
 		/* restore PCI configuration space */
 		dinfo = device_get_ivars(sc->dev);
 		pci_cfg_restore(sc->dev, dinfo);
@@ -3492,10 +3521,22 @@ mxge_watchdog_reset(mxge_softc_t *sc)
 		/* and redo any changes we made to our config space */
 		mxge_setup_cfg_space(sc);
 
-		if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
-			mxge_close(sc);
-			err = mxge_open(sc);
+		/* reload f/w */
+		err = mxge_load_firmware(sc, 0);
+		if (err) {
+			device_printf(sc->dev,
+				      "Unable to re-load f/w\n");
 		}
+		if (running) {
+			if (!err)
+				err = mxge_open(sc);
+			/* release all TX locks */
+			for (s = 0; s < num_tx_slices; s++) {
+				ss = &sc->ss[s];
+				mtx_unlock(&ss->tx.mtx);
+			}
+		}
+		sc->watchdog_resets++;
 	} else {
 		device_printf(sc->dev, "NIC did not reboot, ring state:\n");
 		device_printf(sc->dev, "tx.req=%d tx.done=%d\n",
@@ -3505,6 +3546,9 @@ mxge_watchdog_reset(mxge_softc_t *sc)
 			      be32toh(sc->ss->fw_stats->send_done_count));
 		device_printf(sc->dev, "not resetting\n");
 	}
+	if (err)
+		device_printf(sc->dev, "watchdog reset failed\n");
+
 	return (err);
 }
 
@@ -3590,11 +3634,11 @@ mxge_change_mtu(mxge_softc_t *sc, int mt
 	old_mtu = ifp->if_mtu;
 	ifp->if_mtu = mtu;
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		mxge_close(sc);
+		mxge_close(sc, 0);
 		err = mxge_open(sc);
 		if (err != 0) {
 			ifp->if_mtu = old_mtu;
-			mxge_close(sc);
+			mxge_close(sc, 0);
 			(void) mxge_open(sc);
 		}
 	}
@@ -3648,7 +3692,7 @@ mxge_ioctl(struct ifnet *ifp, u_long com
 			}
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-				mxge_close(sc);
+				mxge_close(sc, 0);
 			}
 		}
 		mtx_unlock(&sc->driver_mtx);
@@ -4345,7 +4389,7 @@ mxge_detach(device_t dev)
 	}
 	mtx_lock(&sc->driver_mtx);
 	if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
-		mxge_close(sc);
+		mxge_close(sc, 0);
 	mtx_unlock(&sc->driver_mtx);
 	ether_ifdetach(sc->ifp);
 	callout_drain(&sc->co_hdl);
From edwin at FreeBSD.org  Mon Sep 28 22:03:02 2009
From: edwin at FreeBSD.org (Edwin Groothuis)
Date: Mon Sep 28 22:03:09 2009
Subject: svn commit: r197598 - stable/7/share/zoneinfo
Message-ID: <200909282203.n8SM318J067429@svn.freebsd.org>

Author: edwin
Date: Mon Sep 28 22:03:01 2009
New Revision: 197598
URL: http://svn.freebsd.org/changeset/base/197598

Log:
  MFC of r197597
  
  Update to tzdata2009n:
  
  Pakistan will go back from DST at 1 October.
  Headsup for changes in Argentina.

Modified:
  stable/7/share/zoneinfo/   (props changed)
  stable/7/share/zoneinfo/asia
  stable/7/share/zoneinfo/southamerica

Modified: stable/7/share/zoneinfo/asia
==============================================================================
--- stable/7/share/zoneinfo/asia	Mon Sep 28 21:53:28 2009	(r197597)
+++ stable/7/share/zoneinfo/asia	Mon Sep 28 22:03:01 2009	(r197598)
@@ -1,5 +1,5 @@
 # 
-# @(#)asia	8.40
+# @(#)asia	8.41
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -1674,8 +1674,15 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
 # advance clocks in the country by one hour from April 15 to
 # conserve energy"
 
-# From Arthur David Olson (2009-04-10):
-# Assume for now that Pakistan will end DST in 2009 as it did in 2008.
+# From Steffen Thorsen (2009-09-17):
+# "The News International," Pakistan reports that: "The Federal
+# Government has decided to restore the previous time by moving the
+# clocks backward by one hour from October 1. A formal announcement to
+# this effect will be made after the Prime Minister grants approval in
+# this regard." 
+# 
+# http://www.thenews.com.pk/updates.asp?id=87168
+# 
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
@@ -1683,7 +1690,7 @@ Rule Pakistan	2002	only	-	Oct	Sun>=2	0:0
 Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
 Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
 Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
-Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
+Rule Pakistan	2009	only	-	Oct	1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep

Modified: stable/7/share/zoneinfo/southamerica
==============================================================================
--- stable/7/share/zoneinfo/southamerica	Mon Sep 28 21:53:28 2009	(r197597)
+++ stable/7/share/zoneinfo/southamerica	Mon Sep 28 22:03:01 2009	(r197598)
@@ -1,5 +1,5 @@
 # 
-# @(#)southamerica	8.36
+# @(#)southamerica	8.37
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -397,7 +397,37 @@ Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:0
 # is that "The province will most likely follow the next daylight saving schedule,
 # which is planned for the second Sunday in October."
 
-#
+# From Alexander Krivenyshev (2009-09-19):
+# Some  Argentinian Provinces (Buenos Aires, Entre Ríos) are opposing to the
+# Daylight Saving Time for the 2009-2010 season.
+#
+# (Spanish)
+# "El cambio de huso horario en Entre Ríos deberá ser aprobado por la
+# Legislatura":
+# 
+# http://www.analisisdigital.com.ar/noticias.php?ed=1&di=0&no=110168
+# 
+# English translation - "The time zone change in Entre Rios must be approved by
+# the Legislature."
+#
+# (Spanish)
+# "Mar del Plata no quiere cambiar la hora."
+# 
+# http://www.mensajeroweb.com.ar/index.php?x=nota/33861/1/mar-del-plata-no-quiere-cambiar-la-hora
+# 
+# English translation - "Mar del Plata is not to change the time"
+#
+# or
+# (some English translation)
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_argentina07.html
+# 
+
+# From Arthur David Olson (2009-09-22):
+# "Mar del Plata no quiere cambiar la hora" translates to
+# "Mar del Plata doesn't want to change the time"
+# (less definitive than "is not to").
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
From delphij at FreeBSD.org  Mon Sep 28 22:29:29 2009
From: delphij at FreeBSD.org (Xin LI)
Date: Mon Sep 28 22:29:36 2009
Subject: svn commit: r197601 - in stable/7/lib/libc: . net resolv
Message-ID: <200909282229.n8SMTTGM068086@svn.freebsd.org>

Author: delphij
Date: Mon Sep 28 22:29:28 2009
New Revision: 197601
URL: http://svn.freebsd.org/changeset/base/197601

Log:
  MFC 193023+193024:
  
  Add an option to enforce strict RFC 1034 compliance.
  Document how to enable strict RFC 1034 enforcements.
  
  PR:		kern/129477

Modified:
  stable/7/lib/libc/   (props changed)
  stable/7/lib/libc/net/resolver.3
  stable/7/lib/libc/resolv/res_comp.c

Modified: stable/7/lib/libc/net/resolver.3
==============================================================================
--- stable/7/lib/libc/net/resolver.3	Mon Sep 28 22:18:38 2009	(r197600)
+++ stable/7/lib/libc/net/resolver.3	Mon Sep 28 22:29:28 2009	(r197601)
@@ -28,7 +28,7 @@
 .\"     @(#)resolver.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd November 4, 2006
+.Dd May 29, 2009
 .Dt RESOLVER 3
 .Os
 .Sh NAME
@@ -401,6 +401,19 @@ function properly if the programmer atte
 .Va _res
 structure in an attempt to replace the per-thread version referred to
 by that macro.
+.Pp
+The following compile-time option can be specified to change the default
+behavior of resolver routines when necessary.
+.Bl -tag -width RES_ENFORCE_RFC1034
+.It Dv RES_ENFORCE_RFC1034
+If this symbol is defined during compile-time,
+.Fn res_search
+will enforce RFC 1034 check, namely, disallow using of underscore character
+within host names.
+This is used by the standard host lookup routines like
+.Xr gethostbyname 3 .
+For compatibility reasons this option is not enabled by default.
+.El
 .Sh RETURN VALUES
 The
 .Fn res_init

Modified: stable/7/lib/libc/resolv/res_comp.c
==============================================================================
--- stable/7/lib/libc/resolv/res_comp.c	Mon Sep 28 22:18:38 2009	(r197600)
+++ stable/7/lib/libc/resolv/res_comp.c	Mon Sep 28 22:29:28 2009	(r197601)
@@ -148,7 +148,11 @@ dn_skipname(const u_char *ptr, const u_c
 #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
 
 #define borderchar(c) (alphachar(c) || digitchar(c))
+#ifdef	RES_ENFORCE_RFC1034
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#else
 #define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
+#endif
 #define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
 
 int
From mav at FreeBSD.org  Tue Sep 29 16:19:49 2009
From: mav at FreeBSD.org (Alexander Motin)
Date: Tue Sep 29 16:19:55 2009
Subject: svn commit: r197617 - stable/7/sys/dev/ata
Message-ID: <200909291619.n8TGJmRg089759@svn.freebsd.org>

Author: mav
Date: Tue Sep 29 16:19:48 2009
New Revision: 197617
URL: http://svn.freebsd.org/changeset/base/197617

Log:
  Partial MFC rev. 191568:
  Do not hide second channel of ATI IXP700 ATA controller.
  While this chip indeed has only one PATA channel, second channel of the
  controller is used by two SATA channels working in legacy emulation mode.

Modified:
  stable/7/sys/dev/ata/ata-chipset.c

Modified: stable/7/sys/dev/ata/ata-chipset.c
==============================================================================
--- stable/7/sys/dev/ata/ata-chipset.c	Tue Sep 29 12:59:31 2009	(r197616)
+++ stable/7/sys/dev/ata/ata-chipset.c	Tue Sep 29 16:19:48 2009	(r197617)
@@ -1406,9 +1406,8 @@ ata_ati_chipinit(device_t dev)
     if (ata_setup_interrupt(dev))
 	return ENXIO;
 
-    /* IXP600 & IXP700 only have 1 PATA channel */
-    if ((ctlr->chip->chipid == ATA_ATI_IXP600) ||
-	(ctlr->chip->chipid == ATA_ATI_IXP700))
+    /* IXP600 only have 1 PATA channel */
+    if (ctlr->chip->chipid == ATA_ATI_IXP600)
 	ctlr->channels = 1;
 
     ctlr->setmode = ata_ati_setmode;
From zml at FreeBSD.org  Wed Sep 30 19:40:51 2009
From: zml at FreeBSD.org (Zachary Loafman)
Date: Wed Sep 30 19:40:57 2009
Subject: svn commit: r197652 - stable/7/sys/kern
Message-ID: <200909301940.n8UJep9X024249@svn.freebsd.org>

Author: zml
Date: Wed Sep 30 19:40:51 2009
New Revision: 197652
URL: http://svn.freebsd.org/changeset/base/197652

Log:
  sched_ule in stable/7 has a bug (introduced in r180607) where a thread
  that is running often will appear to not be running much at all.
  
  sched_ule has a much less accurate mechanism for determining how much
  various threads are running.  Every tick, hardclock_cpu() calls
  sched_tick(), and the currently running thread gets it's ts_ticks
  incremented.  Whenever an event of interest happens to a thread, the
  ts_ticks value may be decayed; it's supposed to be a rough running
  average of the last 10 seconds.  So there's a ts_ltick which is the last
  tick we looked at decaying ts_ticks.
  
  The increment in sched_tick() was slightly buggy on SMP, because a
  thread could get incremented on two different CPUs in the rare case
  where it was swapped from one which had run sched_tick() this tick to
  one which hadn't.  The fix that was used relied on ts_ltick and only
  incremented ts_ticks if ts_ltick was not from the current tick.
  This is buggy, because any time the thread began running on a CPU in the
  current tick, we would have set ts_ltick to ticks, so if it was still
  running at sched_tick() we wouldn't increment.
  
  A system with a single process that hogs the CPU and is otherwise idle,
  therefore, would look like all threads were at 0%. The threads not
  running are really at 0%, and the hog is not getting its ts_ticks
  incremented since it went through some other runq stats that set
  ts_ltick.  On a 2-way SMP the thread used to get shuffled regularly
  between CPUs (I think fallout from this bug), so it would appear a
  little over 50% busy.
  
  The fix is to use a separate variable to record when the last
  sched_tick() increment happened.
  
  Submitted by:       Matthew Fleming (matthew.fleming at isilon.com)
  Reviewed by:        zml, dfr
  Approved by:        dfr (mentor)

Modified:
  stable/7/sys/kern/sched_ule.c

Modified: stable/7/sys/kern/sched_ule.c
==============================================================================
--- stable/7/sys/kern/sched_ule.c	Wed Sep 30 19:19:53 2009	(r197651)
+++ stable/7/sys/kern/sched_ule.c	Wed Sep 30 19:40:51 2009	(r197652)
@@ -101,6 +101,7 @@ struct td_sched {	
 	u_int		ts_runtime;	/* Number of ticks we were running */
 	/* The following variables are only used for pctcpu calculation */
 	int		ts_ltick;	/* Last tick that we were running on */
+	int		ts_incrtick;	/* Last tick that we incremented on */
 	int		ts_ftick;	/* First tick that we were running on */
 	int		ts_ticks;	/* Tick count */
 #ifdef SMP
@@ -2075,6 +2076,7 @@ sched_fork_thread(struct thread *td, str
 	 */
 	ts2->ts_ticks = ts->ts_ticks;
 	ts2->ts_ltick = ts->ts_ltick;
+	ts2->ts_incrtick = ts->ts_incrtick;
 	ts2->ts_ftick = ts->ts_ftick;
 	child->td_user_pri = td->td_user_pri;
 	child->td_base_user_pri = td->td_base_user_pri;
@@ -2266,10 +2268,11 @@ sched_tick(void)
 	 * Ticks is updated asynchronously on a single cpu.  Check here to
 	 * avoid incrementing ts_ticks multiple times in a single tick.
 	 */
-	if (ts->ts_ltick == ticks)
+	if (ts->ts_incrtick == ticks)
 		return;
 	/* Adjust ticks for pctcpu */
 	ts->ts_ticks += 1 << SCHED_TICK_SHIFT;
+	ts->ts_incrtick = ticks;
 	ts->ts_ltick = ticks;
 	/*
 	 * Update if we've exceeded our desired tick threshhold by over one
From kostikbel at gmail.com  Wed Sep 30 19:53:02 2009
From: kostikbel at gmail.com (Kostik Belousov)
Date: Wed Sep 30 19:53:19 2009
Subject: svn commit: r197652 - stable/7/sys/kern
In-Reply-To: <200909301940.n8UJep9X024249@svn.freebsd.org>
References: <200909301940.n8UJep9X024249@svn.freebsd.org>
Message-ID: <20090930195254.GK3130@deviant.kiev.zoral.com.ua>

On Wed, Sep 30, 2009 at 07:40:51PM +0000, Zachary Loafman wrote:
> Author: zml
> Date: Wed Sep 30 19:40:51 2009
> New Revision: 197652
> URL: http://svn.freebsd.org/changeset/base/197652
> 
> Log:
>   sched_ule in stable/7 has a bug (introduced in r180607) where a thread
>   that is running often will appear to not be running much at all.
Why is this not a problem on HEAD ?

>   
>   sched_ule has a much less accurate mechanism for determining how much
>   various threads are running.  Every tick, hardclock_cpu() calls
>   sched_tick(), and the currently running thread gets it's ts_ticks
>   incremented.  Whenever an event of interest happens to a thread, the
>   ts_ticks value may be decayed; it's supposed to be a rough running
>   average of the last 10 seconds.  So there's a ts_ltick which is the last
>   tick we looked at decaying ts_ticks.
>   
>   The increment in sched_tick() was slightly buggy on SMP, because a
>   thread could get incremented on two different CPUs in the rare case
>   where it was swapped from one which had run sched_tick() this tick to
>   one which hadn't.  The fix that was used relied on ts_ltick and only
>   incremented ts_ticks if ts_ltick was not from the current tick.
>   This is buggy, because any time the thread began running on a CPU in the
>   current tick, we would have set ts_ltick to ticks, so if it was still
>   running at sched_tick() we wouldn't increment.
>   
>   A system with a single process that hogs the CPU and is otherwise idle,
>   therefore, would look like all threads were at 0%. The threads not
>   running are really at 0%, and the hog is not getting its ts_ticks
>   incremented since it went through some other runq stats that set
>   ts_ltick.  On a 2-way SMP the thread used to get shuffled regularly
>   between CPUs (I think fallout from this bug), so it would appear a
>   little over 50% busy.
>   
>   The fix is to use a separate variable to record when the last
>   sched_tick() increment happened.
>   
>   Submitted by:       Matthew Fleming (matthew.fleming at isilon.com)
>   Reviewed by:        zml, dfr
>   Approved by:        dfr (mentor)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/svn-src-stable-7/attachments/20090930/0296652e/attachment.pgp
From bms at FreeBSD.org  Wed Sep 30 20:01:45 2009
From: bms at FreeBSD.org (Bruce Simpson)
Date: Wed Sep 30 20:01:56 2009
Subject: svn commit: r197652 - stable/7/sys/kern
In-Reply-To: <200909301940.n8UJep9X024249@svn.freebsd.org>
References: <200909301940.n8UJep9X024249@svn.freebsd.org>
Message-ID: <4AC3B50B.60806@FreeBSD.org>

Nice fix.

Timing problems are the subtlest.
From matthew.fleming at isilon.com  Wed Sep 30 20:21:41 2009
From: matthew.fleming at isilon.com (Matthew Fleming)
Date: Wed Sep 30 20:21:52 2009
Subject: svn commit: r197652 - stable/7/sys/kern
In-Reply-To: <20090930195254.GK3130@deviant.kiev.zoral.com.ua>
References: <200909301940.n8UJep9X024249@svn.freebsd.org>
	<20090930195254.GK3130@deviant.kiev.zoral.com.ua>
Message-ID: <06D5F9F6F655AD4C92E28B662F7F853E03171462@seaxch09.desktop.isilon.com>

> >   sched_ule in stable/7 has a bug (introduced in r180607) where a
thread
> >   that is running often will appear to not be running much at all.
> Why is this not a problem on HEAD ?

I can't say definitively there's not a bug on HEAD of some kind, but
when I ran a CPU hog and looked at the output of top(1), on HEAD the hog
was listed as near 100%, and on stable/7 it was listed as 0% after a few
seconds for the system to settle.  Since the code looked at least
somewhat different and the bug did not reproduce on HEAD, I assumed it
was only a problem on stable/7.  I had to run HEAD code in a virtual
machine, perhaps this made a difference?

>From a code inspection standpoint, I don't see anything obvious.  On
stable/7, the set of ts_ltick in tdq_runq_rem() appears to be the reason
a cpu hog was not getting incremented by sched_tick().  On HEAD this set
is moved to sched_choose().

Thanks,
matthew