From owner-p4-projects@FreeBSD.ORG Sun Sep 10 17:41:01 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4E55916A416; Sun, 10 Sep 2006 17:41:01 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 088C116A412 for ; Sun, 10 Sep 2006 17:41:01 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id A139843D46 for ; Sun, 10 Sep 2006 17:41:00 +0000 (GMT) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8AHf0GA073876 for ; Sun, 10 Sep 2006 17:41:00 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8AHexwr073869 for perforce@freebsd.org; Sun, 10 Sep 2006 17:40:59 GMT (envelope-from mjacob@freebsd.org) Date: Sun, 10 Sep 2006 17:40:59 GMT Message-Id: <200609101740.k8AHexwr073869@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 105939 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Sep 2006 17:41:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=105939 Change 105939 by mjacob@newisp on 2006/09/10 17:40:25 IFC Affected files ... .. //depot/projects/newisp/amd64/linux32/linux32_sysvec.c#2 integrate .. //depot/projects/newisp/compat/freebsd32/freebsd32_proto.h#3 integrate .. //depot/projects/newisp/compat/freebsd32/freebsd32_syscall.h#3 integrate .. //depot/projects/newisp/compat/freebsd32/freebsd32_syscalls.c#3 integrate .. //depot/projects/newisp/compat/freebsd32/freebsd32_sysent.c#3 integrate .. //depot/projects/newisp/compat/freebsd32/syscalls.master#3 integrate .. //depot/projects/newisp/compat/linux/linux_emul.c#3 integrate .. //depot/projects/newisp/compat/linux/linux_file.c#2 integrate .. //depot/projects/newisp/compat/linux/linux_futex.c#2 integrate .. //depot/projects/newisp/dev/bge/if_bge.c#3 integrate .. //depot/projects/newisp/dev/bge/if_bgereg.h#3 integrate .. //depot/projects/newisp/dev/em/if_em.c#4 integrate .. //depot/projects/newisp/dev/em/if_em.h#3 integrate .. //depot/projects/newisp/dev/fdc/fdc.c#3 integrate .. //depot/projects/newisp/dev/ic/nec765.h#2 integrate .. //depot/projects/newisp/dev/mpt/mpt_pci.c#3 integrate .. //depot/projects/newisp/dev/re/if_re.c#2 integrate .. //depot/projects/newisp/dev/sound/usb/uaudio.c#3 integrate .. //depot/projects/newisp/dev/usb/usb_subr.c#3 integrate .. //depot/projects/newisp/geom/gate/g_gate.c#3 integrate .. //depot/projects/newisp/geom/gate/g_gate.h#3 integrate .. //depot/projects/newisp/geom/geom_event.c#2 integrate .. //depot/projects/newisp/geom/mirror/g_mirror.c#2 integrate .. //depot/projects/newisp/geom/nop/g_nop.c#2 integrate .. //depot/projects/newisp/geom/nop/g_nop.h#2 integrate .. //depot/projects/newisp/geom/raid3/g_raid3.c#2 integrate .. //depot/projects/newisp/i386/i386/sys_machdep.c#2 integrate .. //depot/projects/newisp/i386/linux/linux_sysvec.c#2 integrate .. //depot/projects/newisp/kern/kern_ktr.c#2 integrate .. //depot/projects/newisp/kern/tty.c#2 integrate .. //depot/projects/newisp/kern/uipc_socket.c#2 integrate .. //depot/projects/newisp/modules/Makefile#3 integrate .. //depot/projects/newisp/netgraph/bluetooth/drivers/ubt/ng_ubt.c#3 integrate .. //depot/projects/newisp/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#3 integrate .. //depot/projects/newisp/netinet/tcp_subr.c#5 integrate .. //depot/projects/newisp/pc98/cbus/fdc.c#2 integrate .. //depot/projects/newisp/security/audit/audit.c#3 integrate .. //depot/projects/newisp/security/audit/audit_bsm.c#3 integrate .. //depot/projects/newisp/sys/mac_policy.h#2 integrate .. //depot/projects/newisp/sys/param.h#4 integrate Differences ... ==== //depot/projects/newisp/amd64/linux32/linux32_sysvec.c#2 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_sysvec.c,v 1.23 2006/08/17 21:06:48 netchild Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_sysvec.c,v 1.24 2006/09/09 16:25:25 netchild Exp $"); #include "opt_compat.h" #ifndef COMPAT_IA32 @@ -124,7 +124,7 @@ static void linux32_fixlimits(struct proc *p); extern LIST_HEAD(futex_list, futex) futex_list; -extern struct mtx futex_mtx; +extern struct sx futex_sx; static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; @@ -1080,7 +1080,7 @@ sx_init(&emul_lock, "emuldata lock"); sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); - mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF); + sx_init(&futex_sx, "futex protection lock"); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, NULL, 1000); linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail, @@ -1110,7 +1110,7 @@ linux_device_unregister_handler(*ldhp); sx_destroy(&emul_lock); sx_destroy(&emul_shared_lock); - mtx_destroy(&futex_mtx); + sx_destroy(&futex_sx); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); ==== //depot/projects/newisp/compat/freebsd32/freebsd32_proto.h#3 (text+ko) ==== @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/compat/freebsd32/freebsd32_proto.h,v 1.60 2006/09/03 16:24:36 rwatson Exp $ + * $FreeBSD: src/sys/compat/freebsd32/freebsd32_proto.h,v 1.61 2006/09/09 01:22:13 davidxu Exp $ * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.73 2006/09/03 16:17:49 rwatson Exp */ ==== //depot/projects/newisp/compat/freebsd32/freebsd32_syscall.h#3 (text+ko) ==== @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/compat/freebsd32/freebsd32_syscall.h,v 1.58 2006/09/03 16:24:36 rwatson Exp $ + * $FreeBSD: src/sys/compat/freebsd32/freebsd32_syscall.h,v 1.59 2006/09/09 01:22:13 davidxu Exp $ * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.73 2006/09/03 16:17:49 rwatson Exp */ @@ -310,5 +310,10 @@ #define FREEBSD32_SYS_thr_suspend 442 #define FREEBSD32_SYS_thr_wake 443 #define FREEBSD32_SYS_kldunloadf 444 +#define FREEBSD32_SYS_sigqueue 456 #define FREEBSD32_SYS_abort2 463 +#define FREEBSD32_SYS_thr_set_name 464 +#define FREEBSD32_SYS_thr_setscheduler 466 +#define FREEBSD32_SYS_thr_getscheduler 467 +#define FREEBSD32_SYS_thr_setschedparam 468 #define FREEBSD32_SYS_MAXSYSCALL 471 ==== //depot/projects/newisp/compat/freebsd32/freebsd32_syscalls.c#3 (text+ko) ==== @@ -2,7 +2,7 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/compat/freebsd32/freebsd32_syscalls.c,v 1.49 2006/09/03 16:24:36 rwatson Exp $ + * $FreeBSD: src/sys/compat/freebsd32/freebsd32_syscalls.c,v 1.50 2006/09/09 01:22:13 davidxu Exp $ * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.73 2006/09/03 16:17:49 rwatson Exp */ @@ -463,7 +463,7 @@ "#453", /* 453 = auditctl */ "#454", /* 454 = _umtx_op */ "#455", /* 455 = thr_new */ - "#456", /* 456 = sigqueue */ + "sigqueue", /* 456 = sigqueue */ "#457", /* 457 = kmq_open */ "#458", /* 458 = kmq_setattr */ "#459", /* 459 = kmq_timedreceive */ @@ -471,11 +471,11 @@ "#461", /* 461 = kmq_notify */ "#462", /* 462 = kmq_unlink */ "abort2", /* 463 = abort2 */ - "#464", /* 464 = thr_set_name */ + "thr_set_name", /* 464 = thr_set_name */ "#465", /* 465 = aio_fsync */ - "#466", /* 466 = thr_setscheduler */ - "#467", /* 467 = thr_getscheduler */ - "#468", /* 468 = thr_setschedparam */ + "thr_setscheduler", /* 466 = thr_setscheduler */ + "thr_getscheduler", /* 467 = thr_getscheduler */ + "thr_setschedparam", /* 468 = thr_setschedparam */ "#469", /* 469 = __getpath_fromfd */ "#470", /* 470 = __getpath_fromaddr */ }; ==== //depot/projects/newisp/compat/freebsd32/freebsd32_sysent.c#3 (text+ko) ==== @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/compat/freebsd32/freebsd32_sysent.c,v 1.59 2006/09/03 16:24:36 rwatson Exp $ + * $FreeBSD: src/sys/compat/freebsd32/freebsd32_sysent.c,v 1.60 2006/09/09 01:22:13 davidxu Exp $ * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.73 2006/09/03 16:17:49 rwatson Exp */ @@ -488,7 +488,7 @@ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 453 = auditctl */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 454 = _umtx_op */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 455 = thr_new */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 456 = sigqueue */ + { AS(sigqueue_args), (sy_call_t *)sigqueue, AUE_NULL, NULL, 0, 0 }, /* 456 = sigqueue */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 457 = kmq_open */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 458 = kmq_setattr */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 459 = kmq_timedreceive */ @@ -496,11 +496,11 @@ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 461 = kmq_notify */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 462 = kmq_unlink */ { AS(abort2_args), (sy_call_t *)abort2, AUE_NULL, NULL, 0, 0 }, /* 463 = abort2 */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 464 = thr_set_name */ + { AS(thr_set_name_args), (sy_call_t *)thr_set_name, AUE_NULL, NULL, 0, 0 }, /* 464 = thr_set_name */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 465 = aio_fsync */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 466 = thr_setscheduler */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 467 = thr_getscheduler */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 468 = thr_setschedparam */ + { AS(thr_setscheduler_args), (sy_call_t *)thr_setscheduler, AUE_NULL, NULL, 0, 0 }, /* 466 = thr_setscheduler */ + { AS(thr_getscheduler_args), (sy_call_t *)thr_getscheduler, AUE_NULL, NULL, 0, 0 }, /* 467 = thr_getscheduler */ + { AS(thr_setschedparam_args), (sy_call_t *)thr_setschedparam, AUE_NULL, NULL, 0, 0 }, /* 468 = thr_setschedparam */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 469 = __getpath_fromfd */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 470 = __getpath_fromaddr */ }; ==== //depot/projects/newisp/compat/freebsd32/syscalls.master#3 (text+ko) ==== @@ -1,4 +1,4 @@ - $FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.73 2006/09/03 16:17:49 rwatson Exp $ + $FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.74 2006/09/09 01:22:13 davidxu Exp $ ; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; from: src/sys/kern/syscalls.master 1.107 ; @@ -743,7 +743,8 @@ 453 AUE_AUDITCTL UNIMPL auditctl 454 AUE_NULL UNIMPL _umtx_op 455 AUE_NULL UNIMPL thr_new -456 AUE_NULL UNIMPL sigqueue +456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \ + void *value); } 457 AUE_NULL UNIMPL kmq_open 458 AUE_NULL UNIMPL kmq_setattr 459 AUE_NULL UNIMPL kmq_timedreceive @@ -751,10 +752,16 @@ 461 AUE_NULL UNIMPL kmq_notify 462 AUE_NULL UNIMPL kmq_unlink 463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args); } -464 AUE_NULL UNIMPL thr_set_name +464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); } 465 AUE_NULL UNIMPL aio_fsync -466 AUE_NULL UNIMPL thr_setscheduler -467 AUE_NULL UNIMPL thr_getscheduler -468 AUE_NULL UNIMPL thr_setschedparam +466 AUE_NULL NOPROTO { int thr_setscheduler(long id, int policy,\ + const struct sched_param *param, \ + int param_size); } +467 AUE_NULL NOPROTO { int thr_getscheduler(long id, int *policy,\ + struct sched_param *param, \ + int param_size); } +468 AUE_NULL NOPROTO { int thr_setschedparam(long id, \ + const struct sched_param *param, \ + int param_size); } 469 AUE_NULL UNIMPL __getpath_fromfd 470 AUE_NULL UNIMPL __getpath_fromaddr ==== //depot/projects/newisp/compat/linux/linux_emul.c#3 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_emul.c,v 1.5 2006/08/28 13:52:27 ssouhlal Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linux/linux_emul.c,v 1.6 2006/09/09 16:55:55 netchild Exp $"); #include "opt_compat.h" @@ -101,6 +101,7 @@ panic("process not found in proc_init\n"); p->p_emuldata = em; PROC_UNLOCK(p); + EMUL_LOCK(&emul_lock); } else { /* lookup the old one */ em = em_find(td->td_proc, EMUL_UNLOCKED); @@ -129,14 +130,15 @@ if (child != 0) { + EMUL_UNLOCK(&emul_lock); EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_INSERT_HEAD(&em->shared->threads, em, threads); EMUL_SHARED_WUNLOCK(&emul_shared_lock); p = pfind(child); - PROC_UNLOCK(p); /* we might have a sleeping linux_schedtail */ wakeup(&p->p_emuldata); + PROC_UNLOCK(p); } else EMUL_UNLOCK(&emul_lock); ==== //depot/projects/newisp/compat/linux/linux_file.c#2 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_file.c,v 1.96 2006/07/11 20:52:07 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linux/linux_file.c,v 1.97 2006/09/10 13:47:56 netchild Exp $"); #include "opt_compat.h" #include "opt_mac.h" @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -495,6 +496,7 @@ { char *path; int error; + struct stat st; LCONVPATHEXIST(td, args->path, &path); @@ -504,6 +506,11 @@ #endif error = kern_unlink(td, path, UIO_SYSSPACE); + if (error == EPERM) + /* Introduce POSIX noncompliant behaviour of Linux */ + if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0) + if (S_ISDIR(st.st_mode)) + error = EISDIR; LFREEPATH(path); return (error); } ==== //depot/projects/newisp/compat/linux/linux_futex.c#2 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_futex.c,v 1.4 2006/08/26 10:36:16 netchild Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linux/linux_futex.c,v 1.6 2006/09/09 16:25:25 netchild Exp $"); #if 0 __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.5 2005/11/23 16:14:57 manu Exp $"); #endif @@ -47,6 +47,7 @@ #include #include #include +#include #include #ifdef COMPAT_LINUX32 @@ -73,10 +74,10 @@ }; LIST_HEAD(futex_list, futex) futex_list; -struct mtx futex_mtx; /* this protects the LIST of futexes */ +struct sx futex_sx; /* this protects the LIST of futexes */ -#define FUTEX_LOCK mtx_lock(&futex_mtx) -#define FUTEX_UNLOCK mtx_unlock(&futex_mtx) +#define FUTEX_LOCK sx_xlock(&futex_sx) +#define FUTEX_UNLOCK sx_xunlock(&futex_sx) #define FUTEX_LOCKED 1 #define FUTEX_UNLOCKED 0 @@ -302,9 +303,6 @@ ret = futex_wake(f, args->val, NULL); futex_put(f); if (op_ret > 0) { -#ifdef DEBUG - printf("second wakeup\n"); -#endif op_ret = 0; /* * Linux uses the address of the timespec parameter @@ -346,16 +344,11 @@ return f; } } - if (locked == FUTEX_UNLOCKED) - FUTEX_UNLOCK; - /* Not found, create it */ f = malloc(sizeof(*f), M_LINUX, M_WAITOK); f->f_uaddr = uaddr; f->f_refcount = 1; TAILQ_INIT(&f->f_waiting_proc); - if (locked == FUTEX_UNLOCKED) - FUTEX_LOCK; LIST_INSERT_HEAD(&futex_list, f, f_list); if (locked == FUTEX_UNLOCKED) FUTEX_UNLOCK; @@ -421,13 +414,13 @@ FUTEX_LOCK; TAILQ_FOREACH(wp, &f->f_waiting_proc, wp_list) { if (count <= n) { - wakeup(wp); + wakeup_one(wp); count++; } else { if (newf != NULL) { /* futex_put called after tsleep */ wp->wp_new_futex = futex_get(newf->f_uaddr, FUTEX_LOCKED); - wakeup(wp); + wakeup_one(wp); } } } ==== //depot/projects/newisp/dev/bge/if_bge.c#3 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.143 2006/09/03 00:27:41 jmg Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.144 2006/09/09 03:36:57 ambrisko Exp $"); /* * Broadcom BCM570x family gigabit ethernet driver for FreeBSD. @@ -326,6 +326,7 @@ static void bge_txeof(struct bge_softc *); static void bge_rxeof(struct bge_softc *); +static void bge_asf_driver_up (struct bge_softc *); static void bge_tick_locked(struct bge_softc *); static void bge_tick(void *); static void bge_stats_update(struct bge_softc *); @@ -376,7 +377,12 @@ static void bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif -static void bge_reset(struct bge_softc *); +#define BGE_RESET_START 1 +#define BGE_RESET_STOP 2 +static void bge_sig_post_reset(struct bge_softc *, int); +static void bge_sig_legacy(struct bge_softc *, int); +static void bge_sig_pre_reset(struct bge_softc *, int); +static int bge_reset(struct bge_softc *); static void bge_link_upd(struct bge_softc *); static device_method_t bge_methods[] = { @@ -646,7 +652,6 @@ { struct bge_softc *sc; struct mii_data *mii; - sc = device_get_softc(dev); mii = device_get_softc(sc->bge_miibus); @@ -968,6 +973,84 @@ CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]); } +static void +bge_sig_pre_reset(sc, type) + struct bge_softc *sc; + int type; +{ + /* + * Some chips don't like this so only do this if ASF is enabled + */ + if (sc->bge_asf_mode) + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); + + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +static void +bge_sig_post_reset(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001); + /* START DONE */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002); + break; + } + } +} + +static void +bge_sig_legacy(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +void bge_stop_fw(struct bge_softc *); +void +bge_stop_fw(sc) + struct bge_softc *sc; +{ + int i; + + if (sc->bge_asf_mode) { + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE); + CSR_WRITE_4(sc, BGE_CPU_EVENT, + CSR_READ_4(sc, BGE_CPU_EVENT) != (1 << 14)); + + for (i = 0; i < 100; i++ ) { + if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14))) + break; + DELAY(10); + } + } +} + /* * Do endian, PCI and DMA initialization. Also check the on-board ROM * self-test results. @@ -978,7 +1061,7 @@ uint32_t dma_rw_ctl; int i; - /* Set endian type before we access any non-PCI registers. */ + /* Set endianness before we access any non-PCI registers. */ pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, BGE_INIT, 4); /* @@ -1070,6 +1153,12 @@ BGE_MODECTL_TX_NO_PHDR_CSUM); /* + * Tell the firmware the driver is running + */ + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + + /* * Disable memory write invalidate. Apparently it is not supported * properly by these devices. */ @@ -1992,6 +2081,7 @@ uint32_t mac_tmp = 0; u_char eaddr[6]; int error = 0, rid; + int trys; sc = device_get_softc(dev); sc->bge_dev = dev; @@ -2059,7 +2149,38 @@ sc->bge_flags |= BGE_FLAG_PCIX; /* Try to reset the chip. */ - bge_reset(sc); + if (bge_reset(sc)) { + device_printf(sc->bge_dev, "chip reset failed\n"); + bge_release_resources(sc); + error = ENXIO; + goto fail; + } + + sc->bge_asf_mode = 0; + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) + == BGE_MAGIC_NUMBER) { + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG) + & BGE_HWCFG_ASF) { + sc->bge_asf_mode |= ASF_ENABLE; + sc->bge_asf_mode |= ASF_STACKUP; + if (sc->bge_asicrev == BGE_ASICREV_BCM5750) { + sc->bge_asf_mode |= ASF_NEW_HANDSHAKE; + } + } + } + + /* Try to reset the chip again the nice way. */ + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + if (bge_reset(sc)) { + device_printf(sc->bge_dev, "chip reset failed\n"); + bge_release_resources(sc); + error = ENXIO; + goto fail; + } + + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); if (bge_chipinit(sc)) { device_printf(sc->bge_dev, "chip initialization failed\n"); @@ -2186,15 +2307,36 @@ sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media; } else { /* - * Do transceiver setup. + * Do transceiver setup and tell the firmware the + * driver is down so we can try to get access the + * probe if ASF is running. Retry a couple of times + * if we get a conflict with the ASF firmware accessing + * the PHY. */ + BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); +again: + bge_asf_driver_up(sc); + + trys = 0; if (mii_phy_probe(dev, &sc->bge_miibus, bge_ifmedia_upd, bge_ifmedia_sts)) { + if (trys++ < 4) { + device_printf(sc->bge_dev, "Try again\n"); + bge_miibus_writereg(sc->bge_dev, 1, MII_BMCR, BMCR_RESET); + goto again; + } + device_printf(sc->bge_dev, "MII without any PHY!\n"); bge_release_resources(sc); error = ENXIO; goto fail; } + + /* + * Now tell the firmware we are going up after probing the PHY + */ + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); } /* @@ -2295,7 +2437,7 @@ BGE_LOCK_DESTROY(sc); } -static void +static int bge_reset(struct bge_softc *sc) { device_t dev; @@ -2382,7 +2524,7 @@ if (i == BGE_TIMEOUT) { device_printf(sc->bge_dev, "firmware handshake timed out\n"); - return; + return(0); } /* @@ -2403,6 +2545,10 @@ CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS| BGE_MODECTL_BYTESWAP_DATA); + /* Tell the ASF firmware we are up */ + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + CSR_WRITE_4(sc, BGE_MAC_MODE, 0); /* @@ -2428,6 +2574,8 @@ CSR_WRITE_4(sc, 0x7c00, v | (1<<25)); } DELAY(10000); + + return(0); } /* @@ -2741,6 +2889,25 @@ } static void +bge_asf_driver_up(struct bge_softc *sc) +{ + if (sc->bge_asf_mode & ASF_STACKUP) { + /* Send ASF heartbeat aprox. every 2s */ + if (sc->bge_asf_count) + sc->bge_asf_count --; + else { + sc->bge_asf_count = 5; + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, + BGE_FW_DRV_ALIVE); + bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4); + bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3); + CSR_WRITE_4(sc, BGE_CPU_EVENT, + CSR_READ_4(sc, BGE_CPU_EVENT) != (1 << 14)); + } + } +} + +static void bge_tick_locked(struct bge_softc *sc) { struct mii_data *mii = NULL; @@ -2754,7 +2921,9 @@ if ((sc->bge_flags & BGE_FLAG_TBI) == 0) { mii = device_get_softc(sc->bge_miibus); - mii_tick(mii); + /* Don't mess with the PHY in IPMI/ASF mode */ + if (!((sc->bge_asf_mode & ASF_STACKUP) && (sc->bge_link))) + mii_tick(mii); } else { /* * Since in TBI mode auto-polling can't be used we should poll @@ -2771,6 +2940,8 @@ } } + bge_asf_driver_up(sc); + callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc); } @@ -3117,7 +3288,13 @@ /* Cancel pending I/O and flush buffers. */ bge_stop(sc); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_START); bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_START); + bge_sig_post_reset(sc, BGE_RESET_START); + bge_chipinit(sc); /* @@ -3200,7 +3377,7 @@ CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 1); } else #endif - + /* Enable host interrupts. */ { BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA); @@ -3552,7 +3729,20 @@ /* * Tell firmware we're shutting down. */ - BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); + + /* + * Keep the ASF firmware running if up. + */ + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + else + BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); /* Free the RX lists. */ bge_free_rx_ring_std(sc); ==== //depot/projects/newisp/dev/bge/if_bgereg.h#3 (text+ko) ==== @@ -30,7 +30,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.54 2006/09/01 22:45:11 davidch Exp $ + * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.55 2006/09/09 03:36:57 ambrisko Exp $ */ /* @@ -74,6 +74,11 @@ #define BGE_SOFTWARE_GENCOMM 0x00000B50 #define BGE_SOFTWARE_GENCOMM_SIG 0x00000B54 #define BGE_SOFTWARE_GENCOMM_NICCFG 0x00000B58 +#define BGE_SOFTWARE_GENCOMM_FW 0x00000B78 +#define BGE_FW_DRV_ALIVE 0x00000001 +#define BGE_FW_PAUSE 0x00000002 +#define BGE_SOFTWARE_GENNCOMM_FW_LEN 0x00000B7C +#define BGE_SOFTWARE_GENNCOMM_FW_DATA 0x00000B80 #define BGE_SOFTWARE_GENCOMM_END 0x00000FFF #define BGE_UNMAPPED 0x00001000 #define BGE_UNMAPPED_END 0x00001FFF @@ -1651,6 +1656,7 @@ #define BGE_MODE_CTL 0x6800 #define BGE_MISC_CFG 0x6804 #define BGE_MISC_LOCAL_CTL 0x6808 +#define BGE_CPU_EVENT 0x6810 #define BGE_EE_ADDR 0x6838 #define BGE_EE_DATA 0x683C #define BGE_EE_CTL 0x6840 @@ -2064,6 +2070,7 @@ #define BGE_HWCFG_VOLTAGE 0x00000003 #define BGE_HWCFG_PHYLED_MODE 0x0000000C #define BGE_HWCFG_MEDIA 0x00000030 +#define BGE_HWCFG_ASF 0x00000080 #define BGE_VOLTAGE_1POINT3 0x00000000 #define BGE_VOLTAGE_1POINT8 0x00000001 @@ -2434,6 +2441,10 @@ int val; }; +#define ASF_ENABLE 1 +#define ASF_NEW_HANDSHAKE 2 +#define ASF_STACKUP 4 + struct bge_softc { struct ifnet *bge_ifp; /* interface info */ device_t bge_dev; @@ -2453,8 +2464,10 @@ #define BGE_FLAG_PCIX 0x00000010 #define BGE_FLAG_PCIE 0x00000020 uint32_t bge_chipid; - uint8_t bge_asicrev; - uint8_t bge_chiprev; + uint8_t bge_asicrev; + uint8_t bge_chiprev; + uint8_t bge_asf_mode; + uint8_t bge_asf_count; struct bge_ring_data bge_ldata; /* rings */ struct bge_chain_data bge_cdata; /* mbufs */ uint16_t bge_tx_saved_considx; ==== //depot/projects/newisp/dev/em/if_em.c#4 (text+ko) ==== @@ -31,7 +31,7 @@ ***************************************************************************/ -/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.139 2006/09/03 00:27:41 jmg Exp $*/ +/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.142 2006/09/09 20:05:24 pdeuskar Exp $*/ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" @@ -72,6 +72,7 @@ #include #include +#include #include #include #include @@ -86,7 +87,7 @@ * Driver version *********************************************************************/ -char em_driver_version[] = "Version - 6.1.4"; +char em_driver_version[] = "Version - 6.1.4 - TSO"; /********************************************************************* @@ -231,6 +232,8 @@ struct mbuf *); static void em_transmit_checksum_setup(struct adapter *, struct mbuf *, uint32_t *, uint32_t *); +static boolean_t em_tso_setup(struct adapter *, struct mbuf *, + uint32_t *, uint32_t *); static void em_set_promisc(struct adapter *); static void em_disable_promisc(struct adapter *); static void em_set_multi(struct adapter *); @@ -304,6 +307,7 @@ #define E1000_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000) #define E1000_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) +#define M_TSO_LEN 66 static int em_tx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TIDV); static int em_rx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RDTR); @@ -907,6 +911,10 @@ ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; } + if (mask & IFCAP_TSO) { + ifp->if_capenable ^= IFCAP_TSO; + reinit = 1; + } if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; reinit = 1; @@ -1075,11 +1083,12 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_hwassist = 0; if (adapter->hw.mac_type >= em_82543) { if (ifp->if_capenable & IFCAP_TXCSUM) ifp->if_hwassist = EM_CHECKSUM_FEATURES; - else - ifp->if_hwassist = 0; + if (ifp->if_capenable & IFCAP_TSO) + ifp->if_hwassist |= EM_TCPSEG_FEATURES; } callout_reset(&adapter->timer, hz, em_local_timer, adapter); @@ -1441,11 +1450,13 @@ struct m_tag *mtag; uint32_t txd_upper, txd_lower, txd_used, txd_saved; int nsegs, i, j; - int error; + int error, do_tso, tso_desc = 0; m_head = *m_headp; current_tx_desc = NULL; - txd_used = txd_saved = 0; + txd_upper = txd_lower = txd_used = txd_saved = 0; + + do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); /* * Force a cleanup if number of TX descriptors @@ -1498,6 +1509,17 @@ *m_headp = m_head; } + /* + * TSO workaround: + * If an mbuf is only header we need + * to pull 4 bytes of data into it. + */ + if (do_tso && (m_head->m_len <= M_TSO_LEN)) { + m_head = m_pullup(m_head, M_TSO_LEN + 4); + if (m_head == NULL) + return (ENOBUFS); + } + /* * Map the packet for DMA. */ @@ -1536,24 +1558,42 @@ return (EIO); } - if (nsegs > adapter->num_tx_desc_avail) { + /* + * TSO Hardware workaround, if this packet is not + * TSO, and is only a single descriptor long, and + * it follows a TSO burst, then we need to add a + * sentinel descriptor to prevent premature writeback. + */ + if ((do_tso == 0) && (adapter->tx_tso == TRUE)) { + if (nsegs == 1) + tso_desc = TRUE; + adapter->tx_tso = FALSE; + } + + if (nsegs > adapter->num_tx_desc_avail - 2) { adapter->no_tx_desc_avail2++; bus_dmamap_unload(adapter->txtag, map); return (ENOBUFS); } + /* Do hardware assists */ m_head = *m_headp; - if (ifp->if_hwassist > 0) - em_transmit_checksum_setup(adapter, m_head, &txd_upper, &txd_lower); - else - txd_upper = txd_lower = 0; + if ( ifp->if_hwassist > 0) { + if (em_tso_setup(adapter, m_head, &txd_upper, &txd_lower)) { + /* we need to make a final sentinel transmit desc */ + tso_desc = TRUE; + } else + em_transmit_checksum_setup(adapter, m_head, + &txd_upper, &txd_lower); + } i = adapter->next_avail_tx_desc; - if (adapter->pcix_82544) { + if (adapter->pcix_82544) txd_saved = i; - txd_used = 0; - } + for (j = 0; j < nsegs; j++) { + bus_size_t seg_len; + bus_addr_t seg_addr; /* If adapter is 82544 and on PCIX bus. */ if(adapter->pcix_82544) { DESC_ARRAY desc_array; @@ -1587,26 +1627,57 @@ txd_used++; } } else { - tx_buffer = &adapter->tx_buffer_area[i]; - current_tx_desc = &adapter->tx_desc_base[i]; - - current_tx_desc->buffer_addr = htole64(segs[j].ds_addr); - current_tx_desc->lower.data = htole32( - adapter->txd_cmd | txd_lower | segs[j].ds_len); - current_tx_desc->upper.data = htole32(txd_upper); - - if (++i == adapter->num_tx_desc) - i = 0; - - tx_buffer->m_head = NULL; + tx_buffer = &adapter->tx_buffer_area[i]; + current_tx_desc = &adapter->tx_desc_base[i]; + seg_addr = htole64(segs[j].ds_addr); + seg_len = segs[j].ds_len; + /* + ** TSO Workaround: + ** If this is the last descriptor, we want to + ** split it so we have a small final sentinel + */ >>> TRUNCATED FOR MAIL (1000 lines) <<<