Date: Wed, 1 Oct 2008 15:29:57 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 150753 for review Message-ID: <200810011529.m91FTvv9058448@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=150753 Change 150753 by jhb@jhb_mutex on 2008/10/01 15:29:41 IFC @150751 Affected files ... .. //depot/projects/smpng/sys/dev/cxgb/cxgb_main.c#14 integrate .. //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#9 integrate .. //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_ddp.c#7 integrate .. //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_vm.c#4 integrate .. //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_vm.h#2 integrate .. //depot/projects/smpng/sys/dev/dc/dcphy.c#6 integrate .. //depot/projects/smpng/sys/dev/dc/pnphy.c#4 integrate .. //depot/projects/smpng/sys/dev/nfe/if_nfe.c#13 integrate .. //depot/projects/smpng/sys/dev/nfe/if_nfereg.h#8 integrate .. //depot/projects/smpng/sys/geom/vinum/geom_vinum.h#12 integrate .. //depot/projects/smpng/sys/geom/vinum/geom_vinum_drive.c#21 integrate .. //depot/projects/smpng/sys/geom/vinum/geom_vinum_var.h#11 integrate .. //depot/projects/smpng/sys/kern/uipc_socket.c#115 integrate .. //depot/projects/smpng/sys/mips/mips/pmap.c#3 integrate Differences ... ==== //depot/projects/smpng/sys/dev/cxgb/cxgb_main.c#14 (text+ko) ==== @@ -28,7 +28,7 @@ ***************************************************************************/ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.67 2008/09/23 03:16:54 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.68 2008/09/30 21:21:52 kmacy Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -981,6 +981,12 @@ ifmedia_add(&p->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); media_flags = 0; + } else if (!strcmp(p->phy.desc, "1000BASE-X")) { + /* + * XXX: This is not very accurate. Fix when common code + * returns more specific value - eg 1000BASE-SX, LX, etc. + */ + media_flags = IFM_ETHER | IFM_1000_SX | IFM_FDX; } else { printf("unsupported media type %s\n", p->phy.desc); return (ENXIO); ==== //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#9 (text+ko) ==== @@ -28,7 +28,7 @@ ***************************************************************************/ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c,v 1.15 2008/09/23 03:16:54 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c,v 1.16 2008/09/30 23:45:22 kmacy Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -193,14 +193,16 @@ static int -cxgb_hold_iovec_pages(struct uio *uio, vm_page_t *m, int *held, int flags) +cxgb_hold_iovec_pages(struct uio *uio, vm_page_t *m, int *held, vm_prot_t prot) { struct iovec *iov = uio->uio_iov; int iovcnt = uio->uio_iovcnt; int err, i, count, totcount, maxcount, totbytes, npages, curbytes; uint64_t start, end; vm_page_t *mp; - + vm_map_t map; + + map = &uio->uio_td->td_proc->p_vmspace->vm_map; totbytes = totcount = 0; maxcount = *held; @@ -217,11 +219,8 @@ count = min(count, npages); - err = vm_fault_hold_user_pages((vm_offset_t)iov->iov_base, mp, count, flags); - if (err) { - vm_fault_unhold_pages(m, totcount); - return (err); - } + err = vm_fault_hold_user_pages(map, + (vm_offset_t)iov->iov_base, mp, count, prot); mp += count; totcount += count; curbytes = iov->iov_len; @@ -429,7 +428,7 @@ * Make sure we don't exceed the socket buffer */ count = min(toep->tp_page_count, (sockbuf_sbspace(snd) >> PAGE_SHIFT) + 2*PAGE_SIZE); - rv = cxgb_hold_iovec_pages(&uiotmp, toep->tp_pages, &count, 0); + rv = cxgb_hold_iovec_pages(&uiotmp, toep->tp_pages, &count, VM_PROT_READ); hold_resid = uiotmp.uio_resid; if (rv) return (rv); ==== //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_ddp.c#7 (text+ko) ==== @@ -28,7 +28,7 @@ ***************************************************************************/ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_ddp.c,v 1.8 2008/09/23 03:16:54 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_ddp.c,v 1.9 2008/09/30 23:45:22 kmacy Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -120,7 +120,7 @@ * a new gather list was allocated it is returned in @newgl. */ static int -t3_pin_pages(bus_dma_tag_t tag, bus_dmamap_t map, vm_offset_t addr, +t3_pin_pages(bus_dma_tag_t tag, bus_dmamap_t dmamap, vm_offset_t addr, size_t len, struct ddp_gather_list **newgl, const struct ddp_gather_list *gl) { @@ -128,13 +128,16 @@ size_t pg_off; unsigned int npages; struct ddp_gather_list *p; - + vm_map_t map; + /* * XXX need x86 agnostic check */ if (addr + len > VM_MAXUSER_ADDRESS) return (EFAULT); + + pg_off = addr & PAGE_MASK; npages = (pg_off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; p = malloc(sizeof(struct ddp_gather_list) + npages * sizeof(vm_page_t *), @@ -142,7 +145,9 @@ if (p == NULL) return (ENOMEM); - err = vm_fault_hold_user_pages(addr, p->dgl_pages, npages, VM_HOLD_WRITEABLE); + map = &curthread->td_proc->p_vmspace->vm_map; + err = vm_fault_hold_user_pages(map, addr, p->dgl_pages, npages, + VM_PROT_READ | VM_PROT_WRITE); if (err) goto free_gl; ==== //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_vm.c#4 (text+ko) ==== @@ -1,6 +1,6 @@ /************************************************************************** -Copyright (c) 2007, Chelsio Inc. +Copyright (c) 2007-2008, Chelsio Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,7 +28,7 @@ ***************************************************************************/ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_vm.c,v 1.3 2008/09/29 22:13:29 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_vm.c,v 1.4 2008/09/30 23:44:44 kmacy Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -41,6 +41,7 @@ #include <sys/condvar.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/syslog.h> #include <vm/vm.h> #include <vm/vm_page.h> @@ -49,32 +50,29 @@ #include <vm/pmap.h> #include <ulp/tom/cxgb_vm.h> -#define TRACE_ENTER printf("%s:%s entered", __FUNCTION__, __FILE__) -#define TRACE_EXIT printf("%s:%s:%d exited", __FUNCTION__, __FILE__, __LINE__) - /* - * This routine takes a user address range and does the following: - * - validate that the user has access to those pages (flags indicates read or write) - if not fail + * This routine takes a user's map, array of pages, number of pages, and flags + * and then does the following: + * - validate that the user has access to those pages (flags indicates read + * or write) - if not fail * - validate that count is enough to hold range number of pages - if not fail * - fault in any non-resident pages * - if the user is doing a read force a write fault for any COWed pages * - if the user is doing a read mark all pages as dirty * - hold all pages - * - return number of pages in count */ int -vm_fault_hold_user_pages(vm_offset_t addr, vm_page_t *mp, int count, int flags) +vm_fault_hold_user_pages(vm_map_t map, vm_offset_t addr, vm_page_t *mp, + int count, vm_prot_t prot) { vm_offset_t end, va; int faults, rv; - - struct thread *td; - vm_map_t map; pmap_t pmap; vm_page_t m, *pages; - vm_prot_t prot; - + pmap = vm_map_pmap(map); + pages = mp; + addr &= ~PAGE_MASK; /* * Check that virtual address range is legal * This check is somewhat bogus as on some architectures kernel @@ -83,79 +81,73 @@ */ end = addr + (count * PAGE_SIZE); if (end > VM_MAXUSER_ADDRESS) { - printf("bad address passed\n"); + log(LOG_WARNING, "bad address passed to vm_fault_hold_user_pages"); return (EFAULT); } - td = curthread; - map = &td->td_proc->p_vmspace->vm_map; - pmap = &td->td_proc->p_vmspace->vm_pmap; - pages = mp; - - prot = VM_PROT_READ; - prot |= (flags & VM_HOLD_WRITEABLE) ? VM_PROT_WRITE : 0; -retry: - /* - * First optimistically assume that all pages are resident (and R/W if for write) - * if so just mark pages as held (and dirty if for write) and return + * First optimistically assume that all pages are resident + * (and R/W if for write) if so just mark pages as held (and + * dirty if for write) and return */ vm_page_lock_queues(); - for (pages = mp, faults = 0, va = addr; va < end; va += PAGE_SIZE, pages++) { + for (pages = mp, faults = 0, va = addr; va < end; + va += PAGE_SIZE, pages++) { /* - * Assure that we only hold the page once + * page queue mutex is recursable so this is OK + * it would be really nice if we had an unlocked + * version of this so we were only acquiring the + * pmap lock 1 time as opposed to potentially + * many dozens of times */ - if (*pages == NULL) { - /* - * page queue mutex is recursable so this is OK - * it would be really nice if we had an unlocked version of this so - * we were only acquiring the pmap lock 1 time as opposed to potentially - * many dozens of times - */ - *pages = m = pmap_extract_and_hold(pmap, va, prot); - if (m == NULL) { - faults++; - continue; - } - - if (flags & VM_HOLD_WRITEABLE) - vm_page_dirty(m); + *pages = m = pmap_extract_and_hold(pmap, va, prot); + if (m == NULL) { + faults++; + continue; } + /* + * Preemptively mark dirty - the pages + * will never have the modified bit set if + * they are only changed via DMA + */ + if (prot & VM_PROT_WRITE) + vm_page_dirty(m); + } vm_page_unlock_queues(); - if (faults == 0) { + if (faults == 0) return (0); - } /* * Pages either have insufficient permissions or are not present * trigger a fault where neccessary * */ + rv = 0; for (pages = mp, va = addr; va < end; va += PAGE_SIZE, pages++) { - m = *pages; - rv = 0; - if (m) - continue; - if (flags & VM_HOLD_WRITEABLE) - rv = vm_fault(map, va, VM_PROT_WRITE, VM_FAULT_DIRTY); - else - rv = vm_fault(map, va, VM_PROT_READ, VM_FAULT_NORMAL); - if (rv) { - printf("vm_fault bad return rv=%d va=0x%zx\n", rv, va); - - goto error; - } + /* + * Account for a very narrow race where the page may be + * taken away from us before it is held + */ + while (*pages == NULL) { + rv = vm_fault(map, va, prot, + (prot & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); + if (rv) + goto error; + *pages = pmap_extract_and_hold(pmap, va, prot); + } } - - goto retry; - + return (0); error: + log(LOG_WARNING, + "vm_fault bad return rv=%d va=0x%zx\n", rv, va); vm_page_lock_queues(); for (pages = mp, va = addr; va < end; va += PAGE_SIZE, pages++) - if (*pages) + if (*pages) { vm_page_unhold(*pages); + *pages = NULL; + } vm_page_unlock_queues(); return (EFAULT); } ==== //depot/projects/smpng/sys/dev/cxgb/ulp/tom/cxgb_vm.h#2 (text+ko) ==== @@ -1,6 +1,6 @@ /************************************************************************** -Copyright (c) 2007, Chelsio Inc. +Copyright (c) 2007-2008, Chelsio Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -26,15 +26,14 @@ POSSIBILITY OF SUCH DAMAGE. -$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_vm.h,v 1.1 2008/02/23 01:06:17 kmacy Exp $ +$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_vm.h,v 1.2 2008/09/30 23:44:44 kmacy Exp $ ***************************************************************************/ #ifndef CXGB_VM_H_ #define CXGB_VM_H_ -#define VM_HOLD_WRITEABLE 0x1 - -int vm_fault_hold_user_pages(vm_offset_t addr, vm_page_t *mp, int count, int flags); +int vm_fault_hold_user_pages(vm_map_t map, vm_offset_t addr, + vm_page_t *mp, int count, vm_prot_t prot); void vm_fault_unhold_pages(vm_page_t *mp, int count); #endif ==== //depot/projects/smpng/sys/dev/dc/dcphy.c#6 (text+ko) ==== @@ -31,13 +31,13 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/dc/dcphy.c,v 1.33 2007/11/16 10:25:36 yongari Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/dc/dcphy.c,v 1.34 2008/09/30 20:53:15 marius Exp $"); /* * Pseudo-driver for internal NWAY support on DEC 21143 and workalike - * controllers. Technically we're abusing the miibus code to handle + * controllers. Technically we're abusing the miibus code to handle * media selection and NWAY support here since there is no MII - * interface. However the logical operations are roughly the same, + * interface. However the logical operations are roughly the same, * and the alternative is to create a fake MII interface in the driver, * which is harder to do. */ @@ -82,7 +82,7 @@ /* * This is the subsystem ID for the built-in 21143 ethernet - * in several Compaq Presario systems. Apparently these are + * in several Compaq Presario systems. Apparently these are * 10Mbps only, so we need to treat them specially. */ #define COMPAQ_PRESARIO_ID 0xb0bb0e11 @@ -127,7 +127,7 @@ */ if (ma->mii_id1 != DC_VENDORID_DEC || ma->mii_id2 != DC_DEVICEID_21143) - return(ENXIO); + return (ENXIO); device_set_desc(dev, "Intel 21143 NWAY media interface"); @@ -171,20 +171,16 @@ switch (pci_get_subdevice(brdev) << 16 | pci_get_subvendor(brdev)) { case COMPAQ_PRESARIO_ID: /* Example of how to only allow 10Mbps modes. */ - sc->mii_capabilities = BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; + sc->mii_capabilities = BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX; break; default: - if (dc_sc->dc_pmode == DC_PMODE_SIA) { + if (dc_sc->dc_pmode == DC_PMODE_SIA) sc->mii_capabilities = - BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; - } else { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, - sc->mii_inst), BMCR_LOOP|BMCR_S100); - + BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX; + else sc->mii_capabilities = - BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX| - BMSR_10TFDX|BMSR_10THDX; - } + BMSR_ANEG | BMSR_100TXFDX | BMSR_100TXHDX | + BMSR_10TFDX | BMSR_10THDX; break; } @@ -195,7 +191,7 @@ #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); - return(0); + return (0); } static int @@ -213,9 +209,8 @@ /* * If we're not polling our PHY instance, just return. */ - if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); - } break; case MII_MEDIACHG: @@ -223,9 +218,8 @@ * If the media indicates a different PHY instance, * isolate ourselves. */ - if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); - } /* * If the interface is not up, don't do anything. @@ -236,8 +230,8 @@ sc->mii_flags = 0; mii->mii_media_active = IFM_NONE; mode = CSR_READ_4(dc_sc, DC_NETCFG); - mode &= ~(DC_NETCFG_FULLDUPLEX|DC_NETCFG_PORTSEL| - DC_NETCFG_PCS|DC_NETCFG_SCRAMBLER|DC_NETCFG_SPEEDSEL); + mode &= ~(DC_NETCFG_FULLDUPLEX | DC_NETCFG_PORTSEL | + DC_NETCFG_PCS | DC_NETCFG_SCRAMBLER | DC_NETCFG_SPEEDSEL); switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: @@ -252,7 +246,7 @@ case IFM_100_TX: dcphy_reset(sc); DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL); - mode |= DC_NETCFG_PORTSEL|DC_NETCFG_PCS| + mode |= DC_NETCFG_PORTSEL | DC_NETCFG_PCS | DC_NETCFG_SCRAMBLER; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mode |= DC_NETCFG_FULLDUPLEX; @@ -278,7 +272,7 @@ CSR_WRITE_4(dc_sc, DC_NETCFG, mode); break; default: - return(EINVAL); + return (EINVAL); } break; @@ -366,7 +360,7 @@ anlpar = tstat >> 16; if (anlpar & ANLPAR_TX_FD && sc->mii_capabilities & BMSR_100TXFDX) - mii->mii_media_active |= IFM_100_TX|IFM_FDX; + mii->mii_media_active |= IFM_100_TX | IFM_FDX; else if (anlpar & ANLPAR_T4 && sc->mii_capabilities & BMSR_100T4) mii->mii_media_active |= IFM_100_T4; @@ -374,7 +368,7 @@ sc->mii_capabilities & BMSR_100TXHDX) mii->mii_media_active |= IFM_100_TX; else if (anlpar & ANLPAR_10_FD) - mii->mii_media_active |= IFM_10_T|IFM_FDX; + mii->mii_media_active |= IFM_10_T | IFM_FDX; else if (anlpar & ANLPAR_10) mii->mii_media_active |= IFM_10_T; else @@ -384,10 +378,11 @@ DC_TCTL_AUTONEGENBL); return; } + /* * If the other side doesn't support NWAY, then the * best we can do is determine if we have a 10Mbps or - * 100Mbps link. There's no way to know if the link + * 100Mbps link. There's no way to know if the link * is full or half duplex, so we default to half duplex * and hope that the user is clever enough to manually * change the media settings if we're wrong. @@ -404,15 +399,12 @@ } skip: - if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL) mii->mii_media_active |= IFM_10_T; else mii->mii_media_active |= IFM_100_TX; if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX) mii->mii_media_active |= IFM_FDX; - - return; } static int @@ -433,7 +425,7 @@ DC_SETBIT(sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL); DC_SETBIT(sc, DC_10BTSTAT, DC_ASTAT_TXDISABLE); - return(EJUSTRETURN); + return (EJUSTRETURN); } static void @@ -446,7 +438,4 @@ DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET); DELAY(1000); DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET); - - return; } - ==== //depot/projects/smpng/sys/dev/dc/pnphy.c#4 (text+ko) ==== @@ -31,12 +31,12 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/dc/pnphy.c,v 1.21 2006/08/02 05:28:52 yongari Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/dc/pnphy.c,v 1.22 2008/09/30 20:53:15 marius Exp $"); /* * Pseudo-driver for media selection on the Lite-On PNIC 82c168 - * chip. The NWAY support on this chip is horribly broken, so we - * only support manual mode selection. This is lame, but getting + * chip. The NWAY support on this chip is horribly broken, so we + * only support manual mode selection. This is lame, but getting * NWAY to work right is amazingly difficult. */ @@ -112,7 +112,7 @@ */ if (ma->mii_id1 != DC_VENDORID_LO || ma->mii_id2 != DC_DEVICEID_82C168) - return(ENXIO); + return (ENXIO); device_set_desc(dev, "PNIC 82c168 media interface"); @@ -143,7 +143,7 @@ #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) sc->mii_capabilities = - BMSR_100TXFDX|BMSR_100TXHDX|BMSR_10TFDX|BMSR_10THDX; + BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX | BMSR_10THDX; sc->mii_capabilities &= ma->mii_capmask; device_printf(dev, " "); mii_add_media(sc); @@ -157,7 +157,7 @@ #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); - return(0); + return (0); } static int @@ -170,9 +170,8 @@ /* * If we're not polling our PHY instance, just return. */ - if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); - } break; case MII_MEDIACHG: @@ -200,19 +199,19 @@ */ return (EINVAL); case IFM_100_TX: - mii->mii_media_active = IFM_ETHER|IFM_100_TX; + mii->mii_media_active = IFM_ETHER | IFM_100_TX; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); - return(0); + return (0); case IFM_10_T: - mii->mii_media_active = IFM_ETHER|IFM_10_T; + mii->mii_media_active = IFM_ETHER | IFM_10_T; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); - return(0); + return (0); default: - return(EINVAL); + return (EINVAL); } break; @@ -263,6 +262,4 @@ mii->mii_media_active |= IFM_100_TX; if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX) mii->mii_media_active |= IFM_FDX; - - return; } ==== //depot/projects/smpng/sys/dev/nfe/if_nfe.c#13 (text+ko) ==== @@ -21,7 +21,7 @@ /* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/nfe/if_nfe.c,v 1.28 2008/04/10 01:25:09 yongari Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/nfe/if_nfe.c,v 1.29 2008/10/01 00:17:54 yongari Exp $"); #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" @@ -245,6 +245,22 @@ "NVIDIA nForce MCP73 Networking Adapter"}, {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN4, "NVIDIA nForce MCP73 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN1, + "NVIDIA nForce MCP77 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN2, + "NVIDIA nForce MCP77 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN3, + "NVIDIA nForce MCP77 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN4, + "NVIDIA nForce MCP77 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN1, + "NVIDIA nForce MCP79 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN2, + "NVIDIA nForce MCP79 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN3, + "NVIDIA nForce MCP79 Networking Adapter"}, + {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN4, + "NVIDIA nForce MCP79 Networking Adapter"}, {0, 0, NULL} }; @@ -467,6 +483,22 @@ sc->nfe_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT | NFE_CORRECT_MACADDR | NFE_TX_FLOW_CTRL; break; + case PCI_PRODUCT_NVIDIA_MCP77_LAN1: + case PCI_PRODUCT_NVIDIA_MCP77_LAN2: + case PCI_PRODUCT_NVIDIA_MCP77_LAN3: + case PCI_PRODUCT_NVIDIA_MCP77_LAN4: + /* XXX flow control */ + sc->nfe_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_PWR_MGMT | + NFE_CORRECT_MACADDR; + break; + case PCI_PRODUCT_NVIDIA_MCP79_LAN1: + case PCI_PRODUCT_NVIDIA_MCP79_LAN2: + case PCI_PRODUCT_NVIDIA_MCP79_LAN3: + case PCI_PRODUCT_NVIDIA_MCP79_LAN4: + /* XXX flow control */ + sc->nfe_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | + NFE_PWR_MGMT | NFE_CORRECT_MACADDR; + break; case PCI_PRODUCT_NVIDIA_MCP65_LAN1: case PCI_PRODUCT_NVIDIA_MCP65_LAN2: case PCI_PRODUCT_NVIDIA_MCP65_LAN3: ==== //depot/projects/smpng/sys/dev/nfe/if_nfereg.h#8 (text+ko) ==== @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $FreeBSD: src/sys/dev/nfe/if_nfereg.h,v 1.12 2008/04/10 01:25:09 yongari Exp $ + * $FreeBSD: src/sys/dev/nfe/if_nfereg.h,v 1.13 2008/10/01 00:17:54 yongari Exp $ */ #define NFE_RX_RING_COUNT 256 @@ -295,6 +295,14 @@ #define PCI_PRODUCT_NVIDIA_MCP73_LAN2 0x07dd #define PCI_PRODUCT_NVIDIA_MCP73_LAN3 0x07de #define PCI_PRODUCT_NVIDIA_MCP73_LAN4 0x07df +#define PCI_PRODUCT_NVIDIA_MCP77_LAN1 0x0760 +#define PCI_PRODUCT_NVIDIA_MCP77_LAN2 0x0761 +#define PCI_PRODUCT_NVIDIA_MCP77_LAN3 0x0762 +#define PCI_PRODUCT_NVIDIA_MCP77_LAN4 0x0763 +#define PCI_PRODUCT_NVIDIA_MCP79_LAN1 0x0ab0 +#define PCI_PRODUCT_NVIDIA_MCP79_LAN2 0x0ab1 +#define PCI_PRODUCT_NVIDIA_MCP79_LAN3 0x0ab2 +#define PCI_PRODUCT_NVIDIA_MCP79_LAN4 0x0ab3 #define PCI_PRODUCT_NVIDIA_NFORCE3_LAN2 PCI_PRODUCT_NVIDIA_NFORCE2_400_LAN1 #define PCI_PRODUCT_NVIDIA_NFORCE3_LAN3 PCI_PRODUCT_NVIDIA_NFORCE2_400_LAN2 ==== //depot/projects/smpng/sys/geom/vinum/geom_vinum.h#12 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/geom/vinum/geom_vinum.h,v 1.13 2007/04/12 17:54:35 le Exp $ + * $FreeBSD: src/sys/geom/vinum/geom_vinum.h,v 1.14 2008/10/01 14:50:36 lulf Exp $ */ #ifndef _GEOM_VINUM_H_ @@ -34,9 +34,11 @@ /* geom_vinum_drive.c */ void gv_config_new_drive(struct gv_drive *); void gv_drive_modify(struct gv_drive *); +int gv_read_header(struct g_consumer *, struct gv_hdr *); void gv_save_config_all(struct gv_softc *); void gv_save_config(struct g_consumer *, struct gv_drive *, struct gv_softc *); +int gv_write_header(struct g_consumer *, struct gv_hdr *); /* geom_vinum_init.c */ void gv_parityop(struct g_geom *, struct gctl_req *); ==== //depot/projects/smpng/sys/geom/vinum/geom_vinum_drive.c#21 (text+ko) ==== @@ -25,11 +25,12 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/geom/vinum/geom_vinum_drive.c,v 1.29 2008/08/17 23:27:27 bz Exp $"); +__FBSDID("$FreeBSD: src/sys/geom/vinum/geom_vinum_drive.c,v 1.30 2008/10/01 14:50:36 lulf Exp $"); #include <sys/param.h> #include <sys/bio.h> #include <sys/errno.h> +#include <sys/endian.h> #include <sys/conf.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -48,9 +49,229 @@ #include <geom/vinum/geom_vinum.h> #include <geom/vinum/geom_vinum_share.h> +#define GV_LEGACY_I386 0 +#define GV_LEGACY_AMD64 1 +#define GV_LEGACY_SPARC64 2 +#define GV_LEGACY_POWERPC 3 + static void gv_drive_dead(void *, int); static void gv_drive_worker(void *); +static int gv_legacy_header_type(uint8_t *, int); + +/* + * Here are the "offset (size)" for the various struct gv_hdr fields, + * for the legacy i386 (or 32-bit powerpc), legacy amd64 (or sparc64), and + * current (cpu & endian agnostic) versions of the on-disk format of the vinum + * header structure: + * + * i386 amd64 current field + * -------- -------- -------- ----- + * 0 ( 8) 0 ( 8) 0 ( 8) magic + * 8 ( 4) 8 ( 8) 8 ( 8) config_length + * 12 (32) 16 (32) 16 (32) label.sysname + * 44 (32) 48 (32) 48 (32) label.name + * 76 ( 4) 80 ( 8) 80 ( 8) label.date_of_birth.tv_sec + * 80 ( 4) 88 ( 8) 88 ( 8) label.date_of_birth.tv_usec + * 84 ( 4) 96 ( 8) 96 ( 8) label.last_update.tv_sec + * 88 ( 4) 104 ( 8) 104 ( 8) label.last_update.tv_usec + * 92 ( 8) 112 ( 8) 112 ( 8) label.drive_size + * ======== ======== ======== + * 100 120 120 total size + * + * NOTE: i386 and amd64 formats are stored as little-endian; the current + * format uses big-endian (network order). + */ + + +/* Checks for legacy format depending on platform. */ +static int +gv_legacy_header_type(uint8_t *hdr, int bigendian) +{ + uint32_t *i32; + int arch_32, arch_64, i; + + /* Set arch according to endianess. */ + if (bigendian) { + arch_32 = GV_LEGACY_POWERPC; + arch_64 = GV_LEGACY_SPARC64; + } else { + arch_32 = GV_LEGACY_I386; + arch_64 = GV_LEGACY_AMD64; + } + + /* if non-empty hostname overlaps 64-bit config_length */ + i32 = (uint32_t *)(hdr + 12); + if (*i32 != 0) + return (arch_32); + /* check for non-empty hostname */ + if (hdr[16] != 0) + return (arch_64); + /* check bytes past 32-bit structure */ + for (i = 100; i < 120; i++) + if (hdr[i] != 0) + return (arch_32); + /* check for overlapping timestamp */ + i32 = (uint32_t *)(hdr + 84); + + if (*i32 == 0) + return (arch_64); + return (arch_32); +} + +/* + * Read the header while taking magic number into account, and write it to + * destination pointer. + */ +int +gv_read_header(struct g_consumer *cp, struct gv_hdr *m_hdr) +{ + struct g_provider *pp; + uint64_t magic_machdep; + uint8_t *d_hdr; + int be, off; + +#define GV_GET32(endian) \ + endian##32toh(*((uint32_t *)&d_hdr[off])); \ + off += 4 +#define GV_GET64(endian) \ + endian##64toh(*((uint64_t *)&d_hdr[off])); \ + off += 8 + + KASSERT(m_hdr != NULL, ("gv_read_header: null m_hdr")); + KASSERT(cp != NULL, ("gv_read_header: null cp")); + pp = cp->provider; + KASSERT(pp != NULL, ("gv_read_header: null pp")); + + d_hdr = g_read_data(cp, GV_HDR_OFFSET, pp->sectorsize, NULL); + if (d_hdr == NULL) + return (-1); + off = 0; + m_hdr->magic = GV_GET64(be); + magic_machdep = *((uint64_t *)&d_hdr[0]); + /* + * The big endian machines will have a reverse of GV_OLD_MAGIC, so we + * need to decide if we are running on a big endian machine as well as + * checking the magic against the reverse of GV_OLD_MAGIC. + */ + be = (m_hdr->magic == magic_machdep); + if (m_hdr->magic == GV_MAGIC) { + m_hdr->config_length = GV_GET64(be); + off = 16; + bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + m_hdr->label.date_of_birth.tv_sec = GV_GET64(be); + m_hdr->label.date_of_birth.tv_usec = GV_GET64(be); + m_hdr->label.last_update.tv_sec = GV_GET64(be); + m_hdr->label.last_update.tv_usec = GV_GET64(be); + m_hdr->label.drive_size = GV_GET64(be); + } else if (m_hdr->magic != GV_OLD_MAGIC && + m_hdr->magic != le64toh(GV_OLD_MAGIC)) { + /* Not a gvinum drive. */ + g_free(d_hdr); + return (-1); + } else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_SPARC64) { + printf("VINUM: detected legacy sparc64 header\n"); + m_hdr->magic = GV_MAGIC; + /* Legacy sparc64 on-disk header */ + m_hdr->config_length = GV_GET64(be); + bcopy(d_hdr + 16, m_hdr->label.sysname, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(d_hdr + 48, m_hdr->label.name, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + m_hdr->label.date_of_birth.tv_sec = GV_GET64(be); + m_hdr->label.date_of_birth.tv_usec = GV_GET64(be); + m_hdr->label.last_update.tv_sec = GV_GET64(be); + m_hdr->label.last_update.tv_usec = GV_GET64(be); + m_hdr->label.drive_size = GV_GET64(be); + } else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_POWERPC) { + printf("VINUM: detected legacy PowerPC header\n"); + m_hdr->magic = GV_MAGIC; + /* legacy 32-bit big endian on-disk header */ + m_hdr->config_length = GV_GET32(be); + bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + m_hdr->label.date_of_birth.tv_sec = GV_GET32(be); + m_hdr->label.date_of_birth.tv_usec = GV_GET32(be); + m_hdr->label.last_update.tv_sec = GV_GET32(be); + m_hdr->label.last_update.tv_usec = GV_GET32(be); + m_hdr->label.drive_size = GV_GET64(be); + } else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_I386) { + printf("VINUM: detected legacy i386 header\n"); + m_hdr->magic = GV_MAGIC; + /* legacy i386 on-disk header */ + m_hdr->config_length = GV_GET32(le); + bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + m_hdr->label.date_of_birth.tv_sec = GV_GET32(le); + m_hdr->label.date_of_birth.tv_usec = GV_GET32(le); + m_hdr->label.last_update.tv_sec = GV_GET32(le); + m_hdr->label.last_update.tv_usec = GV_GET32(le); + m_hdr->label.drive_size = GV_GET64(le); + } else { + printf("VINUM: detected legacy amd64 header\n"); + m_hdr->magic = GV_MAGIC; + /* legacy amd64 on-disk header */ + m_hdr->config_length = GV_GET64(le); + bcopy(d_hdr + 16, m_hdr->label.sysname, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(d_hdr + 48, m_hdr->label.name, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + m_hdr->label.date_of_birth.tv_sec = GV_GET64(le); + m_hdr->label.date_of_birth.tv_usec = GV_GET64(le); + m_hdr->label.last_update.tv_sec = GV_GET64(le); + m_hdr->label.last_update.tv_usec = GV_GET64(le); + m_hdr->label.drive_size = GV_GET64(le); + } + + g_free(d_hdr); + return (0); +} + +/* Write out the gvinum header. */ +int +gv_write_header(struct g_consumer *cp, struct gv_hdr *m_hdr) +{ + uint8_t d_hdr[GV_HDR_LEN]; + int off, ret; + +#define GV_SET32BE(field) \ + do { \ + *((uint32_t *)&d_hdr[off]) = htobe32(field); \ + off += 4; \ + } while (0) +#define GV_SET64BE(field) \ + do { \ + *((uint64_t *)&d_hdr[off]) = htobe64(field); \ + off += 8; \ + } while (0) + + KASSERT(m_hdr != NULL, ("gv_write_header: null m_hdr")); + off = 0; + memset(d_hdr, 0, GV_HDR_LEN); + GV_SET64BE(m_hdr->magic); + GV_SET64BE(m_hdr->config_length); + off = 16; + bcopy(m_hdr->label.sysname, d_hdr + off, GV_HOSTNAME_LEN); + off += GV_HOSTNAME_LEN; + bcopy(m_hdr->label.name, d_hdr + off, GV_MAXDRIVENAME); + off += GV_MAXDRIVENAME; + GV_SET64BE(m_hdr->label.date_of_birth.tv_sec); + GV_SET64BE(m_hdr->label.date_of_birth.tv_usec); + GV_SET64BE(m_hdr->label.last_update.tv_sec); + GV_SET64BE(m_hdr->label.last_update.tv_usec); + GV_SET64BE(m_hdr->label.drive_size); + >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810011529.m91FTvv9058448>