From 165a00d1dead06c8b5c6d4562be540554229a936 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Thu, 1 Oct 2009 20:56:15 +0000 Subject: [PATCH 001/646] Compile ACPI debugger and disassembler for kernel modules unconditionally. These files will generate almost empty object files without ACPI_DEBUG/DDB options. As a result, size of acpi.ko will increase slightly. --- sys/modules/acpi/acpi/Makefile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/sys/modules/acpi/acpi/Makefile b/sys/modules/acpi/acpi/Makefile index 24e688d7cea..80b9b942880 100644 --- a/sys/modules/acpi/acpi/Makefile +++ b/sys/modules/acpi/acpi/Makefile @@ -27,6 +27,10 @@ KMOD= acpi # ACPI CA sources +SRCS+= dbcmds.c dbdisply.c dbexec.c dbfileio.c dbhistry.c dbinput.c dbstats.c +SRCS+= dbutils.c dbxface.c +SRCS+= dmbuffer.c dmnames.c dmopcode.c dmobject.c dmresrc.c dmresrcl.c +SRCS+= dmresrcs.c dmutils.c dmwalk.c SRCS+= dsfield.c dsinit.c dsmethod.c dsmthdat.c dsobject.c dsopcode.c SRCS+= dsutils.c dswexec.c dswload.c dswscope.c dswstate.c SRCS+= evevent.c evgpe.c evgpeblk.c evmisc.c evregion.c evrgnini.c evsci.c @@ -69,12 +73,6 @@ SRCS+= cpufreq_if.h device_if.h isa_if.h pci_if.h pcib_if.h # This obviously needs a better and more structural fix. SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_compat.h opt_hwpmc_hooks.h -# Debugging support -DBSRC= dbcmds.c dbdisply.c dbexec.c dbfileio.c dbhistry.c dbinput.c dbstats.c -DBSRC+= dbutils.c dbxface.c -DBSRC+= dmbuffer.c dmnames.c dmopcode.c dmobject.c dmresrc.c dmresrcl.c -DBSRC+= dmresrcs.c dmutils.c dmwalk.c - .if !defined(KERNBUILDDIR) .if KTR CFLAGS+=-DKTR @@ -87,7 +85,6 @@ CFLAGS+=-DACPI_MAX_THREADS=${ACPI_MAX_THREADS} .endif .if ACPI_DEBUG CFLAGS+=-DACPI_DEBUG -SRCS+= ${DBSRC} opt_ddb.h: Makefile echo "#define DDB 1" > ${.TARGET} .else @@ -98,10 +95,12 @@ opt_ddb.h: Makefile # Machine-specific code such as sleep/wakeup SRCS+= acpi_machdep.c acpi_wakecode.h acpi_wakeup.c -.if ${MACHINE} == "i386" -SRCS+= madt.c assym.s +SRCS+= assym.s madt.c +CLEANFILES+= acpi_wakecode.bin acpi_wakecode.h acpi_wakecode.o +.if ${MACHINE_ARCH} == "amd64" +SRCS+= opt_global.h +CLEANFILES+= acpi_wakedata.h .endif -CLEANFILES+= acpi_wakecode.h acpi_wakecode.o acpi_wakecode.bin ${DBSRC:.c=.o} acpi_wakecode.h: acpi_wakecode.S assym.s ${MAKE} -f ${.CURDIR}/../../../${MACHINE_ARCH}/acpica/Makefile \ From 47e5ae08a16d8d540ce8db74488530e976b78c33 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Thu, 1 Oct 2009 21:40:08 +0000 Subject: [PATCH 002/646] sh: Disallow mismatched quotes in backticks (`...`). Due to the amount of code removed by this, it seems that allowing unmatched quotes was a deliberate imitation of System V sh and real ksh. Most other shells do not allow unmatched quotes (e.g. bash, zsh, pdksh, NetBSD /bin/sh, dash). PR: bin/137657 --- bin/sh/parser.c | 8 +------- tools/regression/bin/sh/errors/backquote-error2.0 | 7 +++++++ 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 tools/regression/bin/sh/errors/backquote-error2.0 diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 54a80a715d0..9e861620e5f 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -82,7 +82,6 @@ struct heredoc { STATIC struct heredoc *heredoclist; /* list of here documents to read */ -STATIC int parsebackquote; /* nonzero if we are inside backquotes */ STATIC int doprompt; /* if set, prompt the user */ STATIC int needprompt; /* true if interactive and at start of line */ STATIC int lasttoken; /* last token read */ @@ -1043,7 +1042,7 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs) endword: if (syntax == ARISYNTAX) synerror("Missing '))'"); - if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) + if (syntax != BASESYNTAX && eofmark == NULL) synerror("Unterminated quoted string"); if (varnest != 0) { startlinno = plinno; @@ -1303,7 +1302,6 @@ parsesub: { parsebackq: { struct nodelist **nlpp; - int savepbq; union node *n; char *volatile str; struct jmploc jmploc; @@ -1311,11 +1309,9 @@ parsebackq: { int savelen; int saveprompt; - savepbq = parsebackquote; if (setjmp(jmploc.loc)) { if (str) ckfree(str); - parsebackquote = 0; handler = savehandler; longjmp(handler->loc, 1); } @@ -1397,7 +1393,6 @@ done: nlpp = &(*nlpp)->next; *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); (*nlpp)->next = NULL; - parsebackquote = oldstyle; if (oldstyle) { saveprompt = doprompt; @@ -1433,7 +1428,6 @@ done: str = NULL; INTON; } - parsebackquote = savepbq; handler = savehandler; if (arinest || dblquote) USTPUTC(CTLBACKQ | CTLQUOTE, out); diff --git a/tools/regression/bin/sh/errors/backquote-error2.0 b/tools/regression/bin/sh/errors/backquote-error2.0 new file mode 100644 index 00000000000..977c055a2af --- /dev/null +++ b/tools/regression/bin/sh/errors/backquote-error2.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +sh -c 'echo `echo .BA"DCODE.` +echo ".BAD"CODE.' 2>&1 | grep -q BADCODE && exit 1 +echo '`"`' | sh -n 2>/dev/null && exit 1 +echo '`'"'"'`' | sh -n 2>/dev/null && exit 1 +exit 0 From e380cc73ed3b1be0ad30edab07313573504d61a5 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 1 Oct 2009 21:44:30 +0000 Subject: [PATCH 003/646] In fill_kinfo_thread, copy the thread's name into struct kinfo_proc even if it is empty. Otherwise the previous thread's name would remain in the struct and then be reported for this thread. Submitted by: Ryan Stone MFC after: 1 week --- sys/kern/kern_proc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index e012a3ed4c0..f931245fda4 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -847,8 +847,7 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) strlcpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg)); else bzero(kp->ki_wmesg, sizeof(kp->ki_wmesg)); - if (td->td_name[0] != '\0') - strlcpy(kp->ki_ocomm, td->td_name, sizeof(kp->ki_ocomm)); + strlcpy(kp->ki_ocomm, td->td_name, sizeof(kp->ki_ocomm)); if (TD_ON_LOCK(td)) { kp->ki_kiflag |= KI_LOCKBLOCK; strlcpy(kp->ki_lockname, td->td_lockname, From 46aba52a50f762e621dd71ab87c10fca9ab8fb52 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 1 Oct 2009 22:05:38 +0000 Subject: [PATCH 004/646] make read_eflags and write_eflags accomplish the same effect on PVM as native, simplifying interrupt handling --- sys/i386/i386/vm_machdep.c | 8 ------- sys/i386/include/cpufunc.h | 20 ++++++++--------- sys/i386/xen/xen_machdep.c | 44 ++++++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index b6fd4b6067c..e7f55a1aac4 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -270,11 +270,7 @@ cpu_fork(td1, p2, td2, flags) /* * XXX XEN need to check on PSL_USER is handled */ -#ifdef XEN - td2->td_md.md_saved_flags = 0; -#else td2->td_md.md_saved_flags = PSL_KERNEL | PSL_I; -#endif /* * Now, cpu_switch() can schedule the new process. * pcb_esp is loaded pointing to the cpu_switch() stack frame @@ -446,11 +442,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0) /* Setup to release spin count in fork_exit(). */ td->td_md.md_spinlock_count = 1; -#ifdef XEN - td->td_md.md_saved_flags = 0; -#else td->td_md.md_saved_flags = PSL_KERNEL | PSL_I; -#endif } /* diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index 78863d1467c..a0cecca0578 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -49,8 +49,8 @@ extern u_int xen_rcr2(void); extern void xen_load_cr3(u_int data); extern void xen_tlb_flush(void); extern void xen_invlpg(u_int addr); -extern int xen_save_and_cli(void); -extern void xen_restore_flags(u_int eflags); +extern void write_eflags(u_int eflags); +extern u_int read_eflags(void); #endif struct region_descriptor; @@ -293,7 +293,11 @@ ia32_pause(void) } static __inline u_int +#ifdef XEN +_read_eflags(void) +#else read_eflags(void) +#endif { u_int ef; @@ -335,7 +339,11 @@ wbinvd(void) } static __inline void +#ifdef XEN +_write_eflags(u_int ef) +#else write_eflags(u_int ef) +#endif { __asm __volatile("pushl %0; popfl" : : "r" (ef)); } @@ -653,23 +661,15 @@ intr_disable(void) { register_t eflags; -#ifdef XEN - eflags = xen_save_and_cli(); -#else eflags = read_eflags(); disable_intr(); -#endif return (eflags); } static __inline void intr_restore(register_t eflags) { -#ifdef XEN - xen_restore_flags(eflags); -#else write_eflags(eflags); -#endif } #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index 878f436fde7..2c5ba5b2156 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -101,6 +102,7 @@ void ni_sti(void); void ni_cli(void) { + CTR0(KTR_SPARE2, "ni_cli disabling interrupts"); __asm__("pushl %edx;" "pushl %eax;" ); @@ -345,33 +347,53 @@ xen_load_cr3(u_int val) PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); } -void -xen_restore_flags(u_int eflags) +#ifdef KTR +static __inline u_int +rebp(void) { - if (eflags > 1) - eflags = ((eflags & PSL_I) == 0); + u_int data; - __restore_flags(eflags); + __asm __volatile("movl 4(%%ebp),%0" : "=r" (data)); + return (data); +} +#endif + +u_int +read_eflags(void) +{ + vcpu_info_t *_vcpu; + u_int eflags; + + eflags = _read_eflags(); + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; + if (_vcpu->evtchn_upcall_mask) + eflags &= ~PSL_I; + + return (eflags); } -int -xen_save_and_cli(void) +void +write_eflags(u_int eflags) { - int eflags; - - __save_and_cli(eflags); - return (eflags); + u_int intr; + + CTR2(KTR_SPARE2, "%x xen_restore_flags eflags %x", rebp(), eflags); + intr = ((eflags & PSL_I) == 0); + __restore_flags(intr); + _write_eflags(eflags); } void xen_cli(void) { + CTR1(KTR_SPARE2, "%x xen_cli disabling interrupts", rebp()); __cli(); } void xen_sti(void) { + CTR1(KTR_SPARE2, "%x xen_sti enabling interrupts", rebp()); __sti(); } From fa3cfd39ff667b00cdb61d99f4877c1080340b14 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Oct 2009 01:34:55 +0000 Subject: [PATCH 005/646] Previously, if an address alias is configured on an interface, and this address alias has a prefix matching that of another address configured on the same interface, then the ARP entry for the alias is not deleted from the ARP table when that address alias is removed. This patch fixes the aforementioned issue. PR: kern/139113 MFC after: 3 days --- sys/netinet/in.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 11e098ed0cf..5b20d5ba10c 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1060,6 +1060,8 @@ in_scrubprefix(struct in_ifaddr *target) !(target->ia_ifp->if_flags & IFF_LOOPBACK)) { error = ifa_del_loopback_route((struct ifaddr *)target, (struct sockaddr *)&target->ia_addr); + /* remove arp cache */ + arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr); } if ((target->ia_flags & IFA_ROUTE) == 0) { @@ -1082,8 +1084,6 @@ in_scrubprefix(struct in_ifaddr *target) prefix = target->ia_addr.sin_addr; mask = target->ia_sockmask.sin_addr; prefix.s_addr &= mask.s_addr; - /* remove arp cache */ - arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr); } IN_IFADDR_RLOCK(); From b4a22c365c85296832a41baa613415117449517c Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Oct 2009 01:45:11 +0000 Subject: [PATCH 006/646] Remove a log message from production code. This log message can be triggered by a misconfigured host that is sending out gratuious ARPs. This log message can also be triggered during a network renumbering event when multiple prefixes co-exist on a single network segment. MFC after: immediately --- sys/netinet/in.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 5b20d5ba10c..dc4a8e1eb46 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1327,8 +1327,10 @@ in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr) /* XXX rtalloc1 should take a const param */ rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0); if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) { +#ifdef DIAGNOSTICS log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); +#endif if (rt != NULL) RTFREE_LOCKED(rt); return (EINVAL); From b558571de612b5cef92ca5a7f76dbe5983eafc66 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 02:24:25 +0000 Subject: [PATCH 007/646] - Add AF_IPX and AF_NATM to afexists(). - Add afexists() check to address family specific rc.d scripts. A script for an AF will be silently ignored if the kernel has no support for the AF. --- etc/network.subr | 10 ++++++++++ etc/rc.d/defaultroute | 2 ++ etc/rc.d/faith | 4 ++++ etc/rc.d/ip6addrctl | 34 ++++++++++++++++++---------------- etc/rc.d/static_arp | 5 +++++ etc/rc.d/stf | 4 ++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/etc/network.subr b/etc/network.subr index 83141ec3879..d2c2111d5f8 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -356,6 +356,16 @@ afexists() inet6) ${SYSCTL_N} net.inet6 > /dev/null 2>&1 ;; + ipx) + ${SYSCTL_N} net.ipx > /dev/null 2>&1 + ;; + atm) + if [ -x /sbin/atmconfig ]; then + /sbin/atmconfig diag list > /dev/null 2>&1 + else + return 1 + fi + ;; *) err 1 "afexists(): Unsupported address family: $_af" ;; diff --git a/etc/rc.d/defaultroute b/etc/rc.d/defaultroute index cade406b796..b4dc3731546 100755 --- a/etc/rc.d/defaultroute +++ b/etc/rc.d/defaultroute @@ -20,6 +20,8 @@ defaultroute_start() { local output carrier nocarrier nl + afexists inet || return 0 + # Return without waiting if we don't have dhcp interfaces or # if none of the dhcp interfaces is plugged in. dhcp_interfaces=`list_net_interfaces dhcp` diff --git a/etc/rc.d/faith b/etc/rc.d/faith index 020b947ec86..e48fff78bd4 100755 --- a/etc/rc.d/faith +++ b/etc/rc.d/faith @@ -15,6 +15,8 @@ stop_cmd="faith_down" faith_up() { + afexists inet6 || return 0 + case ${ipv6_faith_prefix} in [Nn][Oo] | '') ;; @@ -48,6 +50,8 @@ faith_up() faith_down() { + afexists inet6 || return 0 + echo "Removing IPv6-to-IPv4 TCP relay capturing interface: faith0." ifconfig faith0 destroy ${SYSCTL_W} net.inet6.ip6.keepfaith=0 diff --git a/etc/rc.d/ip6addrctl b/etc/rc.d/ip6addrctl index 66f1952a65b..d3b18561795 100755 --- a/etc/rc.d/ip6addrctl +++ b/etc/rc.d/ip6addrctl @@ -9,6 +9,7 @@ # KEYWORD: nojail . /etc/rc.subr +. /etc/network.subr name="ip6addrctl" rcvar=`set_rcvar` @@ -23,6 +24,8 @@ set_rcvar_obsolete ipv6_enable ipv6_prefer ip6addrctl_prefer_ipv6() { + afexists inet6 || return 0 + ip6addrctl flush >/dev/null 2>&1 ip6addrctl add ::1/128 50 0 ip6addrctl add ::/0 40 1 @@ -34,6 +37,8 @@ ip6addrctl_prefer_ipv6() ip6addrctl_prefer_ipv4() { + afexists inet6 || return 0 + ip6addrctl flush >/dev/null 2>&1 ip6addrctl add ::ffff:0:0/96 50 0 ip6addrctl add ::1/128 40 1 @@ -45,30 +50,27 @@ ip6addrctl_prefer_ipv4() ip6addrctl_start() { - if ifconfig lo0 inet6 >/dev/null 2>&1; then - # We have IPv6 support in kernel. + afexists inet6 || return 0 - # install the policy of the address selection algorithm. - if [ -f /etc/ip6addrctl.conf ]; then - ip6addrctl flush >/dev/null 2>&1 - ip6addrctl install /etc/ip6addrctl.conf - checkyesno ip6addrctl_verbose && ip6addrctl + # install the policy of the address selection algorithm. + if [ -f /etc/ip6addrctl.conf ]; then + ip6addrctl flush >/dev/null 2>&1 + ip6addrctl install /etc/ip6addrctl.conf + checkyesno ip6addrctl_verbose && ip6addrctl + else + if checkyesno ipv6_prefer; then + ip6addrctl_prefer_ipv6 else - if checkyesno ipv6_prefer; then - ip6addrctl_prefer_ipv6 - else - ip6addrctl_prefer_ipv4 - fi + ip6addrctl_prefer_ipv4 fi fi } ip6addrctl_stop() { - if ifconfig lo0 inet6 >/dev/null 2>&1; then - # We have IPv6 support in kernel. - ip6addrctl flush >/dev/null 2>&1 - fi + afexists inet6 || return 0 + + ip6addrctl flush >/dev/null 2>&1 } load_rc_config $name diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp index 582518fe97e..816d581d7ce 100644 --- a/etc/rc.d/static_arp +++ b/etc/rc.d/static_arp @@ -34,6 +34,7 @@ # KEYWORD: nojail . /etc/rc.subr +. /etc/network.subr name="static_arp" start_cmd="static_arp_start" @@ -43,6 +44,8 @@ static_arp_start() { local e arp_args + afexists inet || return 0 + if [ -n "${static_arp_pairs}" ]; then echo -n 'Binding static ARP pair(s):' for e in ${static_arp_pairs}; do @@ -58,6 +61,8 @@ static_arp_stop() { local e arp_args + afexists inet || return 0 + if [ -n "${static_arp_pairs}" ]; then echo -n 'Unbinding static ARP pair(s):' for e in ${static_arp_pairs}; do diff --git a/etc/rc.d/stf b/etc/rc.d/stf index 40b182a0de9..fa1bfbd522d 100755 --- a/etc/rc.d/stf +++ b/etc/rc.d/stf @@ -15,6 +15,8 @@ stop_cmd="stf_down" stf_up() { + afexists inet6 || return 0 + case ${stf_interface_ipv4addr} in [Nn][Oo] | '') ;; @@ -67,6 +69,8 @@ stf_up() stf_down() { + afexists inet6 || return 0 + echo "Removing 6to4 tunnel interface: stf0." ifconfig stf0 destroy route delete -inet6 2002:e000:: -prefixlen 20 ::1 From 01ce5591adfbae93370eb4a7644c04f9496396e2 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 02:27:49 +0000 Subject: [PATCH 008/646] - Fix logic inversion bug of net.inet.tcp.rfc1323[*]. - Split netoptions_start() to netoptions_AF() and add afexists() check for each address family. - Display a message only if the user sets a non-default value, and set a sysctl explicitly even if it is the default value. Spotted by: Pegasus Mc Cleaft[*] --- etc/rc.d/netoptions | 49 +++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/etc/rc.d/netoptions b/etc/rc.d/netoptions index 2d21525d50c..c30563d213f 100755 --- a/etc/rc.d/netoptions +++ b/etc/rc.d/netoptions @@ -25,30 +25,49 @@ netoptions_init() } netoptions_start() +{ + local _af + + for _af in inet inet6; do + afexists ${_af} && eval netoptions_${_af} + done + [ -n "${_netoptions_initdone}" ] && echo '.' +} + +netoptions_inet() { if checkyesno log_in_vain; then netoptions_init echo -n " log_in_vain=${log_in_vain}" - ${SYSCTL_W} net.inet.tcp.log_in_vain="${log_in_vain}" >/dev/null - ${SYSCTL_W} net.inet.udp.log_in_vain="${log_in_vain}" >/dev/null + ${SYSCTL_W} net.inet.tcp.log_in_vain=1 >/dev/null + ${SYSCTL_W} net.inet.udp.log_in_vain=1 >/dev/null + else + ${SYSCTL_W} net.inet.tcp.log_in_vain=0 >/dev/null + ${SYSCTL_W} net.inet.udp.log_in_vain=0 >/dev/null fi if checkyesno tcp_extensions; then + ${SYSCTL_W} net.inet.tcp.rfc1323=1 >/dev/null + else netoptions_init - echo -n ' rfc1323 extensions=NO' + echo -n ' rfc1323 extensions=${tcp_extensions}' ${SYSCTL_W} net.inet.tcp.rfc1323=0 >/dev/null fi - if ! checkyesno tcp_keepalive; then + if checkyesno tcp_keepalive; then + ${SYSCTL_W} net.inet.tcp.always_keepalive=1 >/dev/null + else netoptions_init - echo -n ' TCP keepalive=NO' + echo -n ' TCP keepalive=${tcp_keepalive}' ${SYSCTL_W} net.inet.tcp.always_keepalive=0 >/dev/null fi if checkyesno tcp_drop_synfin; then netoptions_init - echo -n ' drop SYN+FIN packets=YES' + echo -n ' drop SYN+FIN packets=${tcp_drop_synfin}' ${SYSCTL_W} net.inet.tcp.drop_synfin=1 >/dev/null + else + ${SYSCTL_W} net.inet.tcp.drop_synfin=0 >/dev/null fi case ${ip_portrange_first} in @@ -66,17 +85,17 @@ netoptions_start() ${SYSCTL_W} net.inet.ip.portrange.last=$ip_portrange_last >/dev/null ;; esac +} - if afexists inet6; then - if checkyesno ipv6_ipv4mapping; then - ${SYSCTL_W} net.inet6.ip6.v6only=0 >/dev/null - else - echo -n " no-ipv4-mapped-ipv6" - ${SYSCTL_W} net.inet6.ip6.v6only=1 >/dev/null - fi +netoptions_inet6() +{ + if checkyesno ipv6_ipv4mapping; then + netoptions_init + echo -n " ipv4-mapped-ipv6=${ipv6_ipv4mapping}" + ${SYSCTL_W} net.inet6.ip6.v6only=0 >/dev/null + else + ${SYSCTL_W} net.inet6.ip6.v6only=1 >/dev/null fi - - [ -n "${_netoptions_initdone}" ] && echo '.' } load_rc_config $name From e248dc09a8f5d9ad2b09c957fc992b0761f76e6f Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 02:28:59 +0000 Subject: [PATCH 009/646] - Split routing_*() and option_*() to *_AF() and add afexists() check for each address family. Replace AF_static() with static_AF() for consistency. - Display a message only if the user sets a non-default value, and set a sysctl explicitly even if it is the default value. --- etc/rc.d/routing | 142 ++++++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 56 deletions(-) diff --git a/etc/rc.d/routing b/etc/rc.d/routing index 3b399882f96..7edc3bab168 100755 --- a/etc/rc.d/routing +++ b/etc/rc.d/routing @@ -27,8 +27,24 @@ routing_start() routing_stop() { + local _af + static_stop "$@" - route -n flush + for _af in inet inet6; do + afexists ${_af} && eval routing_stop_${_af} + done +} + +routing_stop_inet() +{ + route -n flush -inet +} + +routing_stop_inet6() +{ + local i + + route -n flush -inet6 for i in ${ipv6_network_interfaces}; do ifconfig $i inet6 -defaultif done @@ -40,21 +56,11 @@ static_start() _af=$1 case ${_af} in - inet) - do_static inet add + inet|inet6|atm) + do_static add ${_af} ;; - inet6) - do_static inet6 add - ;; - atm) - do_static atm add - ;; - *) - do_static inet add - if afexists inet6; then - do_static inet6 add - fi - do_static atm add + "") + do_static add inet inet6 atm ;; esac } @@ -65,21 +71,11 @@ static_stop() _af=$1 case ${_af} in - inet) - do_static inet delete + inet|inet6|atm) + do_static delete ${_af} ;; - inet6) - do_static inet6 delete - ;; - atm) - do_static atm delete - ;; - *) - do_static inet delete - if afexists inet6; then - do_static inet6 delete - fi - do_static atm delete + "") + do_static delete inet inet6 atm ;; esac } @@ -87,13 +83,15 @@ static_stop() do_static() { local _af _action - _af=$1 - _action=$2 + _action=$1 - eval $1_static $2 + shift + for _af in "$@"; do + afexists ${_af} && eval static_${_af} ${_action} + done } -inet_static() +static_inet() { local _action _action=$1 @@ -115,7 +113,7 @@ inet_static() fi } -inet6_static() +static_inet6() { local _action i _action=$1 @@ -222,9 +220,9 @@ inet6_static() esac } -atm_static() +static_atm() { - local _action i + local _action i route_args _action=$1 if [ -n "${natm_static_routes}" ]; then @@ -245,62 +243,94 @@ ropts_init() } options_start() +{ + local _af + + for _af in inet inet6 ipx; do + afexists ${_af} && eval options_${_af} + done + [ -n "${_ropts_initdone}" ] && echo '.' +} + +options_inet() { if checkyesno icmp_bmcastecho; then ropts_init echo -n ' broadcast ping responses=YES' - sysctl net.inet.icmp.bmcastecho=1 >/dev/null + ${SYSCTL_W} net.inet.icmp.bmcastecho=1 > /dev/null + else + ${SYSCTL_W} net.inet.icmp.bmcastecho=0 > /dev/null fi if checkyesno icmp_drop_redirect; then ropts_init echo -n ' ignore ICMP redirect=YES' - sysctl net.inet.icmp.drop_redirect=1 >/dev/null + ${SYSCTL_W} net.inet.icmp.drop_redirect=1 > /dev/null + else + ${SYSCTL_W} net.inet.icmp.drop_redirect=0 > /dev/null fi if checkyesno icmp_log_redirect; then ropts_init echo -n ' log ICMP redirect=YES' - sysctl net.inet.icmp.log_redirect=1 >/dev/null + ${SYSCTL_W} net.inet.icmp.log_redirect=1 > /dev/null + else + ${SYSCTL_W} net.inet.icmp.log_redirect=0 > /dev/null fi if checkyesno gateway_enable; then ropts_init echo -n ' IPv4 gateway=YES' - sysctl net.inet.ip.forwarding=1 >/dev/null - fi - - if checkyesno ipv6_gateway_enable; then - ropts_init - echo -n ' IPv6 gateway=YES' - sysctl net.inet6.ip6.forwarding=1 >/dev/null + ${SYSCTL_W} net.inet.ip.forwarding=1 > /dev/null + else + ${SYSCTL_W} net.inet.ip.forwarding=0 > /dev/null fi if checkyesno forward_sourceroute; then ropts_init echo -n ' do source routing=YES' - sysctl net.inet.ip.sourceroute=1 >/dev/null + ${SYSCTL_W} net.inet.ip.sourceroute=1 > /dev/null + else + ${SYSCTL_W} net.inet.ip.sourceroute=0 > /dev/null fi if checkyesno accept_sourceroute; then ropts_init echo -n ' accept source routing=YES' - sysctl net.inet.ip.accept_sourceroute=1 >/dev/null - fi - - if checkyesno ipxgateway_enable; then - ropts_init - echo -n ' IPX gateway=YES' - sysctl net.ipx.ipx.ipxforwarding=1 >/dev/null + ${SYSCTL_W} net.inet.ip.accept_sourceroute=1 > /dev/null + else + ${SYSCTL_W} net.inet.ip.accept_sourceroute=0 > /dev/null fi if checkyesno arpproxy_all; then ropts_init echo -n ' ARP proxyall=YES' - sysctl net.link.ether.inet.proxyall=1 >/dev/null + ${SYSCTL_W} net.link.ether.inet.proxyall=1 > /dev/null + else + ${SYSCTL_W} net.link.ether.inet.proxyall=0 > /dev/null fi +} - [ -n "${_ropts_initdone}" ] && echo '.' +options_inet6() +{ + if checkyesno ipv6_gateway_enable; then + ropts_init + echo -n ' IPv6 gateway=YES' + ${SYSCTL_W} net.inet6.ip6.forwarding=1 > /dev/null + else + ${SYSCTL_W} net.inet6.ip6.forwarding=0 > /dev/null + fi +} + +options_ipx() +{ + if checkyesno ipxgateway_enable; then + ropts_init + echo -n ' IPX gateway=YES' + ${SYSCTL_W} net.ipx.ipx.ipxforwarding=1 > /dev/null + else + ${SYSCTL_W} net.ipx.ipx.ipxforwarding=0 > /dev/null + fi } load_rc_config $name From ccbc06d893adcccddaa4089aa42c3adec9b51a23 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 06:19:34 +0000 Subject: [PATCH 010/646] Revert the previous afexists() change. Knobs configured explicitly by the user should not be ignored if possible even if the kernel does not support the prerequisite feature. Discussed with: ume --- etc/rc.d/faith | 4 ---- etc/rc.d/static_arp | 4 ---- etc/rc.d/stf | 4 ---- 3 files changed, 12 deletions(-) diff --git a/etc/rc.d/faith b/etc/rc.d/faith index e48fff78bd4..020b947ec86 100755 --- a/etc/rc.d/faith +++ b/etc/rc.d/faith @@ -15,8 +15,6 @@ stop_cmd="faith_down" faith_up() { - afexists inet6 || return 0 - case ${ipv6_faith_prefix} in [Nn][Oo] | '') ;; @@ -50,8 +48,6 @@ faith_up() faith_down() { - afexists inet6 || return 0 - echo "Removing IPv6-to-IPv4 TCP relay capturing interface: faith0." ifconfig faith0 destroy ${SYSCTL_W} net.inet6.ip6.keepfaith=0 diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp index 816d581d7ce..6283b56ef08 100644 --- a/etc/rc.d/static_arp +++ b/etc/rc.d/static_arp @@ -44,8 +44,6 @@ static_arp_start() { local e arp_args - afexists inet || return 0 - if [ -n "${static_arp_pairs}" ]; then echo -n 'Binding static ARP pair(s):' for e in ${static_arp_pairs}; do @@ -61,8 +59,6 @@ static_arp_stop() { local e arp_args - afexists inet || return 0 - if [ -n "${static_arp_pairs}" ]; then echo -n 'Unbinding static ARP pair(s):' for e in ${static_arp_pairs}; do diff --git a/etc/rc.d/stf b/etc/rc.d/stf index fa1bfbd522d..40b182a0de9 100755 --- a/etc/rc.d/stf +++ b/etc/rc.d/stf @@ -15,8 +15,6 @@ stop_cmd="stf_down" stf_up() { - afexists inet6 || return 0 - case ${stf_interface_ipv4addr} in [Nn][Oo] | '') ;; @@ -69,8 +67,6 @@ stf_up() stf_down() { - afexists inet6 || return 0 - echo "Removing 6to4 tunnel interface: stf0." ifconfig stf0 destroy route delete -inet6 2002:e000:: -prefixlen 20 ::1 From b5a70c98b2d1c455c30a96d1c67e182f15acf7dd Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 06:51:39 +0000 Subject: [PATCH 011/646] The net.inet.tcp.log_in_vain accepts 0, 1 or 2, not Y/N. --- etc/rc.d/netoptions | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/etc/rc.d/netoptions b/etc/rc.d/netoptions index c30563d213f..f2012c5f3e8 100755 --- a/etc/rc.d/netoptions +++ b/etc/rc.d/netoptions @@ -36,15 +36,18 @@ netoptions_start() netoptions_inet() { - if checkyesno log_in_vain; then + case ${log_in_vain} in + [12]) netoptions_init echo -n " log_in_vain=${log_in_vain}" - ${SYSCTL_W} net.inet.tcp.log_in_vain=1 >/dev/null - ${SYSCTL_W} net.inet.udp.log_in_vain=1 >/dev/null - else + ${SYSCTL_W} net.inet.tcp.log_in_vain=${log_in_vain} >/dev/null + ${SYSCTL_W} net.inet.udp.log_in_vain=${log_in_vain} >/dev/null + ;; + *) ${SYSCTL_W} net.inet.tcp.log_in_vain=0 >/dev/null ${SYSCTL_W} net.inet.udp.log_in_vain=0 >/dev/null - fi + ;; + esac if checkyesno tcp_extensions; then ${SYSCTL_W} net.inet.tcp.rfc1323=1 >/dev/null From d7caaef2e5d5b7937333f6fffb19c93965fa31d6 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 07:00:20 +0000 Subject: [PATCH 012/646] Enable adding a link-local address even if ND6_IFF_IFDISABLED. Note that when the interface has ND6_IFF_IFDISABLED, a newly-added address is always marked as IN6_IFF_TENTATIVE so that the interface can perform DAD after the ND6_IFF_IFDISABLED is cleared. --- sys/netinet6/in6_ifattach.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index eab70133c90..c77b93f8e03 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -751,7 +751,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) * assign a link-local address, if there's none. */ if (ifp->if_type != IFT_BRIDGE && - !(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) { int error; From f143a35bf1d96bd8797c5ffb8cbd6bdee44eb24d Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Fri, 2 Oct 2009 11:10:05 +0000 Subject: [PATCH 013/646] Remove performance counter headers. This code came from NetBSD, but our hardware perf. counter support is different, so we don't need these files. Reviewed by: freebsd-arm (no comments) --- sys/arm/arm/cpufunc.c | 29 --------------- sys/arm/xscale/xscalereg.h | 73 -------------------------------------- sys/arm/xscale/xscalevar.h | 48 ------------------------- 3 files changed, 150 deletions(-) delete mode 100644 sys/arm/xscale/xscalereg.h delete mode 100644 sys/arm/xscale/xscalevar.h diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 583293355a9..7389095b2ea 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -83,15 +83,6 @@ __FBSDID("$FreeBSD$"); #include #endif -#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ - defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) -#include -#endif - -#if defined(PERFCTRS) -struct arm_pmc_funcs *arm_pmc; -#endif - /* PRIMARY CACHE VARIABLES */ int arm_picache_size; int arm_picache_line_size; @@ -1128,10 +1119,6 @@ set_cpufuncs() : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); cpufuncs = xscale_cpufuncs; -#if defined(PERFCTRS) - xscale_pmu_init(); -#endif - /* * i80200 errata: Step-A0 and A1 have a bug where * D$ dirty bits are not cleared on "invalidate by @@ -1165,10 +1152,6 @@ set_cpufuncs() PMNC_CC_IF)); cpufuncs = xscale_cpufuncs; -#if defined(PERFCTRS) - xscale_pmu_init(); -#endif - cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ get_cachetype_cp15(); pmap_pte_init_xscale(); @@ -1179,10 +1162,6 @@ set_cpufuncs() #if defined(CPU_XSCALE_81342) if (cputype == CPU_ID_81342) { cpufuncs = xscalec3_cpufuncs; -#if defined(PERFCTRS) - xscale_pmu_init(); -#endif - cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ get_cachetype_cp15(); pmap_pte_init_xscale(); @@ -1196,10 +1175,6 @@ set_cpufuncs() (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { cpufuncs = xscale_cpufuncs; -#if defined(PERFCTRS) - xscale_pmu_init(); -#endif - cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ get_cachetype_cp15(); pmap_pte_init_xscale(); @@ -1215,10 +1190,6 @@ set_cpufuncs() cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { cpufuncs = xscale_cpufuncs; -#if defined(PERFCTRS) - xscale_pmu_init(); -#endif - cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ get_cachetype_cp15(); pmap_pte_init_xscale(); diff --git a/sys/arm/xscale/xscalereg.h b/sys/arm/xscale/xscalereg.h deleted file mode 100644 index 85e64d194cd..00000000000 --- a/sys/arm/xscale/xscalereg.h +++ /dev/null @@ -1,73 +0,0 @@ -/* $NetBSD: xscalereg.h,v 1.2 2002/08/07 05:15:02 briggs Exp $ */ - -/*- - * Copyright (c) 2001 Wasabi Systems, Inc. - * All rights reserved. - * - * Written by Jason R. Thorpe for Wasabi Systems, Inc. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project by - * Wasabi Systems, Inc. - * 4. The name of Wasabi Systems, Inc. may not be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC - * 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$ - */ - -#ifndef _ARM_XSCALE_XSCALEREG_H_ -#define _ARM_XSCALE_XSCALEREG_H_ - -/* - * Register definitions for the Intel XScale processor core. - */ - -/* - * Performance Monitoring Unit (CP14) - * - * CP14.0 Performance Monitor Control Register - * CP14.1 Clock Counter - * CP14.2 Performance Counter Register 0 - * CP14.3 Performance Counter Register 1 - */ - -#define PMNC_E 0x00000001 /* enable counters */ -#define PMNC_P 0x00000002 /* reset both PMNs to 0 */ -#define PMNC_C 0x00000004 /* clock counter reset */ -#define PMNC_D 0x00000008 /* clock counter / 64 */ -#define PMNC_PMN0_IE 0x00000010 /* enable PMN0 interrupt */ -#define PMNC_PMN1_IE 0x00000020 /* enable PMN1 interrupt */ -#define PMNC_CC_IE 0x00000040 /* enable clock counter interrupt */ -#define PMNC_PMN0_IF 0x00000100 /* PMN0 overflow/interrupt */ -#define PMNC_PMN1_IF 0x00000200 /* PMN1 overflow/interrupt */ -#define PMNC_CC_IF 0x00000400 /* clock counter overflow/interrupt */ -#define PMNC_EVCNT0_MASK 0x000ff000 /* event to count for PMN0 */ -#define PMNC_EVCNT0_SHIFT 12 -#define PMNC_EVCNT1_MASK 0x0ff00000 /* event to count for PMN1 */ -#define PMNC_EVCNT1_SHIFT 20 - -void xscale_pmu_init(void); - -#endif /* _ARM_XSCALE_XSCALEREG_H_ */ diff --git a/sys/arm/xscale/xscalevar.h b/sys/arm/xscale/xscalevar.h deleted file mode 100644 index 32a510ff458..00000000000 --- a/sys/arm/xscale/xscalevar.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: xscalevar.h,v 1.1 2002/10/08 23:59:41 thorpej Exp $ */ - -/*- - * Copyright (c) 2002 Wasabi Systems, Inc. - * All rights reserved. - * - * Written by Jason R. Thorpe for Wasabi Systems, Inc. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project by - * Wasabi Systems, Inc. - * 4. The name of Wasabi Systems, Inc. may not be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC - * 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$ - * - */ - -#ifndef _ARM_XSCALE_XSCALEVAR_H_ -#define _ARM_XSCALE_XSCALEVAR_H_ - -/* Performance Monitoring Unit */ -void xscale_pmu_init(void); -int xscale_pmc_dispatch(void *); - -#endif /* _ARM_XSCALE_XSCALEVAR_H_ */ From f49e371d3bae51e51b248cf35a7aac17522ce929 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Fri, 2 Oct 2009 11:14:12 +0000 Subject: [PATCH 014/646] Reserve numbers for XScale. Reviewed by: jkoshy --- sys/sys/pmc.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 68d7df0af14..3bad4432624 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -84,7 +84,8 @@ __PMC_CPU(INTEL_CORE2, 0x88, "Intel Core2") \ __PMC_CPU(INTEL_CORE2EXTREME, 0x89, "Intel Core2 Extreme") \ __PMC_CPU(INTEL_ATOM, 0x8A, "Intel Atom") \ - __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") + __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") \ + __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale") enum pmc_cputype { #undef __PMC_CPU @@ -93,7 +94,7 @@ enum pmc_cputype { }; #define PMC_CPU_FIRST PMC_CPU_AMD_K7 -#define PMC_CPU_LAST PMC_CPU_INTEL_COREI7 +#define PMC_CPU_LAST PMC_CPU_INTEL_XSCALE /* * Classes of PMCs @@ -107,7 +108,8 @@ enum pmc_cputype { __PMC_CLASS(P6) /* Intel Pentium Pro counters */ \ __PMC_CLASS(P4) /* Intel Pentium-IV counters */ \ __PMC_CLASS(IAF) /* Intel Core2/Atom, fixed function */ \ - __PMC_CLASS(IAP) /* Intel Core...Atom, programmable */ + __PMC_CLASS(IAP) /* Intel Core...Atom, programmable */ \ + __PMC_CLASS(XSCALE) /* Intel XScale counters */ enum pmc_class { #undef __PMC_CLASS @@ -116,7 +118,7 @@ enum pmc_class { }; #define PMC_CLASS_FIRST PMC_CLASS_TSC -#define PMC_CLASS_LAST PMC_CLASS_IAP +#define PMC_CLASS_LAST PMC_CLASS_XSCALE /* * A PMC can be in the following states: From a38f6f86d20f5db75a4dd2dc619f7a0972e4eb64 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Fri, 2 Oct 2009 12:47:01 +0000 Subject: [PATCH 015/646] Fix build nfscl and/or nfsd. MFC after: 3 days --- sys/conf/files | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index 5888834241a..ef906a72527 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2668,12 +2668,12 @@ vm/vm_reserv.c standard vm/vm_unix.c standard vm/vm_zeroidle.c standard vm/vnode_pager.c standard -xdr/xdr.c optional krpc | nfslockd | nfsclient | nfsserver -xdr/xdr_array.c optional krpc | nfslockd | nfsclient | nfsserver -xdr/xdr_mbuf.c optional krpc | nfslockd | nfsclient | nfsserver -xdr/xdr_mem.c optional krpc | nfslockd | nfsclient | nfsserver -xdr/xdr_reference.c optional krpc | nfslockd | nfsclient | nfsserver -xdr/xdr_sizeof.c optional krpc | nfslockd | nfsclient | nfsserver +xdr/xdr.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr_array.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr_mbuf.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr_mem.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr_reference.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr_sizeof.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd # gnu/fs/xfs/xfs_alloc.c optional xfs \ compile-with "${NORMAL_C} -I$S/gnu/fs/xfs/FreeBSD -I$S/gnu/fs/xfs/FreeBSD/support -I$S/gnu/fs/xfs" \ From 878adb851786315ed1f5aafb625e1fab4bf6195d Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 2 Oct 2009 17:48:51 +0000 Subject: [PATCH 016/646] Add a mitigation feature that will prevent user mappings at virtual address 0, limiting the ability to convert a kernel NULL pointer dereference into a privilege escalation attack. If the sysctl is set to 0 a newly started process will not be able to map anything in the address range of the first page (0 to PAGE_SIZE). This is the default. Already running processes are not affected by this. You can either change the sysctl or the tunable from loader in case you need to map at a virtual address of 0, for example when running any of the extinct species of a set of a.out binaries, vm86 emulation, .. In that case set security.bsd.map_at_zero="1". Superseeds: r197537 In collaboration with: jhb, kib, alc --- sys/kern/init_main.c | 5 +++++ sys/kern/kern_exec.c | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 2c1b4cf8380..0af22faa3a5 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -505,6 +505,11 @@ proc0_init(void *dummy __unused) pmap_pinit0(vmspace_pmap(&vmspace0)); p->p_vmspace = &vmspace0; vmspace0.vm_refcnt = 1; + + /* + * proc0 is not expected to enter usermode, so there is no special + * handling for sv_minuser here, like is done for exec_new_vmspace(). + */ vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser, p->p_sysent->sv_maxuser); vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a90968f0368..033f64122fc 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -122,6 +122,11 @@ u_long ps_arg_cache_limit = PAGE_SIZE / 16; SYSCTL_ULONG(_kern, OID_AUTO, ps_arg_cache_limit, CTLFLAG_RW, &ps_arg_cache_limit, 0, ""); +static int map_at_zero = 0; +TUNABLE_INT("security.bsd.map_at_zero", &map_at_zero); +SYSCTL_INT(_security_bsd, OID_AUTO, map_at_zero, CTLFLAG_RW, &map_at_zero, 0, + "Permit processes to map an object at virtual address 0."); + static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS) { @@ -999,7 +1004,7 @@ exec_new_vmspace(imgp, sv) int error; struct proc *p = imgp->proc; struct vmspace *vmspace = p->p_vmspace; - vm_offset_t stack_addr; + vm_offset_t sv_minuser, stack_addr; vm_map_t map; u_long ssiz; @@ -1015,13 +1020,17 @@ exec_new_vmspace(imgp, sv) * not disrupted */ map = &vmspace->vm_map; - if (vmspace->vm_refcnt == 1 && vm_map_min(map) == sv->sv_minuser && + if (map_at_zero) + sv_minuser = sv->sv_minuser; + else + sv_minuser = MAX(sv->sv_minuser, PAGE_SIZE); + if (vmspace->vm_refcnt == 1 && vm_map_min(map) == sv_minuser && vm_map_max(map) == sv->sv_maxuser) { shmexit(vmspace); pmap_remove_pages(vmspace_pmap(vmspace)); vm_map_remove(map, vm_map_min(map), vm_map_max(map)); } else { - error = vmspace_exec(p, sv->sv_minuser, sv->sv_maxuser); + error = vmspace_exec(p, sv_minuser, sv->sv_maxuser); if (error) return (error); vmspace = p->p_vmspace; From fc5083273109726d360a61f4763356788382f473 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 2 Oct 2009 17:51:46 +0000 Subject: [PATCH 017/646] Back out the functional parts from r197537. After r197711, affecting all user mappings, mmap no longer needs special treatment. --- sys/vm/vm_mmap.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index e8ba13415a7..4963a603833 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -96,14 +96,6 @@ static int max_proc_mmap; SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0, "Maximum number of memory-mapped files per process"); -/* - * 'mmap_zero' determines whether or not MAP_FIXED mmap() requests for - * virtual address zero are permitted. - */ -static int mmap_zero; -SYSCTL_INT(_security_bsd, OID_AUTO, mmap_zero, CTLFLAG_RW, &mmap_zero, 0, - "Processes may map an object at virtual address zero"); - /* * Set the maximum number of vm_map_entry structures per process. Roughly * speaking vm_map_entry structures are tiny, so allowing them to eat 1/100 @@ -277,13 +269,6 @@ mmap(td, uap) if (addr & PAGE_MASK) return (EINVAL); - /* - * Mapping to address zero is only permitted if - * mmap_zero is enabled. - */ - if (addr == 0 && !mmap_zero) - return (EINVAL); - /* Address range must be all in user VM space. */ if (addr < vm_map_min(&vms->vm_map) || addr + size > vm_map_max(&vms->vm_map)) From 492ffed1e3d406b1247c62ea13c33055339903ac Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 2 Oct 2009 17:53:48 +0000 Subject: [PATCH 018/646] Replace the name of the sysctl to security.bsd.map_at_zero and to be consistent updated the name of the variable as well, after the change in r197711. --- tools/regression/mmap/mmap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/regression/mmap/mmap.c b/tools/regression/mmap/mmap.c index 34da6b24ae5..14c55a1aed1 100644 --- a/tools/regression/mmap/mmap.c +++ b/tools/regression/mmap/mmap.c @@ -36,7 +36,7 @@ const struct tests { void *addr; - int ok[2]; /* Depending on security.bsd.mmap_zero {0, !=0}. */ + int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */ } tests[] = { { (void *)0, { 0, 1 } }, /* Test sysctl. */ { (void *)1, { 0, 0 } }, @@ -54,37 +54,37 @@ main(void) { void *p; size_t len; - int i, error, mib[3], mmap_zero; + int i, error, mib[3], map_at_zero; error = 0; - /* Get the current sysctl value of security.bsd.mmap_zero. */ + /* Get the current sysctl value of security.bsd.map_at_zero. */ len = sizeof(mib) / sizeof(*mib); - if (sysctlnametomib("security.bsd.mmap_zero", mib, &len) == -1) - err(1, "sysctlnametomib(security.bsd.mmap_zero)"); + if (sysctlnametomib("security.bsd.map_at_zero", mib, &len) == -1) + err(1, "sysctlnametomib(security.bsd.map_at_zero)"); - len = sizeof(mmap_zero); - if (sysctl(mib, 3, &mmap_zero, &len, NULL, 0) == -1) - err(1, "sysctl(security.bsd.mmap_zero)"); + len = sizeof(map_at_zero); + if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1) + err(1, "sysctl(security.bsd.map_at_zero)"); /* Normalize to 0 or 1 for array access. */ - mmap_zero = !!mmap_zero; + map_at_zero = !!map_at_zero; for (i=0; i < (sizeof(tests) / sizeof(*tests)); i++) { p = mmap((void *)tests[i].addr, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, -1, 0); if (p == MAP_FAILED) { - if (tests[i].ok[mmap_zero] != 0) + if (tests[i].ok[map_at_zero] != 0) error++; warnx("%s: mmap(%p, ...) failed.", - (tests[i].ok[mmap_zero] == 0) ? "OK " : "ERR", + (tests[i].ok[map_at_zero] == 0) ? "OK " : "ERR", tests[i].addr); } else { - if (tests[i].ok[mmap_zero] != 1) + if (tests[i].ok[map_at_zero] != 1) error++; warnx("%s: mmap(%p, ...) succeeded: p=%p", - (tests[i].ok[mmap_zero] == 1) ? "OK " : "ERR", + (tests[i].ok[map_at_zero] == 1) ? "OK " : "ERR", tests[i].addr, p); } } From df2b25f6eebbe022e08add7c69f47c73119c5400 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 2 Oct 2009 20:19:53 +0000 Subject: [PATCH 019/646] - Enable an afexists() check only when no AF argument is specified. - Simplify helper functions. Discussed with: ume --- etc/rc.d/routing | 131 +++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/etc/rc.d/routing b/etc/rc.d/routing index 7edc3bab168..befceca0752 100755 --- a/etc/rc.d/routing +++ b/etc/rc.d/routing @@ -13,26 +13,80 @@ . /etc/network.subr name="routing" -start_cmd="routing_start" +start_cmd="routing_start doall" stop_cmd="routing_stop" extra_commands="options static" -static_cmd="static_start" -options_cmd="options_start" +static_cmd="routing_start static" +options_cmd="routing_start options" + +afcheck() +{ + case $_af in + ""|inet|inet6|ipx|atm) + ;; + *) + err 1 "Unsupported address family: $_af." + ;; + esac +} routing_start() { - static_start "$@" - options_start "$@" + local _cmd _af _a + _cmd=$1 + _af=$2 + + afcheck + + case $_af in + inet|inet6|ipx|atm) + setroutes $_cmd $_af + ;; + "") + for _a in inet inet6 ipx atm; do + afexists $_a && setroutes $_cmd $_a + done + ;; + esac + [ -n "${_ropts_initdone}" ] && echo '.' } routing_stop() { - local _af + local _af _a + _af=$1 - static_stop "$@" - for _af in inet inet6; do - afexists ${_af} && eval routing_stop_${_af} - done + afcheck + + case $_af in + inet|inet6|ipx|atm) + eval static_${_af} delete + eval routing_stop_${_af} + ;; + "") + for _a in inet inet6 ipx atm; do + afexists $_a || continue + eval static_${_a} delete + eval routing_stop_${_a} + done + ;; + esac +} + +setroutes() +{ + case $1 in + static) + static_$2 add + ;; + options) + options_$2 + ;; + doall) + static_$2 add + options_$2 + ;; + esac } routing_stop_inet() @@ -50,45 +104,14 @@ routing_stop_inet6() done } -static_start() +routing_stop_atm() { - local _af - _af=$1 - - case ${_af} in - inet|inet6|atm) - do_static add ${_af} - ;; - "") - do_static add inet inet6 atm - ;; - esac + return 0 } -static_stop() +routing_stop_ipx() { - local _af - _af=$1 - - case ${_af} in - inet|inet6|atm) - do_static delete ${_af} - ;; - "") - do_static delete inet inet6 atm - ;; - esac -} - -do_static() -{ - local _af _action - _action=$1 - - shift - for _af in "$@"; do - afexists ${_af} && eval static_${_af} ${_action} - done + return 0 } static_inet() @@ -233,6 +256,10 @@ static_atm() fi } +static_ipx() +{ +} + _ropts_initdone= ropts_init() { @@ -242,16 +269,6 @@ ropts_init() fi } -options_start() -{ - local _af - - for _af in inet inet6 ipx; do - afexists ${_af} && eval options_${_af} - done - [ -n "${_ropts_initdone}" ] && echo '.' -} - options_inet() { if checkyesno icmp_bmcastecho; then @@ -322,6 +339,10 @@ options_inet6() fi } +options_atm() +{ +} + options_ipx() { if checkyesno ipxgateway_enable; then From afd8e45b4569be9094fb96d971b2206f3eac6228 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 2 Oct 2009 21:31:15 +0000 Subject: [PATCH 020/646] Don't comment on stream socket handling in sosend_dgram, since that's not handled. MFC after: 3 weeks --- sys/kern/uipc_socket.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 34d5edc345f..cc16c49fc32 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -970,9 +970,6 @@ sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, * must use a signed comparison of space and resid. On the other * hand, a negative resid causes us to loop sending 0-length * segments to the protocol. - * - * Also check to make sure that MSG_EOR isn't used on SOCK_STREAM - * type sockets since that's an error. */ if (resid < 0) { error = EINVAL; From 0acb3c4aacb5cb3650e5540a56c28f6325da3c62 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 2 Oct 2009 22:30:44 +0000 Subject: [PATCH 021/646] Fix RTS/CTS flow control, broken by the TTY overhaul. The new TTY interface is fairly simple WRT dealing with flow control, but needed 2 new RX buffer functions with "get-char-from-buf" separated from "advance-buf-pointer" so that the pointer could be advanced only when ttydisc_rint() succeeded. MFC after: 1 week --- sys/dev/uart/uart_bus.h | 25 ++++++++++++++++++ sys/dev/uart/uart_core.c | 2 +- sys/dev/uart/uart_tty.c | 55 +++++++++++++++++++++------------------- 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h index 7154d859026..b1498f5f0a9 100644 --- a/sys/dev/uart/uart_bus.h +++ b/sys/dev/uart/uart_bus.h @@ -96,6 +96,7 @@ struct uart_softc { int sc_opened:1; /* This UART is open for business. */ int sc_polled:1; /* This UART has no interrupts. */ int sc_txbusy:1; /* This UART is transmitting. */ + int sc_isquelch:1; /* This UART has input squelched. */ struct uart_devinfo *sc_sysdev; /* System device (or NULL). */ @@ -141,6 +142,8 @@ int uart_bus_ipend(device_t dev); int uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan); int uart_bus_sysdev(device_t dev); +void uart_sched_softih(struct uart_softc *, uint32_t); + int uart_tty_attach(struct uart_softc *); int uart_tty_detach(struct uart_softc *); void uart_tty_intr(void *arg); @@ -174,6 +177,28 @@ uart_rx_get(struct uart_softc *sc) return (xc); } +static __inline int +uart_rx_next(struct uart_softc *sc) +{ + int ptr; + + ptr = sc->sc_rxget; + if (ptr == sc->sc_rxput) + return (-1); + ptr += 1; + sc->sc_rxget = (ptr < sc->sc_rxbufsz) ? ptr : 0; + return (0); +} + +static __inline int +uart_rx_peek(struct uart_softc *sc) +{ + int ptr; + + ptr = sc->sc_rxget; + return ((ptr == sc->sc_rxput) ? -1 : sc->sc_rxbuf[ptr]); +} + static __inline int uart_rx_put(struct uart_softc *sc, int xc) { diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index 932c08ab463..98b044f7a7e 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -91,7 +91,7 @@ uart_getrange(struct uart_class *uc) * Schedule a soft interrupt. We do this on the 0 to !0 transition * of the TTY pending interrupt status. */ -static void +void uart_sched_softih(struct uart_softc *sc, uint32_t ipend) { uint32_t new, old; diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c index cb77f65ecae..2f442f7805d 100644 --- a/sys/dev/uart/uart_tty.c +++ b/sys/dev/uart/uart_tty.c @@ -166,27 +166,6 @@ uart_tty_outwakeup(struct tty *tp) if (sc == NULL || sc->sc_leaving) return; - /* - * Handle input flow control. Note that if we have hardware support, - * we don't do anything here. We continue to receive until our buffer - * is full. At that time we cannot empty the UART itself and it will - * de-assert RTS for us. In that situation we're completely stuffed. - * Without hardware support, we need to toggle RTS ourselves. - */ - if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) { -#if 0 - /*if ((tp->t_state & TS_TBLOCK) && - (sc->sc_hwsig & SER_RTS)) - UART_SETSIG(sc, SER_DRTS); - else */ if (/*!(tp->t_state & TS_TBLOCK) &&*/ - !(sc->sc_hwsig & SER_RTS)) - UART_SETSIG(sc, SER_DRTS|SER_RTS); -#endif - /* XXX: we should use inwakeup to implement this! */ - if (!(sc->sc_hwsig & SER_RTS)) - UART_SETSIG(sc, SER_DRTS|SER_RTS); - } - if (sc->sc_txbusy) return; @@ -195,6 +174,23 @@ uart_tty_outwakeup(struct tty *tp) UART_TRANSMIT(sc); } +static void +uart_tty_inwakeup(struct tty *tp) +{ + struct uart_softc *sc; + + sc = tty_softc(tp); + if (sc == NULL || sc->sc_leaving) + return; + + if (sc->sc_isquelch) { + if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) + UART_SETSIG(sc, SER_DRTS|SER_RTS); + sc->sc_isquelch = 0; + uart_sched_softih(sc, SER_INT_RXREADY); + } +} + static int uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { @@ -252,9 +248,9 @@ uart_tty_param(struct tty *tp, struct termios *t) UART_SETSIG(sc, SER_DDTR | SER_DTR); /* Set input flow control state. */ if (!sc->sc_hwiflow) { - /* if ((t->c_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK)) + if ((t->c_cflag & CRTS_IFLOW) && sc->sc_isquelch) UART_SETSIG(sc, SER_DRTS); - else */ + else UART_SETSIG(sc, SER_DRTS | SER_RTS); } else UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW)); @@ -294,8 +290,8 @@ uart_tty_intr(void *arg) tty_lock(tp); if (pend & SER_INT_RXREADY) { - while (!uart_rx_empty(sc) /* && !(tp->t_state & TS_TBLOCK)*/) { - xc = uart_rx_get(sc); + while (!uart_rx_empty(sc) && !sc->sc_isquelch) { + xc = uart_rx_peek(sc); c = xc & 0xff; if (xc & UART_STAT_FRAMERR) err |= TRE_FRAMING; @@ -303,7 +299,13 @@ uart_tty_intr(void *arg) err |= TRE_OVERRUN; if (xc & UART_STAT_PARERR) err |= TRE_PARITY; - ttydisc_rint(tp, c, err); + if (ttydisc_rint(tp, c, err) != 0) { + sc->sc_isquelch = 1; + if ((tp->t_termios.c_cflag & CRTS_IFLOW) && + !sc->sc_hwiflow) + UART_SETSIG(sc, SER_DRTS); + } else + uart_rx_next(sc); } } @@ -344,6 +346,7 @@ static struct ttydevsw uart_tty_class = { .tsw_open = uart_tty_open, .tsw_close = uart_tty_close, .tsw_outwakeup = uart_tty_outwakeup, + .tsw_inwakeup = uart_tty_inwakeup, .tsw_ioctl = uart_tty_ioctl, .tsw_param = uart_tty_param, .tsw_modem = uart_tty_modem, From 1db9493a641cc6d3eaf8da2606985a31f34a6867 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Sat, 3 Oct 2009 02:28:28 +0000 Subject: [PATCH 022/646] TRENDnet TEW-424UB has multiple revisions so clarify zyd(4) man page and adds a device to urtw(4). The revision informations are as follows: rev A ZD1211 V2 SiS163U V2.1R SiS163U V3.xR RTL8187B and bump date. Obtained from: OpenBSD Reported by: Albert Shih --- share/man/man4/urtw.4 | 3 ++- share/man/man4/zyd.4 | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/share/man/man4/urtw.4 b/share/man/man4/urtw.4 index c5a3ac5f419..1eb6d7df46c 100644 --- a/share/man/man4/urtw.4 +++ b/share/man/man4/urtw.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2009 +.Dd October 2, 2009 .Dt URTW 4 .Os .Sh NAME @@ -73,6 +73,7 @@ driver supports Realtek RTL8187B/L based wireless network devices, including: .It "Netgear WG111v2 RTL8225 USB" .It "Safehome WLG-1500SMA5 RTL8225 USB" .It "Shuttle XPC Accessory PN20 RTL8225 USB" +.It "TRENDnet TEW-424UB V3.xR RTL8225 USB" .El .Sh EXAMPLES Join an existing BSS network (i.e., connect to an access point): diff --git a/share/man/man4/zyd.4 b/share/man/man4/zyd.4 index 15c63921674..ba8f5737df6 100644 --- a/share/man/man4/zyd.4 +++ b/share/man/man4/zyd.4 @@ -32,7 +32,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF .\" THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 1, 2008 +.Dd October 2, 2009 .Dt ZYD 4 .Os .Sh NAME @@ -113,7 +113,7 @@ driver: .It Sweex wireless USB 54 Mbps .It Tekram/Siemens USB adapter .It Telegent TG54USB -.It Trendnet TEW-424UB +.It Trendnet TEW-424UB rev A .It Trendnet TEW-429UB .It TwinMOS G240 .It Unicorn WL-54G From 85f67d69721bae2854fdfd732a9e8d02460a3958 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 3 Oct 2009 02:37:21 +0000 Subject: [PATCH 023/646] The 6bone was decommissioned on 6/6/06, so remove references to it. --- usr.bin/whois/whois.1 | 22 +++++----------------- usr.bin/whois/whois.c | 5 +++-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/usr.bin/whois/whois.1 b/usr.bin/whois/whois.1 index 52da2209177..56db1606f0e 100644 --- a/usr.bin/whois/whois.1 +++ b/usr.bin/whois/whois.1 @@ -32,7 +32,7 @@ .\" From: @(#)whois.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd January 23, 2006 +.Dd October 2, 2009 .Dt WHOIS 1 .Os .Sh NAME @@ -40,7 +40,7 @@ .Nd "Internet domain name and network number directory service" .Sh SYNOPSIS .Nm -.Op Fl aAbdfgiIklmQrR6 +.Op Fl aAbdfgiIklmQrR .Op Fl c Ar country-code | Fl h Ar host .Op Fl p Ar port .Ar name ... @@ -212,17 +212,14 @@ This option is deprecated; use the option with an argument of .Qq Li RU instead. -.It Fl 6 -Use the IPv6 Resource Center -.Pq Tn 6bone -database. -It contains network names and addresses for the IPv6 network. -.El .Pp The operands specified to .Nm are treated independently and may be used as queries on different whois servers. +.El +.Sh EXIT STATUS +.Ex -std .Sh EXAMPLES Most types of data, such as domain names and .Tn IP @@ -255,15 +252,6 @@ but other .Tn TLDs can be queried by using a similar syntax.) .Pp -The following example demonstrates how to obtain information about an -.Tn IPv6 -address or hostname using the -.Fl 6 -option, which directs the query to -.Tn 6bone . -.Pp -.Dl "whois -6 IPv6-IP-Address" -.Pp The following example demonstrates how to query a whois server using a non-standard port, where .Dq Li query-data diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c index c2165562517..adb62320390 100644 --- a/usr.bin/whois/whois.c +++ b/usr.bin/whois/whois.c @@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$"); #define PNICHOST "whois.apnic.net" #define MNICHOST "whois.ra.net" #define QNICHOST_TAIL ".whois-servers.net" -#define SNICHOST "whois.6bone.net" #define BNICHOST "whois.registro.br" #define NORIDHOST "whois.norid.no" #define IANAHOST "whois.iana.org" @@ -164,8 +163,10 @@ main(int argc, char *argv[]) warnx("-R is deprecated; use '-c ru' instead"); country = "ru"; break; + /* Remove in FreeBSD 10 */ case '6': - host = SNICHOST; + errx(EX_USAGE, + "-6 is deprecated; use -[aAflr] instead"); break; case '?': default: From 925c8b5b0447000beeed372ddd6ff0093dc32b77 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 3 Oct 2009 10:50:00 +0000 Subject: [PATCH 024/646] Print a warning in case we cannot add more brandinfo because we would overflow the MAX_BRANDS sized array. Reviewed by: kib MFC After: 1 month --- sys/kern/imgact_elf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index ba5833a5bd6..4ed7382a6f6 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -180,8 +180,11 @@ __elfN(insert_brand_entry)(Elf_Brandinfo *entry) break; } } - if (i == MAX_BRANDS) + if (i == MAX_BRANDS) { + printf("WARNING: %s: could not insert brandinfo entry: %p\n", + __func__, entry); return (-1); + } return (0); } From db44ff4047cbb4e9935b515d5e1b3a5f7dfd8682 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 3 Oct 2009 10:56:03 +0000 Subject: [PATCH 025/646] Put #ifdef INET around parts of the FLOWTABLE code, to unbreak nooptions INET kernel builds. MFC after: 3 days X-MFC: with r197687 --- sys/net/route.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/net/route.c b/sys/net/route.c index 1ab039f6d9a..2fc53af45be 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1162,6 +1162,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, /* XXX * "flow-table" only support IPv4 at the moment. */ +#ifdef INET if (dst->sa_family == AF_INET) { rn = rnh->rnh_matchaddr(dst, rnh); if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) { @@ -1202,6 +1203,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, } } } +#endif #endif /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ @@ -1224,7 +1226,9 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, } #ifdef FLOWTABLE else if (rt0 != NULL) { +#ifdef INET flowtable_route_flush(V_ip_ft, rt0); +#endif RTFREE(rt0); } #endif From 4011f96514ece680455f8a9f89fcf6097e54637c Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 3 Oct 2009 11:02:36 +0000 Subject: [PATCH 026/646] Add OpenVPN IANA assigned port number. --- etc/services | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/services b/etc/services index 729f20be11d..f5de48b8473 100644 --- a/etc/services +++ b/etc/services @@ -1521,6 +1521,8 @@ nfa 1155/tcp #Network File Access nfa 1155/udp #Network File Access phone 1167/udp #conference calling skkserv 1178/tcp #SKK (kanji input) +openvpn 1194/tcp #OpenVPN +openvpn 1194/udp #OpenVPN lupa 1212/tcp lupa 1212/udp nerv 1222/tcp #SNI R&D network From 52bf2041ac197f17c00c32f752ad0e30dad0e53d Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 3 Oct 2009 11:57:21 +0000 Subject: [PATCH 027/646] Make sure that the primary native brandinfo always gets added first and the native ia32 compat as middle (before other things). o(ld)brandinfo as well as third party like linux, kfreebsd, etc. stays on SI_ORDER_ANY coming last. The reason for this is only to make sure that even in case we would overflow the MAX_BRANDS sized array, the native FreeBSD brandinfo would still be there and the system would be operational. Reviewed by: kib MFC after: 1 month --- sys/amd64/amd64/elf_machdep.c | 2 +- sys/arm/arm/elf_machdep.c | 2 +- sys/compat/ia32/ia32_sysvec.c | 2 +- sys/i386/i386/elf_machdep.c | 2 +- sys/ia64/ia64/elf_machdep.c | 2 +- sys/mips/mips/elf64_machdep.c | 2 +- sys/mips/mips/elf_machdep.c | 2 +- sys/powerpc/powerpc/elf_machdep.c | 2 +- sys/sparc64/sparc64/elf_machdep.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index d5e7a6ead78..dc7c8b9ed8a 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -89,7 +89,7 @@ static Elf64_Brandinfo freebsd_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_info); diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 8b6105315d3..d77e7d49a98 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -88,7 +88,7 @@ static Elf32_Brandinfo freebsd_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_info); diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 46e0b80d270..cb8d33df43a 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -152,7 +152,7 @@ static Elf32_Brandinfo ia32_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_MIDDLE, (sysinit_cfunc_t) elf32_insert_brand_entry, &ia32_brand_info); diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index abfe147769b..408d6ad4a76 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -88,7 +88,7 @@ static Elf32_Brandinfo freebsd_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_info); diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index 31765cc3500..836016563bc 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -95,7 +95,7 @@ static Elf64_Brandinfo freebsd_brand_info = { .brand_note = &elf64_freebsd_brandnote, .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info); static Elf64_Brandinfo freebsd_brand_oinfo = { diff --git a/sys/mips/mips/elf64_machdep.c b/sys/mips/mips/elf64_machdep.c index c10fb5f280a..d63fdbccb43 100644 --- a/sys/mips/mips/elf64_machdep.c +++ b/sys/mips/mips/elf64_machdep.c @@ -108,7 +108,7 @@ static Elf64_Brandinfo freebsd_brand_info64 = { .flags = BI_BRAND_NOTE }; -SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_info64); diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index 974f2960813..d276b8f7eb0 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -90,7 +90,7 @@ static Elf32_Brandinfo freebsd_brand_info = { .flags = BI_BRAND_NOTE }; -SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_info); diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index fdf830afeb7..c370309e2d2 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -91,7 +91,7 @@ static Elf32_Brandinfo freebsd_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_info); diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index d113b49a022..2f9ee396e8d 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -103,7 +103,7 @@ static Elf64_Brandinfo freebsd_brand_info = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; -SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_info); From 057b3c8c60ce48fd8bde84bc752f988ae4a64de7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Sat, 3 Oct 2009 12:22:12 +0000 Subject: [PATCH 028/646] unifdef NFSCLIENT because the nlm depends on the nfsclient even if NFSCLIENT is not defined. Now the nfslockd module works with the nfsclient module. Reviewed by: kib MFC after: 3 days --- sys/modules/nfslockd/Makefile | 6 ------ sys/nlm/nlm_prot_impl.c | 13 ------------- 2 files changed, 19 deletions(-) diff --git a/sys/modules/nfslockd/Makefile b/sys/modules/nfslockd/Makefile index d8255aa7546..337314470d4 100644 --- a/sys/modules/nfslockd/Makefile +++ b/sys/modules/nfslockd/Makefile @@ -14,18 +14,12 @@ SRCS+= opt_inet6.h opt_nfs.h .if !defined(KERNBUILDDIR) NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel -NFSCLIENT?= 1 # 0/1 - requires NFSCLIENT to be configured in kernel .if ${NFS_INET6} > 0 opt_inet6.h: echo "#define INET6 1" > ${.TARGET} .endif -.if ${NFSCLIENT} > 0 -opt_nfs.h: - echo "#define NFSCLIENT 1" > ${.TARGET} -.endif - .endif .include diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 049c7ba9750..f7db7591876 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -26,7 +26,6 @@ */ #include "opt_inet6.h" -#include "opt_nfs.h" #include __FBSDID("$FreeBSD$"); @@ -671,8 +670,6 @@ nlm_host_destroy(struct nlm_host *host) free(host, M_NLM); } -#ifdef NFSCLIENT - /* * Thread start callback for client lock recovery */ @@ -695,8 +692,6 @@ nlm_client_recovery_start(void *arg) kthread_exit(); } -#endif - /* * This is called when we receive a host state change notification. We * unlock any active locks owned by the host. When rpc.lockd is @@ -735,7 +730,6 @@ nlm_host_notify(struct nlm_host *host, int newstate) lf_clearremotesys(host->nh_sysid); host->nh_state = newstate; -#ifdef NFSCLIENT /* * If we have any remote locks for this host (i.e. it * represents a remote NFS server that our local NFS client @@ -750,7 +744,6 @@ nlm_host_notify(struct nlm_host *host, int newstate) kthread_add(nlm_client_recovery_start, host, curproc, &td, 0, 0, "NFS lock recovery for %s", host->nh_caller_name); } -#endif } /* @@ -1479,10 +1472,8 @@ nlm_server_main(int addr_count, char **addrs) enum clnt_stat stat; struct nlm_host *host, *nhost; struct nlm_waiting_lock *nw; -#ifdef NFSCLIENT vop_advlock_t *old_nfs_advlock; vop_reclaim_t *old_nfs_reclaim; -#endif int v4_used; #ifdef INET6 int v6_used; @@ -1583,20 +1574,16 @@ nlm_server_main(int addr_count, char **addrs) NLM_DEBUG(1, "NLM: local NSM state is %d\n", smstat.state); nlm_nsm_state = smstat.state; -#ifdef NFSCLIENT old_nfs_advlock = nfs_advlock_p; nfs_advlock_p = nlm_advlock; old_nfs_reclaim = nfs_reclaim_p; nfs_reclaim_p = nlm_reclaim; -#endif svc_run(pool); error = 0; -#ifdef NFSCLIENT nfs_advlock_p = old_nfs_advlock; nfs_reclaim_p = old_nfs_reclaim; -#endif out: if (pool) From bba017d6a0a22e2b996607d6b3ec87353b85a4c9 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 3 Oct 2009 13:59:15 +0000 Subject: [PATCH 029/646] Remove remaining bits of performance counter support. Submitted by: Tom Judge --- sys/arm/arm/cpufunc.c | 24 ------------------------ sys/arm/xscale/i80321/i80321_timer.c | 2 -- 2 files changed, 26 deletions(-) diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 7389095b2ea..18291a15fae 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -1088,18 +1088,6 @@ set_cpufuncs() i80200_icu_init(); - /* - * Reset the Performance Monitoring Unit to a - * pristine state: - * - CCNT, PMN0, PMN1 reset to 0 - * - overflow indications cleared - * - all counters disabled - */ - __asm __volatile("mcr p14, 0, %0, c0, c0, 0" - : - : "r" (PMNC_P|PMNC_C|PMNC_PMN0_IF|PMNC_PMN1_IF| - PMNC_CC_IF)); - #if defined(XSCALE_CCLKCFG) /* * Crank CCLKCFG to maximum legal value. @@ -1139,18 +1127,6 @@ set_cpufuncs() if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { - /* - * Reset the Performance Monitoring Unit to a - * pristine state: - * - CCNT, PMN0, PMN1 reset to 0 - * - overflow indications cleared - * - all counters disabled - */ - __asm __volatile("mcr p14, 0, %0, c0, c0, 0" - : - : "r" (PMNC_P|PMNC_C|PMNC_PMN0_IF|PMNC_PMN1_IF| - PMNC_CC_IF)); - cpufuncs = xscale_cpufuncs; cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ get_cachetype_cp15(); diff --git a/sys/arm/xscale/i80321/i80321_timer.c b/sys/arm/xscale/i80321/i80321_timer.c index 7b2fdcb5d04..78492b81f1a 100644 --- a/sys/arm/xscale/i80321/i80321_timer.c +++ b/sys/arm/xscale/i80321/i80321_timer.c @@ -66,8 +66,6 @@ __FBSDID("$FreeBSD$"); definitions overrides the ones from i80321reg.h */ #endif -#include - #include "opt_timer.h" void (*i80321_hardclock_hook)(void) = NULL; From 7f9f80ce03da2dee0add43195dc6c3c5f0e1beeb Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 3 Oct 2009 15:02:55 +0000 Subject: [PATCH 030/646] When releasing a lockmgr held in shared way we need to use a write memory barrier in order to avoid, on architectures which doesn't have strong ordered writes, CPU instructions reordering. Diagnosed by: fabio --- sys/kern/kern_lock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index e6f2f536249..60b51f7b315 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -241,7 +241,7 @@ wakeupshlk(struct lock *lk, const char *file, int line) * and return. */ if (LK_SHARERS(x) > 1) { - if (atomic_cmpset_ptr(&lk->lk_lock, x, + if (atomic_cmpset_rel_ptr(&lk->lk_lock, x, x - LK_ONE_SHARER)) break; continue; @@ -254,7 +254,7 @@ wakeupshlk(struct lock *lk, const char *file, int line) if ((x & LK_ALL_WAITERS) == 0) { MPASS((x & ~LK_EXCLUSIVE_SPINNERS) == LK_SHARERS_LOCK(1)); - if (atomic_cmpset_ptr(&lk->lk_lock, x, LK_UNLOCKED)) + if (atomic_cmpset_rel_ptr(&lk->lk_lock, x, LK_UNLOCKED)) break; continue; } @@ -280,7 +280,7 @@ wakeupshlk(struct lock *lk, const char *file, int line) queue = SQ_SHARED_QUEUE; } - if (!atomic_cmpset_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1) | x, + if (!atomic_cmpset_rel_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1) | x, v)) { sleepq_release(&lk->lock_object); continue; From 7441ac4618ad167bff57d40c83af37816b917330 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sun, 4 Oct 2009 10:38:04 +0000 Subject: [PATCH 031/646] Fix a bug that causes the fsx test case of mmap'ed page being out of sync of read/write, inspired by ZFS's counterpart. PR: kern/139312 Submitted by: gk@ MFC after: 1 week --- sys/fs/tmpfs/tmpfs_vnops.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index db8ceeae17b..59d94d75db9 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -444,7 +444,8 @@ tmpfs_mappedread(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *uio offset = addr & PAGE_MASK; tlen = MIN(PAGE_SIZE - offset, len); - if ((vobj == NULL) || (vobj->resident_page_count == 0)) + if ((vobj == NULL) || + (vobj->resident_page_count == 0 && vobj->cache == NULL)) goto nocache; VM_OBJECT_LOCK(vobj); @@ -555,7 +556,8 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *ui offset = addr & PAGE_MASK; tlen = MIN(PAGE_SIZE - offset, len); - if ((vobj == NULL) || (vobj->resident_page_count == 0)) { + if ((vobj == NULL) || + (vobj->resident_page_count == 0 && vobj->cache == NULL)) { vpg = NULL; goto nocache; } @@ -573,6 +575,8 @@ lookupvpg: VM_OBJECT_UNLOCK(vobj); error = uiomove_fromphys(&vpg, offset, tlen, uio); } else { + if (__predict_false(vobj->cache != NULL)) + vm_page_cache_free(vobj, idx, idx + 1); VM_OBJECT_UNLOCK(vobj); vpg = NULL; } From 45c607224938dd071b2ec5398ea64e547939d665 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sun, 4 Oct 2009 10:54:20 +0000 Subject: [PATCH 032/646] Install x86 related man pages on x86 systems only. Reviewed by: jkoshy --- lib/libpmc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile index 7d97c96a0da..d307b4916db 100644 --- a/lib/libpmc/Makefile +++ b/lib/libpmc/Makefile @@ -24,6 +24,7 @@ MAN+= pmc_start.3 MAN+= pmclog.3 # PMC-dependent manual pages +.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" MAN+= pmc.atom.3 MAN+= pmc.core.3 MAN+= pmc.core2.3 @@ -34,6 +35,7 @@ MAN+= pmc.p4.3 MAN+= pmc.p5.3 MAN+= pmc.p6.3 MAN+= pmc.tsc.3 +.endif MLINKS+= \ pmc_allocate.3 pmc_release.3 \ From a7835d55789d1100d12c2940f57430e5d22df9b5 Mon Sep 17 00:00:00 2001 From: "Simon L. B. Nielsen" Date: Sun, 4 Oct 2009 16:30:33 +0000 Subject: [PATCH 033/646] In lists, if there is a Li command remove it. This fixes markup for uath(4). MFC after: 3 days Reported by: Warren Block --- release/doc/share/misc/man2hwnotes.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release/doc/share/misc/man2hwnotes.pl b/release/doc/share/misc/man2hwnotes.pl index b5ec96971a1..2fbc06601f3 100644 --- a/release/doc/share/misc/man2hwnotes.pl +++ b/release/doc/share/misc/man2hwnotes.pl @@ -252,6 +252,10 @@ sub parse { $txt =~ s/ Ta /\t/g; $txt =~ s/([^\t]+)\t.*/$1/; } + + # Remove Li commands + $txt =~ s/^Li //g; + parabuf_addline(\%mdocvars, normalize($txt)); } elsif (/^Bl/) { $mdocvars{isin_list} = 1; From e67e0775e6f7f349bb1dca6b821a265499b9def8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 4 Oct 2009 18:53:10 +0000 Subject: [PATCH 034/646] Align and pad the page queue and free page queue locks so that the linker can't possibly place them together within the same cache line. MFC after: 3 weeks --- sys/vm/vm_page.c | 4 ++-- sys/vm/vm_page.h | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index ac363b70166..c6bcfa07eb1 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -135,8 +135,8 @@ __FBSDID("$FreeBSD$"); */ struct vpgqueues vm_page_queues[PQ_COUNT]; -struct mtx vm_page_queue_mtx; -struct mtx vm_page_queue_free_mtx; +struct vpglocks vm_page_queue_lock; +struct vpglocks vm_page_queue_free_lock; vm_page_t vm_page_array = 0; int vm_page_array_size = 0; diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index b1b1070ae48..662af98be83 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -170,7 +170,15 @@ struct vpgqueues { }; extern struct vpgqueues vm_page_queues[PQ_COUNT]; -extern struct mtx vm_page_queue_free_mtx; + +struct vpglocks { + struct mtx data; + char pad[CACHE_LINE_SIZE - sizeof(struct mtx)]; +} __aligned(CACHE_LINE_SIZE); + +extern struct vpglocks vm_page_queue_free_lock; + +#define vm_page_queue_free_mtx vm_page_queue_free_lock.data /* * These are the flags defined for vm_page. @@ -258,7 +266,9 @@ PHYS_TO_VM_PAGE(vm_paddr_t pa) #endif } -extern struct mtx vm_page_queue_mtx; +extern struct vpglocks vm_page_queue_lock; + +#define vm_page_queue_mtx vm_page_queue_lock.data #define vm_page_lock_queues() mtx_lock(&vm_page_queue_mtx) #define vm_page_unlock_queues() mtx_unlock(&vm_page_queue_mtx) From 7e817e2a0306e91da5289df797333995c12abc4c Mon Sep 17 00:00:00 2001 From: David Schultz Date: Sun, 4 Oct 2009 19:43:36 +0000 Subject: [PATCH 035/646] Better glibc compatibility for getline/getdelim: - Tolerate applications that pass a NULL pointer for the buffer and claim that the capacity of the buffer is nonzero. - If an application passes in a non-NULL buffer pointer and claims the buffer has zero capacity, we should free (well, realloc) it anyway. It could have been obtained from malloc(0), so failing to free it would be a small memory leak. MFC After: 2 weeks Reported by: naddy PR: ports/138320 --- lib/libc/stdio/getdelim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c index 7af154f6af5..d7d5627ec92 100644 --- a/lib/libc/stdio/getdelim.c +++ b/lib/libc/stdio/getdelim.c @@ -120,8 +120,8 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim, goto error; } - if (*linecapp == 0) - *linep = NULL; + if (*linep == NULL) + *linecapp = 0; if (fp->_r <= 0 && __srefill(fp)) { /* If fp is at EOF already, we just need space for the NUL. */ From caf17d8660b69832e6ae0d0d868d5a3970dac7c4 Mon Sep 17 00:00:00 2001 From: David Schultz Date: Sun, 4 Oct 2009 19:44:41 +0000 Subject: [PATCH 036/646] Regression tests for r197752 (handling of empty/NULL buffers). --- .../regression/lib/libc/stdio/test-getdelim.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/regression/lib/libc/stdio/test-getdelim.c b/tools/regression/lib/libc/stdio/test-getdelim.c index 1102c20fd5a..c68c21ef624 100644 --- a/tools/regression/lib/libc/stdio/test-getdelim.c +++ b/tools/regression/lib/libc/stdio/test-getdelim.c @@ -80,7 +80,7 @@ main(int argc, char *argv[]) srandom(0); - printf("1..5\n"); + printf("1..6\n"); /* * Test multiple times with different buffer sizes @@ -103,6 +103,7 @@ main(int argc, char *argv[]) assert(getline(&line, &linecap, fp) == -1); assert(line[0] == '\0'); free(line); + line = NULL; assert(feof(fp)); assert(!ferror(fp)); fclose(fp); @@ -164,5 +165,23 @@ main(int argc, char *argv[]) fclose(fp); printf("ok 5 - nul\n"); + /* Make sure NULL *linep and zero *linecapp are handled. */ + fp = mkfilebuf(); + free(line); + line = NULL; + linecap = 42; + assert(getline(&line, &linecap, fp) == sizeof(apothegm) - 1); + assert(memcmp(line, apothegm, sizeof(apothegm)) == 0); + fp = mkfilebuf(); + free(line); + line = malloc(100); + linecap = 0; + assert(getline(&line, &linecap, fp) == sizeof(apothegm) - 1); + assert(memcmp(line, apothegm, sizeof(apothegm)) == 0); + free(line); + assert(!ferror(fp)); + fclose(fp); + printf("ok 6 - empty/NULL initial buffer\n"); + exit(0); } From f8b51ca5e9299cdd7aec679a553e712e48cb36a0 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Sun, 4 Oct 2009 23:30:08 +0000 Subject: [PATCH 037/646] updates device entries supported with the product name not magic numbers and sorts entries. WUSB54GCV2 is added. Obtained from: OpenBSD --- sys/dev/usb/usbdevs | 10 ++++++++++ sys/dev/usb/wlan/if_urtw.c | 23 ++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 17285b3cec1..4662107869b 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -908,6 +908,7 @@ product ASIX AX88772 0x7720 AX88772 product ASUS WL167G 0x1707 WL-167g Wireless Adapter product ASUS WL159G 0x170c WL-159g product ASUS A9T_WIFI 0x171b A9T wireless +product ASUS P5B_WIFI 0x171d P5B wireless product ASUS RT2573_1 0x1723 RT2573 product ASUS RT2573_2 0x1724 RT2573 product ASUS LCM 0x1726 LCM display @@ -975,6 +976,7 @@ product BELKIN F5D7051 0x7051 F5D7051 54g USB Network Adapter product BELKIN F5D7050A 0x705a F5D7050A Wireless Adapter /* Also sold as 'Ativa 802.11g wireless card' */ product BELKIN F5D7050_V4000 0x705c F5D7050 v4000 Wireless Adapter +product BELKIN F5D7050E 0x705e F5D7050E Wireless Adapter product BELKIN F5D9050V3 0x905b F5D9050 ver 3 Wireless Adapter product BELKIN2 F5U002 0x0002 F5U002 Parallel printer @@ -1656,6 +1658,7 @@ product LINKSYS2 WUSB11 0x2219 WUSB11 Wireless Adapter product LINKSYS2 USB200M 0x2226 USB 2.0 10/100 Ethernet product LINKSYS3 WUSB11v28 0x2233 WUSB11 v2.8 Wireless Adapter product LINKSYS4 USB1000 0x0039 USB1000 +product LINKSYS4 WUSB54GCV2 0x0073 WUSB54GC v2 /* Logitech products */ product LOGITECH M2452 0x0203 M2452 keyboard @@ -1876,6 +1879,7 @@ product NETGEAR EA101X 0x1002 Ethernet product NETGEAR FA101 0x1020 Ethernet 10/100, USB1.1 product NETGEAR FA120 0x1040 USB 2.0 Ethernet product NETGEAR WG111V2_2 0x4240 PrismGT USB 2.0 WLAN +product NETGEAR WG111V3 0x4260 WG111v3 product NETGEAR WG111U 0x4300 WG111U product NETGEAR WG111U_NF 0x4301 WG111U (no firmware) product NETGEAR WG111V2 0x6a00 WG111V2 @@ -2101,6 +2105,9 @@ product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter /* Green House and CompUSA OEM this part */ product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter +product REALTEK RTL8187B_0 0x8189 RTL8187B Wireless Adapter +product REALTEK RTL8187B_1 0x8197 RTL8187B Wireless Adapter +product REALTEK RTL8187B_2 0x8198 RTL8187B Wireless Adapter /* Ricoh products */ product RICOH VGPVCC2 0x1830 VGP-VCC2 Camera @@ -2270,6 +2277,8 @@ product SITECOM SERIAL 0x2068 USB to serial cable (v2) product SITECOM2 WL022 0x182d WL-022 /* Sitecom Europe products */ +product SITECOMEU WL168V1 0x000d WL-168 v1 +product SITECOMEU WL168V4 0x0028 WL-168 v4 product SITECOMEU LN028 0x061c LN-028 product SITECOMEU WL113 0x9071 WL-113 product SITECOMEU ZD1211B 0x9075 ZD1211B @@ -2375,6 +2384,7 @@ product DIAMOND2 RIO600USB 0x5001 Rio 600 USB product DIAMOND2 RIO800USB 0x5002 Rio 800 USB /* Surecom Technology products */ +product SURECOM EP9001G2A 0x11f2 EP-9001-G rev 2A product SURECOM RT2570 0x11f3 RT2570 product SURECOM RT2573 0x31f3 RT2573 diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 0cd8d3535a3..391a32c3942 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -102,23 +102,24 @@ TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode); #define URTW_REV_RTL8187B 0 #define URTW_REV_RTL8187L 1 static const struct usb_device_id urtw_devs[] = { - { USB_VPI(USB_VENDOR_BELKIN, 0x705e, URTW_REV_RTL8187B) }, - { USB_VPI(USB_VENDOR_REALTEK, 0x8189, URTW_REV_RTL8187B) }, - { USB_VPI(USB_VENDOR_REALTEK, 0x8197, URTW_REV_RTL8187B) }, - { USB_VPI(USB_VENDOR_REALTEK, 0x8198, URTW_REV_RTL8187B) }, - { USB_VPI(USB_VENDOR_NETGEAR, 0x4260, URTW_REV_RTL8187B) }, + URTW_DEV_B(NETGEAR, WG111V3), + URTW_DEV_B(REALTEK, RTL8187B_0), + URTW_DEV_B(REALTEK, RTL8187B_1), + URTW_DEV_B(REALTEK, RTL8187B_2), + URTW_DEV_B(SITECOMEU, WL168V4), + URTW_DEV_L(ASUS, P5B_WIFI), + URTW_DEV_L(BELKIN, F5D7050E), + URTW_DEV_L(LINKSYS4, WUSB54GCV2), + URTW_DEV_L(NETGEAR, WG111V2), + URTW_DEV_L(REALTEK, RTL8187), + URTW_DEV_L(SITECOMEU, WL168V1), + URTW_DEV_L(SURECOM, EP9001G2A), { USB_VPI(0x1b75, 0x8187, URTW_REV_RTL8187L) }, - { USB_VPI(USB_VENDOR_ASUS, 0x171d, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) }, - URTW_DEV_L(NETGEAR, WG111V2), - URTW_DEV_L(REALTEK, RTL8187), - { USB_VPI(USB_VENDOR_SITECOMEU, 0x000d, URTW_REV_RTL8187L) }, - { USB_VPI(USB_VENDOR_SITECOMEU, 0x0028, URTW_REV_RTL8187B) }, { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) }, - { USB_VPI(USB_VENDOR_SURECOM, 0x11f2, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) }, #undef URTW_DEV_L #undef URTW_DEV_B From 4bdcc9c7d71b83892309efffef6513840797a461 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Mon, 5 Oct 2009 01:31:16 +0000 Subject: [PATCH 038/646] The cylinder group tag cg_initediblk needs to match the number of inodes actually initialized. In the growfs case for UFS2, no inodes were actually being initialized and the number of inodes noted as initialized was the number of inodes per group. This created a filesystem that was deemed corrupted because the inodes thus added were full of garbage. MFC after: 1 month --- sbin/growfs/growfs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index 89b14dac27f..96b5c6ca405 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -397,11 +397,17 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); cs = &fscs[cylno]; memset(&acg, 0, sblock.fs_cgsize); + /* + * Note that we do not set cg_initediblk at all. + * In this extension of a previous filesystem + * we have no inodes initialized for the cylinder + * group at all. The first access to that cylinder + * group will do the correct initialization. + */ acg.cg_time = utime; acg.cg_magic = CG_MAGIC; acg.cg_cgx = cylno; acg.cg_niblk = sblock.fs_ipg; - acg.cg_initediblk = sblock.fs_ipg; acg.cg_ndblk = dmax - cbase; if (sblock.fs_contigsumsize > 0) acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; @@ -414,7 +420,6 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) acg.cg_time = 0; acg.cg_old_niblk = acg.cg_niblk; acg.cg_niblk = 0; - acg.cg_initediblk = 0; acg.cg_old_btotoff = start; acg.cg_old_boff = acg.cg_old_btotoff + sblock.fs_old_cpg * sizeof(int32_t); @@ -2217,6 +2222,7 @@ main(int argc, char **argv) printf("Warning: %jd sector(s) cannot be allocated.\n", (intmax_t)fsbtodb(&sblock, sblock.fs_size % sblock.fs_fpg)); sblock.fs_size = sblock.fs_ncg * sblock.fs_fpg; + maxino -= sblock.fs_ipg; } /* From a250649bd8d6999d8511cb826085deb34236f3f3 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 5 Oct 2009 07:11:19 +0000 Subject: [PATCH 039/646] Modified locale(1) to be able to show the altmon_X fields and the [cxX]_fmt's. Also modify the "-k list" option to display only fields with a certain prefix. MFC after: 1 week --- include/langinfo.h | 14 ++++++++++++++ usr.bin/locale/locale.1 | 10 ++++++++-- usr.bin/locale/locale.c | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/include/langinfo.h b/include/langinfo.h index 59b50f9ce34..6d6b95f2cc4 100644 --- a/include/langinfo.h +++ b/include/langinfo.h @@ -114,6 +114,20 @@ typedef __nl_item nl_item; #define D_MD_ORDER 57 /* month/day order (local extension) */ #endif +/* standalone months forms for %OB */ +#define ALTMON_1 58 +#define ALTMON_2 59 +#define ALTMON_3 60 +#define ALTMON_4 61 +#define ALTMON_5 62 +#define ALTMON_6 63 +#define ALTMON_7 64 +#define ALTMON_8 65 +#define ALTMON_9 66 +#define ALTMON_10 67 +#define ALTMON_11 68 +#define ALTMON_12 69 + __BEGIN_DECLS char *nl_langinfo(nl_item); __END_DECLS diff --git a/usr.bin/locale/locale.1 b/usr.bin/locale/locale.1 index e6b64518078..b2aba5defdb 100644 --- a/usr.bin/locale/locale.1 +++ b/usr.bin/locale/locale.1 @@ -35,8 +35,12 @@ .Nm .Op Fl a | m .Nm -.Op Fl ck -.Op Ar keyword ... +.Fl k +.Ic list +.Op Ar prefix +.Nm +.Op Fl ck +.Ar keyword ... .Sh DESCRIPTION The .Nm @@ -79,6 +83,8 @@ The special specific) keyword .Cm list can be used to retrieve the human readable list of all available keywords. +If so, +a prefix string can be defined to limit the amount of keywords returned. .Sh EXIT STATUS .Ex -std .Sh SEE ALSO diff --git a/usr.bin/locale/locale.c b/usr.bin/locale/locale.c index a4b6b400183..e40cefae037 100644 --- a/usr.bin/locale/locale.c +++ b/usr.bin/locale/locale.c @@ -55,7 +55,7 @@ const char *lookup_localecat(int); char *kwval_lconv(int); int kwval_lookup(char *, char **, int *, int *); void showdetails(char *); -void showkeywordslist(void); +void showkeywordslist(char *substring); void showlocale(void); void usage(void); @@ -149,6 +149,9 @@ struct _kwinfo { { "d_t_fmt", 1, LC_TIME, D_T_FMT, "" }, { "d_fmt", 1, LC_TIME, D_FMT, "" }, { "t_fmt", 1, LC_TIME, T_FMT, "" }, + { "c_fmt", 1, LC_TIME, C_FMT, "" }, + { "x_fmt", 1, LC_TIME, X_FMT, "" }, + { "X_fmt", 1, LC_TIME, CAPITALX_FMT, "" }, { "am_str", 1, LC_TIME, AM_STR, "" }, { "pm_str", 1, LC_TIME, PM_STR, "" }, { "t_fmt_ampm", 1, LC_TIME, T_FMT_AMPM, "" }, @@ -190,6 +193,18 @@ struct _kwinfo { { "abmon_10", 1, LC_TIME, ABMON_10, "" }, { "abmon_11", 1, LC_TIME, ABMON_11, "" }, { "abmon_12", 1, LC_TIME, ABMON_12, "" }, + { "altmon_1", 1, LC_TIME, ALTMON_1, "" }, + { "altmon_2", 1, LC_TIME, ALTMON_2, "" }, + { "altmon_3", 1, LC_TIME, ALTMON_3, "" }, + { "altmon_4", 1, LC_TIME, ALTMON_4, "" }, + { "altmon_5", 1, LC_TIME, ALTMON_5, "" }, + { "altmon_6", 1, LC_TIME, ALTMON_6, "" }, + { "altmon_7", 1, LC_TIME, ALTMON_7, "" }, + { "altmon_8", 1, LC_TIME, ALTMON_8, "" }, + { "altmon_9", 1, LC_TIME, ALTMON_9, "" }, + { "altmon_10", 1, LC_TIME, ALTMON_10, "" }, + { "altmon_11", 1, LC_TIME, ALTMON_11, "" }, + { "altmon_12", 1, LC_TIME, ALTMON_12, "" }, { "era", 1, LC_TIME, ERA, "(unavailable)" }, { "era_d_fmt", 1, LC_TIME, ERA_D_FMT, "(unavailable)" }, { "era_d_t_fmt", 1, LC_TIME, ERA_D_T_FMT, "(unavailable)" }, @@ -217,7 +232,7 @@ main(int argc, char *argv[]) int ch; int tmp; - while ((ch = getopt(argc, argv, "ackm")) != -1) { + while ((ch = getopt(argc, argv, "ackms:")) != -1) { switch (ch) { case 'a': all_locales = 1; @@ -265,7 +280,7 @@ main(int argc, char *argv[]) if (prt_keywords && argc > 0) while (tmp < argc) if (strcasecmp(argv[tmp++], "list") == 0) { - showkeywordslist(); + showkeywordslist(argv[tmp]); exit(0); } @@ -290,7 +305,8 @@ void usage(void) { printf("Usage: locale [ -a | -m ]\n" - " locale [ -ck ] name ...\n"); + " locale -k list [prefix]\n" + " locale [ -ck ] keyword ...\n"); exit(1); } @@ -594,6 +610,7 @@ showdetails(char *kw) * invalid keyword specified. * XXX: any actions? */ + fprintf(stderr, "Unknown keyword: `%s'\n", kw); return; } @@ -639,16 +656,25 @@ lookup_localecat(int cat) * Show list of keywords */ void -showkeywordslist(void) +showkeywordslist(char *substring) { size_t i; #define FMT "%-20s %-12s %-7s %-20s\n" - printf("List of available keywords\n\n"); + if (substring == NULL) + printf("List of available keywords\n\n"); + else + printf("List of available keywords starting with '%s'\n\n", + substring); printf(FMT, "Keyword", "Category", "Type", "Comment"); printf("-------------------- ------------ ------- --------------------\n"); for (i = 0; i < NKWINFO; i++) { + if (substring != NULL) { + if (strncmp(kwinfo[i].name, substring, + strlen(substring)) != 0) + continue; + } printf(FMT, kwinfo[i].name, lookup_localecat(kwinfo[i].catid), From 28c42042d8f1bb8283227af2572dd7f95fb12f2d Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 5 Oct 2009 07:13:15 +0000 Subject: [PATCH 040/646] Modified locale(1) to be able to show the altmon_X fields and the [cxX]_fmt's. Also modify the "-k list" option to display only fields with a certain prefix. MFC after: 1 week --- lib/libc/locale/nl_langinfo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/libc/locale/nl_langinfo.c b/lib/libc/locale/nl_langinfo.c index 9bd508214e4..26ca0254498 100644 --- a/lib/libc/locale/nl_langinfo.c +++ b/lib/libc/locale/nl_langinfo.c @@ -93,6 +93,12 @@ nl_langinfo(nl_item item) case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: ret = (char*) __get_current_time_locale()->mon[_REL(ABMON_1)]; break; + case ALTMON_1: case ALTMON_2: case ALTMON_3: case ALTMON_4: + case ALTMON_5: case ALTMON_6: case ALTMON_7: case ALTMON_8: + case ALTMON_9: case ALTMON_10: case ALTMON_11: case ALTMON_12: + ret = (char*) + __get_current_time_locale()->alt_month[_REL(ALTMON_1)]; + break; case ERA: /* XXX: need to be implemented */ ret = ""; From d5060740e31551a3248277a35de430fdbcb6d8d5 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 5 Oct 2009 07:21:21 +0000 Subject: [PATCH 041/646] Backout changes for c_fmt, x_fmt and X_fmt, they were coming from the wrong patches. Apologies. --- usr.bin/locale/locale.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/usr.bin/locale/locale.c b/usr.bin/locale/locale.c index e40cefae037..da4a560b2d2 100644 --- a/usr.bin/locale/locale.c +++ b/usr.bin/locale/locale.c @@ -149,9 +149,6 @@ struct _kwinfo { { "d_t_fmt", 1, LC_TIME, D_T_FMT, "" }, { "d_fmt", 1, LC_TIME, D_FMT, "" }, { "t_fmt", 1, LC_TIME, T_FMT, "" }, - { "c_fmt", 1, LC_TIME, C_FMT, "" }, - { "x_fmt", 1, LC_TIME, X_FMT, "" }, - { "X_fmt", 1, LC_TIME, CAPITALX_FMT, "" }, { "am_str", 1, LC_TIME, AM_STR, "" }, { "pm_str", 1, LC_TIME, PM_STR, "" }, { "t_fmt_ampm", 1, LC_TIME, T_FMT_AMPM, "" }, From a8a3cd7d9d1c16eae8501dcd49d219bc48dd4dbd Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Mon, 5 Oct 2009 08:44:31 +0000 Subject: [PATCH 042/646] - Improve error message consistency and wording. --- sys/geom/vinum/geom_vinum_create.c | 18 +++++++++--------- sys/geom/vinum/geom_vinum_events.c | 2 +- sys/geom/vinum/geom_vinum_init.c | 6 +++--- sys/geom/vinum/geom_vinum_move.c | 4 ++-- sys/geom/vinum/geom_vinum_rm.c | 8 ++++---- sys/geom/vinum/geom_vinum_subr.c | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sys/geom/vinum/geom_vinum_create.c b/sys/geom/vinum/geom_vinum_create.c index 0ea0ef308bb..289710da114 100644 --- a/sys/geom/vinum/geom_vinum_create.c +++ b/sys/geom/vinum/geom_vinum_create.c @@ -94,7 +94,7 @@ gv_create_drive(struct gv_softc *sc, struct gv_drive *d) if (g_attach(cp, pp) != 0) { g_destroy_consumer(cp); g_topology_unlock(); - G_VINUM_DEBUG(0, "create drive '%s': couldn't attach", + G_VINUM_DEBUG(0, "create drive '%s': unable to attach", d->name); g_free(d); return (GV_ERR_CREATE); @@ -135,7 +135,7 @@ gv_create_drive(struct gv_softc *sc, struct gv_drive *d) g_detach(cp); g_destroy_consumer(cp); g_topology_unlock(); - G_VINUM_DEBUG(0, "create drive '%s': couldn't update " + G_VINUM_DEBUG(0, "create drive '%s': unable to update " "access counts", d->name); if (d->hdr != NULL) g_free(d->hdr); @@ -320,7 +320,7 @@ gv_concat(struct g_geom *gp, struct gctl_req *req) dcount = 0; vol = gctl_get_param(req, "name", NULL); if (vol == NULL) { - gctl_error(req, "volume names not given"); + gctl_error(req, "volume name not given"); return; } @@ -388,7 +388,7 @@ gv_mirror(struct g_geom *gp, struct gctl_req *req) pcount = 0; vol = gctl_get_param(req, "name", NULL); if (vol == NULL) { - gctl_error(req, "volume's not given"); + gctl_error(req, "volume name not given"); return; } @@ -396,7 +396,7 @@ gv_mirror(struct g_geom *gp, struct gctl_req *req) drives = gctl_get_paraml(req, "drives", sizeof(*drives)); if (drives == NULL) { - gctl_error(req, "drives not given"); + gctl_error(req, "drive names not given"); return; } @@ -480,7 +480,7 @@ gv_raid5(struct g_geom *gp, struct gctl_req *req) vol = gctl_get_param(req, "name", NULL); if (vol == NULL) { - gctl_error(req, "volume's not given"); + gctl_error(req, "volume name not given"); return; } flags = gctl_get_paraml(req, "flags", sizeof(*flags)); @@ -493,7 +493,7 @@ gv_raid5(struct g_geom *gp, struct gctl_req *req) } if (drives == NULL) { - gctl_error(req, "drives not given"); + gctl_error(req, "drive names not given"); return; } @@ -558,14 +558,14 @@ gv_stripe(struct g_geom *gp, struct gctl_req *req) pcount = 0; vol = gctl_get_param(req, "name", NULL); if (vol == NULL) { - gctl_error(req, "volume's not given"); + gctl_error(req, "volume name not given"); return; } flags = gctl_get_paraml(req, "flags", sizeof(*flags)); drives = gctl_get_paraml(req, "drives", sizeof(*drives)); if (drives == NULL) { - gctl_error(req, "drives not given"); + gctl_error(req, "drive names not given"); return; } diff --git a/sys/geom/vinum/geom_vinum_events.c b/sys/geom/vinum/geom_vinum_events.c index 81e87f3fa87..02c14ce5532 100644 --- a/sys/geom/vinum/geom_vinum_events.c +++ b/sys/geom/vinum/geom_vinum_events.c @@ -193,7 +193,7 @@ gv_drive_lost(struct gv_softc *sc, struct gv_drive *d) if (cp != NULL) { if (cp->nstart != cp->nend) { G_VINUM_DEBUG(0, "dead drive '%s' has still active " - "requests, can't detach consumer", d->name); + "requests, unable to detach consumer", d->name); gv_post_event(sc, GV_EVENT_DRIVE_LOST, d, NULL, 0, 0); return; } diff --git a/sys/geom/vinum/geom_vinum_init.c b/sys/geom/vinum/geom_vinum_init.c index 34f11563e00..de3ad9c49da 100644 --- a/sys/geom/vinum/geom_vinum_init.c +++ b/sys/geom/vinum/geom_vinum_init.c @@ -87,7 +87,7 @@ gv_start_obj(struct g_geom *gp, struct gctl_req *req) case GV_TYPE_SD: case GV_TYPE_DRIVE: /* XXX Not implemented, but what is the use? */ - gctl_error(req, "cannot start '%s' - not yet supported", + gctl_error(req, "unable to start '%s' - not yet supported", argv); return; default: @@ -279,8 +279,8 @@ gv_rebuild_plex(struct gv_plex *p) LIST_FOREACH(s, &p->subdisks, in_plex) { d = s->drive_sc; if (d == NULL || (d->flags & GV_DRIVE_REFERENCED)) { - G_VINUM_DEBUG(0, "can't rebuild %s, subdisk(s) have no " - "drives", p->name); + G_VINUM_DEBUG(0, "unable to rebuild %s, subdisk(s) have" + " no drives", p->name); return (ENXIO); } } diff --git a/sys/geom/vinum/geom_vinum_move.c b/sys/geom/vinum/geom_vinum_move.c index e55a6a2a48b..8c295f60821 100644 --- a/sys/geom/vinum/geom_vinum_move.c +++ b/sys/geom/vinum/geom_vinum_move.c @@ -84,7 +84,7 @@ gv_move(struct g_geom *gp, struct gctl_req *req) type = gv_object_type(sc, object); if (type != GV_TYPE_SD) { gctl_error(req, "you can only move subdisks; " - "'%s' isn't one", object); + "'%s' is not a subdisk", object); return; } @@ -145,7 +145,7 @@ gv_move_sd(struct gv_softc *sc, struct gv_sd *cursd, err = gv_set_sd_state(cursd, GV_SD_STALE, GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG); if (err) { - G_VINUM_DEBUG(0, "could not set the subdisk '%s' to state " + G_VINUM_DEBUG(0, "unable to set the subdisk '%s' to state " "'stale'", cursd->name); return (err); } diff --git a/sys/geom/vinum/geom_vinum_rm.c b/sys/geom/vinum/geom_vinum_rm.c index fa56bc302c1..0d94de9626c 100644 --- a/sys/geom/vinum/geom_vinum_rm.c +++ b/sys/geom/vinum/geom_vinum_rm.c @@ -207,7 +207,7 @@ gv_rm_vol(struct gv_softc *sc, struct gv_volume *v) /* Check if any of our consumers is open. */ if (gv_provider_is_open(pp)) { - G_VINUM_DEBUG(0, "Unable to remove %s: volume still in use", + G_VINUM_DEBUG(0, "unable to remove %s: volume still in use", v->name); return; } @@ -241,7 +241,7 @@ gv_rm_plex(struct gv_softc *sc, struct gv_plex *p) /* Check if any of our consumers is open. */ if (v != NULL && gv_provider_is_open(v->provider) && v->plexcount < 2) { - G_VINUM_DEBUG(0, "Unable to remove %s: volume still in use", + G_VINUM_DEBUG(0, "unable to remove %s: volume still in use", p->name); return; } @@ -318,7 +318,7 @@ gv_rm_drive(struct gv_softc *sc, struct gv_drive *d, int flags) g_topology_unlock(); if (err) { - G_VINUM_DEBUG(0, "%s: couldn't access '%s', " + G_VINUM_DEBUG(0, "%s: unable to access '%s', " "errno: %d", __func__, cp->provider->name, err); return; } @@ -327,7 +327,7 @@ gv_rm_drive(struct gv_softc *sc, struct gv_drive *d, int flags) d->hdr->magic = GV_NOMAGIC; err = gv_write_header(cp, d->hdr); if (err) - G_VINUM_DEBUG(0, "gv_rm_drive: couldn't write header to" + G_VINUM_DEBUG(0, "gv_rm_drive: error writing header to" " '%s', errno: %d", cp->provider->name, err); g_topology_lock(); diff --git a/sys/geom/vinum/geom_vinum_subr.c b/sys/geom/vinum/geom_vinum_subr.c index 95767fdff10..e381ff2bf59 100644 --- a/sys/geom/vinum/geom_vinum_subr.c +++ b/sys/geom/vinum/geom_vinum_subr.c @@ -585,7 +585,7 @@ gv_sd_to_drive(struct gv_sd *s, struct gv_drive *d) return (0); } } else { - G_VINUM_DEBUG(0, "can't give sd '%s' to '%s' " + G_VINUM_DEBUG(0, "error giving subdisk '%s' to '%s' " "(already on '%s')", s->name, d->name, s->drive_sc->name); return (GV_ERR_ISATTACHED); @@ -612,7 +612,7 @@ gv_sd_to_drive(struct gv_sd *s, struct gv_drive *d) /* No good slot found? */ if (s->size == -1) { - G_VINUM_DEBUG(0, "couldn't autosize '%s' on '%s'", + G_VINUM_DEBUG(0, "unable to autosize '%s' on '%s'", s->name, d->name); return (GV_ERR_BADSIZE); } From 3e485d4cba809555b556afc25ee4ffa5785ee786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 5 Oct 2009 09:26:22 +0000 Subject: [PATCH 043/646] Change the pam_ssh examples: if you use it, you probably want want_agent. MFC after: 3 weeks --- etc/pam.d/kde | 2 +- etc/pam.d/other | 2 +- etc/pam.d/sshd | 2 +- etc/pam.d/system | 2 +- etc/pam.d/telnetd | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/etc/pam.d/kde b/etc/pam.d/kde index a384d628940..99ae791984f 100644 --- a/etc/pam.d/kde +++ b/etc/pam.d/kde @@ -15,5 +15,5 @@ account required pam_nologin.so account required pam_unix.so # session -#session optional pam_ssh.so +#session optional pam_ssh.so want_agent session required pam_permit.so diff --git a/etc/pam.d/other b/etc/pam.d/other index c86239cb56d..cb4e939e489 100644 --- a/etc/pam.d/other +++ b/etc/pam.d/other @@ -18,7 +18,7 @@ account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so +#session optional pam_ssh.so want_agent session required pam_permit.so # password diff --git a/etc/pam.d/sshd b/etc/pam.d/sshd index 46f536c74a4..27e2b21dd5c 100644 --- a/etc/pam.d/sshd +++ b/etc/pam.d/sshd @@ -18,7 +18,7 @@ account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so +#session optional pam_ssh.so want_agent session required pam_permit.so # password diff --git a/etc/pam.d/system b/etc/pam.d/system index c2f4d8b3fda..56607f29221 100644 --- a/etc/pam.d/system +++ b/etc/pam.d/system @@ -17,7 +17,7 @@ account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so +#session optional pam_ssh.so want_agent session required pam_lastlog.so no_fail # password diff --git a/etc/pam.d/telnetd b/etc/pam.d/telnetd index 535afc29315..53cdd82b686 100644 --- a/etc/pam.d/telnetd +++ b/etc/pam.d/telnetd @@ -18,7 +18,7 @@ account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so +#session optional pam_ssh.so want_agent session required pam_lastlog.so no_fail # password From 4fa5b48f39afe6371fa0c71dbafcd1ecfc1b068f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 5 Oct 2009 09:28:54 +0000 Subject: [PATCH 044/646] tabify MFC after: 3 weeks --- etc/pam.d/ftpd | 4 ++-- etc/pam.d/kde | 4 ++-- etc/pam.d/other | 4 ++-- etc/pam.d/sshd | 4 ++-- etc/pam.d/system | 4 ++-- etc/pam.d/telnetd | 4 ++-- etc/pam.d/xdm | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/etc/pam.d/ftpd b/etc/pam.d/ftpd index 632c97333f1..0d0b0766cc2 100644 --- a/etc/pam.d/ftpd +++ b/etc/pam.d/ftpd @@ -8,12 +8,12 @@ auth sufficient pam_opie.so no_warn no_fake_prompts auth requisite pam_opieaccess.so no_warn allow_local #auth sufficient pam_krb5.so no_warn -#auth sufficient pam_ssh.so no_warn try_first_pass +#auth sufficient pam_ssh.so no_warn try_first_pass auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_unix.so # session diff --git a/etc/pam.d/kde b/etc/pam.d/kde index 99ae791984f..f7d54f66c6c 100644 --- a/etc/pam.d/kde +++ b/etc/pam.d/kde @@ -11,9 +11,9 @@ auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_unix.so # session -#session optional pam_ssh.so want_agent +#session optional pam_ssh.so want_agent session required pam_permit.so diff --git a/etc/pam.d/other b/etc/pam.d/other index cb4e939e489..110aa00e74d 100644 --- a/etc/pam.d/other +++ b/etc/pam.d/other @@ -13,12 +13,12 @@ auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so want_agent +#session optional pam_ssh.so want_agent session required pam_permit.so # password diff --git a/etc/pam.d/sshd b/etc/pam.d/sshd index 27e2b21dd5c..b4707c009f4 100644 --- a/etc/pam.d/sshd +++ b/etc/pam.d/sshd @@ -13,12 +13,12 @@ auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so want_agent +#session optional pam_ssh.so want_agent session required pam_permit.so # password diff --git a/etc/pam.d/system b/etc/pam.d/system index 56607f29221..b8b7101e6b8 100644 --- a/etc/pam.d/system +++ b/etc/pam.d/system @@ -12,12 +12,12 @@ auth requisite pam_opieaccess.so no_warn allow_local auth required pam_unix.so no_warn try_first_pass nullok # account -#account required pam_krb5.so +#account required pam_krb5.so account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so want_agent +#session optional pam_ssh.so want_agent session required pam_lastlog.so no_fail # password diff --git a/etc/pam.d/telnetd b/etc/pam.d/telnetd index 53cdd82b686..fb2f523d4ad 100644 --- a/etc/pam.d/telnetd +++ b/etc/pam.d/telnetd @@ -13,12 +13,12 @@ auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_login_access.so account required pam_unix.so # session -#session optional pam_ssh.so want_agent +#session optional pam_ssh.so want_agent session required pam_lastlog.so no_fail # password diff --git a/etc/pam.d/xdm b/etc/pam.d/xdm index b883de762a4..2a7db08053f 100644 --- a/etc/pam.d/xdm +++ b/etc/pam.d/xdm @@ -11,11 +11,11 @@ auth required pam_unix.so no_warn try_first_pass # account account required pam_nologin.so -#account required pam_krb5.so +#account required pam_krb5.so account required pam_unix.so # session -#session required pam_ssh.so want_agent +#session required pam_ssh.so want_agent session required pam_lastlog.so no_fail # password From 2c7cd48d3cc2212a2cb379d3896222cbb03c7cf1 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Mon, 5 Oct 2009 10:08:58 +0000 Subject: [PATCH 045/646] - Drop unused pmap_use_l1 function and comment out currently unused pmap_dcache_wbinv_all/pmap_copy_page functions which we might want to take advatage of later. This fixes the build with PMAP_DEBUG defined. Discussed with: cognet --- sys/arm/arm/pmap.c | 54 +++++++--------------------------------------- 1 file changed, 8 insertions(+), 46 deletions(-) diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index 1b9bf81f174..5e55f8ee09a 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -203,7 +203,6 @@ static void pmap_enter_locked(pmap_t, vm_offset_t, vm_page_t, static void pmap_fix_cache(struct vm_page *, pmap_t, vm_offset_t); static void pmap_alloc_l1(pmap_t); static void pmap_free_l1(pmap_t); -static void pmap_use_l1(pmap_t); static int pmap_clearbit(struct vm_page *, u_int); @@ -829,47 +828,6 @@ pmap_free_l1(pmap_t pm) mtx_unlock(&l1_lru_lock); } -static PMAP_INLINE void -pmap_use_l1(pmap_t pm) -{ - struct l1_ttable *l1; - - /* - * Do nothing if we're in interrupt context. - * Access to an L1 by the kernel pmap must not affect - * the LRU list. - */ - if (pm == pmap_kernel()) - return; - - l1 = pm->pm_l1; - - /* - * If the L1 is not currently on the LRU list, just return - */ - if (l1->l1_domain_use_count == PMAP_DOMAINS) - return; - - mtx_lock(&l1_lru_lock); - - /* - * Check the use count again, now that we've acquired the lock - */ - if (l1->l1_domain_use_count == PMAP_DOMAINS) { - mtx_unlock(&l1_lru_lock); - return; - } - - /* - * Move the L1 to the back of the LRU list - */ - TAILQ_REMOVE(&l1_lru_list, l1, l1_lru); - TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru); - - mtx_unlock(&l1_lru_lock); -} - - /* * Returns a pointer to the L2 bucket associated with the specified pmap * and VA, or NULL if no L2 bucket exists for the address. @@ -1311,6 +1269,7 @@ pmap_idcache_wbinv_all(pmap_t pm) } } +#ifdef notyet static PMAP_INLINE void pmap_dcache_wbinv_all(pmap_t pm) { @@ -1320,6 +1279,7 @@ pmap_dcache_wbinv_all(pmap_t pm) cpu_l2cache_wbinv_all(); } } +#endif /* * PTE_SYNC_CURRENT: @@ -1914,7 +1874,7 @@ pmap_init(void) { int shpgperproc = PMAP_SHPGPERPROC; - PDEBUG(1, printf("pmap_init: phys_start = %08x\n")); + PDEBUG(1, printf("pmap_init: phys_start = %08x\n", PHYSADDR)); /* * init the pv free list @@ -2373,8 +2333,8 @@ pmap_bootstrap(vm_offset_t firstaddr, vm_offset_t lastaddr, struct pv_addr *l1pt vm_size_t size; int l1idx, l2idx, l2next = 0; - PDEBUG(1, printf("firstaddr = %08x, loadaddr = %08x\n", - firstaddr, loadaddr)); + PDEBUG(1, printf("firstaddr = %08x, lastaddr = %08x\n", + firstaddr, lastaddr)); virtual_avail = firstaddr; kernel_pmap->pm_l1 = l1; @@ -4251,7 +4211,7 @@ pmap_zero_page_idle(vm_page_t m) * pmap_clean_page() * * This is a local function used to work out the best strategy to clean - * a single page referenced by its entry in the PV table. It's used by + * a single page referenced by its entry in the PV table. It should be used by * pmap_copy_page, pmap_zero page and maybe some others later on. * * Its policy is effectively: @@ -4266,6 +4226,8 @@ pmap_zero_page_idle(vm_page_t m) * mapped at 0x00000000 a whole cache clean will be performed rather than * just the 1 page. Since this should not occur in everyday use and if it does * it will just result in not the most efficient clean for the page. + * + * We don't yet use this function but may want to. */ static int pmap_clean_page(struct pv_entry *pv, boolean_t is_src) From 432e1942d27c2b37f0a495a84d9736e8c968d806 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 5 Oct 2009 14:13:16 +0000 Subject: [PATCH 046/646] When the timeout backoff hits the maximum value, leave it capped at the maximum value rather than setting it to the result of a boolean expression that is always true. Submitted by: Joseph Kong MFC after: 1 month --- sys/dev/ppbus/lpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c index 10d67d91811..77ebaea561f 100644 --- a/sys/dev/ppbus/lpt.c +++ b/sys/dev/ppbus/lpt.c @@ -456,7 +456,7 @@ lptout(void *arg) if (sc->sc_state & OPEN) { sc->sc_backoff++; if (sc->sc_backoff > hz/LPTOUTMAX) - sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX; + sc->sc_backoff = hz/LPTOUTMAX; callout_reset(&sc->sc_timer, sc->sc_backoff, lptout, sc); } else sc->sc_state &= ~TOUT; From 84d61770bcdd6c8ff1fe0f26c58158c5c2128274 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 14:49:16 +0000 Subject: [PATCH 047/646] First cut at implementing SOCK_SEQPACKET support for UNIX (local) domain sockets. This allows for reliable bi-directional datagram communication over UNIX domain sockets, in contrast to SOCK_DGRAM (M:N, unreliable) or SOCK_STERAM (bi-directional bytestream). Largely, this reuses existing UNIX domain socket code. This allows applications requiring record- oriented semantics to do so reliably via local IPC. Some implementation notes (also present in XXX comments): - Currently we lack an sbappend variant able to do datagrams and control data without doing addresses, so we mark SOCK_SEQPACKET as PR_ADDR. Adding a new variant will solve this problem. - UNIX domain sockets on FreeBSD provide back-pressure/flow control notification for stream sockets by manipulating the send socket buffer's size during pru_send and pru_rcvd. This trick works less well for SOCK_SEQPACKET as sosend_generic() uses sb_hiwat not just to manage blocking, but also to determine maximum datagram size. Fixing this requires rethinking how back-pressure is done for SOCK_SEQPACKET; in the mean time, it's possible to get EMSGSIZE when buffers fill, instead of blocking. Discussed with: benl Reviewed by: bz, rpaulo MFC after: 3 months Sponsored by: Google --- sys/kern/uipc_usrreq.c | 139 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 123 insertions(+), 16 deletions(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index e002b2a90d2..598080171ab 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -50,7 +50,8 @@ * garbage collector to find and tear down cycles of disconnected sockets. * * TODO: - * SEQPACKET, RDM + * RDM + * distinguish datagram size limits from flow control limits in SEQPACKET * rethink name space problems * need a proper out-of-band */ @@ -112,6 +113,7 @@ static ino_t unp_ino; /* Prototype for fake inode numbers. */ static int unp_rights; /* (g) File descriptors in flight. */ static struct unp_head unp_shead; /* (l) List of stream sockets. */ static struct unp_head unp_dhead; /* (l) List of datagram sockets. */ +static struct unp_head unp_sphead; /* (l) List of seqpacket sockets. */ static const struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL }; @@ -139,10 +141,14 @@ static u_long unpst_sendspace = PIPSIZ; static u_long unpst_recvspace = PIPSIZ; static u_long unpdg_sendspace = 2*1024; /* really max datagram size */ static u_long unpdg_recvspace = 4*1024; +static u_long unpsp_sendspace = PIPSIZ; /* really max datagram size */ +static u_long unpsp_recvspace = PIPSIZ; SYSCTL_NODE(_net, PF_LOCAL, local, CTLFLAG_RW, 0, "Local domain"); SYSCTL_NODE(_net_local, SOCK_STREAM, stream, CTLFLAG_RW, 0, "SOCK_STREAM"); SYSCTL_NODE(_net_local, SOCK_DGRAM, dgram, CTLFLAG_RW, 0, "SOCK_DGRAM"); +SYSCTL_NODE(_net_local, SOCK_SEQPACKET, seqpacket, CTLFLAG_RW, 0, + "SOCK_SEQPACKET"); SYSCTL_ULONG(_net_local_stream, OID_AUTO, sendspace, CTLFLAG_RW, &unpst_sendspace, 0, "Default stream send space."); @@ -152,6 +158,10 @@ SYSCTL_ULONG(_net_local_dgram, OID_AUTO, maxdgram, CTLFLAG_RW, &unpdg_sendspace, 0, "Default datagram send space."); SYSCTL_ULONG(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW, &unpdg_recvspace, 0, "Default datagram receive space."); +SYSCTL_ULONG(_net_local_seqpacket, OID_AUTO, maxseqpacket, CTLFLAG_RW, + &unpsp_sendspace, 0, "Default seqpacket send space."); +SYSCTL_ULONG(_net_local_seqpacket, OID_AUTO, recvspace, CTLFLAG_RW, + &unpsp_recvspace, 0, "Default seqpacket receive space."); SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0, "File descriptors in flight."); @@ -257,6 +267,7 @@ static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *); */ static struct domain localdomain; static struct pr_usrreqs uipc_usrreqs_dgram, uipc_usrreqs_stream; +static struct pr_usrreqs uipc_usrreqs_seqpacket; static struct protosw localsw[] = { { .pr_type = SOCK_STREAM, @@ -271,6 +282,19 @@ static struct protosw localsw[] = { .pr_flags = PR_ATOMIC|PR_ADDR|PR_RIGHTS, .pr_usrreqs = &uipc_usrreqs_dgram }, +{ + .pr_type = SOCK_SEQPACKET, + .pr_domain = &localdomain, + + /* + * XXXRW: For now, PR_ADDR because soreceive will bump into them + * due to our use of sbappendaddr. A new sbappend variants is needed + * that supports both atomic record writes and control data. + */ + .pr_flags = PR_ADDR|PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD| + PR_RIGHTS, + .pr_usrreqs = &uipc_usrreqs_seqpacket, +}, }; static struct domain localdomain = { @@ -353,6 +377,11 @@ uipc_attach(struct socket *so, int proto, struct thread *td) recvspace = unpdg_recvspace; break; + case SOCK_SEQPACKET: + sendspace = unpsp_sendspace; + recvspace = unpsp_recvspace; + break; + default: panic("uipc_attach"); } @@ -372,8 +401,22 @@ uipc_attach(struct socket *so, int proto, struct thread *td) UNP_LIST_LOCK(); unp->unp_gencnt = ++unp_gencnt; unp_count++; - LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead : &unp_shead, - unp, unp_link); + switch (so->so_type) { + case SOCK_STREAM: + LIST_INSERT_HEAD(&unp_shead, unp, unp_link); + break; + + case SOCK_DGRAM: + LIST_INSERT_HEAD(&unp_dhead, unp, unp_link); + break; + + case SOCK_SEQPACKET: + LIST_INSERT_HEAD(&unp_sphead, unp, unp_link); + break; + + default: + panic("uipc_attach"); + } UNP_LIST_UNLOCK(); return (0); @@ -705,11 +748,8 @@ uipc_rcvd(struct socket *so, int flags) unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_rcvd: unp == NULL")); - if (so->so_type == SOCK_DGRAM) - panic("uipc_rcvd DGRAM?"); - - if (so->so_type != SOCK_STREAM) - panic("uipc_rcvd unknown socktype"); + if (so->so_type != SOCK_STREAM && so->so_type != SOCK_SEQPACKET) + panic("uipc_rcvd socktype %d", so->so_type); /* * Adjust backpressure on sender and wakeup any waiting to write. @@ -824,6 +864,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, break; } + case SOCK_SEQPACKET: case SOCK_STREAM: if ((so->so_state & SS_ISCONNECTED) == 0) { if (nam != NULL) { @@ -875,11 +916,33 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, * Send to paired receive port, and then reduce send buffer * hiwater marks to maintain backpressure. Wake up readers. */ - if (control != NULL) { - if (sbappendcontrol_locked(&so2->so_rcv, m, control)) + switch (so->so_type) { + case SOCK_STREAM: + if (control != NULL) { + if (sbappendcontrol_locked(&so2->so_rcv, m, + control)) + control = NULL; + } else + sbappend_locked(&so2->so_rcv, m); + break; + + case SOCK_SEQPACKET: { + const struct sockaddr *from; + + from = &sun_noname; + if (sbappendaddr_locked(&so2->so_rcv, from, m, + control)) control = NULL; - } else - sbappend_locked(&so2->so_rcv, m); + break; + } + } + + /* + * XXXRW: While fine for SOCK_STREAM, this conflates maximum + * datagram size and back-pressure for SOCK_SEQPACKET, which + * can lead to undesired return of EMSGSIZE on send instead + * of more desirable blocking. + */ mbcnt_delta = so2->so_rcv.sb_mbcnt - unp2->unp_mbcnt; unp2->unp_mbcnt = so2->so_rcv.sb_mbcnt; sbcc = so2->so_rcv.sb_cc; @@ -939,7 +1002,8 @@ uipc_sense(struct socket *so, struct stat *sb) UNP_LINK_RLOCK(); UNP_PCB_LOCK(unp); unp2 = unp->unp_conn; - if (so->so_type == SOCK_STREAM && unp2 != NULL) { + if ((so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET) && + unp2 != NULL) { so2 = unp2->unp_socket; sb->st_blksize += so2->so_rcv.sb_cc; } @@ -1009,6 +1073,26 @@ static struct pr_usrreqs uipc_usrreqs_dgram = { .pru_close = uipc_close, }; +static struct pr_usrreqs uipc_usrreqs_seqpacket = { + .pru_abort = uipc_abort, + .pru_accept = uipc_accept, + .pru_attach = uipc_attach, + .pru_bind = uipc_bind, + .pru_connect = uipc_connect, + .pru_connect2 = uipc_connect2, + .pru_detach = uipc_detach, + .pru_disconnect = uipc_disconnect, + .pru_listen = uipc_listen, + .pru_peeraddr = uipc_peeraddr, + .pru_rcvd = uipc_rcvd, + .pru_send = uipc_send, + .pru_sense = uipc_sense, + .pru_shutdown = uipc_shutdown, + .pru_sockaddr = uipc_sockaddr, + .pru_soreceive = soreceive_generic, /* XXX: or...? */ + .pru_close = uipc_close, +}; + static struct pr_usrreqs uipc_usrreqs_stream = { .pru_abort = uipc_abort, .pru_accept = uipc_accept, @@ -1306,6 +1390,7 @@ unp_connect2(struct socket *so, struct socket *so2, int req) break; case SOCK_STREAM: + case SOCK_SEQPACKET: unp2->unp_conn = unp; if (req == PRU_CONNECT && ((unp->unp_flags | unp2->unp_flags) & UNP_CONNWAIT)) @@ -1343,6 +1428,7 @@ unp_disconnect(struct unpcb *unp, struct unpcb *unp2) break; case SOCK_STREAM: + case SOCK_SEQPACKET: soisdisconnected(unp->unp_socket); unp2->unp_conn = NULL; soisdisconnected(unp2->unp_socket); @@ -1368,7 +1454,22 @@ unp_pcblist(SYSCTL_HANDLER_ARGS) struct unp_head *head; struct xunpcb *xu; - head = ((intptr_t)arg1 == SOCK_DGRAM ? &unp_dhead : &unp_shead); + switch ((intptr_t)arg1) { + case SOCK_STREAM: + head = &unp_shead; + break; + + case SOCK_DGRAM: + head = &unp_dhead; + break; + + case SOCK_SEQPACKET: + head = &unp_sphead; + break; + + default: + panic("unp_pcblist: arg1 %d", (intptr_t)arg1); + } /* * The process of preparing the PCB list is too time-consuming and @@ -1481,6 +1582,9 @@ SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist, CTLFLAG_RD, SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist, CTLFLAG_RD, (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb", "List of active local stream sockets"); +SYSCTL_PROC(_net_local_seqpacket, OID_AUTO, pcblist, CTLFLAG_RD, + (caddr_t)(long)SOCK_SEQPACKET, 0, unp_pcblist, "S,xunpcb", + "List of active local seqpacket sockets"); static void unp_shutdown(struct unpcb *unp) @@ -1492,7 +1596,8 @@ unp_shutdown(struct unpcb *unp) UNP_PCB_LOCK_ASSERT(unp); unp2 = unp->unp_conn; - if (unp->unp_socket->so_type == SOCK_STREAM && unp2 != NULL) { + if ((unp->unp_socket->so_type == SOCK_STREAM || + (unp->unp_socket->so_type == SOCK_SEQPACKET)) && unp2 != NULL) { so = unp2->unp_socket; if (so != NULL) socantrcvmore(so); @@ -1658,6 +1763,7 @@ unp_init(void) NULL, EVENTHANDLER_PRI_ANY); LIST_INIT(&unp_dhead); LIST_INIT(&unp_shead); + LIST_INIT(&unp_sphead); TASK_INIT(&unp_gc_task, 0, unp_gc, NULL); UNP_LINK_LOCK_INIT(); UNP_LIST_LOCK_INIT(); @@ -1974,7 +2080,8 @@ SYSCTL_INT(_net_local, OID_AUTO, taskcount, CTLFLAG_RD, &unp_taskcount, 0, static void unp_gc(__unused void *arg, int pending) { - struct unp_head *heads[] = { &unp_dhead, &unp_shead, NULL }; + struct unp_head *heads[] = { &unp_dhead, &unp_shead, &unp_sphead, + NULL }; struct unp_head **head; struct file **unref; struct unpcb *unp; From 3ac5a8e8b122c276080e9ac3d37549d056b043a6 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 5 Oct 2009 15:05:43 +0000 Subject: [PATCH 048/646] Add myself. Approved by: trasz (mentor) --- share/misc/committers-src.dot | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index 2673305f284..626a3cb13ac 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -106,6 +106,7 @@ ivoras [label="Ivan Voras\nivoras@FreeBSD.org\n2008/06/10"] jake [label="Jake Burkholder\njake@FreeBSD.org\n2000/05/16"] jamie [label="Jamie Gritton\njamie@FreeBSD.org\n2009/01/28"] jayanth [label="Jayanth Vijayaraghavan\njayanth@FreeBSD.org\n2000/05/08"] +jh [label="Jaakko Heinonen\njh@FreeBSD.org\n2009/10/02"] jilles [label="Jilles Tjoelker\njilles@FreeBSD.org\n2009/05/22"] jinmei [label="JINMEI Tatuya\njinmei@FreeBSD.org\n2007/03/17"] jdp [label="John Polstra\njdp@FreeBSD.org\n????/??/??"] @@ -406,6 +407,7 @@ rwatson -> bz rwatson -> cperciva rwatson -> emaste rwatson -> gnn +rwatson -> jh rwatson -> kensmith rwatson -> kmacy rwatson -> linimon @@ -435,6 +437,8 @@ sos -> marcel thompsa -> weongyo thompsa -> eri +trasz -> jh + ume -> jinmei ume -> suz ume -> tshiozak From 963b7ccd3b045db7404a023760379bece1756504 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 15:06:14 +0000 Subject: [PATCH 049/646] netstat(1) support for UNIX SOCK_SEQPACKET sockets -- changes were required only for the kvm case, as we supported SOCK_SEQPACKET via sysctl already. Sponsored by: Google MFC after: 3 months --- usr.bin/netstat/main.c | 5 ++++- usr.bin/netstat/netstat.h | 2 +- usr.bin/netstat/unix.c | 26 +++++++++++++++++++++----- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index ebbe1d24fbf..b1c494086ee 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -186,6 +186,8 @@ static struct nlist nl[] = { { .n_name = "_mfctablesize" }, #define N_ARPSTAT 55 { .n_name = "_arpstat" }, +#define N_UNP_SPHEAD 56 + { .n_name = "unp_sphead" }, { .n_name = NULL }, }; @@ -601,7 +603,8 @@ main(int argc, char *argv[]) #endif /* NETGRAPH */ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, - nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value); + nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value, + nl[N_UNP_SPHEAD].n_value); exit(0); } diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index f834495e32b..259ca823e28 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -150,7 +150,7 @@ void ddp_stats(u_long, const char *, int, int); void netgraphprotopr(u_long, const char *, int, int); #endif -void unixpr(u_long, u_long, u_long, u_long); +void unixpr(u_long, u_long, u_long, u_long, u_long); void esis_stats(u_long, const char *, int, int); void clnp_stats(u_long, const char *, int, int); diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c index 209fc8d497b..0ad8f34a52a 100644 --- a/usr.bin/netstat/unix.c +++ b/usr.bin/netstat/unix.c @@ -193,21 +193,37 @@ fail: } void -unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off) +unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, + u_long sphead_off) { char *buf; int ret, type; struct xsocket *so; struct xunpgen *xug, *oxug; struct xunpcb *xunp; + u_long head_off; for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) { if (live) ret = pcblist_sysctl(type, &buf); - else - ret = pcblist_kvm(count_off, gencnt_off, - type == SOCK_STREAM ? shead_off : - (type == SOCK_DGRAM ? dhead_off : 0), &buf); + else { + head_off = 0; + switch (type) { + case SOCK_STREAM: + head_off = shead_off; + break; + + case SOCK_DGRAM: + head_off = dhead_off; + break; + + case SOCK_SEQPACKET: + head_off = sphead_off; + break; + } + ret = pcblist_kvm(count_off, gencnt_off, head_off, + &buf); + } if (ret == -1) continue; if (ret < 0) From ebb8cecb010fa3412af7204439500ae4076ee0a9 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 15:07:44 +0000 Subject: [PATCH 050/646] SOCK_SEQPACKET is now supported on UNIX domain sockets. Sponsored by: Google MFC after: 3 months --- share/man/man4/unix.4 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/share/man/man4/unix.4 b/share/man/man4/unix.4 index 89944ce7a7e..f099122aea6 100644 --- a/share/man/man4/unix.4 +++ b/share/man/man4/unix.4 @@ -52,7 +52,8 @@ mechanisms. The .Ux Ns -domain family supports the -.Dv SOCK_STREAM +.Dv SOCK_STREAM , +.Dv SOCK_SEQPACKET , and .Dv SOCK_DGRAM socket types and uses @@ -127,11 +128,14 @@ The .Ux Ns -domain protocol family is comprised of simple transport protocols that support the -.Dv SOCK_STREAM +.Dv SOCK_STREAM , +.Dv SOCK_SEQPACKET , and .Dv SOCK_DGRAM abstractions. .Dv SOCK_STREAM +and +.Dv SOCK_SEQPACKET sockets also support the communication of .Ux file descriptors through the use of the @@ -206,8 +210,9 @@ and tested with .Xr getsockopt 2 : .Bl -tag -width ".Dv LOCAL_CONNWAIT" .It Dv LOCAL_CREDS -This option may be enabled on a -.Dv SOCK_DGRAM +This option may be enabled on +.Dv SOCK_DGRAM , +.Dv SOCK_SEQPACKET , or a .Dv SOCK_STREAM socket. From 9fa8a03e517e6d543f5aabeec76e390ce2f9b6da Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 15:15:13 +0000 Subject: [PATCH 051/646] Bump unix(4) man page date for SOCK_SEQPACKET. Suggested by: bz MFC after: 3 months --- share/man/man4/unix.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/unix.4 b/share/man/man4/unix.4 index f099122aea6..97e797c2f9e 100644 --- a/share/man/man4/unix.4 +++ b/share/man/man4/unix.4 @@ -32,7 +32,7 @@ .\" @(#)unix.4 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd July 15, 2001 +.Dd October 5, 2009 .Dt UNIX 4 .Os .Sh NAME From 55b95b33ed2ba6feae1139c96bae2f31a0fb23dd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 5 Oct 2009 15:16:28 +0000 Subject: [PATCH 052/646] Make fetch(9) and store(9) manual pages closer to reality. --- share/man/man9/Makefile | 12 ++++++++---- share/man/man9/fetch.9 | 38 +++++++++++++++++++++++++------------- share/man/man9/store.9 | 31 ++++++++++++++++++++----------- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 7adf4d7f1e6..2b1969d50ba 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -606,8 +606,10 @@ MLINKS+=EVENTHANDLER.9 EVENTHANDLER_DECLARE.9 \ EVENTHANDLER.9 eventhandler_register.9 MLINKS+=fetch.9 fubyte.9 \ fetch.9 fuswintr.9 \ - fetch.9 fusword.9 \ - fetch.9 fuword.9 + fetch.9 fuword.9 \ + fetch.9 fuword16.9 \ + fetch.9 fuword32.9 \ + fetch.9 fuword64.9 MLINKS+=g_attach.9 g_detach.9 MLINKS+=g_bio.9 g_clone_bio.9 \ g_bio.9 g_destroy_bio.9 \ @@ -1142,8 +1144,10 @@ MLINKS+=stack.9 stack_copy.9 \ stack.9 stack_zero.9 MLINKS+=store.9 subyte.9 \ store.9 suswintr.9 \ - store.9 susword.9 \ - store.9 suword.9 + store.9 suword.9 \ + store.9 suword16.9 \ + store.9 suword32.9 \ + store.9 suword64.9 MLINKS+=swi.9 swi_add.9 \ swi.9 swi_sched.9 MLINKS+=sx.9 sx_assert.9 \ diff --git a/share/man/man9/fetch.9 b/share/man/man9/fetch.9 index 7de3ff7fbb9..ccf68668d3d 100644 --- a/share/man/man9/fetch.9 +++ b/share/man/man9/fetch.9 @@ -34,29 +34,35 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 1996 +.Dd October 5, 2009 .Dt FETCH 9 .Os .Sh NAME .Nm fetch , .Nm fubyte , -.Nm fusword , .Nm fuswintr , -.Nm fuword +.Nm fuword , +.Nm fuword16 , +.Nm fuword32 , +.Nm fuword64 .Nd fetch data from user-space .Sh SYNOPSIS .In sys/types.h .In sys/time.h .In sys/systm.h -.In sys/resourcevar.h .Ft int .Fn fubyte "const void *base" -.Ft int -.Fn fusword "void *base" -.Ft int -.Fn fuswintr "void *base" .Ft long .Fn fuword "const void *base" +.Ft int +.Fn fuword16 "void *base" +.Ft int32_t +.Fn fuword32 "const void *base" +.Ft int64_t +.Fn fuword64 "const void *base" +.In sys/resourcevar.h +.Ft int +.Fn fuswintr "void *base" .Sh DESCRIPTION The .Nm @@ -69,16 +75,22 @@ routines provide the following functionality: .It Fn fubyte Fetches a byte of data from the user-space address .Pa base . -.It Fn fusword -Fetches a short word of data from the user-space address +.It Fn fuword +Fetches a word of data from the user-space address +.Pa base . +.It Fn fuword16 +Fetches 16 bits of data from the user-space address +.Pa base . +.It Fn fuword32 +Fetches 32 bits of data from the user-space address +.Pa base . +.It Fn fuword64 +Fetches 64 bits of data from the user-space address .Pa base . .It Fn fuswintr Fetches a short word of data from the user-space address .Pa base . This function is safe to call during an interrupt context. -.It Fn fuword -Fetches a word of data from the user-space address -.Pa base . .El .Sh RETURN VALUES The diff --git a/share/man/man9/store.9 b/share/man/man9/store.9 index 4438d84ca5a..e3297e1fb13 100644 --- a/share/man/man9/store.9 +++ b/share/man/man9/store.9 @@ -34,13 +34,12 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 1996 +.Dd October 5, 2009 .Dt STORE 9 .Os .Sh NAME .Nm store , .Nm subyte , -.Nm susword , .Nm suswintr , .Nm suword .Nd store data to user-space @@ -48,15 +47,19 @@ .In sys/types.h .In sys/time.h .In sys/systm.h -.In sys/resourcevar.h .Ft int .Fn subyte "void *base" "int byte" .Ft int -.Fn susword "void *base" "int word" +.Fn suword "void *base" "long word" +.Ft int +.Fn suword16 "void *base" "int word" +.Ft int +.Fn suword32 "void *base" "int32_t word" +.Ft int +.Fn suword64 "void *base" "int64_t word" +.In sys/resourcevar.h .Ft int .Fn suswintr "void *base" "int word" -.Ft int -.Fn suword "void *base" "long word" .Sh DESCRIPTION The .Nm @@ -69,16 +72,22 @@ routines provide the following functionality: .It Fn subyte Stores a byte of data to the user-space address .Pa base . -.It Fn susword -Stores a short word of data to the user-space address +.It Fn suword +Stores a word of data to the user-space address +.Pa base . +.It Fn suword16 +Stores 16 bits of of data to the user-space address +.Pa base . +.It Fn suword32 +Stores 32 bits of of data to the user-space address +.Pa base . +.It Fn suword64 +Stores 64 bits of of data to the user-space address .Pa base . .It Fn suswintr Stores a short word of data to the user-space address .Pa base . This function is safe to call during an interrupt context. -.It Fn suword -Stores a word of data to the user-space address -.Pa base . .El .Sh RETURN VALUES The From 9cad1429d6518aaf341458ad181d89bf1bab9107 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 15:27:01 +0000 Subject: [PATCH 053/646] A few regression tests for SOCK_SEQPACKET UNIX domain sockets. Sponsored by: Google --- .../sockets/unix_seqpacket/Makefile | 9 + .../sockets/unix_seqpacket/unix_seqpacket.c | 140 ++++++ .../sockets/unix_seqpacket_exercise/Makefile | 9 + .../unix_seqpacket_exercise.c | 435 ++++++++++++++++++ 4 files changed, 593 insertions(+) create mode 100644 tools/regression/sockets/unix_seqpacket/Makefile create mode 100644 tools/regression/sockets/unix_seqpacket/unix_seqpacket.c create mode 100644 tools/regression/sockets/unix_seqpacket_exercise/Makefile create mode 100644 tools/regression/sockets/unix_seqpacket_exercise/unix_seqpacket_exercise.c diff --git a/tools/regression/sockets/unix_seqpacket/Makefile b/tools/regression/sockets/unix_seqpacket/Makefile new file mode 100644 index 00000000000..3045065245c --- /dev/null +++ b/tools/regression/sockets/unix_seqpacket/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# + +PROG= unix_seqpacket +CFLAGS+= -Wall -Werror +NO_MAN= + +.include diff --git a/tools/regression/sockets/unix_seqpacket/unix_seqpacket.c b/tools/regression/sockets/unix_seqpacket/unix_seqpacket.c new file mode 100644 index 00000000000..40baa64a76f --- /dev/null +++ b/tools/regression/sockets/unix_seqpacket/unix_seqpacket.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define FAILERR(str) err(-1, "%s: %s", __func__, str) +#define FAILERRX(str) errx(-1, "%s: %s", __func__, str) + +static void +test_socket(void) +{ + int s; + + s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (s < 0) + FAILERR("socket"); + (void)close(s); +} + +static void +test_socketpair(void) +{ + int sv[2]; + + if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv) < 0) + FAILERR("socketpair"); + (void)close(sv[0]); + (void)close(sv[1]); +} + +static void +test_listen_unbound(void) +{ + int s; + + s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (s < 0) + FAILERR("socket"); + if (listen(s, -1) == 0) + FAILERRX("listen"); + (void)close(s); +} + +static void +test_bind(void) +{ + struct sockaddr_un sun; + char path[PATH_MAX]; + int s; + + snprintf(path, sizeof(path), "/tmp/lds.XXXXXXXXX"); + if (mktemp(path) == NULL) + FAILERR("mktemp"); + s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (s < 0) + FAILERR("socket"); + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_LOCAL; + sun.sun_len = sizeof(sun); + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + if (bind(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) + FAILERR("bind"); + close(s); + (void)unlink(path); +} + +static void +test_listen_bound(void) +{ + struct sockaddr_un sun; + char path[PATH_MAX]; + int s; + + snprintf(path, sizeof(path), "/tmp/lds.XXXXXXXXX"); + if (mktemp(path) == NULL) + FAILERR("mktemp"); + s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (s < 0) + FAILERR("socket"); + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_LOCAL; + sun.sun_len = sizeof(sun); + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + if (bind(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) + FAILERR("bind"); + if (listen(s, -1)) { + (void)unlink(path); + FAILERR("bind"); + } + close(s); + (void)unlink(path); +} + +int +main(int argc, char *argv[]) +{ + + test_socket(); + test_socketpair(); + test_listen_unbound(); + test_bind(); + test_listen_bound(); +} diff --git a/tools/regression/sockets/unix_seqpacket_exercise/Makefile b/tools/regression/sockets/unix_seqpacket_exercise/Makefile new file mode 100644 index 00000000000..494575b1705 --- /dev/null +++ b/tools/regression/sockets/unix_seqpacket_exercise/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# + +PROG=unix_seqpacket_exercise +CFLAGS+=-Wall -Werror +NO_MAN= + +.include diff --git a/tools/regression/sockets/unix_seqpacket_exercise/unix_seqpacket_exercise.c b/tools/regression/sockets/unix_seqpacket_exercise/unix_seqpacket_exercise.c new file mode 100644 index 00000000000..00eebb4b894 --- /dev/null +++ b/tools/regression/sockets/unix_seqpacket_exercise/unix_seqpacket_exercise.c @@ -0,0 +1,435 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define min(x, y) (x < y ? x : y) + +#define BUFLEN 32768 + +#define SEQPACKET_RCVBUF (131072-16) +#define SEQPACKET_SNDBUF (131072-16) + +#define FAILERR(str) err(-1, "%s: %s", __func__, str) +#define FAILNERR(str, n) err(-1, "%s %d: %s", __func__, n, str) +#define FAILNMERR(str, n, m) err(-1, "%s %d %d: %s", __func__, n, m, str) +#define FAILERRX(str) errx(-1, "%s: %s", __func__, str) +#define FAILNERRX(str, n) errx(-1, "%s %d: %s", __func__, n, str) +#define FAILNMERRX(str, n, m) errx(-1, "%s %d %d: %s", __func__, n, m, str) + +static int ann = 0; + +#define ANN() (ann ? warnx("%s: start", __func__) : 0) +#define ANNN(n) (ann ? warnx("%s %d: start", __func__, (n)) : 0) +#define ANNNM(n, m) (ann ? warnx("%s %d %d: start", __func__, (n), (m)) : 0) + +#define OK() warnx("%s: ok", __func__) +#define OKN(n) warnx("%s %d: ok", __func__, (n)) +#define OKNM(n, m) warnx("%s %d %d: ok", __func__, (n), (m)) + +#ifdef SO_NOSIGPIPE +#define NEW_SOCKET(s) do { \ + int i; \ + \ + (s) = socket(PF_LOCAL, SOCK_SEQPACKET, 0); \ + if ((s) < 0) \ + FAILERR("socket"); \ + \ + i = 1; \ + if (setsockopt((s), SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0) \ + FAILERR("setsockopt SO_NOSIGPIPE"); \ + \ + i = SEQPACKET_RCVBUF; \ + if (setsockopt((s), SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0) \ + FAILERR("setsockopt SO_RCVBUF"); \ + \ + i = SEQPACKET_SNDBUF; \ + if (setsockopt((s), SOL_SOCKET, SO_SNDBUF, &i, sizeof(i)) < 0) \ + FAILERR("setsockopt SO_SNDBUF"); \ +} while (0) +#else +#define NEW_SOCKET(s) do { \ + int i; \ + \ + (s) = socket(PF_LOCAL, SOCK_SEQPACKET, 0); \ + if ((s) < 0) \ + FAILERR("socket"); \ + \ + i = SEQPACKET_RCVBUF; \ + if (setsockopt((s), SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0) \ + FAILERR("setsockopt SO_RCVBUF"); \ + \ + i = SEQPACKET_SNDBUF; \ + if (setsockopt((s), SOL_SOCKET, SO_SNDBUF, &i, sizeof(i)) < 0) \ + FAILERR("setsockopt SO_SNDBUF"); \ +} while (0) +#endif + +static void +server(int s_listen) +{ + char buffer[BUFLEN]; + ssize_t ssize_recv, ssize_send; + socklen_t socklen; + int i, s_accept; + + while (1) { + s_accept = accept(s_listen, NULL, 0); + if (s_accept >= 0) { + i = SEQPACKET_RCVBUF; + if (setsockopt(s_accept, SOL_SOCKET, SO_RCVBUF, &i, + sizeof(i)) < 0) { + warn("server: setsockopt SO_RCVBUF"); + close(s_accept); + continue; + } + + if (getsockopt(s_accept, SOL_SOCKET, SO_RCVBUF, &i, + &socklen) < 0) { + warn("server: getsockopt SO_RCVBUF"); + close(s_accept); + continue; + } + if (i != SEQPACKET_RCVBUF) { + warnx("server: getsockopt SO_RCVBUF wrong %d", + i); + close(s_accept); + continue; + } + + socklen = sizeof(i); + if (getsockopt(s_accept, SOL_SOCKET, SO_SNDBUF, &i, + &socklen) < 0) { + warn("server: getsockopt SO_SNDBUF"); + close(s_accept); + continue; + } + if (i != SEQPACKET_SNDBUF) { + warnx("server: getsockopt SO_SNDBUF wrong %d", + i); + close(s_accept); + continue; + } + + do { + ssize_recv = recv(s_accept, buffer, + sizeof(buffer), 0); + if (ssize_recv == 0) + break; + if (ssize_recv < 0) { + warn("server: recv"); + break; + } + ssize_send = send(s_accept, buffer, + ssize_recv, 0); + if (ssize_send == 0) + break; + if (ssize_send < 0) { + warn("server: send"); + break; + } + if (ssize_send != ssize_recv) + warnx("server: recv %d sent %d", + ssize_recv, ssize_send); + } while (1); + close(s_accept); + } else + warn("server: accept"); + } +} + +static void +test_connect(struct sockaddr_un *sun) +{ + int s; + + ANN(); + NEW_SOCKET(s); + if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + FAILERR("connect"); + (void)close(s); + OK(); +} + +static void +test_connect_send(struct sockaddr_un *sun) +{ + ssize_t ssize; + char ch; + int s; + + ANN(); + NEW_SOCKET(s); + if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + FAILERR("connect"); + ssize = send(s, &ch, sizeof(ch), 0); + if (ssize < 0) + FAILERR("send"); + if (ssize != sizeof(ch)) + FAILERRX("send wrong size"); + (void)close(s); + OK(); +} + +static void +test_connect_shutdown_send(struct sockaddr_un *sun) +{ + ssize_t ssize; + char ch; + int s; + + ANN(); + NEW_SOCKET(s); + if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + FAILERR("connect"); + if (shutdown(s, SHUT_RDWR) < 0) + FAILERR("shutdown SHUT_RDWR"); + ssize = send(s, &ch, sizeof(ch), 0); + if (ssize >= 0) + FAILERRX("send"); + if (errno != EPIPE) + FAILERR("send unexpected error"); + (void)close(s); + OK(); +} + +static void +test_connect_send_recv(struct sockaddr_un *sun, size_t size) +{ + char buf[size + 4]; /* Detect extra bytes. */ + size_t truncsize; + ssize_t ssize; + int s; + + ANNN(size); + NEW_SOCKET(s); + if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + FAILNERR("connect", size); + ssize = send(s, buf, size, 0); + if (ssize < 0 && size >= SEQPACKET_RCVBUF) + goto out; + if (ssize < 0) + FAILNERR("send", size); + if (ssize == 0) + FAILNERR("send eof", size); + if (ssize != size) + FAILNERRX("send size", size); + + truncsize = min(size, BUFLEN); + ssize = recv(s, buf, sizeof(buf), 0); + if (ssize < 0) + FAILNERR("recv", size); + if (ssize == 0) + FAILNERRX("recv eof", size); + if (ssize < truncsize) + FAILNERRX("recv too few bytes", size); + if (ssize > truncsize) + FAILNERRX("recv too many bytes", size); +out: + (void)close(s); + OKN(size); +} + +static void +test_connect_send_recv_count(struct sockaddr_un *sun, int count, size_t size) +{ + char buf[size + 4]; /* Detect extra bytes and coalescing. */ + size_t truncsize; + ssize_t ssize; + int i, s; + + ANNNM(size, count); + NEW_SOCKET(s); + if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + FAILNMERR("connect", size, count); + for (i = 0; i < count; i++) { + usleep(5000); + ssize = send(s, buf, size, 0); + if (ssize < 0 && size >= SEQPACKET_RCVBUF) + goto out; + if (ssize < 0) + FAILNMERR("send", size, count); + if (ssize == 0) + FAILNMERRX("send eof", size, count); + if (ssize != size) + FAILNMERRX("send size", size, count); + } + + truncsize = min(size, BUFLEN); + for (i = 0; i < count; i++) { + ssize = recv(s, buf, sizeof(buf), 0); + if (ssize < 0) + FAILNMERR("recv", size, count); + if (ssize == 0) + FAILNMERRX("recv eof", size, count); + if (ssize < truncsize) + FAILNMERRX("recv too few bytes", size, count); + if (ssize > truncsize) + FAILNMERRX("recv too many bytes", size, count); + } +out: + (void)close(s); + OKNM(size, count); +} + +static void +test_sendto(struct sockaddr_un *sun) +{ + ssize_t ssize; + char ch; + int s; + + ANN(); + NEW_SOCKET(s); + ssize = sendto(s, &ch, sizeof(ch), 0, (struct sockaddr *)sun, + sizeof(*sun)); + if (ssize < 0) + FAILERR("sendto"); + (void)close(s); + OK(); +} + +static void +client(struct sockaddr_un *sun) +{ + size_t sizes[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768, 65536 /*, 131072 */}; + int c, i; + + test_connect(sun); + test_connect_send(sun); + test_connect_shutdown_send(sun); + + /* + * Try a range of sizes and packet counts. + */ + for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++) + test_connect_send_recv(sun, sizes[i]); + for (c = 1; c <= 8; c++) { + for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++) + test_connect_send_recv_count(sun, c, sizes[i]); + } + test_sendto(sun); + printf("client done\n"); +} + +int +main(int argc, char *argv[]) +{ + struct sockaddr_un sun; + char path[PATH_MAX]; + pid_t pid_client, pid_server; + int i, s_listen; + + snprintf(path, sizeof(path), "/tmp/lds_exercise.XXXXXXXXX"); + if (mktemp(path) == NULL) + FAILERR("mktemp"); + + s_listen = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (s_listen < 0) { + (void)unlink(path); + FAILERR("socket"); + } + + i = SEQPACKET_RCVBUF; + if (setsockopt(s_listen, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0) { + (void)unlink(path); + FAILERR("setsockopt SO_RCVBUF"); + } + + i = SEQPACKET_SNDBUF; + if (setsockopt(s_listen, SOL_SOCKET, SO_SNDBUF, &i, sizeof(i)) < 0) { + (void)unlink(path); + FAILERR("setsockopt SO_SNDBUF"); + } + + i = 1; + if (setsockopt(s_listen, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) + < 0) { + (void)unlink(path); + FAILERR("setsockopt SO_NOSIGPIPE"); + } + + bzero(&sun, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_LOCAL; + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + + if (bind(s_listen, (struct sockaddr *)&sun, sizeof(sun)) < 0) { + (void)unlink(path); + FAILERR("bind"); + } + + if (listen(s_listen, -1) < 0) { + (void)unlink(path); + FAILERR("listen"); + } + + pid_server = fork(); + if (pid_server < 0) { + (void)unlink(path); + FAILERR("fork"); + } + if (pid_server == 0) { + server(s_listen); + return (0); + } + + pid_client = fork(); + if (pid_client < 0) { + (void)kill(pid_server, SIGKILL); + (void)unlink(path); + FAILERR("fork"); + } + if (pid_client == 0) { + client(&sun); + return (0); + } + + /* + * When the client is done, kill the server and clean up. + */ + (void)waitpid(pid_client, NULL, 0); + (void)kill(pid_server, SIGKILL); + (void)unlink(path); + return (0); +} From b6e6000971f6679ebb59ea912a372f00d0504d70 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 5 Oct 2009 16:26:54 +0000 Subject: [PATCH 054/646] - Revert r191568 partially. Forcing AHCI mode by changing device subclass and progif is evil. It doesn't work reliably[1] and we should honor BIOS configuration by the user. - If the SATA controller is enbled but combined mode is disabled, mask off the emulated IDE channel on the legacy IDE controller. Pointed out by: mav[1] --- sys/dev/ata/chipsets/ata-ati.c | 94 +++++++++++----------------------- 1 file changed, 31 insertions(+), 63 deletions(-) diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c index 1dffa918fde..4436c7f53c9 100644 --- a/sys/dev/ata/chipsets/ata-ati.c +++ b/sys/dev/ata/chipsets/ata-ati.c @@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -55,9 +54,6 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_ati_chipinit(device_t dev); static void ata_ati_setmode(device_t dev, int mode); -static void ata_ati_ahci_enable(device_t dev); -static int ata_ati_ahci_chipinit(device_t dev); -static int ata_ati_ahci_resume(device_t dev); /* misc defines */ #define ATI_PATA 0x01 @@ -66,13 +62,6 @@ static int ata_ati_ahci_resume(device_t dev); #define SII_MEMIO 1 #define SII_BUG 0x04 -/* Misc Control Register */ -#define ATI_PCI_MISC_CTRL 0x40 -#define ATI_PCI_MISCCTRL_ENABLE_WR 0x00000001 - -/* Watchdog Control/Status Register */ -#define ATI_PCI_WD_CTRL 0x44 -#define ATI_PCI_WDCTRL_ENABLE 0x0001 /* * ATI chipset support functions @@ -121,19 +110,7 @@ ata_ati_probe(device_t dev) ctlr->chipinit = ata_sii_chipinit; break; case ATI_AHCI: - /* - * Force AHCI mode if IDE mode is set from BIOS. - */ - if ((ctlr->chip->chipid == ATA_ATI_IXP600_S1 || - ctlr->chip->chipid == ATA_ATI_IXP700_S1) && - pci_get_subclass(dev) == PCIS_STORAGE_IDE) { - struct pci_devinfo *dinfo = device_get_ivars(dev); - pcicfgregs *cfg = &dinfo->cfg; - cfg->subclass = PCIS_STORAGE_SATA; - cfg->progif = PCIP_STORAGE_SATA_AHCI_1_0; - ata_ati_ahci_enable(dev); - } - ctlr->chipinit = ata_ati_ahci_chipinit; + ctlr->chipinit = ata_ahci_chipinit; break; } return (BUS_PROBE_DEFAULT); @@ -143,13 +120,41 @@ static int ata_ati_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); + device_t smbdev; + int satacfg; if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; - /* IXP600 only has 1 PATA channel */ - if (ctlr->chip->chipid == ATA_ATI_IXP600) + switch (ctlr->chip->chipid) { + case ATA_ATI_IXP600: + /* IXP600 only has 1 PATA channel */ ctlr->channels = 1; + break; + case ATA_ATI_IXP700: + /* + * When "combined mode" is enabled, an additional PATA channel is + * emulated with two SATA ports and appears on this device. + * This mode can only be detected via SMB controller. + */ + smbdev = pci_find_device(ATA_ATI_ID, 0x4385); + if (smbdev != NULL) { + satacfg = pci_read_config(smbdev, 0xad, 1); + if (bootverbose) + device_printf(dev, "SATA controller %s (%s%s channel)\n", + (satacfg & 0x01) == 0 ? "disabled" : "enabled", + (satacfg & 0x08) == 0 ? "" : "combined mode, ", + (satacfg & 0x10) == 0 ? "primary" : "secondary"); + + /* + * If SATA controller is enabled but combined mode is disabled, + * we have only one PATA channel. Ignore a non-existent channel. + */ + if ((satacfg & 0x09) == 0x01) + ctlr->ichannels &= ~(1 << ((satacfg & 0x10) >> 4)); + } + break; + } ctlr->setmode = ata_ati_setmode; return 0; @@ -219,43 +224,6 @@ ata_ati_setmode(device_t dev, int mode) } } -static void -ata_ati_ahci_enable(device_t dev) -{ - struct pci_devinfo *dinfo = device_get_ivars(dev); - pcicfgregs *cfg = &dinfo->cfg; - uint32_t ctrl; - - ctrl = pci_read_config(dev, ATI_PCI_MISC_CTRL, 4); - pci_write_config(dev, ATI_PCI_MISC_CTRL, - ctrl | ATI_PCI_MISCCTRL_ENABLE_WR, 4); - pci_write_config(dev, PCIR_SUBCLASS, cfg->subclass, 1); - pci_write_config(dev, PCIR_PROGIF, cfg->progif, 1); - pci_write_config(dev, ATI_PCI_WD_CTRL, - pci_read_config(dev, ATI_PCI_WD_CTRL, 2) | ATI_PCI_WDCTRL_ENABLE, 2); - pci_write_config(dev, ATI_PCI_MISC_CTRL, - ctrl & ~ATI_PCI_MISCCTRL_ENABLE_WR, 4); -} - -static int -ata_ati_ahci_chipinit(device_t dev) -{ - struct ata_pci_controller *ctlr = device_get_softc(dev); - int error; - - error = ata_ahci_chipinit(dev); - ctlr->resume = ata_ati_ahci_resume; - return (error); -} - -static int -ata_ati_ahci_resume(device_t dev) -{ - - ata_ati_ahci_enable(dev); - return (ata_ahci_ctlr_reset(dev)); -} - ATA_DECLARE_DRIVER(ata_ati); MODULE_DEPEND(ata_ati, ata_ahci, 1, 1, 1); MODULE_DEPEND(ata_ati, ata_sii, 1, 1, 1); From e21bf2c43bfccfe70858a31ed4535b4e851254f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 5 Oct 2009 18:55:13 +0000 Subject: [PATCH 055/646] Add more symbols that need to be masked: - initialized and uninitialized data - symbols from roaming_dummy.c which end up in pam_ssh Update the command line used to generate the #defines. --- crypto/openssh/ssh_namespace.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h index 108a0a475d3..5a61eff81f7 100644 --- a/crypto/openssh/ssh_namespace.h +++ b/crypto/openssh/ssh_namespace.h @@ -7,7 +7,7 @@ * * A list of symbols which need munging is obtained as follows: * - * nm libssh.a | awk '$2 == "T" && $3 !~ /^ssh_/ { print "#define", $3, "ssh_" $3 }' + * nm libssh.a | awk '/[0-9a-z] [A-Z] / && $3 !~ /^ssh_/ { print "#define", $3, "ssh_" $3 }' * * $FreeBSD$ */ @@ -18,6 +18,7 @@ #define acss_setkey ssh_acss_setkey #define acss_setsubkey ssh_acss_setsubkey #define add_host_to_hostfile ssh_add_host_to_hostfile +#define add_recv_bytes ssh_add_recv_bytes #define addargs ssh_addargs #define addr_match_list ssh_addr_match_list #define ask_permission ssh_ask_permission @@ -111,6 +112,8 @@ #define channel_open_message ssh_channel_open_message #define channel_output_poll ssh_channel_output_poll #define channel_permit_all_opens ssh_channel_permit_all_opens +#define channel_post ssh_channel_post +#define channel_pre ssh_channel_pre #define channel_prepare_select ssh_channel_prepare_select #define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens #define channel_register_cleanup ssh_channel_register_cleanup @@ -150,14 +153,19 @@ #define cipher_set_key_string ssh_cipher_set_key_string #define cipher_set_keycontext ssh_cipher_set_keycontext #define cipher_set_keyiv ssh_cipher_set_keyiv +#define ciphers ssh_ciphers #define ciphers_valid ssh_ciphers_valid #define cleanhostname ssh_cleanhostname #define cleanup_exit ssh_cleanup_exit #define clear_cached_addr ssh_clear_cached_addr #define colon ssh_colon +#define compat13 ssh_compat13 +#define compat20 ssh_compat20 #define compat_cipher_proposal ssh_compat_cipher_proposal #define compat_datafellows ssh_compat_datafellows #define convtime ssh_convtime +#define current_keys ssh_current_keys +#define datafellows ssh_datafellows #define debug ssh_debug #define debug ssh_debug #define debug2 ssh_debug2 @@ -175,6 +183,7 @@ #define dh_new_group14 ssh_dh_new_group14 #define dh_new_group_asc ssh_dh_new_group_asc #define dh_pub_is_valid ssh_dh_pub_is_valid +#define dispatch ssh_dispatch #define dispatch_init ssh_dispatch_init #define dispatch_protocol_error ssh_dispatch_protocol_error #define dispatch_protocol_ignore ssh_dispatch_protocol_ignore @@ -205,6 +214,7 @@ #define get_local_port ssh_get_local_port #define get_peer_ipaddr ssh_get_peer_ipaddr #define get_peer_port ssh_get_peer_port +#define get_recv_bytes ssh_get_recv_bytes #define get_remote_ipaddr ssh_get_remote_ipaddr #define get_remote_name_or_ip ssh_get_remote_name_or_ip #define get_remote_port ssh_get_remote_port @@ -216,6 +226,7 @@ #define host_hash ssh_host_hash #define hostfile_read_key ssh_hostfile_read_key #define hpdelim ssh_hpdelim +#define incoming_stream ssh_incoming_stream #define init_rng ssh_init_rng #define ipv64_normalise_mapped ssh_ipv64_normalise_mapped #define kex_derive_keys ssh_kex_derive_keys @@ -268,6 +279,7 @@ #define mac_init ssh_mac_init #define mac_setup ssh_mac_setup #define mac_valid ssh_mac_valid +#define macs ssh_macs #define match_host_and_ip ssh_match_host_and_ip #define match_hostname ssh_match_hostname #define match_list ssh_match_list @@ -279,6 +291,7 @@ #define ms_subtract_diff ssh_ms_subtract_diff #define ms_to_timeval ssh_ms_to_timeval #define mysignal ssh_mysignal +#define outgoing_stream ssh_outgoing_stream #define packet_add_padding ssh_packet_add_padding #define packet_backup_state ssh_packet_backup_state #define packet_close ssh_packet_close @@ -363,9 +376,13 @@ #define refresh_progress_meter ssh_refresh_progress_meter #define replacearg ssh_replacearg #define restore_uid ssh_restore_uid +#define resume_in_progress ssh_resume_in_progress +#define resume_kex ssh_resume_kex #define rijndael_decrypt ssh_rijndael_decrypt #define rijndael_encrypt ssh_rijndael_encrypt #define rijndael_set_key ssh_rijndael_set_key +#define roaming_read ssh_roaming_read +#define roaming_write ssh_roaming_write #define rsa_generate_additional_parameters ssh_rsa_generate_additional_parameters #define rsa_private_decrypt ssh_rsa_private_decrypt #define rsa_public_encrypt ssh_rsa_public_encrypt @@ -393,6 +410,7 @@ #define tty_make_modes ssh_tty_make_modes #define tty_parse_modes ssh_tty_parse_modes #define tun_open ssh_tun_open +#define umac_ctx ssh_umac_ctx #define umac_delete ssh_umac_delete #define umac_final ssh_umac_final #define umac_new ssh_umac_new From 040b962309949fbe5a728006177c971d97bc516b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 5 Oct 2009 18:56:18 +0000 Subject: [PATCH 056/646] pam_ssh needs roaming_dummy to link correctly against libssh. --- lib/libpam/modules/pam_ssh/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/libpam/modules/pam_ssh/Makefile b/lib/libpam/modules/pam_ssh/Makefile index f7dcd0c5424..b638d8b052b 100644 --- a/lib/libpam/modules/pam_ssh/Makefile +++ b/lib/libpam/modules/pam_ssh/Makefile @@ -7,6 +7,9 @@ LIB= pam_ssh MAN= pam_ssh.8 SRCS= pam_ssh.c +# required when linking with a dynamic libssh +SRCS+= roaming_dummy.c + WARNS?= 0 CFLAGS+= -I${SSHDIR} -include ssh_namespace.h From ee06ebdf46695710482d587423f6420b736c199d Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Mon, 5 Oct 2009 19:29:49 +0000 Subject: [PATCH 057/646] Belatedly add my calendar entry. Discussed with: remko Approved by: remko, jkois (mentor) --- usr.bin/calendar/calendars/calendar.freebsd | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index a2803377309..d542d99cb2d 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -244,6 +244,7 @@ 09/10 Wesley R. Peters born in Hartford, Alabama, United States, 1961 09/12 Weongyo Jeong born in Haman, Korea, 1980 09/12 William C. Fumerola II born in Detroit, Michigan, United States, 1981 +09/12 Benedict Christopher Reuschling born in Darmstadt, Germany, 1981 09/15 Dima Panov born in Khabarovsk, Russian Federation, 1978 09/17 Maxim Bolotin born in Rostov-on-Don, Russian Federation, 1976 09/20 Kevin Lo born in Taipei, Taiwan, Republic of China, 1972 From d5e0b215417bd62be22ca59504823a4a58d9c8c9 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 5 Oct 2009 19:56:56 +0000 Subject: [PATCH 058/646] Fix NFSv4 ACLs on sparc64. Turns out that fuword(9) fetches 64 bits instead of sizeof(int), and on sparc64 that resulted in fetching wrong value for acl_maxcnt, which in turn caused __acl_get_link(2) to fail with EINVAL. PR: sparc64/139304 Submitted by: Dmitry Afanasiev --- sys/kern/vfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index ce1fa33b427..2dd64f44e45 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -161,7 +161,7 @@ acl_copyout(struct acl *kernel_acl, void *user_acl, acl_type_t type) break; default: - if (fuword((char *)user_acl + + if (fuword32((char *)user_acl + offsetof(struct acl, acl_maxcnt)) != ACL_MAX_ENTRIES) return (EINVAL); From 2880192bf207cdbe7d7a415f1c6a4818281a0569 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 5 Oct 2009 20:11:33 +0000 Subject: [PATCH 059/646] Fix a case when both ${name}_program and ${command} are defined. Spotted by: Michio "Karl" Jinbo --- etc/rc.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.subr b/etc/rc.subr index 6cb7db51c9a..fd94cc9c372 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -602,7 +602,7 @@ run_rc_command() esac eval _override_command=\$${name}_program - command=${command:-${_override_command}} + command=${command:+${_override_command:-$command}} _keywords="start stop restart rcvar $extra_commands" rc_pid= From c01f2b830100064370fe9b0fe63f8d822967c755 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Mon, 5 Oct 2009 20:21:41 +0000 Subject: [PATCH 060/646] cxgb(4) updates, including: - support for the new Gen-2, BT, and LP-CR cards. - T3 firmware 7.7.0 - shared "common code" updates. Approved by: gnn (mentor) Obtained from: Chelsio MFC after: 1 month --- sys/conf/files | 2 + sys/dev/cxgb/common/cxgb_ael1002.c | 959 ++++- sys/dev/cxgb/common/cxgb_aq100x.c | 544 +++ sys/dev/cxgb/common/cxgb_common.h | 42 +- sys/dev/cxgb/common/cxgb_mv88e1xxx.c | 5 +- sys/dev/cxgb/common/cxgb_regs.h | 28 + sys/dev/cxgb/common/cxgb_t3_hw.c | 273 +- sys/dev/cxgb/common/cxgb_tn1010.c | 4 +- sys/dev/cxgb/common/cxgb_vsc8211.c | 54 +- sys/dev/cxgb/common/cxgb_xgmac.c | 165 +- sys/dev/cxgb/cxgb_adapter.h | 4 +- sys/dev/cxgb/cxgb_main.c | 45 +- sys/dev/cxgb/cxgb_osdep.h | 28 +- sys/dev/cxgb/cxgb_t3fw.h | 4855 +++++++++++++------------- sys/modules/cxgb/cxgb/Makefile | 2 +- 15 files changed, 4412 insertions(+), 2598 deletions(-) create mode 100644 sys/dev/cxgb/common/cxgb_aq100x.c diff --git a/sys/conf/files b/sys/conf/files index ef906a72527..e0dff65ca94 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -774,6 +774,8 @@ dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_ael1002.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" +dev/cxgb/common/cxgb_aq100x.c optional cxgb pci \ + compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_xgmac.c optional cxgb pci \ diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c index c92abda4c36..d7bb3869831 100644 --- a/sys/dev/cxgb/common/cxgb_ael1002.c +++ b/sys/dev/cxgb/common/cxgb_ael1002.c @@ -45,16 +45,30 @@ enum { enum { AEL100X_TX_DISABLE = 9, AEL100X_TX_CONFIG1 = 0xc002, + AEL1002_PWR_DOWN_HI = 0xc011, AEL1002_PWR_DOWN_LO = 0xc012, AEL1002_XFI_EQL = 0xc015, AEL1002_LB_EN = 0xc017, + AEL_OPT_SETTINGS = 0xc017, AEL_I2C_CTRL = 0xc30a, AEL_I2C_DATA = 0xc30b, AEL_I2C_STAT = 0xc30c, + AEL2005_GPIO_CTRL = 0xc214, AEL2005_GPIO_STAT = 0xc215, + + AEL2020_GPIO_INTR = 0xc103, + AEL2020_GPIO_CTRL = 0xc108, + AEL2020_GPIO_STAT = 0xc10c, + AEL2020_GPIO_CFG = 0xc110, + + AEL2020_GPIO_SDA = 0, + AEL2020_GPIO_MODDET = 1, + AEL2020_GPIO_0 = 3, + AEL2020_GPIO_1 = 2, + AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, }; enum { edc_none, edc_sr, edc_twinax }; @@ -81,7 +95,7 @@ struct reg_val { unsigned short set_bits; }; -static int get_module_type(struct cphy *phy); +static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms); static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) { @@ -108,6 +122,9 @@ static void ael100x_txon(struct cphy *phy) msleep(30); } +/* + * Read an 8-bit word from a device attached to the PHY's i2c bus. + */ static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) { int i, err; @@ -131,11 +148,14 @@ static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) return data >> 8; } } - CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", - phy->addr, word_addr); + CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %x.%x timed out\n", + phy->addr, dev_addr, word_addr); return -ETIMEDOUT; } +/* + * Write an 8-bit word to a device attached to the PHY's i2c bus. + */ static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data) { int i, err; @@ -158,8 +178,8 @@ static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data) if ((stat & 3) == 1) return 0; } - CH_WARN(phy->adapter, "PHY %u I2C Write of addr %u timed out\n", - phy->addr, word_addr); + CH_WARN(phy->adapter, "PHY %u i2c Write of dev.addr %x.%x = %#x timed out\n", + phy->addr, dev_addr, word_addr, data); return -ETIMEDOUT; } @@ -230,9 +250,9 @@ static int ael1002_get_module_type(struct cphy *phy, int delay_ms) if (delay_ms) msleep(delay_ms); - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0); + v = ael2xxx_get_module_type(phy, delay_ms); - return v == -ETIMEDOUT ? phy_modtype_none : get_module_type(phy); + return (v == -ETIMEDOUT ? phy_modtype_none : v); } static int ael1002_reset(struct cphy *phy, int wait) @@ -312,12 +332,13 @@ static struct cphy_ops ael1002_ops = { }; #endif -int t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { int err; + struct cphy *phy = &pinfo->phy; - cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops, + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1002_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, "10GBASE-R"); ael100x_txon(phy); @@ -366,12 +387,6 @@ static int ael1006_reset(struct cphy *phy, int wait) } -static int ael1006_power_down(struct cphy *phy, int enable) -{ - return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, - BMCR_PDOWN, enable ? BMCR_PDOWN : 0); -} - #ifdef C99_NOT_SUPPORTED static struct cphy_ops ael1006_ops = { ael1006_reset, @@ -385,7 +400,7 @@ static struct cphy_ops ael1006_ops = { NULL, NULL, get_link_status_r, - ael1006_power_down, + ael1002_power_down, }; #else static struct cphy_ops ael1006_ops = { @@ -395,20 +410,97 @@ static struct cphy_ops ael1006_ops = { .intr_clear = t3_phy_lasi_intr_clear, .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_r, - .power_down = ael1006_power_down, + .power_down = ael1002_power_down, }; #endif -int t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops, + struct cphy *phy = &pinfo->phy; + + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1006_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, "10GBASE-SR"); + phy->modtype = phy_modtype_sr; ael100x_txon(phy); return 0; } +/* + * Decode our module type. + */ +static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) +{ + int v; + + if (delay_ms) + msleep(delay_ms); + + v = get_phytrans_type(phy); + if (v == phy_transtype_sfp) { + /* SFP: see SFF-8472 for below */ + + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); + if (v < 0) + return v; + + if (v == 0x1) + return phy_modtype_twinax; + if (v == 0x10) + return phy_modtype_sr; + if (v == 0x20) + return phy_modtype_lr; + if (v == 0x40) + return phy_modtype_lrm; + + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); + if (v < 0) + return v; + if (v != 4) + return phy_modtype_unknown; + + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); + if (v < 0) + return v; + + if (v & 0x80) { + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); + if (v < 0) + return v; + return v > 10 ? phy_modtype_twinax_long : + phy_modtype_twinax; + } + } else if (v == phy_transtype_xfp) { + /* XFP: See INF-8077i for details. */ + + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127); + if (v < 0) + return v; + + if (v != 1) { + /* XXX: set page select to table 1 yourself */ + return phy_modtype_unknown; + } + + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); + if (v < 0) + return v; + v &= 0xf0; + if (v == 0x10) + return phy_modtype_lrm; + if (v == 0x40) + return phy_modtype_lr; + if (v == 0x80) + return phy_modtype_sr; + } + + return phy_modtype_unknown; +} + +/* + * Code to support the Aeluros/NetLogic 2005 10Gb PHY. + */ static int ael2005_setup_sr_edc(struct cphy *phy) { static struct reg_val regs[] = { @@ -1103,72 +1195,21 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) return err; } -static int get_module_type(struct cphy *phy) +static int ael2005_get_module_type(struct cphy *phy, int delay_ms) { int v; + unsigned int stat; - v = get_phytrans_type(phy); - if (v == phy_transtype_sfp) { - /* SFP: see SFF-8472 for below */ + v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); + if (v) + return v; - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); - if (v < 0) - return v; + if (stat & (1 << 8)) /* module absent */ + return phy_modtype_none; - if (v == 0x1) - return phy_modtype_twinax; - if (v == 0x10) - return phy_modtype_sr; - if (v == 0x20) - return phy_modtype_lr; - if (v == 0x40) - return phy_modtype_lrm; - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); - if (v < 0) - return v; - if (v != 4) - return phy_modtype_unknown; - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); - if (v < 0) - return v; - - if (v & 0x80) { - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); - if (v < 0) - return v; - return v > 10 ? phy_modtype_twinax_long : - phy_modtype_twinax; - } - } else if (v == phy_transtype_xfp) { - /* XFP: See INF-8077i for details. */ - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127); - if (v < 0) - return v; - - if (v != 1) { - /* XXX: set page select to table 1 yourself */ - return phy_modtype_unknown; - } - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); - if (v < 0) - return v; - v &= 0xf0; - if (v == 0x10) - return phy_modtype_lrm; - if (v == 0x40) - return phy_modtype_lr; - if (v == 0x80) - return phy_modtype_sr; - } - - return phy_modtype_unknown; + return ael2xxx_get_module_type(phy, delay_ms); } - static int ael2005_intr_enable(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); @@ -1187,24 +1228,6 @@ static int ael2005_intr_clear(struct cphy *phy) return err ? err : t3_phy_lasi_intr_clear(phy); } -static int ael2005_get_module_type(struct cphy *phy, int delay_ms) -{ - int v; - unsigned int stat; - - v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); - if (v) - return v; - - if (stat & (1 << 8)) /* module absent */ - return phy_modtype_none; - - if (delay_ms) - msleep(delay_ms); - - return get_module_type(phy); -} - static int ael2005_reset(struct cphy *phy, int wait) { static struct reg_val regs0[] = { @@ -1223,7 +1246,8 @@ static int ael2005_reset(struct cphy *phy, int wait) { 0, 0, 0, 0 } }; - int err, lasi_ctrl; + int err; + unsigned int lasi_ctrl; err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); if (err) @@ -1311,8 +1335,8 @@ static int ael2005_intr_handler(struct cphy *phy) return ret; } -#ifdef C99_NOT_SUPPORTED static struct cphy_ops ael2005_ops = { +#ifdef C99_NOT_SUPPORTED ael2005_reset, ael2005_intr_enable, ael2005_intr_disable, @@ -1325,9 +1349,7 @@ static struct cphy_ops ael2005_ops = { NULL, get_link_status_r, ael1002_power_down, -}; #else -static struct cphy_ops ael2005_ops = { .reset = ael2005_reset, .intr_enable = ael2005_intr_enable, .intr_disable = ael2005_intr_disable, @@ -1335,14 +1357,16 @@ static struct cphy_ops ael2005_ops = { .intr_handler = ael2005_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, -}; #endif +}; -int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { int err; - cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops, + struct cphy *phy = &pinfo->phy; + + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | SUPPORTED_IRQ, "10GBASE-R"); msleep(125); @@ -1356,6 +1380,713 @@ int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 1 << 5); } +/* + * Setup EDC and other parameters for operation with an optical module. + */ +static int ael2020_setup_sr_edc(struct cphy *phy) +{ + static struct reg_val regs[] = { + { MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a }, + + { MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 }, + { MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 }, + { MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 }, + + /* end */ + { 0, 0, 0, 0 } + }; + int err; + + err = set_phy_regs(phy, regs); + msleep(50); + if (err) + return err; + + phy->priv = edc_sr; + return 0; +} + +/* + * Setup EDC and other parameters for operation with an TWINAX module. + */ +static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) +{ + static struct reg_val uCclock40MHz[] = { + { MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 }, + { MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 }, + { 0, 0, 0, 0 } + }; + + static struct reg_val uCclockActivate[] = { + { MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 }, + { 0, 0, 0, 0 } + }; + + static struct reg_val uCactivate[] = { + { MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 }, + { MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 }, + { 0, 0, 0, 0 } + }; + + static u16 twinax_edc[] = { + 0xd800, 0x4009, + 0xd801, 0x2fff, + 0xd802, 0x300f, + 0xd803, 0x40aa, + 0xd804, 0x401c, + 0xd805, 0x401e, + 0xd806, 0x2ff4, + 0xd807, 0x3dc4, + 0xd808, 0x2035, + 0xd809, 0x3035, + 0xd80a, 0x6524, + 0xd80b, 0x2cb2, + 0xd80c, 0x3012, + 0xd80d, 0x1002, + 0xd80e, 0x26e2, + 0xd80f, 0x3022, + 0xd810, 0x1002, + 0xd811, 0x27d2, + 0xd812, 0x3022, + 0xd813, 0x1002, + 0xd814, 0x2822, + 0xd815, 0x3012, + 0xd816, 0x1002, + 0xd817, 0x2492, + 0xd818, 0x3022, + 0xd819, 0x1002, + 0xd81a, 0x2772, + 0xd81b, 0x3012, + 0xd81c, 0x1002, + 0xd81d, 0x23d2, + 0xd81e, 0x3022, + 0xd81f, 0x1002, + 0xd820, 0x22cd, + 0xd821, 0x301d, + 0xd822, 0x27f2, + 0xd823, 0x3022, + 0xd824, 0x1002, + 0xd825, 0x5553, + 0xd826, 0x0307, + 0xd827, 0x2522, + 0xd828, 0x3022, + 0xd829, 0x1002, + 0xd82a, 0x2142, + 0xd82b, 0x3012, + 0xd82c, 0x1002, + 0xd82d, 0x4016, + 0xd82e, 0x5e63, + 0xd82f, 0x0344, + 0xd830, 0x2142, + 0xd831, 0x3012, + 0xd832, 0x1002, + 0xd833, 0x400e, + 0xd834, 0x2522, + 0xd835, 0x3022, + 0xd836, 0x1002, + 0xd837, 0x2b52, + 0xd838, 0x3012, + 0xd839, 0x1002, + 0xd83a, 0x2742, + 0xd83b, 0x3022, + 0xd83c, 0x1002, + 0xd83d, 0x25e2, + 0xd83e, 0x3022, + 0xd83f, 0x1002, + 0xd840, 0x2fa4, + 0xd841, 0x3dc4, + 0xd842, 0x6624, + 0xd843, 0x414b, + 0xd844, 0x56b3, + 0xd845, 0x03c6, + 0xd846, 0x866b, + 0xd847, 0x400c, + 0xd848, 0x2712, + 0xd849, 0x3012, + 0xd84a, 0x1002, + 0xd84b, 0x2c4b, + 0xd84c, 0x309b, + 0xd84d, 0x56b3, + 0xd84e, 0x03c3, + 0xd84f, 0x866b, + 0xd850, 0x400c, + 0xd851, 0x2272, + 0xd852, 0x3022, + 0xd853, 0x1002, + 0xd854, 0x2742, + 0xd855, 0x3022, + 0xd856, 0x1002, + 0xd857, 0x25e2, + 0xd858, 0x3022, + 0xd859, 0x1002, + 0xd85a, 0x2fb4, + 0xd85b, 0x3dc4, + 0xd85c, 0x6624, + 0xd85d, 0x56b3, + 0xd85e, 0x03c3, + 0xd85f, 0x866b, + 0xd860, 0x401c, + 0xd861, 0x2c45, + 0xd862, 0x3095, + 0xd863, 0x5b53, + 0xd864, 0x2372, + 0xd865, 0x3012, + 0xd866, 0x13c2, + 0xd867, 0x5cc3, + 0xd868, 0x2712, + 0xd869, 0x3012, + 0xd86a, 0x1312, + 0xd86b, 0x2b52, + 0xd86c, 0x3012, + 0xd86d, 0x1002, + 0xd86e, 0x2742, + 0xd86f, 0x3022, + 0xd870, 0x1002, + 0xd871, 0x2582, + 0xd872, 0x3022, + 0xd873, 0x1002, + 0xd874, 0x2142, + 0xd875, 0x3012, + 0xd876, 0x1002, + 0xd877, 0x628f, + 0xd878, 0x2985, + 0xd879, 0x33a5, + 0xd87a, 0x25e2, + 0xd87b, 0x3022, + 0xd87c, 0x1002, + 0xd87d, 0x5653, + 0xd87e, 0x03d2, + 0xd87f, 0x401e, + 0xd880, 0x6f72, + 0xd881, 0x1002, + 0xd882, 0x628f, + 0xd883, 0x2304, + 0xd884, 0x3c84, + 0xd885, 0x6436, + 0xd886, 0xdff4, + 0xd887, 0x6436, + 0xd888, 0x2ff5, + 0xd889, 0x3005, + 0xd88a, 0x8656, + 0xd88b, 0xdfba, + 0xd88c, 0x56a3, + 0xd88d, 0xd05a, + 0xd88e, 0x2972, + 0xd88f, 0x3012, + 0xd890, 0x1392, + 0xd891, 0xd05a, + 0xd892, 0x56a3, + 0xd893, 0xdfba, + 0xd894, 0x0383, + 0xd895, 0x6f72, + 0xd896, 0x1002, + 0xd897, 0x2b45, + 0xd898, 0x3005, + 0xd899, 0x4178, + 0xd89a, 0x5653, + 0xd89b, 0x0384, + 0xd89c, 0x2a62, + 0xd89d, 0x3012, + 0xd89e, 0x1002, + 0xd89f, 0x2f05, + 0xd8a0, 0x3005, + 0xd8a1, 0x41c8, + 0xd8a2, 0x5653, + 0xd8a3, 0x0382, + 0xd8a4, 0x0002, + 0xd8a5, 0x4218, + 0xd8a6, 0x2474, + 0xd8a7, 0x3c84, + 0xd8a8, 0x6437, + 0xd8a9, 0xdff4, + 0xd8aa, 0x6437, + 0xd8ab, 0x2ff5, + 0xd8ac, 0x3c05, + 0xd8ad, 0x8757, + 0xd8ae, 0xb888, + 0xd8af, 0x9787, + 0xd8b0, 0xdff4, + 0xd8b1, 0x6724, + 0xd8b2, 0x866a, + 0xd8b3, 0x6f72, + 0xd8b4, 0x1002, + 0xd8b5, 0x2641, + 0xd8b6, 0x3021, + 0xd8b7, 0x1001, + 0xd8b8, 0xc620, + 0xd8b9, 0x0000, + 0xd8ba, 0xc621, + 0xd8bb, 0x0000, + 0xd8bc, 0xc622, + 0xd8bd, 0x00ce, + 0xd8be, 0xc623, + 0xd8bf, 0x007f, + 0xd8c0, 0xc624, + 0xd8c1, 0x0032, + 0xd8c2, 0xc625, + 0xd8c3, 0x0000, + 0xd8c4, 0xc627, + 0xd8c5, 0x0000, + 0xd8c6, 0xc628, + 0xd8c7, 0x0000, + 0xd8c8, 0xc62c, + 0xd8c9, 0x0000, + 0xd8ca, 0x0000, + 0xd8cb, 0x2641, + 0xd8cc, 0x3021, + 0xd8cd, 0x1001, + 0xd8ce, 0xc502, + 0xd8cf, 0x53ac, + 0xd8d0, 0xc503, + 0xd8d1, 0x2cd3, + 0xd8d2, 0xc600, + 0xd8d3, 0x2a6e, + 0xd8d4, 0xc601, + 0xd8d5, 0x2a2c, + 0xd8d6, 0xc605, + 0xd8d7, 0x5557, + 0xd8d8, 0xc60c, + 0xd8d9, 0x5400, + 0xd8da, 0xc710, + 0xd8db, 0x0700, + 0xd8dc, 0xc711, + 0xd8dd, 0x0f06, + 0xd8de, 0xc718, + 0xd8df, 0x0700, + 0xd8e0, 0xc719, + 0xd8e1, 0x0f06, + 0xd8e2, 0xc720, + 0xd8e3, 0x4700, + 0xd8e4, 0xc721, + 0xd8e5, 0x0f06, + 0xd8e6, 0xc728, + 0xd8e7, 0x0700, + 0xd8e8, 0xc729, + 0xd8e9, 0x1207, + 0xd8ea, 0xc801, + 0xd8eb, 0x7f50, + 0xd8ec, 0xc802, + 0xd8ed, 0x7760, + 0xd8ee, 0xc803, + 0xd8ef, 0x7fce, + 0xd8f0, 0xc804, + 0xd8f1, 0x520e, + 0xd8f2, 0xc805, + 0xd8f3, 0x5c11, + 0xd8f4, 0xc806, + 0xd8f5, 0x3c51, + 0xd8f6, 0xc807, + 0xd8f7, 0x4061, + 0xd8f8, 0xc808, + 0xd8f9, 0x49c1, + 0xd8fa, 0xc809, + 0xd8fb, 0x3840, + 0xd8fc, 0xc80a, + 0xd8fd, 0x0000, + 0xd8fe, 0xc821, + 0xd8ff, 0x0002, + 0xd900, 0xc822, + 0xd901, 0x0046, + 0xd902, 0xc844, + 0xd903, 0x182f, + 0xd904, 0xc013, + 0xd905, 0xf341, + 0xd906, 0xc084, + 0xd907, 0x0030, + 0xd908, 0xc904, + 0xd909, 0x1401, + 0xd90a, 0xcb0c, + 0xd90b, 0x0004, + 0xd90c, 0xcb0e, + 0xd90d, 0xa00a, + 0xd90e, 0xcb0f, + 0xd90f, 0xc0c0, + 0xd910, 0xcb10, + 0xd911, 0xc0c0, + 0xd912, 0xcb11, + 0xd913, 0x00a0, + 0xd914, 0xcb12, + 0xd915, 0x0007, + 0xd916, 0xc241, + 0xd917, 0xa000, + 0xd918, 0xc243, + 0xd919, 0x7fe0, + 0xd91a, 0xc604, + 0xd91b, 0x000e, + 0xd91c, 0xc609, + 0xd91d, 0x00f5, + 0xd91e, 0xc611, + 0xd91f, 0x000e, + 0xd920, 0xc660, + 0xd921, 0x9600, + 0xd922, 0xc687, + 0xd923, 0x0004, + 0xd924, 0xc60a, + 0xd925, 0x04f5, + 0xd926, 0x0000, + 0xd927, 0x2641, + 0xd928, 0x3021, + 0xd929, 0x1001, + 0xd92a, 0xc620, + 0xd92b, 0x14e5, + 0xd92c, 0xc621, + 0xd92d, 0xc53d, + 0xd92e, 0xc622, + 0xd92f, 0x3cbe, + 0xd930, 0xc623, + 0xd931, 0x4452, + 0xd932, 0xc624, + 0xd933, 0xc5c5, + 0xd934, 0xc625, + 0xd935, 0xe01e, + 0xd936, 0xc627, + 0xd937, 0x0000, + 0xd938, 0xc628, + 0xd939, 0x0000, + 0xd93a, 0xc62c, + 0xd93b, 0x0000, + 0xd93c, 0x0000, + 0xd93d, 0x2b84, + 0xd93e, 0x3c74, + 0xd93f, 0x6435, + 0xd940, 0xdff4, + 0xd941, 0x6435, + 0xd942, 0x2806, + 0xd943, 0x3006, + 0xd944, 0x8565, + 0xd945, 0x2b24, + 0xd946, 0x3c24, + 0xd947, 0x6436, + 0xd948, 0x1002, + 0xd949, 0x2b24, + 0xd94a, 0x3c24, + 0xd94b, 0x6436, + 0xd94c, 0x4045, + 0xd94d, 0x8656, + 0xd94e, 0x5663, + 0xd94f, 0x0302, + 0xd950, 0x401e, + 0xd951, 0x1002, + 0xd952, 0x2807, + 0xd953, 0x31a7, + 0xd954, 0x20c4, + 0xd955, 0x3c24, + 0xd956, 0x6724, + 0xd957, 0x1002, + 0xd958, 0x2807, + 0xd959, 0x3187, + 0xd95a, 0x20c4, + 0xd95b, 0x3c24, + 0xd95c, 0x6724, + 0xd95d, 0x1002, + 0xd95e, 0x24f4, + 0xd95f, 0x3c64, + 0xd960, 0x6436, + 0xd961, 0xdff4, + 0xd962, 0x6436, + 0xd963, 0x1002, + 0xd964, 0x2006, + 0xd965, 0x3d76, + 0xd966, 0xc161, + 0xd967, 0x6134, + 0xd968, 0x6135, + 0xd969, 0x5443, + 0xd96a, 0x0303, + 0xd96b, 0x6524, + 0xd96c, 0x00fb, + 0xd96d, 0x1002, + 0xd96e, 0x20d4, + 0xd96f, 0x3c24, + 0xd970, 0x2025, + 0xd971, 0x3005, + 0xd972, 0x6524, + 0xd973, 0x1002, + 0xd974, 0xd019, + 0xd975, 0x2104, + 0xd976, 0x3c24, + 0xd977, 0x2105, + 0xd978, 0x3805, + 0xd979, 0x6524, + 0xd97a, 0xdff4, + 0xd97b, 0x4005, + 0xd97c, 0x6524, + 0xd97d, 0x2e8d, + 0xd97e, 0x303d, + 0xd97f, 0x2408, + 0xd980, 0x35d8, + 0xd981, 0x5dd3, + 0xd982, 0x0307, + 0xd983, 0x8887, + 0xd984, 0x63a7, + 0xd985, 0x8887, + 0xd986, 0x63a7, + 0xd987, 0xdffd, + 0xd988, 0x00f9, + 0xd989, 0x1002, + 0xd98a, 0x0000, + }; + int i, err; + + /* set uC clock and activate it */ + err = set_phy_regs(phy, uCclock40MHz); + msleep(500); + if (err) + return err; + err = set_phy_regs(phy, uCclockActivate); + msleep(500); + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) + err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], + twinax_edc[i + 1]); + /* activate uC */ + err = set_phy_regs(phy, uCactivate); + if (!err) + phy->priv = edc_twinax; + return err; +} + +/* + * Return Module Type. + */ +static int ael2020_get_module_type(struct cphy *phy, int delay_ms) +{ + int v; + unsigned int stat; + + v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat); + if (v) + return v; + + if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { + /* module absent */ + return phy_modtype_none; + } + + return ael2xxx_get_module_type(phy, delay_ms); +} + +/* + * Enable PHY interrupts. We enable "Module Detection" interrupts (on any + * state transition) and then generic Link Alarm Status Interrupt (LASI). + */ +static int ael2020_intr_enable(struct cphy *phy) +{ + struct reg_val regs[] = { + { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, + 0xffff, 0x4 }, + { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, + 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, + + { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, + 0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) }, + + /* end */ + { 0, 0, 0, 0 } + }; + int err; + + err = set_phy_regs(phy, regs); + if (err) + return err; + + phy->caps |= POLL_LINK_1ST_TIME; + + /* enable standard Link Alarm Status Interrupts */ + err = t3_phy_lasi_intr_enable(phy); + if (err) + return err; + + return 0; +} + +/* + * Disable PHY interrupts. The mirror of the above ... + */ +static int ael2020_intr_disable(struct cphy *phy) +{ + struct reg_val regs[] = { + { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, + 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) }, + + { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, + 0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) }, + + /* end */ + { 0, 0, 0, 0 } + }; + int err; + + err = set_phy_regs(phy, regs); + if (err) + return err; + + /* disable standard Link Alarm Status Interrupts */ + return t3_phy_lasi_intr_disable(phy); +} + +/* + * Clear PHY interrupt state. + */ +static int ael2020_intr_clear(struct cphy *phy) +{ + unsigned int stat; + int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); + return err ? err : t3_phy_lasi_intr_clear(phy); +} + +/* + * Common register settings for the AEL2020 when it comes out of reset. + */ +static struct reg_val ael2020_reset_regs[] = { + { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 }, + + { MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 }, + + { MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 }, + { MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 }, + { MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 }, + + /* end */ + { 0, 0, 0, 0 } +}; + +/* + * Reset the PHY and put it into a canonical operating state. + */ +static int ael2020_reset(struct cphy *phy, int wait) +{ + int err; + unsigned int lasi_ctrl; + + /* grab current interrupt state */ + err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); + if (err) + return err; + + err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125); + if (err) + return err; + msleep(100); + + /* basic initialization for all module types */ + phy->priv = edc_none; + err = set_phy_regs(phy, ael2020_reset_regs); + if (err) + return err; + + /* determine module type and perform appropriate initialization */ + err = ael2020_get_module_type(phy, 0); + if (err < 0) + return err; + phy->modtype = (u8)err; + if (err == phy_modtype_none || err == phy_modtype_unknown) + err = 0; + else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) + err = ael2020_setup_twinax_edc(phy, err); + else + err = ael2020_setup_sr_edc(phy); + if (err) + return err; + + /* reset wipes out interrupts, reenable them if they were on */ + if (lasi_ctrl & 1) + err = ael2020_intr_enable(phy); + return err; +} + +/* + * Handle a PHY interrupt. + */ +static int ael2020_intr_handler(struct cphy *phy) +{ + unsigned int stat; + int ret, edc_needed, cause = 0; + + ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); + if (ret) + return ret; + + if (stat & (0x1 << AEL2020_GPIO_MODDET)) { + /* modules have max 300 ms init time after hot plug */ + ret = ael2020_get_module_type(phy, 300); + if (ret < 0) + return ret; + + phy->modtype = (u8)ret; + if (ret == phy_modtype_none) + edc_needed = phy->priv; /* on unplug retain EDC */ + else if (ret == phy_modtype_twinax || + ret == phy_modtype_twinax_long) + edc_needed = edc_twinax; + else + edc_needed = edc_sr; + + if (edc_needed != phy->priv) { + ret = ael2020_reset(phy, 0); + return ret ? ret : cphy_cause_module_change; + } + cause = cphy_cause_module_change; + } + + ret = t3_phy_lasi_intr_handler(phy); + if (ret < 0) + return ret; + + ret |= cause; + if (!ret) + ret |= cphy_cause_link_change; + return ret; +} + +static struct cphy_ops ael2020_ops = { +#ifdef C99_NOT_SUPPORTED + ael2020_reset, + ael2020_intr_enable, + ael2020_intr_disable, + ael2020_intr_clear, + ael2020_intr_handler, + NULL, + NULL, + NULL, + NULL, + NULL, + get_link_status_r, + ael1002_power_down, +#else + .reset = ael2020_reset, + .intr_enable = ael2020_intr_enable, + .intr_disable = ael2020_intr_disable, + .intr_clear = ael2020_intr_clear, + .intr_handler = ael2020_intr_handler, + .get_link_status = get_link_status_r, + .power_down = ael1002_power_down, +#endif +}; + +int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr, + const struct mdio_ops *mdio_ops) +{ + int err; + struct cphy *phy = &pinfo->phy; + + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops, + SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | + SUPPORTED_IRQ, "10GBASE-R"); + msleep(125); + + err = set_phy_regs(phy, ael2020_reset_regs); + if (err) + return err; + err = ael2020_get_module_type(phy, 0); + if (err >= 0) + phy->modtype = err; + + ael_laser_down(phy, 0); + return 0; +} + /* * Get link status for a 10GBASE-X device. */ @@ -1394,7 +2125,7 @@ static struct cphy_ops qt2045_ops = { NULL, NULL, get_link_status_x, - ael1006_power_down, + ael1002_power_down, }; #else static struct cphy_ops qt2045_ops = { @@ -1404,16 +2135,17 @@ static struct cphy_ops qt2045_ops = { .intr_clear = t3_phy_lasi_intr_clear, .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_x, - .power_down = ael1006_power_down, + .power_down = ael1002_power_down, }; #endif -int t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int stat; + struct cphy *phy = &pinfo->phy; - cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops, + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); @@ -1437,14 +2169,15 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, { if (link_ok) { unsigned int status; + adapter_t *adapter = phy->adapter; - status = t3_read_reg(phy->adapter, + status = t3_read_reg(adapter, XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | - t3_read_reg(phy->adapter, + t3_read_reg(adapter, XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | - t3_read_reg(phy->adapter, + t3_read_reg(adapter, XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | - t3_read_reg(phy->adapter, + t3_read_reg(adapter, XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); *link_ok = !(status & F_LOWSIG0); } @@ -1487,10 +2220,10 @@ static struct cphy_ops xaui_direct_ops = { }; #endif -int t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, + cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; diff --git a/sys/dev/cxgb/common/cxgb_aq100x.c b/sys/dev/cxgb/common/cxgb_aq100x.c new file mode 100644 index 00000000000..abb93c4055f --- /dev/null +++ b/sys/dev/cxgb/common/cxgb_aq100x.c @@ -0,0 +1,544 @@ +/************************************************************************** + +Copyright (c) 2009 Chelsio Inc. +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. Neither the name of the Chelsio Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +***************************************************************************/ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#undef msleep +#define msleep t3_os_sleep + +enum { + /* MDIO_DEV_PMA_PMD registers */ + AQ_LINK_STAT = 0xe800, + + /* MDIO_DEV_XGXS registers */ + AQ_XAUI_RX_CFG = 0xc400, + AQ_XAUI_KX_CFG = 0xc440, + AQ_XAUI_TX_CFG = 0xe400, + + /* MDIO_DEV_ANEG registers */ + AQ_100M_CTRL = 0x0010, + AQ_10G_CTRL = 0x0020, + AQ_1G_CTRL = 0xc400, + AQ_ANEG_STAT = 0xc800, + + /* MDIO_DEV_VEND1 registers */ + AQ_FW_VERSION = 0x0020, + AQ_THERMAL_THR = 0xc421, + AQ_THERMAL1 = 0xc820, + AQ_THERMAL2 = 0xc821, + AQ_IFLAG_GLOBAL = 0xfc00, + AQ_IMASK_GLOBAL = 0xff00, +}; + +#define AQBIT(x) (1 << (0x##x)) +#define ADV_1G_FULL AQBIT(f) +#define ADV_1G_HALF AQBIT(e) +#define ADV_10G_FULL AQBIT(c) + +#define AQ_WRITE_REGS(phy, regs) do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(regs); i++) { \ + (void) mdio_write(phy, regs[i].mmd, regs[i].reg, regs[i].val); \ + } \ +} while (0) +#define AQ_READ_REGS(phy, regs) do { \ + unsigned i, v; \ + for (i = 0; i < ARRAY_SIZE(regs); i++) { \ + (void) mdio_read(phy, regs[i].mmd, regs[i].reg, &v); \ + } \ +} while (0) + +/* + * Return value is temperature in celcius, 0xffff for error or don't know. + */ +static int +aq100x_temperature(struct cphy *phy) +{ + unsigned int v; + + if (mdio_read(phy, MDIO_DEV_VEND1, AQ_THERMAL2, &v) || + v == 0xffff || (v & 1) != 1) + return (0xffff); + + if (mdio_read(phy, MDIO_DEV_VEND1, AQ_THERMAL1, &v)) + return (0xffff); + + return ((int)((signed char)(v >> 8))); +} + +static int +aq100x_set_defaults(struct cphy *phy) +{ + return mdio_write(phy, MDIO_DEV_VEND1, AQ_THERMAL_THR, 0x6c00); +} + +static int +aq100x_reset(struct cphy *phy, int wait) +{ + int err; + err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); + if (!err) + err = aq100x_set_defaults(phy); + return (err); +} + +static int +aq100x_intr_enable(struct cphy *phy) +{ + struct { + int mmd; + int reg; + int val; + } imasks[] = { + {MDIO_DEV_VEND1, 0xd400, AQBIT(e)}, + {MDIO_DEV_VEND1, 0xff01, AQBIT(2)}, + {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL, AQBIT(0)} + }; + + AQ_WRITE_REGS(phy, imasks); + + return (0); +} + +static int +aq100x_intr_disable(struct cphy *phy) +{ + struct { + int mmd; + int reg; + int val; + } imasks[] = { + {MDIO_DEV_VEND1, 0xd400, 0}, + {MDIO_DEV_VEND1, 0xff01, 0}, + {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL, 0} + }; + + AQ_WRITE_REGS(phy, imasks); + + return (0); +} + +static int +aq100x_intr_clear(struct cphy *phy) +{ + struct { + int mmd; + int reg; + } iclr[] = { + {MDIO_DEV_VEND1, 0xcc00}, + {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL} /* needed? */ + }; + + AQ_READ_REGS(phy, iclr); + + return (0); +} + +static int +aq100x_vendor_intr(struct cphy *phy, int *rc) +{ + int err; + unsigned int cause, v; + + err = mdio_read(phy, MDIO_DEV_VEND1, 0xfc01, &cause); + if (err) + return (err); + + if (cause & AQBIT(2)) { + err = mdio_read(phy, MDIO_DEV_VEND1, 0xcc00, &v); + if (err) + return (err); + + if (v & AQBIT(e)) { + CH_WARN(phy->adapter, "PHY%d: temperature is now %dC\n", + phy->addr, aq100x_temperature(phy)); + + t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, + phy->addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL, 0); + + *rc |= cphy_cause_alarm; + } + + cause &= ~4; + } + + if (cause) + CH_WARN(phy->adapter, "PHY%d: unhandled vendor interrupt" + " (0x%x)\n", phy->addr, cause); + + return (0); + +} + +static int +aq100x_intr_handler(struct cphy *phy) +{ + int err, rc = 0; + unsigned int cause; + + err = mdio_read(phy, MDIO_DEV_VEND1, AQ_IFLAG_GLOBAL, &cause); + if (err) + return (err); + + if (cause & AQBIT(0)) { + err = aq100x_vendor_intr(phy, &rc); + if (err) + return (err); + cause &= ~AQBIT(0); + } + + if (cause) + CH_WARN(phy->adapter, "PHY%d: unhandled interrupt (0x%x)\n", + phy->addr, cause); + + return (rc); +} + +static int +aq100x_power_down(struct cphy *phy, int off) +{ + int err, wait = 500; + unsigned int v; + + err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, + off ? BMCR_PDOWN : 0); + if (err || off) + return (v); + + msleep(300); + do { + err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); + if (err) + return (err); + v &= BMCR_RESET; + if (v) + msleep(10); + } while (v && --wait); + if (v) { + CH_WARN(phy->adapter, "PHY%d: power-up timed out (0x%x).\n", + phy->addr, v); + return (ETIMEDOUT); + } + + return (0); +} + +static int +aq100x_autoneg_enable(struct cphy *phy) +{ + int err; + + err = aq100x_power_down(phy, 0); + if (!err) + err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, MII_BMCR, + BMCR_RESET, BMCR_ANENABLE | BMCR_ANRESTART); + + return (err); +} + +static int +aq100x_autoneg_restart(struct cphy *phy) +{ + return aq100x_autoneg_enable(phy); +} + +static int +aq100x_advertise(struct cphy *phy, unsigned int advertise_map) +{ + unsigned int adv; + int err; + + /* 10G advertisement */ + adv = 0; + if (advertise_map & ADVERTISED_10000baseT_Full) + adv |= ADV_10G_FULL; + err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_10G_CTRL, + ADV_10G_FULL, adv); + if (err) + return (err); + + /* 1G advertisement */ + adv = 0; + if (advertise_map & ADVERTISED_1000baseT_Full) + adv |= ADV_1G_FULL; + if (advertise_map & ADVERTISED_1000baseT_Half) + adv |= ADV_1G_HALF; + err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_1G_CTRL, + ADV_1G_FULL | ADV_1G_HALF, adv); + if (err) + return (err); + + /* 100M, pause advertisement */ + adv = 0; + if (advertise_map & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise_map & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + if (advertise_map & ADVERTISED_Pause) + adv |= ADVERTISE_PAUSE_CAP; + if (advertise_map & ADVERTISED_Asym_Pause) + adv |= ADVERTISE_PAUSE_ASYM; + err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_100M_CTRL, 0xfe0, adv); + + return (err); +} + +static int +aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable) +{ + return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, + BMCR_LOOPBACK, enable ? BMCR_LOOPBACK : 0); +} + +static int +aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex) +{ + int err, set; + + if (speed == SPEED_100) + set = BMCR_SPEED100; + else if (speed == SPEED_1000) + set = BMCR_SPEED1000; + else if (speed == SPEED_10000) + set = BMCR_SPEED1000 | BMCR_SPEED100; + else + return (EINVAL); + + if (duplex != DUPLEX_FULL) + return (EINVAL); + + err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, MII_BMCR, + BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART, 0); + if (err) + return (err); + + err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, + BMCR_SPEED1000 | BMCR_SPEED100, set); + if (err) + return (err); + + return (0); +} + +static int +aq100x_get_link_status(struct cphy *phy, int *link_ok, int *speed, int *duplex, + int *fc) +{ + int err; + unsigned int v, link = 0; + + err = mdio_read(phy, MDIO_DEV_PMA_PMD, AQ_LINK_STAT, &v); + if (err) + return (err); + if (v == 0xffff || !(v & 1)) + goto done; + + err = mdio_read(phy, MDIO_DEV_ANEG, MII_BMCR, &v); + if (err) + return (err); + if (v & 0x8000) + goto done; + if (v & BMCR_ANENABLE) { + + err = mdio_read(phy, MDIO_DEV_ANEG, 1, &v); + if (err) + return (err); + if ((v & 0x20) == 0) + goto done; + + err = mdio_read(phy, MDIO_DEV_ANEG, AQ_ANEG_STAT, &v); + if (err) + return (err); + + if (speed) { + switch (v & 0x6) { + case 0x6: *speed = SPEED_10000; + break; + case 0x4: *speed = SPEED_1000; + break; + case 0x2: *speed = SPEED_100; + break; + case 0x0: *speed = SPEED_10; + break; + } + } + + if (duplex) + *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF; + + if (fc) { + unsigned int lpa, adv; + err = mdio_read(phy, MDIO_DEV_ANEG, 0x13, &lpa); + if (!err) + err = mdio_read(phy, MDIO_DEV_ANEG, + AQ_100M_CTRL, &adv); + if (err) + return err; + + if (lpa & adv & ADVERTISE_PAUSE_CAP) + *fc = PAUSE_RX | PAUSE_TX; + else if (lpa & ADVERTISE_PAUSE_CAP && + lpa & ADVERTISE_PAUSE_ASYM && + adv & ADVERTISE_PAUSE_ASYM) + *fc = PAUSE_TX; + else if (lpa & ADVERTISE_PAUSE_ASYM && + adv & ADVERTISE_PAUSE_CAP) + *fc = PAUSE_RX; + else + *fc = 0; + } + + } else { + err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); + if (err) + return (err); + + v &= BMCR_SPEED1000 | BMCR_SPEED100; + if (speed) { + if (v == (BMCR_SPEED1000 | BMCR_SPEED100)) + *speed = SPEED_10000; + else if (v == BMCR_SPEED1000) + *speed = SPEED_1000; + else if (v == BMCR_SPEED100) + *speed = SPEED_100; + else + *speed = SPEED_10; + } + + if (duplex) + *duplex = DUPLEX_FULL; + } + + link = 1; +done: + if (link_ok) + *link_ok = link; + return (0); +} + +static struct cphy_ops aq100x_ops = { + .reset = aq100x_reset, + .intr_enable = aq100x_intr_enable, + .intr_disable = aq100x_intr_disable, + .intr_clear = aq100x_intr_clear, + .intr_handler = aq100x_intr_handler, + .autoneg_enable = aq100x_autoneg_enable, + .autoneg_restart = aq100x_autoneg_restart, + .advertise = aq100x_advertise, + .set_loopback = aq100x_set_loopback, + .set_speed_duplex = aq100x_set_speed_duplex, + .get_link_status = aq100x_get_link_status, + .power_down = aq100x_power_down, +}; + +int +t3_aq100x_phy_prep(pinfo_t *pinfo, int phy_addr, + const struct mdio_ops *mdio_ops) +{ + struct cphy *phy = &pinfo->phy; + unsigned int v, v2, gpio, wait; + int err; + adapter_t *adapter = pinfo->adapter; + + cphy_init(&pinfo->phy, adapter, pinfo, phy_addr, &aq100x_ops, mdio_ops, + SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | + SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI | + SUPPORTED_MISC_IRQ, "1000/10GBASE-T"); + + /* + * Hard reset the PHY. + */ + gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; + t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); + msleep(1); + t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); + + /* + * Give it enough time to load the firmware and get ready for mdio. + */ + msleep(1000); + wait = 500; /* in 10ms increments */ + do { + err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); + if (err || v == 0xffff) { + + /* Allow prep_adapter to succeed when ffff is read */ + + CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", + phy_addr, err, v); + goto done; + } + + v &= BMCR_RESET; + if (v) + msleep(10); + } while (v && --wait); + if (v) { + CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", + phy_addr, v); + + goto done; /* let prep_adapter succeed */ + } + + /* Firmware version check. */ + (void) mdio_read(phy, MDIO_DEV_VEND1, AQ_FW_VERSION, &v); + if (v < 0x115) + CH_WARN(adapter, "PHY%d: unknown firmware %d.%d\n", phy_addr, + v >> 8, v & 0xff); + +#if 0 + /* The PHY should start in really-low-power mode. */ + (void) mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); + if ((v & BMCR_PDOWN) == 0) + CH_WARN(adapter, "PHY%d does not start in low power mode.\n", + phy_addr); +#endif + + /* + * Verify XAUI and 1000-X settings, but let prep succeed no matter what. + */ + v = v2 = 0; + (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_RX_CFG, &v); + (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_TX_CFG, &v2); + if (v != 0x1b || v2 != 0x1b) + CH_WARN(adapter, "PHY%d: incorrect XAUI settings " + "(0x%x, 0x%x).\n", phy_addr, v, v2); + v = 0; + (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_KX_CFG, &v); + if ((v & 0xf) != 0xf) + CH_WARN(adapter, "PHY%d: incorrect 1000-X settings " + "(0x%x).\n", phy_addr, v); + + (void) aq100x_set_defaults(phy); +done: + return (err); +} diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h index 09e78407307..1aa3642ea9d 100644 --- a/sys/dev/cxgb/common/cxgb_common.h +++ b/sys/dev/cxgb/common/cxgb_common.h @@ -56,7 +56,11 @@ enum { }; enum { - SUPPORTED_IRQ = 1 << 24 + SUPPORTED_LINK_IRQ = 1 << 24, + /* skip 25 */ + SUPPORTED_MISC_IRQ = 1 << 26, + SUPPORTED_IRQ = (SUPPORTED_LINK_IRQ | SUPPORTED_MISC_IRQ), + POLL_LINK_1ST_TIME = 1 << 27 }; enum { /* adapter interrupt-maintained statistics */ @@ -93,7 +97,7 @@ enum { enum { FW_VERSION_MAJOR = 7, - FW_VERSION_MINOR = 1, + FW_VERSION_MINOR = 7, FW_VERSION_MICRO = 0 }; @@ -484,6 +488,7 @@ struct cmac { u64 rx_mcnt; unsigned int toggle_cnt; unsigned int txen; + unsigned int was_reset; u64 rx_pause; struct mac_stats stats; }; @@ -526,6 +531,7 @@ enum { cphy_cause_link_change = 1, cphy_cause_fifo_error = 2, cphy_cause_module_change = 4, + cphy_cause_alarm = 8, }; /* PHY module types */ @@ -563,9 +569,10 @@ struct cphy_ops { struct cphy { u8 addr; /* PHY address */ u8 modtype; /* PHY module type */ - short priv; /* scratch pad */ + unsigned int priv; /* scratch pad */ unsigned int caps; /* PHY capabilities */ adapter_t *adapter; /* associated adapter */ + pinfo_t *pinfo; /* associated port */ const char *desc; /* PHY description */ unsigned long fifo_errors; /* FIFO over/under-flows */ const struct cphy_ops *ops; /* PHY operations */ @@ -589,7 +596,7 @@ static inline int mdio_write(struct cphy *phy, int mmd, int reg, } /* Convenience initializer */ -static inline void cphy_init(struct cphy *phy, adapter_t *adapter, +static inline void cphy_init(struct cphy *phy, adapter_t *adapter, pinfo_t *pinfo, int phy_addr, struct cphy_ops *phy_ops, const struct mdio_ops *mdio_ops, unsigned int caps, const char *desc) @@ -597,6 +604,7 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter, phy->addr = (u8)phy_addr; phy->caps = caps; phy->adapter = adapter; + phy->pinfo = pinfo; phy->desc = desc; phy->ops = phy_ops; if (mdio_ops) { @@ -742,7 +750,7 @@ int t3_cim_ctl_blk_read(adapter_t *adap, unsigned int addr, unsigned int n, int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, u64 *buf); -int t3_mac_reset(struct cmac *mac); +int t3_mac_init(struct cmac *mac); void t3b_pcs_reset(struct cmac *mac); void t3_mac_disable_exact_filters(struct cmac *mac); void t3_mac_enable_exact_filters(struct cmac *mac); @@ -827,25 +835,33 @@ int t3_vsc7323_enable(adapter_t *adap, int port, int which); int t3_vsc7323_disable(adapter_t *adap, int port, int which); const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac); +int t3_i2c_read8(adapter_t *adapter, int chained, u8 *valp); +int t3_i2c_write8(adapter_t *adapter, int chained, u8 val); + int t3_mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *valp); int t3_mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val); -int t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_mv88e1xxx_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_vsc8211_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_vsc8211_fifo_depth(adapter_t *adap, unsigned int mtu, int port); +int t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr, + const struct mdio_ops *mdio_ops); +int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_tn1010_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_tn1010_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops); +int t3_aq100x_phy_prep(pinfo_t *pinfo, int phy_addr, + const struct mdio_ops *mdio_ops); #endif /* __CHELSIO_COMMON_H */ diff --git a/sys/dev/cxgb/common/cxgb_mv88e1xxx.c b/sys/dev/cxgb/common/cxgb_mv88e1xxx.c index 7d39def10da..6281ac8944d 100644 --- a/sys/dev/cxgb/common/cxgb_mv88e1xxx.c +++ b/sys/dev/cxgb/common/cxgb_mv88e1xxx.c @@ -294,12 +294,13 @@ static struct cphy_ops mv88e1xxx_ops = { }; #endif -int t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_mv88e1xxx_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { + struct cphy *phy = &pinfo->phy; int err; - cphy_init(phy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops, + cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &mv88e1xxx_ops, mdio_ops, SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); diff --git a/sys/dev/cxgb/common/cxgb_regs.h b/sys/dev/cxgb/common/cxgb_regs.h index dd8db9ac537..644fa26a339 100644 --- a/sys/dev/cxgb/common/cxgb_regs.h +++ b/sys/dev/cxgb/common/cxgb_regs.h @@ -280,6 +280,11 @@ $FreeBSD$ #define V_RSPQ7STARVED(x) ((x) << S_RSPQ7STARVED) #define F_RSPQ7STARVED V_RSPQ7STARVED(1U) +#define S_RSPQXSTARVED 0 +#define M_RSPQXSTARVED 0xff +#define V_RSPQXSTARVED(x) ((x) << S_RSPQXSTARVED) +#define G_RSPQXSTARVED(x) (((x) >> S_RSPQXSTARVED) & M_RSPQXSTARVED) + #define S_RSPQ0DISABLED 8 #define V_RSPQ0DISABLED(x) ((x) << S_RSPQ0DISABLED) #define F_RSPQ0DISABLED V_RSPQ0DISABLED(1U) @@ -376,6 +381,11 @@ $FreeBSD$ #define V_FL15EMPTY(x) ((x) << S_FL15EMPTY) #define F_FL15EMPTY V_FL15EMPTY(1U) +#define S_FLXEMPTY 16 +#define M_FLXEMPTY 0xffff +#define V_FLXEMPTY(x) ((x) << S_FLXEMPTY) +#define G_FLXEMPTY(x) (((x) >> S_FLXEMPTY) & M_FLXEMPTY) + #define A_SG_EGR_PRI_CNT 0x50 #define S_EGRERROPCODE 24 @@ -6235,10 +6245,28 @@ $FreeBSD$ #define V_ACK(x) ((x) << S_ACK) #define F_ACK V_ACK(1U) +#define S_I2C_DATA 0 +#define M_I2C_DATA 0xff +#define V_I2C_DATA(x) ((x) << S_I2C_DATA) +#define G_I2C_DATA(x) (((x) >> S_I2C_DATA) & M_I2C_DATA) + +#define S_I2C_BUSY 31 +#define V_I2C_BUSY(x) ((x) << S_I2C_BUSY) +#define F_I2C_BUSY V_I2C_BUSY(1U) + +#define S_I2C_ACK 30 +#define V_I2C_ACK(x) ((x) << S_I2C_ACK) +#define F_I2C_ACK V_I2C_ACK(1U) + #define S_I2C_CONT 1 #define V_I2C_CONT(x) ((x) << S_I2C_CONT) #define F_I2C_CONT V_I2C_CONT(1U) +#define S_I2C_RDWR 0 +#define V_I2C_RDWR(x) ((x) << S_I2C_RDWR) +#define F_I2C_READ V_I2C_RDWR(0U) +#define F_I2C_WRITE V_I2C_RDWR(1U) + /* registers for module MI1 */ #define MI1_BASE_ADDR 0x6b0 diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c index 5d6711e4687..e340058552e 100644 --- a/sys/dev/cxgb/common/cxgb_t3_hw.c +++ b/sys/dev/cxgb/common/cxgb_t3_hw.c @@ -188,6 +188,62 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, return 0; } +/* + * Low-level I2C read and write routines. These simply read and write a + * single byte with the option of indicating a "continue" if another operation + * is to be chained. Generally most code will use higher-level routines to + * read and write to I2C Slave Devices. + */ +#define I2C_ATTEMPTS 100 + +/* + * Read an 8-bit value from the I2C bus. If the "chained" parameter is + * non-zero then a STOP bit will not be written after the read command. On + * error (the read timed out, etc.), a negative errno will be returned (e.g. + * -EAGAIN, etc.). On success, the 8-bit value read from the I2C bus is + * stored into the buffer *valp and the value of the I2C ACK bit is returned + * as a 0/1 value. + */ +int t3_i2c_read8(adapter_t *adapter, int chained, u8 *valp) +{ + int ret; + u32 opval; + MDIO_LOCK(adapter); + t3_write_reg(adapter, A_I2C_OP, + F_I2C_READ | (chained ? F_I2C_CONT : 0)); + ret = t3_wait_op_done_val(adapter, A_I2C_OP, F_I2C_BUSY, 0, + I2C_ATTEMPTS, 10, &opval); + if (ret >= 0) { + ret = ((opval & F_I2C_ACK) == F_I2C_ACK); + *valp = G_I2C_DATA(t3_read_reg(adapter, A_I2C_DATA)); + } + MDIO_UNLOCK(adapter); + return ret; +} + +/* + * Write an 8-bit value to the I2C bus. If the "chained" parameter is + * non-zero, then a STOP bit will not be written after the write command. On + * error (the write timed out, etc.), a negative errno will be returned (e.g. + * -EAGAIN, etc.). On success, the value of the I2C ACK bit is returned as a + * 0/1 value. + */ +int t3_i2c_write8(adapter_t *adapter, int chained, u8 val) +{ + int ret; + u32 opval; + MDIO_LOCK(adapter); + t3_write_reg(adapter, A_I2C_DATA, V_I2C_DATA(val)); + t3_write_reg(adapter, A_I2C_OP, + F_I2C_WRITE | (chained ? F_I2C_CONT : 0)); + ret = t3_wait_op_done_val(adapter, A_I2C_OP, F_I2C_BUSY, 0, + I2C_ATTEMPTS, 10, &opval); + if (ret >= 0) + ret = ((opval & F_I2C_ACK) == F_I2C_ACK); + MDIO_UNLOCK(adapter); + return ret; +} + /* * Initialize MI1. */ @@ -515,7 +571,12 @@ static struct adapter_info t3_adap_info[] = { F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, - &mi1_mdio_ext_ops, "Chelsio N310" } + &mi1_mdio_ext_ops, "Chelsio T310" }, + { 1, 0, 0, + F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | + F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL, + { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, + &mi1_mdio_ext_ops, "Chelsio N320E-G2" }, }; /* @@ -528,7 +589,7 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id) } struct port_type_info { - int (*phy_prep)(struct cphy *phy, adapter_t *adapter, int phy_addr, + int (*phy_prep)(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *ops); }; @@ -542,6 +603,8 @@ static struct port_type_info port_types[] = { { t3_qt2045_phy_prep }, { t3_ael1006_phy_prep }, { t3_tn1010_phy_prep }, + { t3_aq100x_phy_prep }, + { t3_ael2020_phy_prep }, }; #define VPD_ENTRY(name, len) \ @@ -669,6 +732,125 @@ static unsigned int hex2int(unsigned char c) return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10; } +/** + * get_desc_len - get the length of a vpd descriptor. + * @adapter: the adapter + * @offset: first byte offset of the vpd descriptor + * + * Retrieves the length of the small/large resource + * data type starting at offset. + */ +static int get_desc_len(adapter_t *adapter, u32 offset) +{ + u32 read_offset, tmp, shift, len = 0; + u8 tag, buf[8]; + int ret; + + read_offset = offset & 0xfffffffc; + shift = offset & 0x03; + + ret = t3_seeprom_read(adapter, read_offset, &tmp); + if (ret < 0) + return ret; + + *((u32 *)buf) = cpu_to_le32(tmp); + + tag = buf[shift]; + if (tag & 0x80) { + ret = t3_seeprom_read(adapter, read_offset + 4, &tmp); + if (ret < 0) + return ret; + + *((u32 *)(&buf[4])) = cpu_to_le32(tmp); + len = (buf[shift + 1] & 0xff) + + ((buf[shift+2] << 8) & 0xff00) + 3; + } else + len = (tag & 0x07) + 1; + + return len; +} + +/** + * is_end_tag - Check if a vpd tag is the end tag. + * @adapter: the adapter + * @offset: first byte offset of the tag + * + * Checks if the tag located at offset is the end tag. + */ +static int is_end_tag(adapter_t * adapter, u32 offset) +{ + u32 read_offset, shift, ret, tmp; + u8 buf[4]; + + read_offset = offset & 0xfffffffc; + shift = offset & 0x03; + + ret = t3_seeprom_read(adapter, read_offset, &tmp); + if (ret) + return ret; + *((u32 *)buf) = cpu_to_le32(tmp); + + if (buf[shift] == 0x78) + return 1; + else + return 0; +} + +/** + * t3_get_vpd_len - computes the length of a vpd structure + * @adapter: the adapter + * @vpd: contains the offset of first byte of vpd + * + * Computes the lentgh of the vpd structure starting at vpd->offset. + */ + +int t3_get_vpd_len(adapter_t * adapter, struct generic_vpd *vpd) +{ + u32 len=0, offset; + int inc, ret; + + offset = vpd->offset; + + while (offset < (vpd->offset + MAX_VPD_BYTES)) { + ret = is_end_tag(adapter, offset); + if (ret < 0) + return ret; + else if (ret == 1) + break; + + inc = get_desc_len(adapter, offset); + if (inc < 0) + return inc; + len += inc; + offset += inc; + } + return (len + 1); +} + +/** + * t3_read_vpd - reads the stream of bytes containing a vpd structure + * @adapter: the adapter + * @vpd: contains a buffer that would hold the stream of bytes + * + * Reads the vpd structure starting at vpd->offset into vpd->data, + * the length of the byte stream to read is vpd->len. + */ + +int t3_read_vpd(adapter_t *adapter, struct generic_vpd *vpd) +{ + u32 i, ret; + + for (i = 0; i < vpd->len; i += 4) { + ret = t3_seeprom_read(adapter, vpd->offset + i, + (u32 *) &(vpd->data[i])); + if (ret) + return ret; + } + + return 0; +} + + /** * get_vpd_params - read VPD parameters from VPD EEPROM * @adapter: adapter to read @@ -1313,11 +1495,6 @@ static void t3_clear_faults(adapter_t *adapter, int port_id) struct port_info *pi = adap2pinfo(adapter, port_id); struct cmac *mac = &pi->mac; - t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, - F_ENDROPPKT, 0); - t3_mac_enable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); - t3_set_reg_field(adapter, A_XGM_STAT_CTRL + mac->offset, F_CLRSTATS, 1); - if (adapter->params.nports <= 2) { t3_xgm_intr_disable(adapter, pi->port_id); t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); @@ -1339,7 +1516,7 @@ static void t3_clear_faults(adapter_t *adapter, int port_id) */ void t3_link_changed(adapter_t *adapter, int port_id) { - int link_ok, speed, duplex, fc, link_fault, link_change; + int link_ok, speed, duplex, fc, link_fault; struct port_info *pi = adap2pinfo(adapter, port_id); struct cphy *phy = &pi->phy; struct cmac *mac = &pi->mac; @@ -1353,6 +1530,16 @@ void t3_link_changed(adapter_t *adapter, int port_id) phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); + if (lc->requested_fc & PAUSE_AUTONEG) + fc &= lc->requested_fc; + else + fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); + + /* Update mac speed before checking for link fault. */ + if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE && + (speed != lc->speed || duplex != lc->duplex || fc != lc->fc)) + t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); + /* * Check for link faults if any of these is true: * a) A link fault is suspected, and PHY says link ok @@ -1368,11 +1555,8 @@ void t3_link_changed(adapter_t *adapter, int port_id) pi->link_fault = LF_YES; } - /* Don't report link up or any other change */ + /* Don't report link up */ link_ok = 0; - speed = lc->speed; - duplex = lc->duplex; - fc = lc->fc; } else { /* clear faults here if this was a false alarm. */ if (pi->link_fault == LF_MAYBE && @@ -1383,37 +1567,29 @@ void t3_link_changed(adapter_t *adapter, int port_id) } } - if (lc->requested_fc & PAUSE_AUTONEG) - fc &= lc->requested_fc; - else - fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); - if (link_ok == lc->link_ok && speed == lc->speed && duplex == lc->duplex && fc == lc->fc) return; /* nothing changed */ - link_change = link_ok != lc->link_ok; lc->link_ok = (unsigned char)link_ok; lc->speed = speed < 0 ? SPEED_INVALID : speed; lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; + lc->fc = fc; if (link_ok) { /* down -> up, or up -> up with changed settings */ - if (link_change && adapter->params.rev > 0 && - uses_xaui(adapter)) { - t3b_pcs_reset(mac); + if (adapter->params.rev > 0 && uses_xaui(adapter)) { t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, F_TXACTENABLE | F_RXEN); } - if (speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { - /* Set MAC settings to match PHY. */ - t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); - lc->fc = (unsigned char)fc; - } - + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, + F_ENDROPPKT, 0); + t3_mac_enable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); + t3_set_reg_field(adapter, A_XGM_STAT_CTRL + mac->offset, + F_CLRSTATS, 1); t3_clear_faults(adapter, port_id); } else { @@ -1450,7 +1626,9 @@ void t3_link_changed(adapter_t *adapter, int port_id) t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN); } - t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); + t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc, + mac->was_reset); + mac->was_reset = 0; } /** @@ -1478,6 +1656,7 @@ int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) if (fc & PAUSE_RX) lc->advertising |= ADVERTISED_Pause; } + phy->ops->advertise(phy, lc->advertising); if (lc->autoneg == AUTONEG_DISABLE) { @@ -1490,7 +1669,7 @@ int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); /* PR 5666. Power phy up when doing an ifup */ if (!is_10G(phy->adapter)) - phy->ops->power_down(phy, 0); + phy->ops->power_down(phy, 0); } else phy->ops->autoneg_enable(phy); } else { @@ -2020,6 +2199,10 @@ int t3_phy_intr_handler(adapter_t *adapter) p->phy.fifo_errors++; if (phy_cause & cphy_cause_module_change) t3_os_phymod_changed(adapter, i); + if (phy_cause & cphy_cause_alarm) + CH_WARN(adapter, "Operation affected due to " + "adverse environment. Check the spec " + "sheet for corrective action."); } } @@ -3871,7 +4054,7 @@ static void config_pcie(adapter_t *adap) { 201, 321, 258, 450, 834, 1602 } }; - u16 val; + u16 val, devid; unsigned int log2_width, pldsize; unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt; @@ -3880,6 +4063,18 @@ static void config_pcie(adapter_t *adap) &val); pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5; + /* + * Gen2 adapter pcie bridge compatibility requires minimum + * Max_Read_Request_size + */ + t3_os_pci_read_config_2(adap, 0x2, &devid); + if (devid == 0x37) { + t3_os_pci_write_config_2(adap, + adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL, + val & ~PCI_EXP_DEVCTL_READRQ & ~PCI_EXP_DEVCTL_PAYLOAD); + pldsize = 0; + } + t3_os_pci_read_config_2(adap, adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL, &val); @@ -3934,7 +4129,7 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params) goto out_err; if (adapter->params.nports > 2) - t3_mac_reset(&adap2pinfo(adapter, 0)->mac); + t3_mac_init(&adap2pinfo(adapter, 0)->mac); if (vpd->mclk) { partition_mem(adapter, &adapter->params.tp); @@ -4098,15 +4293,25 @@ static void __devinit mc7_prep(adapter_t *adapter, struct mc7 *mc7, void mac_prep(struct cmac *mac, adapter_t *adapter, int index) { + u16 devid; + mac->adapter = adapter; mac->multiport = adapter->params.nports > 2; if (mac->multiport) { mac->ext_port = (unsigned char)index; mac->nucast = 8; - index = 0; } else mac->nucast = 1; + /* Gen2 adapter uses VPD xauicfg[] to notify driver which MAC + is connected to each port, its suppose to be using xgmac0 for both ports + */ + t3_os_pci_read_config_2(adapter, 0x2, &devid); + + if (mac->multiport || + (!adapter->params.vpd.xauicfg[1] && (devid==0x37))) + index = 0; + mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index; if (adapter->params.rev == 0 && uses_xaui(adapter)) { @@ -4336,7 +4541,7 @@ int __devinit t3_prep_adapter(adapter_t *adapter, if (j >= ARRAY_SIZE(adapter->params.vpd.port_type)) return -EINVAL; } - ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, + ret = pti->phy_prep(p, ai->phy_base_addr + j, ai->mdio_ops); if (ret) return ret; @@ -4408,7 +4613,7 @@ int t3_reinit_adapter(adapter_t *adap) if (j >= ARRAY_SIZE(adap->params.vpd.port_type)) return -EINVAL; } - ret = pti->phy_prep(&p->phy, adap, p->phy.addr, NULL); + ret = pti->phy_prep(p, p->phy.addr, NULL); if (ret) return ret; p->phy.ops->power_down(&p->phy, 1); diff --git a/sys/dev/cxgb/common/cxgb_tn1010.c b/sys/dev/cxgb/common/cxgb_tn1010.c index 623f784a9ea..45758288d2c 100644 --- a/sys/dev/cxgb/common/cxgb_tn1010.c +++ b/sys/dev/cxgb/common/cxgb_tn1010.c @@ -209,10 +209,10 @@ static struct cphy_ops tn1010_ops = { }; #endif -int t3_tn1010_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +int t3_tn1010_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, phy_addr, &tn1010_ops, mdio_ops, + cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &tn1010_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_AUI | SUPPORTED_TP, "1000/10GBASE-T"); diff --git a/sys/dev/cxgb/common/cxgb_vsc8211.c b/sys/dev/cxgb/common/cxgb_vsc8211.c index 004f2f87726..9d838597329 100644 --- a/sys/dev/cxgb/common/cxgb_vsc8211.c +++ b/sys/dev/cxgb/common/cxgb_vsc8211.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); enum { VSC8211_SIGDET_CTRL = 19, VSC8211_EXT_CTRL = 23, + VSC8211_PHY_CTRL = 24, VSC8211_INTR_ENABLE = 25, VSC8211_INTR_STATUS = 26, VSC8211_LED_CTRL = 27, @@ -375,13 +376,62 @@ static struct cphy_ops vsc8211_fiber_ops = { }; #endif -int t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, +#define VSC8211_PHY_CTRL 24 + +#define S_VSC8211_TXFIFODEPTH 7 +#define M_VSC8211_TXFIFODEPTH 0x7 +#define V_VSC8211_TXFIFODEPTH(x) ((x) << S_VSC8211_TXFIFODEPTH) +#define G_VSC8211_TXFIFODEPTH(x) (((x) >> S_VSC8211_TXFIFODEPTH) & M_VSC8211_TXFIFODEPTH) + +#define S_VSC8211_RXFIFODEPTH 4 +#define M_VSC8211_RXFIFODEPTH 0x7 +#define V_VSC8211_RXFIFODEPTH(x) ((x) << S_VSC8211_RXFIFODEPTH) +#define G_VSC8211_RXFIFODEPTH(x) (((x) >> S_VSC8211_RXFIFODEPTH) & M_VSC8211_RXFIFODEPTH) + +int t3_vsc8211_fifo_depth(adapter_t *adap, unsigned int mtu, int port) +{ + /* TX FIFO Depth set bits 9:7 to 100 (IEEE mode) */ + unsigned int val = 4; + unsigned int currentregval; + unsigned int regval; + int err; + + /* Retrieve the port info structure from adater_t */ + struct port_info *portinfo = adap2pinfo(adap, port); + + /* What phy is this */ + struct cphy *phy = &portinfo->phy; + + /* Read the current value of the PHY control Register */ + err = mdio_read(phy, 0, VSC8211_PHY_CTRL, ¤tregval); + + if (err) + return err; + + /* IEEE mode supports up to 1518 bytes */ + /* mtu does not contain the header + FCS (18 bytes) */ + if (mtu > 1500) + /* + * If using a packet size > 1500 set TX FIFO Depth bits + * 9:7 to 011 (Jumbo packet mode) + */ + val = 3; + + regval = V_VSC8211_TXFIFODEPTH(val) | V_VSC8211_RXFIFODEPTH(val) | + (currentregval & ~V_VSC8211_TXFIFODEPTH(M_VSC8211_TXFIFODEPTH) & + ~V_VSC8211_RXFIFODEPTH(M_VSC8211_RXFIFODEPTH)); + + return mdio_write(phy, 0, VSC8211_PHY_CTRL, regval); +} + +int t3_vsc8211_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { + struct cphy *phy = &pinfo->phy; int err; unsigned int val; - cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops, + cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &vsc8211_ops, mdio_ops, SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); diff --git a/sys/dev/cxgb/common/cxgb_xgmac.c b/sys/dev/cxgb/common/cxgb_xgmac.c index 677f349b0d5..e323c9b2685 100644 --- a/sys/dev/cxgb/common/cxgb_xgmac.c +++ b/sys/dev/cxgb/common/cxgb_xgmac.c @@ -41,6 +41,28 @@ static inline int macidx(const struct cmac *mac) return mac->offset / (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR); } +/* + * Returns a reasonable A_XGM_RESET_CTRL value for the mac specified. + */ +static inline int xgm_reset_ctrl(const struct cmac *mac) +{ + adapter_t *adap = mac->adapter; + int val = F_MAC_RESET_ | F_XGMAC_STOP_EN; + + if (is_10G(adap)) { + int cfg = t3_read_reg(adap, A_XGM_PORT_CFG + mac->offset); + + val |= F_PCS_RESET_; + if (G_PORTSPEED(cfg) != 3) /* not running at 10G */ + val |= F_XG2G_RESET_; + } else if (uses_xaui(adap)) + val |= F_PCS_RESET_ | F_XG2G_RESET_; + else + val |= F_RGMII_RESET_ | F_XG2G_RESET_; + + return (val); +} + static void xaui_serdes_reset(struct cmac *mac) { static const unsigned int clear[] = { @@ -81,12 +103,12 @@ void t3b_pcs_reset(struct cmac *mac) } /** - * t3_mac_reset - reset a MAC - * @mac: the MAC to reset + * t3_mac_init - initialize a MAC + * @mac: the MAC to initialize * - * Reset the given MAC. + * Initialize the given MAC. */ -int t3_mac_reset(struct cmac *mac) +int t3_mac_init(struct cmac *mac) { static struct addr_val_pair mac_reset_avp[] = { { A_XGM_TX_CTRL, 0 }, @@ -138,7 +160,7 @@ int t3_mac_reset(struct cmac *mac) if (mac->multiport) { t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + oft, - MAX_FRAME_SIZE - 4); + V_RXMAXPKTSIZE(MAX_FRAME_SIZE - 4)); t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0, F_DISPREAMBLE); t3_set_reg_field(adap, A_XGM_RX_CFG + oft, 0, F_COPYPREAMBLE | @@ -154,13 +176,7 @@ int t3_mac_reset(struct cmac *mac) V_RXMAXFRAMERSIZE(M_RXMAXFRAMERSIZE), V_RXMAXFRAMERSIZE(MAX_FRAME_SIZE) | F_RXENFRAMER); - val = F_MAC_RESET_ | F_XGMAC_STOP_EN; - if (!mac->multiport) - val |= F_XG2G_RESET_; - if (uses_xaui(adap)) - val |= F_PCS_RESET_; - else - val |= F_RGMII_RESET_; + val = xgm_reset_ctrl(mac); t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val); (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ if ((val & F_PCS_RESET_) && adap->params.rev) { @@ -172,16 +188,17 @@ int t3_mac_reset(struct cmac *mac) return 0; } -static int t3b2_mac_reset(struct cmac *mac) +static int t3_mac_reset(struct cmac *mac, int portspeed) { - u32 val; + u32 val, store_mps; adapter_t *adap = mac->adapter; unsigned int oft = mac->offset; int idx = macidx(mac); unsigned int store; /* Stop egress traffic to xgm*/ - if (!macidx(mac)) + store_mps = t3_read_reg(adap, A_MPS_CFG); + if (!idx) t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0); else t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0); @@ -198,7 +215,7 @@ static int t3b2_mac_reset(struct cmac *mac) /* Store A_TP_TX_DROP_CFG_CH0 */ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); - store = t3_read_reg(adap, A_TP_TX_DROP_CFG_CH0 + idx); + store = t3_read_reg(adap, A_TP_PIO_DATA); msleep(10); @@ -209,44 +226,55 @@ static int t3b2_mac_reset(struct cmac *mac) /* Check for xgm Rx fifo empty */ /* Increased loop count to 1000 from 5 cover 1G and 100Mbps case */ if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft, - 0x80000000, 1, 1000, 2)) { - CH_ERR(adap, "MAC %d Rx fifo drain failed\n", - macidx(mac)); + 0x80000000, 1, 1000, 2) && portspeed < 0) { + CH_ERR(adap, "MAC %d Rx fifo drain failed\n", idx); return -1; } - t3_write_reg(adap, A_XGM_RESET_CTRL + oft, 0); /*MAC in reset*/ - (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + if (portspeed >= 0) { + u32 intr = t3_read_reg(adap, A_XGM_INT_ENABLE + oft); - val = F_MAC_RESET_; - if (is_10G(adap)) - val |= F_PCS_RESET_; - else if (uses_xaui(adap)) - val |= F_PCS_RESET_ | F_XG2G_RESET_; - else - val |= F_RGMII_RESET_ | F_XG2G_RESET_; - t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val); - (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ - if ((val & F_PCS_RESET_) && adap->params.rev) { - msleep(1); - t3b_pcs_reset(mac); + /* + * safespeedchange: wipes out pretty much all XGMAC registers. + */ + + t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, + V_PORTSPEED(M_PORTSPEED) | F_SAFESPEEDCHANGE, + portspeed | F_SAFESPEEDCHANGE); + (void) t3_read_reg(adap, A_XGM_PORT_CFG + oft); + t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, + F_SAFESPEEDCHANGE, 0); + (void) t3_read_reg(adap, A_XGM_PORT_CFG + oft); + t3_mac_init(mac); + + t3_write_reg(adap, A_XGM_INT_ENABLE + oft, intr); + } else { + + t3_write_reg(adap, A_XGM_RESET_CTRL + oft, 0); /*MAC in reset*/ + (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + + val = xgm_reset_ctrl(mac); + t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val); + (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + if ((val & F_PCS_RESET_) && adap->params.rev) { + msleep(1); + t3b_pcs_reset(mac); + } + t3_write_reg(adap, A_XGM_RX_CFG + oft, + F_DISPAUSEFRAMES | F_EN1536BFRAMES | + F_RMFCS | F_ENJUMBO | F_ENHASHMCAST ); } - t3_write_reg(adap, A_XGM_RX_CFG + oft, - F_DISPAUSEFRAMES | F_EN1536BFRAMES | - F_RMFCS | F_ENJUMBO | F_ENHASHMCAST ); /* Restore the DROP_CFG */ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); t3_write_reg(adap, A_TP_PIO_DATA, store); /* Resume egress traffic to xgm */ - if (!macidx(mac)) - t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE); - else - t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE); + t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE, + store_mps); /* Set: re-enable NIC traffic */ - t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1); + t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, F_ENFORCEPKT); return 0; } @@ -409,6 +437,8 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) int ipg; unsigned int thres, v, reg; adapter_t *adap = mac->adapter; + unsigned port_type = adap->params.vpd.port_type[macidx(mac)]; + unsigned int orig_mtu=mtu; /* * MAX_FRAME_SIZE inludes header + FCS, mtu doesn't. The HW max @@ -422,6 +452,14 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) if (mac->multiport) return t3_vsc7323_set_mtu(adap, mtu - 4, mac->ext_port); + /* Modify the TX and RX fifo depth only if the card has a vsc8211 phy */ + if (port_type == 2) { + int err = t3_vsc8211_fifo_depth(adap,orig_mtu,macidx(mac)); + + if (err) + return err; + } + if (adap->params.rev >= T3_REV_B2 && (t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) { t3_mac_disable_exact_filters(mac); @@ -507,10 +545,12 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc) if (duplex >= 0 && duplex != DUPLEX_FULL) return -EINVAL; if (mac->multiport) { + u32 rx_max_pkt_size = + G_RXMAXPKTSIZE(t3_read_reg(adap, + A_XGM_RX_MAX_PKT_SIZE + oft)); val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft); val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM); - val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(t3_read_reg(adap, - A_XGM_RX_MAX_PKT_SIZE + oft)) / 8); + val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(rx_max_pkt_size) / 8); t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val); t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, @@ -529,15 +569,27 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc) else return -EINVAL; - t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, - V_PORTSPEED(M_PORTSPEED), val); + if (!uses_xaui(adap)) /* T302 */ + t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, + V_PORTSPEED(M_PORTSPEED), val); + else { + u32 old = t3_read_reg(adap, A_XGM_PORT_CFG + oft); + + if ((old & V_PORTSPEED(M_PORTSPEED)) != val) { + t3_mac_reset(mac, val); + mac->was_reset = 1; + } + } } val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft); val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM); - if (fc & PAUSE_TX) - val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(t3_read_reg(adap, - A_XGM_RX_MAX_PKT_SIZE + oft)) / 8); + if (fc & PAUSE_TX) { + u32 rx_max_pkt_size = + G_RXMAXPKTSIZE(t3_read_reg(adap, + A_XGM_RX_MAX_PKT_SIZE + oft)); + val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(rx_max_pkt_size) / 8); + } t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val); t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, @@ -618,18 +670,12 @@ int t3_mac_disable(struct cmac *mac, int which) mac->txen = 0; } if (which & MAC_DIRECTION_RX) { - int val = F_MAC_RESET_; + int val = xgm_reset_ctrl(mac); t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, F_PCS_RESET_, 0); msleep(100); t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); - if (is_10G(adap)) - val |= F_PCS_RESET_; - else if (uses_xaui(adap)) - val |= F_PCS_RESET_ | F_XG2G_RESET_; - else - val |= F_RGMII_RESET_ | F_XG2G_RESET_; t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val); } return 0; @@ -650,10 +696,15 @@ int t3b2_mac_watchdog_task(struct cmac *mac) tx_xcnt = 1; /* By default tx_xcnt is making progress*/ tx_tcnt = mac->tx_tcnt; /* If tx_mcnt is progressing ignore tx_tcnt*/ if (tx_mcnt == mac->tx_mcnt && mac->rx_pause == s->rx_pause) { + u32 cfg, active, enforcepkt; + tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, A_XGM_TX_SPI4_SOP_EOP_CNT + mac->offset))); - if (tx_xcnt == 0) { + cfg = t3_read_reg(adap, A_MPS_CFG); + active = macidx(mac) ? cfg & F_PORT1ACTIVE : cfg & F_PORT0ACTIVE; + enforcepkt = cfg & F_ENFORCEPKT; + if (active && enforcepkt && (tx_xcnt == 0)) { t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac)); tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, @@ -691,7 +742,7 @@ out: t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */ mac->toggle_cnt++; } else if (status == 2) { - t3b2_mac_reset(mac); + t3_mac_reset(mac, -1); mac->toggle_cnt = 0; } return status; diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h index 2b25a34090c..71f540223a4 100644 --- a/sys/dev/cxgb/cxgb_adapter.h +++ b/sys/dev/cxgb/cxgb_adapter.h @@ -361,8 +361,6 @@ struct adapter { struct callout cxgb_tick_ch; struct callout sge_timer_ch; - unsigned int check_task_cnt; - /* Register lock for use by the hardware layer */ struct mtx mdio_lock; struct mtx elmer_lock; @@ -500,7 +498,7 @@ int t3_os_find_pci_capability(adapter_t *adapter, int cap); int t3_os_pci_save_state(struct adapter *adapter); int t3_os_pci_restore_state(struct adapter *adapter); void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, - int speed, int duplex, int fc); + int speed, int duplex, int fc, int mac_was_reset); void t3_os_phymod_changed(struct adapter *adap, int port_id); void t3_sge_err_intr_handler(adapter_t *adapter); int t3_offload_tx(struct t3cdev *, struct mbuf *); diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 596609b89d9..26d4b508c0a 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -116,7 +116,7 @@ static int cxgb_get_regs_len(void); static int offload_open(struct port_info *pi); static void touch_bars(device_t dev); static int offload_close(struct t3cdev *tdev); -int t3_detect_link_fault(adapter_t *adapter, int port_id); +static void cxgb_update_mac_settings(struct port_info *p); static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), @@ -291,7 +291,9 @@ struct cxgb_ident { {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, - {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "N310E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"}, + {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"}, + {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"}, {0, 0, 0, NULL} }; @@ -508,6 +510,9 @@ cxgb_controller_attach(device_t dev) sc->bh = rman_get_bushandle(sc->regs_res); sc->mmio_len = rman_get_size(sc->regs_res); + for (i = 0; i < MAX_NPORTS; i++) + sc->port[i].adapter = sc; + if (t3_prep_adapter(sc, ai, 1) < 0) { printf("prep adapter failed\n"); error = ENODEV; @@ -1222,8 +1227,8 @@ t3_os_pci_restore_state(struct adapter *sc) /** * t3_os_link_changed - handle link status changes - * @adapter: the adapter associated with the link change - * @port_id: the port index whose limk status has changed + * @sc: the adapter associated with the link change + * @port_id: the port index whose link status has changed * @link_status: the new status of the link * @speed: the new speed setting * @duplex: the new duplex setting @@ -1235,7 +1240,7 @@ t3_os_pci_restore_state(struct adapter *sc) */ void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, - int duplex, int fc) + int duplex, int fc, int mac_was_reset) { struct port_info *pi = &adapter->port[port_id]; struct ifnet *ifp = pi->ifp; @@ -1243,6 +1248,13 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, /* no race with detach, so ifp should always be good */ KASSERT(ifp, ("%s: if detached.", __func__)); + /* Reapply mac settings if they were lost due to a reset */ + if (mac_was_reset) { + PORT_LOCK(pi); + cxgb_update_mac_settings(pi); + PORT_UNLOCK(pi); + } + if (link_status) { ifp->if_baudrate = IF_Mbps(speed); if_link_state_change(ifp, LINK_STATE_UP); @@ -1917,7 +1929,7 @@ cxgb_init_synchronized(struct port_info *p) PORT_LOCK(p); t3_port_intr_enable(sc, p->port_id); if (!mac->multiport) - t3_mac_reset(mac); + t3_mac_init(mac); cxgb_update_mac_settings(p); t3_link_start(&p->phy, mac, &p->link_config); t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); @@ -1992,7 +2004,7 @@ cxgb_uninit_synchronized(struct port_info *pi) PORT_UNLOCK(pi); pi->link_config.link_ok = 0; - t3_os_link_changed(sc, pi->port_id, 0, 0, 0, 0); + t3_os_link_changed(sc, pi->port_id, 0, 0, 0, 0, 0); if ((sc->open_device_map & PORT_MASK) == 0) offload_close(&sc->tdev); @@ -2335,6 +2347,19 @@ cxgb_ext_intr_handler(void *arg, int count) ADAPTER_UNLOCK(sc); } +static inline int +link_poll_needed(struct port_info *p) +{ + struct cphy *phy = &p->phy; + + if (phy->caps & POLL_LINK_1ST_TIME) { + p->phy.caps &= ~POLL_LINK_1ST_TIME; + return (1); + } + + return (p->link_fault || !(phy->caps & SUPPORTED_LINK_IRQ)); +} + static void check_link_status(adapter_t *sc) { @@ -2346,7 +2371,7 @@ check_link_status(adapter_t *sc) if (!isset(&sc->open_device_map, p->port_id)) continue; - if (p->link_fault || !(p->phy.caps & SUPPORTED_IRQ)) + if (link_poll_needed(p)) t3_link_changed(sc, i); } } @@ -2366,7 +2391,8 @@ check_t3b2_mac(struct adapter *sc) struct ifnet *ifp = p->ifp; #endif - if (!isset(&sc->open_device_map, p->port_id)) + if (!isset(&sc->open_device_map, p->port_id) || p->link_fault || + !p->link_config.link_ok) continue; KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, @@ -2414,7 +2440,6 @@ cxgb_tick_handler(void *arg, int count) return; check_link_status(sc); - sc->check_task_cnt++; if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map) check_t3b2_mac(sc); diff --git a/sys/dev/cxgb/cxgb_osdep.h b/sys/dev/cxgb/cxgb_osdep.h index 6108214c0e7..956789085d8 100644 --- a/sys/dev/cxgb/cxgb_osdep.h +++ b/sys/dev/cxgb/cxgb_osdep.h @@ -48,6 +48,7 @@ $FreeBSD$ #define _CXGB_OSDEP_H_ typedef struct adapter adapter_t; +typedef struct port_info pinfo_t; struct sge_rspq; enum { @@ -247,10 +248,10 @@ static const int debug_flags = DBG_RX; #define MII_CTRL1000 MII_100T2CR #define ADVERTISE_PAUSE_CAP ANAR_FC -#define ADVERTISE_PAUSE_ASYM ANAR_X_PAUSE_ASYM -#define ADVERTISE_PAUSE ANAR_X_PAUSE_SYM -#define ADVERTISE_1000HALF ANAR_X_HD -#define ADVERTISE_1000FULL ANAR_X_FD +#define ADVERTISE_PAUSE_ASYM 0x800 +#define ADVERTISE_PAUSE ANAR_FC +#define ADVERTISE_1000HALF 0x100 +#define ADVERTISE_1000FULL 0x200 #define ADVERTISE_10FULL ANAR_10_FD #define ADVERTISE_10HALF ANAR_10 #define ADVERTISE_100FULL ANAR_TX_FD @@ -266,17 +267,18 @@ static const int debug_flags = DBG_RX; #define ADVERTISE_NPAGE ANAR_NP -/* Standard PCI Extended Capaibilities definitions */ -#define PCI_CAP_ID_VPD 0x03 -#define PCI_VPD_ADDR 2 +/* Standard PCI Extended Capabilities definitions */ +#define PCI_CAP_ID_VPD PCIY_VPD +#define PCI_VPD_ADDR PCIR_VPD_ADDR #define PCI_VPD_ADDR_F 0x8000 -#define PCI_VPD_DATA 4 +#define PCI_VPD_DATA PCIR_VPD_DATA -#define PCI_CAP_ID_EXP 0x10 -#define PCI_EXP_DEVCTL 8 -#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 -#define PCI_EXP_LNKCTL 16 -#define PCI_EXP_LNKSTA 18 +#define PCI_CAP_ID_EXP PCIY_EXPRESS +#define PCI_EXP_DEVCTL PCIR_EXPRESS_DEVICE_CTL +#define PCI_EXP_DEVCTL_PAYLOAD PCIM_EXP_CTL_MAX_PAYLOAD +#define PCI_EXP_DEVCTL_READRQ PCIM_EXP_CTL_MAX_READ_REQUEST +#define PCI_EXP_LNKCTL PCIR_EXPRESS_LINK_CTL +#define PCI_EXP_LNKSTA PCIR_EXPRESS_LINK_STA /* * Linux compatibility macros diff --git a/sys/dev/cxgb/cxgb_t3fw.h b/sys/dev/cxgb/cxgb_t3fw.h index dbc5dd81867..6af06191f99 100644 --- a/sys/dev/cxgb/cxgb_t3fw.h +++ b/sys/dev/cxgb/cxgb_t3fw.h @@ -32,8 +32,8 @@ $FreeBSD$ #define U (unsigned char) -static unsigned int t3fw_length = 30136; -static unsigned char t3fw[30136] = { +static unsigned int t3fw_length = 30772; +static unsigned char t3fw[30772] = { U 0x60, U 0x00, U 0x74, U 0x00, U 0x20, U 0x03, U 0x80, U 0x00, U 0x20, U 0x03, U 0x70, U 0x00, @@ -55,13 +55,13 @@ static unsigned char t3fw[30136] = { U 0x1F, U 0xFF, U 0xC0, U 0x00, U 0xE3, U 0x00, U 0x04, U 0x3C, U 0x02, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x69, U 0x88, + U 0x20, U 0x00, U 0x6B, U 0xE8, U 0x1F, U 0xFF, U 0xC2, U 0x90, - U 0x20, U 0x00, U 0x69, U 0xD0, + U 0x20, U 0x00, U 0x6C, U 0x30, U 0x1F, U 0xFF, U 0xC2, U 0x94, - U 0x20, U 0x00, U 0x6A, U 0x10, + U 0x20, U 0x00, U 0x6C, U 0x70, U 0x1F, U 0xFF, U 0xC2, U 0x98, - U 0x20, U 0x00, U 0x6A, U 0x84, + U 0x20, U 0x00, U 0x6C, U 0xE4, U 0x1F, U 0xFF, U 0xC2, U 0x9C, U 0x20, U 0x00, U 0x03, U 0xC0, U 0xC0, U 0x00, U 0x00, U 0xE4, @@ -324,83 +324,83 @@ static unsigned char t3fw[30136] = { U 0x1F, U 0xFF, U 0xC0, U 0x18, U 0xE3, U 0x00, U 0x05, U 0xE0, U 0x1F, U 0xFF, U 0xC0, U 0x18, - U 0x1F, U 0xFF, U 0xC2, U 0x8C, + U 0x1F, U 0xFF, U 0xC2, U 0x90, U 0xE3, U 0x00, U 0x05, U 0xE0, - U 0x1F, U 0xFF, U 0xC2, U 0x8C, - U 0x1F, U 0xFF, U 0xC2, U 0x8C, - U 0xE3, U 0x00, U 0x08, U 0x54, + U 0x1F, U 0xFF, U 0xC2, U 0x90, + U 0x1F, U 0xFF, U 0xC2, U 0x90, + U 0xE3, U 0x00, U 0x08, U 0x58, U 0x1F, U 0xFF, U 0xC2, U 0x90, U 0x1F, U 0xFF, U 0xC5, U 0x8C, - U 0xE3, U 0x00, U 0x08, U 0x54, + U 0xE3, U 0x00, U 0x08, U 0x58, U 0x20, U 0x00, U 0x00, U 0x00, U 0x20, U 0x00, U 0x01, U 0x6A, - U 0xE3, U 0x00, U 0x0B, U 0x50, + U 0xE3, U 0x00, U 0x0B, U 0x54, U 0x20, U 0x00, U 0x01, U 0x80, U 0x20, U 0x00, U 0x01, U 0x80, - U 0xE3, U 0x00, U 0x0C, U 0xBC, + U 0xE3, U 0x00, U 0x0C, U 0xC0, U 0x20, U 0x00, U 0x02, U 0x00, U 0x20, U 0x00, U 0x02, U 0x03, - U 0xE3, U 0x00, U 0x0C, U 0xBC, + U 0xE3, U 0x00, U 0x0C, U 0xC0, U 0x20, U 0x00, U 0x02, U 0x1C, U 0x20, U 0x00, U 0x02, U 0x20, - U 0xE3, U 0x00, U 0x0C, U 0xC0, + U 0xE3, U 0x00, U 0x0C, U 0xC4, U 0x20, U 0x00, U 0x02, U 0x20, U 0x20, U 0x00, U 0x02, U 0x26, - U 0xE3, U 0x00, U 0x0C, U 0xC4, + U 0xE3, U 0x00, U 0x0C, U 0xC8, U 0x20, U 0x00, U 0x02, U 0x3C, U 0x20, U 0x00, U 0x02, U 0x40, - U 0xE3, U 0x00, U 0x0C, U 0xCC, + U 0xE3, U 0x00, U 0x0C, U 0xD0, U 0x20, U 0x00, U 0x02, U 0x40, U 0x20, U 0x00, U 0x02, U 0x49, - U 0xE3, U 0x00, U 0x0C, U 0xD0, + U 0xE3, U 0x00, U 0x0C, U 0xD4, U 0x20, U 0x00, U 0x02, U 0x4C, U 0x20, U 0x00, U 0x02, U 0x50, - U 0xE3, U 0x00, U 0x0C, U 0xDC, + U 0xE3, U 0x00, U 0x0C, U 0xE0, U 0x20, U 0x00, U 0x02, U 0x50, U 0x20, U 0x00, U 0x02, U 0x59, - U 0xE3, U 0x00, U 0x0C, U 0xE0, + U 0xE3, U 0x00, U 0x0C, U 0xE4, U 0x20, U 0x00, U 0x02, U 0x5C, U 0x20, U 0x00, U 0x02, U 0x60, - U 0xE3, U 0x00, U 0x0C, U 0xEC, + U 0xE3, U 0x00, U 0x0C, U 0xF0, U 0x20, U 0x00, U 0x02, U 0x60, U 0x20, U 0x00, U 0x02, U 0x69, - U 0xE3, U 0x00, U 0x0C, U 0xF0, + U 0xE3, U 0x00, U 0x0C, U 0xF4, U 0x20, U 0x00, U 0x02, U 0x6C, U 0x20, U 0x00, U 0x02, U 0x70, - U 0xE3, U 0x00, U 0x0C, U 0xFC, + U 0xE3, U 0x00, U 0x0D, U 0x00, U 0x20, U 0x00, U 0x02, U 0x70, U 0x20, U 0x00, U 0x02, U 0x79, - U 0xE3, U 0x00, U 0x0D, U 0x00, + U 0xE3, U 0x00, U 0x0D, U 0x04, U 0x20, U 0x00, U 0x02, U 0x8C, U 0x20, U 0x00, U 0x02, U 0x8C, - U 0xE3, U 0x00, U 0x0D, U 0x0C, + U 0xE3, U 0x00, U 0x0D, U 0x10, U 0x20, U 0x00, U 0x02, U 0x90, U 0x20, U 0x00, U 0x02, U 0x93, - U 0xE3, U 0x00, U 0x0D, U 0x0C, + U 0xE3, U 0x00, U 0x0D, U 0x10, U 0x20, U 0x00, U 0x02, U 0xAC, U 0x20, U 0x00, U 0x02, U 0xB0, - U 0xE3, U 0x00, U 0x0D, U 0x10, + U 0xE3, U 0x00, U 0x0D, U 0x14, U 0x20, U 0x00, U 0x02, U 0xD0, U 0x20, U 0x00, U 0x02, U 0xF2, - U 0xE3, U 0x00, U 0x0D, U 0x14, + U 0xE3, U 0x00, U 0x0D, U 0x18, U 0x20, U 0x00, U 0x03, U 0xB0, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0xE3, U 0x00, U 0x0D, U 0x38, + U 0xE3, U 0x00, U 0x0D, U 0x3C, U 0x20, U 0x00, U 0x03, U 0xB0, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0xE3, U 0x00, U 0x0D, U 0x38, + U 0xE3, U 0x00, U 0x0D, U 0x3C, U 0x20, U 0x00, U 0x03, U 0xB0, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0xE3, U 0x00, U 0x0D, U 0x38, + U 0xE3, U 0x00, U 0x0D, U 0x3C, U 0x20, U 0x00, U 0x03, U 0xB0, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0xE3, U 0x00, U 0x0D, U 0x38, + U 0xE3, U 0x00, U 0x0D, U 0x3C, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0x20, U 0x00, U 0x6B, U 0xA8, - U 0xE3, U 0x00, U 0x0D, U 0x38, - U 0x20, U 0x00, U 0x6B, U 0xA8, - U 0x20, U 0x00, U 0x6B, U 0xA8, - U 0xE3, U 0x00, U 0x75, U 0x30, + U 0x20, U 0x00, U 0x6E, U 0x08, + U 0xE3, U 0x00, U 0x0D, U 0x3C, + U 0x20, U 0x00, U 0x6E, U 0x08, + U 0x20, U 0x00, U 0x6E, U 0x08, + U 0xE3, U 0x00, U 0x77, U 0x94, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, @@ -408,8 +408,8 @@ static unsigned char t3fw[30136] = { U 0x1F, U 0xFC, U 0x00, U 0x00, U 0x1F, U 0xFF, U 0xC5, U 0x90, U 0x1F, U 0xFF, U 0xC6, U 0x70, - U 0x20, U 0x00, U 0x6B, U 0xA8, - U 0x20, U 0x00, U 0x6B, U 0xA8, + U 0x20, U 0x00, U 0x6E, U 0x08, + U 0x20, U 0x00, U 0x6E, U 0x08, U 0xDE, U 0xFF, U 0xFE, U 0x00, U 0x00, U 0x00, U 0x08, U 0x0C, U 0xDE, U 0xAD, U 0xBE, U 0xEF, @@ -436,7 +436,6 @@ static unsigned char t3fw[30136] = { U 0x10, U 0x00, U 0x00, U 0x01, U 0x20, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x10, U 0x00, - U 0x7F, U 0xFF, U 0xFF, U 0xFF, U 0x40, U 0x00, U 0x00, U 0x00, U 0x05, U 0x00, U 0x00, U 0x00, U 0x80, U 0x00, U 0x00, U 0x19, @@ -461,15 +460,16 @@ static unsigned char t3fw[30136] = { U 0x60, U 0x40, U 0x00, U 0x00, U 0x1A, U 0x00, U 0x00, U 0x00, U 0x0C, U 0x00, U 0x00, U 0x00, + U 0x10, U 0x00, U 0x00, U 0x0A, U 0x00, U 0x00, U 0x30, U 0x00, - U 0x60, U 0x00, U 0x08, U 0x00, - U 0x80, U 0x00, U 0x00, U 0x1C, U 0x00, U 0x01, U 0x00, U 0x00, - U 0x80, U 0x00, U 0x00, U 0x1A, U 0x80, U 0x00, U 0x00, U 0x18, U 0xFC, U 0x00, U 0x00, U 0x00, U 0x80, U 0x00, U 0x00, U 0x01, U 0x00, U 0x00, U 0x40, U 0x00, + U 0x60, U 0x00, U 0x08, U 0x00, + U 0x80, U 0x00, U 0x00, U 0x1C, + U 0x80, U 0x00, U 0x00, U 0x1A, U 0x03, U 0x00, U 0x00, U 0x00, U 0x80, U 0x00, U 0x04, U 0x00, U 0x50, U 0x00, U 0x00, U 0x03, @@ -517,6 +517,7 @@ static unsigned char t3fw[30136] = { U 0x1F, U 0xFF, U 0xC4, U 0xD0, U 0x1F, U 0xFC, U 0xFF, U 0xD8, U 0x00, U 0x01, U 0x00, U 0x81, + U 0x7F, U 0xFF, U 0xFF, U 0xFF, U 0xE1, U 0x00, U 0x06, U 0x00, U 0x00, U 0x00, U 0x27, U 0x10, U 0x1F, U 0xFC, U 0xFE, U 0x30, @@ -615,70 +616,70 @@ static unsigned char t3fw[30136] = { U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x52, U 0xFC, - U 0x20, U 0x00, U 0x51, U 0xCC, - U 0x20, U 0x00, U 0x52, U 0xFC, - U 0x20, U 0x00, U 0x52, U 0xFC, - U 0x20, U 0x00, U 0x51, U 0x08, - U 0x20, U 0x00, U 0x51, U 0x08, - U 0x20, U 0x00, U 0x51, U 0x08, - U 0x20, U 0x00, U 0x4F, U 0x48, - U 0x20, U 0x00, U 0x4F, U 0x48, - U 0x20, U 0x00, U 0x4F, U 0x40, - U 0x20, U 0x00, U 0x4E, U 0xAC, - U 0x20, U 0x00, U 0x4D, U 0x54, - U 0x20, U 0x00, U 0x4B, U 0x34, - U 0x20, U 0x00, U 0x49, U 0x08, + U 0x20, U 0x00, U 0x55, U 0x08, + U 0x20, U 0x00, U 0x53, U 0xD8, + U 0x20, U 0x00, U 0x55, U 0x08, + U 0x20, U 0x00, U 0x55, U 0x08, + U 0x20, U 0x00, U 0x53, U 0x14, + U 0x20, U 0x00, U 0x53, U 0x14, + U 0x20, U 0x00, U 0x53, U 0x14, + U 0x20, U 0x00, U 0x51, U 0x54, + U 0x20, U 0x00, U 0x51, U 0x54, + U 0x20, U 0x00, U 0x51, U 0x4C, + U 0x20, U 0x00, U 0x50, U 0xB8, + U 0x20, U 0x00, U 0x4F, U 0x60, + U 0x20, U 0x00, U 0x4D, U 0x40, + U 0x20, U 0x00, U 0x4B, U 0x14, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x52, U 0xCC, - U 0x20, U 0x00, U 0x51, U 0x98, - U 0x20, U 0x00, U 0x52, U 0x3C, - U 0x20, U 0x00, U 0x52, U 0x3C, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4F, U 0x38, - U 0x20, U 0x00, U 0x4F, U 0xF0, - U 0x20, U 0x00, U 0x4C, U 0x74, - U 0x20, U 0x00, U 0x4A, U 0xE4, - U 0x20, U 0x00, U 0x48, U 0xB4, + U 0x20, U 0x00, U 0x54, U 0xD8, + U 0x20, U 0x00, U 0x53, U 0xA4, + U 0x20, U 0x00, U 0x54, U 0x48, + U 0x20, U 0x00, U 0x54, U 0x48, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x51, U 0x44, + U 0x20, U 0x00, U 0x51, U 0xFC, + U 0x20, U 0x00, U 0x4E, U 0x80, + U 0x20, U 0x00, U 0x4C, U 0xF0, + U 0x20, U 0x00, U 0x4A, U 0xC0, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x0B, U 0xE0, - U 0x20, U 0x00, U 0x38, U 0xBC, - U 0x20, U 0x00, U 0x04, U 0xC0, - U 0x20, U 0x00, U 0x44, U 0xA8, - U 0x20, U 0x00, U 0x0B, U 0xD8, - U 0x20, U 0x00, U 0x3F, U 0xB4, - U 0x20, U 0x00, U 0x03, U 0xF0, - U 0x20, U 0x00, U 0x44, U 0x68, - U 0x20, U 0x00, U 0x48, U 0x90, - U 0x20, U 0x00, U 0x3C, U 0xC4, - U 0x20, U 0x00, U 0x3B, U 0xE0, - U 0x20, U 0x00, U 0x38, U 0x38, - U 0x20, U 0x00, U 0x36, U 0xC4, - U 0x20, U 0x00, U 0x34, U 0x34, - U 0x20, U 0x00, U 0x2F, U 0x94, - U 0x20, U 0x00, U 0x3A, U 0x3C, - U 0x20, U 0x00, U 0x2B, U 0xF4, - U 0x20, U 0x00, U 0x28, U 0x28, - U 0x20, U 0x00, U 0x65, U 0x34, - U 0x20, U 0x00, U 0x23, U 0xB4, - U 0x20, U 0x00, U 0x20, U 0x94, - U 0x20, U 0x00, U 0x20, U 0x40, - U 0x20, U 0x00, U 0x1D, U 0x2C, - U 0x20, U 0x00, U 0x18, U 0x40, - U 0x20, U 0x00, U 0x15, U 0x70, - U 0x20, U 0x00, U 0x0D, U 0xEC, - U 0x20, U 0x00, U 0x0C, U 0x24, - U 0x20, U 0x00, U 0x11, U 0x34, - U 0x20, U 0x00, U 0x13, U 0x20, - U 0x20, U 0x00, U 0x41, U 0xAC, - U 0x20, U 0x00, U 0x3C, U 0x78, U 0x20, U 0x00, U 0x0B, U 0xE8, + U 0x20, U 0x00, U 0x3A, U 0xA8, + U 0x20, U 0x00, U 0x04, U 0xC0, + U 0x20, U 0x00, U 0x46, U 0xB4, + U 0x20, U 0x00, U 0x0B, U 0xE0, + U 0x20, U 0x00, U 0x41, U 0xC0, + U 0x20, U 0x00, U 0x03, U 0xF0, + U 0x20, U 0x00, U 0x46, U 0x74, + U 0x20, U 0x00, U 0x4A, U 0x9C, + U 0x20, U 0x00, U 0x3E, U 0xCC, + U 0x20, U 0x00, U 0x3D, U 0xE8, + U 0x20, U 0x00, U 0x3A, U 0x24, + U 0x20, U 0x00, U 0x38, U 0xB4, + U 0x20, U 0x00, U 0x36, U 0x24, + U 0x20, U 0x00, U 0x31, U 0x84, + U 0x20, U 0x00, U 0x3C, U 0x44, + U 0x20, U 0x00, U 0x2D, U 0xB0, + U 0x20, U 0x00, U 0x28, U 0x44, + U 0x20, U 0x00, U 0x67, U 0x8C, + U 0x20, U 0x00, U 0x23, U 0xD0, + U 0x20, U 0x00, U 0x20, U 0xB0, + U 0x20, U 0x00, U 0x20, U 0x5C, + U 0x20, U 0x00, U 0x1D, U 0x48, + U 0x20, U 0x00, U 0x18, U 0x40, + U 0x20, U 0x00, U 0x15, U 0x68, + U 0x20, U 0x00, U 0x0E, U 0x4C, + U 0x20, U 0x00, U 0x0C, U 0x2C, + U 0x20, U 0x00, U 0x11, U 0x2C, + U 0x20, U 0x00, U 0x13, U 0x18, + U 0x20, U 0x00, U 0x43, U 0xB8, + U 0x20, U 0x00, U 0x3E, U 0x80, + U 0x20, U 0x00, U 0x0B, U 0xF0, U 0x20, U 0x00, U 0x04, U 0xC0, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, @@ -850,22 +851,22 @@ static unsigned char t3fw[30136] = { U 0x0B, U 0xBB, U 0x90, U 0x00, U 0x53, U 0x00, U 0x00, U 0x00, U 0x63, U 0xFF, U 0xFC, U 0x00, - U 0x20, U 0x00, U 0x69, U 0x64, + U 0x20, U 0x00, U 0x6B, U 0xC4, U 0x10, U 0xFF, U 0xFF, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x69, U 0x88, + U 0x20, U 0x00, U 0x6B, U 0xE8, U 0x00, U 0xD2, U 0x31, U 0x10, U 0xFF, U 0xFE, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x69, U 0xD0, + U 0x20, U 0x00, U 0x6C, U 0x30, U 0x00, U 0xD3, U 0x31, U 0x10, U 0xFF, U 0xFE, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x6A, U 0x10, + U 0x20, U 0x00, U 0x6C, U 0x70, U 0x00, U 0xD4, U 0x31, U 0x10, U 0xFF, U 0xFE, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x6A, U 0x84, + U 0x20, U 0x00, U 0x6C, U 0xE4, U 0x00, U 0xD5, U 0x31, U 0x10, U 0xFF, U 0xFE, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, @@ -892,8 +893,8 @@ static unsigned char t3fw[30136] = { U 0xFA, U 0xD3, U 0x0F, U 0x77, U 0x6B, U 0x06, U 0x90, U 0x60, U 0xB4, U 0x66, U 0x77, U 0x63, - U 0xF8, U 0x54, U 0x15, U 0x50, - U 0x54, U 0x19, U 0xE6, U 0x0F, + U 0xF8, U 0x54, U 0x15, U 0xD3, + U 0x54, U 0x1A, U 0x7E, U 0x0F, U 0x14, U 0x00, U 0x63, U 0xFF, U 0xF9, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, @@ -949,118 +950,119 @@ static unsigned char t3fw[30136] = { U 0x86, U 0x38, U 0x76, U 0xC0, U 0xDA, U 0x63, U 0xFF, U 0xD4, U 0x6C, U 0x10, U 0x12, U 0x16, - U 0xEE, U 0xD8, U 0xC1, U 0xF8, - U 0xC1, U 0xE7, U 0x2B, U 0x22, - U 0x1E, U 0x2C, U 0x22, U 0x1D, - U 0xC0, U 0xD0, U 0x7B, U 0xC1, - U 0x2F, U 0x29, U 0x20, U 0x06, - U 0xD7, U 0xB0, U 0x29, U 0x9C, - U 0xFA, U 0xCC, U 0x57, U 0x28, - U 0x20, U 0x70, U 0x28, U 0x8C, - U 0xFF, U 0x28, U 0x24, U 0x70, + U 0xEE, U 0xD8, U 0xC1, U 0xF9, + U 0xC1, U 0xE8, U 0xC1, U 0xC7, + U 0x2B, U 0x22, U 0x1E, U 0x28, + U 0x22, U 0x1D, U 0xC0, U 0xD0, + U 0x7B, U 0x81, U 0x31, U 0x29, + U 0x20, U 0x06, U 0x0B, U 0xB7, + U 0x02, U 0x29, U 0x9C, U 0xFA, + U 0x65, U 0x50, U 0x08, U 0x28, + U 0x20, U 0x72, U 0x28, U 0x8C, + U 0xFF, U 0x28, U 0x24, U 0x72, U 0x64, U 0x91, U 0x5C, U 0x2A, - U 0xB0, U 0x00, U 0x0E, U 0xA8, + U 0xB0, U 0x00, U 0x0C, U 0xA8, U 0x0C, U 0x64, U 0x81, U 0x67, - U 0x0F, U 0xA9, U 0x0C, U 0x64, - U 0x92, U 0xB3, U 0xC1, U 0xE9, - U 0x7E, U 0xA1, U 0x39, U 0x69, - U 0xAC, U 0x2F, U 0x60, U 0x00, - U 0x36, U 0x29, U 0x20, U 0x06, - U 0xD7, U 0xD0, U 0x29, U 0x9C, - U 0xFA, U 0xCC, U 0x57, U 0x28, - U 0x20, U 0x70, U 0x28, U 0x8C, - U 0xFF, U 0x28, U 0x24, U 0x70, - U 0x64, U 0x91, U 0x35, U 0x2A, - U 0xD0, U 0x00, U 0x0E, U 0xA8, - U 0x0C, U 0x64, U 0x81, U 0x64, - U 0x0F, U 0xA9, U 0x0C, U 0x64, - U 0x93, U 0x1B, U 0xC1, U 0xE9, - U 0x7E, U 0xA1, U 0x09, U 0x68, - U 0xAC, U 0x09, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0x00, U 0x00, + U 0x0E, U 0xA9, U 0x0C, U 0x64, + U 0x92, U 0xB3, U 0x7F, U 0xA1, + U 0x37, U 0x69, U 0xAC, U 0x2F, + U 0x60, U 0x00, U 0x34, U 0x00, + U 0x00, U 0x28, U 0x20, U 0x06, + U 0xD7, U 0xD0, U 0x28, U 0x8C, + U 0xFA, U 0xCC, U 0x57, U 0x2A, + U 0x20, U 0x72, U 0x2A, U 0xAC, + U 0xFF, U 0x2A, U 0x24, U 0x72, + U 0x64, U 0x81, U 0x35, U 0x2A, + U 0xD0, U 0x00, U 0x0C, U 0xA9, + U 0x0C, U 0x64, U 0x91, U 0x64, + U 0x0E, U 0xAC, U 0x0C, U 0x64, + U 0xC3, U 0x1B, U 0x7F, U 0xA1, + U 0x07, U 0x68, U 0xAC, U 0x07, + U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x2D, U 0x25, U 0x02, U 0x8A, U 0x32, U 0xC0, U 0x90, - U 0x0A, U 0x6F, U 0x50, U 0x65, - U 0xF5, U 0xAD, U 0x29, U 0x24, - U 0x67, U 0x09, U 0x08, U 0x47, - U 0x65, U 0x85, U 0xA9, U 0x2F, - U 0x20, U 0x0C, U 0x18, U 0xEE, - U 0xB5, U 0x0C, U 0xFE, U 0x11, - U 0xA8, U 0xEE, U 0x28, U 0xE2, - U 0x86, U 0xB4, U 0x49, U 0x78, - U 0x93, U 0x02, U 0x60, U 0x05, - U 0x7A, U 0x19, U 0xEE, U 0xB1, - U 0x09, U 0xF9, U 0x0A, U 0x29, + U 0x0A, U 0x6E, U 0x50, U 0x65, + U 0xE5, U 0xB5, U 0x29, U 0x24, + U 0x67, U 0x09, U 0x0F, U 0x47, + U 0x65, U 0xF5, U 0xB1, U 0x2C, + U 0x20, U 0x0C, U 0x1F, U 0xEE, + U 0xB5, U 0x0C, U 0xCE, U 0x11, + U 0xAF, U 0xEE, U 0x29, U 0xE2, + U 0x86, U 0xB4, U 0x48, U 0x79, + U 0x83, U 0x02, U 0x60, U 0x05, + U 0x82, U 0x19, U 0xEE, U 0xB1, + U 0x09, U 0xC9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, - U 0x07, U 0x88, U 0x20, U 0x09, - U 0x88, U 0x0C, U 0x65, U 0x85, - U 0x66, U 0x27, U 0xE2, U 0x85, - U 0x64, U 0x75, U 0x60, U 0x65, - U 0x55, U 0x8E, U 0x7B, U 0xC1, - U 0x04, U 0xD9, U 0xB0, U 0x60, - U 0x00, U 0x01, U 0xC0, U 0x90, - U 0x8B, U 0x94, U 0x1C, U 0xEE, - U 0xA8, U 0x0B, U 0x88, U 0x14, - U 0x8C, U 0xC4, U 0x0B, U 0x0B, - U 0x47, U 0xA8, U 0xCC, U 0x18, - U 0xEE, U 0xA6, U 0x09, U 0xBB, - U 0x10, U 0x08, U 0xCC, U 0x02, - U 0x9C, U 0x70, U 0x18, U 0xEE, - U 0xA4, U 0x1C, U 0xEE, U 0xA5, + U 0x07, U 0x8F, U 0x20, U 0x09, + U 0xFF, U 0x0C, U 0x65, U 0xF5, + U 0x6E, U 0x2F, U 0xE2, U 0x85, + U 0x64, U 0xF5, U 0x68, U 0x65, + U 0x55, U 0x96, U 0x28, U 0x22, + U 0x1D, U 0x7B, U 0x81, U 0x05, + U 0xD9, U 0xB0, U 0x60, U 0x00, + U 0x02, U 0x00, U 0xC0, U 0x90, + U 0x8B, U 0x94, U 0x17, U 0xEE, + U 0xA7, U 0x0B, U 0x88, U 0x14, + U 0x87, U 0x74, U 0x0B, U 0x0B, + U 0x47, U 0xA8, U 0x77, U 0x18, + U 0xEE, U 0xA5, U 0x09, U 0xBB, + U 0x10, U 0x08, U 0x77, U 0x02, + U 0x97, U 0xF0, U 0x18, U 0xEE, + U 0xA3, U 0x17, U 0xEE, U 0xA4, U 0x08, U 0xA8, U 0x01, U 0x0B, - U 0x88, U 0x02, U 0x0C, U 0x4C, - U 0x02, U 0x1B, U 0xEE, U 0xA1, - U 0x9C, U 0x71, U 0x0B, U 0x88, - U 0x02, U 0x98, U 0x72, U 0x2C, + U 0x88, U 0x02, U 0x07, U 0x47, + U 0x02, U 0x1B, U 0xEE, U 0xA0, + U 0x97, U 0xF1, U 0x0B, U 0x88, + U 0x02, U 0x98, U 0xF2, U 0x27, U 0x90, U 0x23, U 0x2B, U 0x90, - U 0x22, U 0x04, U 0xC8, U 0x10, - U 0x06, U 0xBB, U 0x10, U 0x0C, - U 0x4C, U 0x12, U 0x08, U 0xBB, + U 0x22, U 0x04, U 0x78, U 0x10, + U 0x06, U 0xBB, U 0x10, U 0x07, + U 0x47, U 0x12, U 0x08, U 0xBB, U 0x02, U 0x28, U 0x90, U 0x21, - U 0x07, U 0xCC, U 0x10, U 0x0C, - U 0x88, U 0x10, U 0x0C, U 0x88, + U 0x07, U 0x77, U 0x10, U 0x0C, + U 0x88, U 0x10, U 0x07, U 0x88, U 0x02, U 0x0B, U 0x88, U 0x02, - U 0x1C, U 0xEE, U 0x99, U 0x8B, - U 0x33, U 0x0C, U 0xBB, U 0x01, - U 0x8C, U 0x34, U 0x0B, U 0x88, - U 0x02, U 0x98, U 0x73, U 0x9C, - U 0x99, U 0x9C, U 0x74, U 0x8B, - U 0x95, U 0x8C, U 0x39, U 0x9B, - U 0x75, U 0x88, U 0x96, U 0x8B, - U 0x38, U 0x98, U 0x76, U 0x88, - U 0x97, U 0x9C, U 0x79, U 0x9B, - U 0x78, U 0x98, U 0x77, U 0x1C, - U 0xEE, U 0x90, U 0x28, U 0xE2, - U 0x85, U 0x0C, U 0xFC, U 0x08, - U 0x2D, U 0xC4, U 0xCF, U 0x08, + U 0x17, U 0xEE, U 0x98, U 0x8B, + U 0x33, U 0x07, U 0xBB, U 0x01, + U 0x87, U 0x34, U 0x0B, U 0x88, + U 0x02, U 0x98, U 0xF3, U 0x97, + U 0x99, U 0x97, U 0xF4, U 0x8B, + U 0x95, U 0x87, U 0x39, U 0x9B, + U 0xF5, U 0x88, U 0x96, U 0x8B, + U 0x38, U 0x98, U 0xF6, U 0x88, + U 0x97, U 0x97, U 0xF9, U 0x9B, + U 0xF8, U 0x98, U 0xF7, U 0x17, + U 0xEE, U 0x8F, U 0x28, U 0xE2, + U 0x85, U 0x07, U 0xC7, U 0x08, + U 0x2D, U 0x74, U 0xCF, U 0x08, U 0x48, U 0x0B, U 0x28, U 0xE6, - U 0x85, U 0x65, U 0x55, U 0x0B, - U 0x2B, U 0x22, U 0x1E, U 0x2D, - U 0x22, U 0x1D, U 0x7B, U 0xD9, + U 0x85, U 0x65, U 0x55, U 0x0F, + U 0x2B, U 0x22, U 0x1E, U 0x28, + U 0x22, U 0x1D, U 0x7B, U 0x89, U 0x02, U 0x2B, U 0x0A, U 0x00, - U 0x64, U 0xBF, U 0x06, U 0x2C, + U 0x64, U 0xBF, U 0x04, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x06, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xC0, U 0xD1, U 0x0B, U 0x80, U 0x00, U 0xDB, U 0xA0, U 0x65, U 0xAF, U 0xE7, U 0x63, - U 0xFE, U 0xEB, U 0x00, U 0x00, - U 0x29, U 0x20, U 0x70, U 0x65, + U 0xFE, U 0xE9, U 0x00, U 0x00, + U 0x29, U 0x20, U 0x72, U 0x65, U 0x9E, U 0x9C, U 0x60, U 0x04, - U 0xE4, U 0x2A, U 0x20, U 0x70, + U 0xE7, U 0x2A, U 0x20, U 0x72, U 0x65, U 0xAE, U 0xC3, U 0x60, - U 0x04, U 0xDB, U 0x00, U 0x00, + U 0x04, U 0xDE, U 0x00, U 0x00, U 0x2E, U 0xB0, U 0x03, U 0x2C, U 0x20, U 0x67, U 0xD4, U 0xE0, U 0x65, U 0xC1, U 0x05, U 0x8A, U 0x32, U 0x8C, U 0x33, U 0x0A, U 0xFF, U 0x50, U 0x0C, U 0x45, U 0x54, U 0xBC, U 0x55, U 0x64, - U 0xF4, U 0xE6, U 0x19, U 0xEE, - U 0x75, U 0x88, U 0x2A, U 0x09, + U 0xF4, U 0xEB, U 0x19, U 0xEE, + U 0x74, U 0x88, U 0x2A, U 0x09, U 0xA9, U 0x01, U 0x09, U 0x88, - U 0x0C, U 0x64, U 0x82, U 0x1B, + U 0x0C, U 0x64, U 0x82, U 0x1F, U 0xC0, U 0x92, U 0x60, U 0x00, U 0xDD, U 0x2E, U 0xD0, U 0x03, U 0x2A, U 0x20, U 0x67, U 0xD4, @@ -1068,11 +1070,11 @@ static unsigned char t3fw[30136] = { U 0x8A, U 0x32, U 0x8B, U 0x33, U 0x0A, U 0xFC, U 0x50, U 0x0B, U 0x45, U 0x54, U 0xBC, U 0x55, - U 0x64, U 0xC4, U 0xB9, U 0x19, - U 0xEE, U 0x6A, U 0x88, U 0x2A, + U 0x64, U 0xC4, U 0xBE, U 0x19, + U 0xEE, U 0x69, U 0x88, U 0x2A, U 0x09, U 0xA9, U 0x01, U 0x79, U 0x89, U 0xD5, U 0x0B, U 0xEA, - U 0x50, U 0x64, U 0xA4, U 0xDD, + U 0x50, U 0x64, U 0xA4, U 0xE3, U 0x0C, U 0xEE, U 0x11, U 0xC0, U 0xF0, U 0x2F, U 0x16, U 0x13, U 0x2E, U 0x16, U 0x16, U 0x8A, @@ -1081,7 +1083,7 @@ static unsigned char t3fw[30136] = { U 0xDF, U 0xC0, U 0xAA, U 0xEA, U 0x7E, U 0xAB, U 0x01, U 0xB1, U 0xCF, U 0x0B, U 0xA8, U 0x50, - U 0x65, U 0x83, U 0x42, U 0x88, + U 0x65, U 0x83, U 0x46, U 0x88, U 0x37, U 0xDB, U 0xC0, U 0xAE, U 0x89, U 0x99, U 0x1E, U 0x78, U 0x9B, U 0x02, U 0x2B, U 0xCC, @@ -1091,12 +1093,12 @@ static unsigned char t3fw[30136] = { U 0x1A, U 0x7F, U 0xC3, U 0x07, U 0x7F, U 0xC9, U 0x02, U 0x7E, U 0xAB, U 0x01, U 0xC0, U 0xB1, - U 0x65, U 0xB4, U 0x98, U 0x8B, + U 0x65, U 0xB4, U 0x9D, U 0x8B, U 0x35, U 0x2F, U 0x0A, U 0x00, U 0x2A, U 0x0A, U 0x00, U 0x7A, U 0xC3, U 0x05, U 0x64, U 0xC3, - U 0xC7, U 0x2F, U 0x0A, U 0x01, - U 0x65, U 0xF4, U 0x84, U 0x2B, + U 0xCB, U 0x2F, U 0x0A, U 0x01, + U 0x65, U 0xF4, U 0x89, U 0x2B, U 0x12, U 0x16, U 0x2B, U 0x16, U 0x19, U 0x00, U 0x51, U 0x04, U 0xC0, U 0xC1, U 0x00, U 0xCC, @@ -1105,7 +1107,7 @@ static unsigned char t3fw[30136] = { U 0xFC, U 0x13, U 0x2C, U 0x16, U 0x18, U 0x2B, U 0x12, U 0x1A, U 0x2A, U 0x12, U 0x1B, U 0xDC, - U 0x50, U 0x58, U 0x18, U 0xFA, + U 0x50, U 0x58, U 0x19, U 0x91, U 0xC0, U 0xD0, U 0xC0, U 0x90, U 0x2E, U 0x5C, U 0xF4, U 0x2C, U 0x12, U 0x17, U 0x28, U 0x12, @@ -1122,25 +1124,25 @@ static unsigned char t3fw[30136] = { U 0x03, U 0x89, U 0x75, U 0xB1, U 0xEA, U 0x2A, U 0x74, U 0x03, U 0xB0, U 0x99, U 0x09, U 0x49, - U 0x0C, U 0x65, U 0x9D, U 0xB5, + U 0x0C, U 0x65, U 0x9D, U 0xB3, U 0x2B, U 0x20, U 0x67, U 0x2D, U 0x25, U 0x02, U 0x65, U 0xB3, - U 0xF4, U 0x2B, U 0x22, U 0x1E, + U 0xFA, U 0x2B, U 0x22, U 0x1E, U 0x2C, U 0x22, U 0x1D, U 0x7B, U 0xC9, U 0x01, U 0xC0, U 0xB0, - U 0x64, U 0xBD, U 0x9E, U 0x2C, + U 0x64, U 0xBD, U 0x9C, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x06, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xC0, U 0xD1, U 0x0B, U 0x80, U 0x00, U 0xDB, U 0xA0, U 0x65, U 0xAF, U 0xE7, U 0x63, - U 0xFD, U 0x83, U 0x89, U 0xBA, + U 0xFD, U 0x81, U 0x89, U 0xBA, U 0xB1, U 0x99, U 0x65, U 0x90, U 0x97, U 0x88, U 0x34, U 0x1C, - U 0xEE, U 0x26, U 0x98, U 0xBA, + U 0xEE, U 0x25, U 0x98, U 0xBA, U 0x8F, U 0x33, U 0x1E, U 0xEE, - U 0x1F, U 0x0F, U 0x4F, U 0x54, + U 0x1E, U 0x0F, U 0x4F, U 0x54, U 0x2F, U 0xB4, U 0x2C, U 0x8D, U 0x2A, U 0x8A, U 0x32, U 0x0E, U 0xDD, U 0x02, U 0x0C, U 0xAC, @@ -1154,7 +1156,7 @@ static unsigned char t3fw[30136] = { U 0x0C, U 0x41, U 0x7D, U 0xC9, U 0x49, U 0x2E, U 0xB0, U 0x12, U 0xB0, U 0xEE, U 0x65, U 0xE3, - U 0xC2, U 0xC0, U 0xD0, U 0x8E, + U 0xC6, U 0xC0, U 0xD0, U 0x8E, U 0x37, U 0x8C, U 0xB8, U 0x8A, U 0x36, U 0x8F, U 0xB9, U 0x7C, U 0xA3, U 0x07, U 0x7A, U 0xC9, @@ -1170,34 +1172,35 @@ static unsigned char t3fw[30136] = { U 0xB0, U 0x7D, U 0xA3, U 0x07, U 0x7A, U 0xD9, U 0x02, U 0x7C, U 0xEB, U 0x01, U 0xC0, U 0xB1, - U 0x64, U 0xB1, U 0x5D, U 0xC0, + U 0x64, U 0xB1, U 0x61, U 0xC0, U 0x91, U 0x29, U 0x24, U 0x67, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x8A, U 0xDA, U 0xB1, U 0xAA, U 0x64, U 0xA0, - U 0xBC, U 0x2E, U 0x20, U 0x67, + U 0xC0, U 0x2C, U 0x20, U 0x67, U 0x2D, U 0x25, U 0x02, U 0x65, - U 0xE3, U 0x0B, U 0x1F, U 0xED, - U 0xF9, U 0x8A, U 0x32, U 0x18, - U 0xED, U 0xFE, U 0x0F, U 0xAF, - U 0x01, U 0x08, U 0xFF, U 0x0C, - U 0x65, U 0xF2, U 0x86, U 0x0A, - U 0x48, U 0x51, U 0x6F, U 0x82, - U 0x02, U 0x60, U 0x02, U 0x7D, + U 0xC3, U 0x11, U 0x1D, U 0xED, + U 0xF8, U 0x8A, U 0x32, U 0x1E, + U 0xED, U 0xFD, U 0x0D, U 0xAD, + U 0x01, U 0x0E, U 0xDD, U 0x0C, + U 0x65, U 0xD2, U 0x8A, U 0x0A, + U 0x4E, U 0x51, U 0x6F, U 0xE2, + U 0x02, U 0x60, U 0x02, U 0x81, U 0xC0, U 0x90, U 0x29, U 0x24, - U 0x67, U 0x09, U 0x0A, U 0x47, - U 0x65, U 0xA2, U 0xF2, U 0x7B, - U 0xC9, U 0x01, U 0xC0, U 0xB0, - U 0x64, U 0xBC, U 0xAE, U 0x2C, + U 0x67, U 0x09, U 0x0F, U 0x47, + U 0x65, U 0xF2, U 0xF8, U 0x28, + U 0x22, U 0x1D, U 0x7B, U 0x89, + U 0x02, U 0x2B, U 0x0A, U 0x00, + U 0x64, U 0xBC, U 0xA8, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x06, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xC0, U 0xD1, U 0x0B, U 0x80, U 0x00, U 0xDB, U 0xA0, U 0x65, U 0xAF, U 0xE7, U 0x63, - U 0xFC, U 0x93, U 0x00, U 0x00, + U 0xFC, U 0x8D, U 0x00, U 0x00, U 0x0C, U 0xE9, U 0x50, U 0x64, - U 0x92, U 0xEB, U 0x0C, U 0xEF, + U 0x92, U 0xED, U 0x0C, U 0xEF, U 0x11, U 0xC0, U 0x80, U 0x28, U 0x16, U 0x11, U 0xAF, U 0xBF, U 0x2F, U 0x16, U 0x19, U 0x8E, @@ -1216,31 +1219,31 @@ static unsigned char t3fw[30136] = { U 0x1A, U 0x7A, U 0xE3, U 0x07, U 0x7A, U 0xE9, U 0x02, U 0x7F, U 0xBB, U 0x01, U 0xC0, U 0xC1, - U 0x65, U 0xC2, U 0xA4, U 0x8B, + U 0x65, U 0xC2, U 0xA5, U 0x8B, U 0x35, U 0x2C, U 0x0A, U 0x00, U 0x2A, U 0x0A, U 0x00, U 0x7A, U 0xE3, U 0x05, U 0x64, U 0xE1, U 0xCA, U 0x2C, U 0x0A, U 0x01, - U 0x64, U 0xCE, U 0x11, U 0x60, - U 0x02, U 0x8D, U 0x88, U 0x34, - U 0x1B, U 0xED, U 0xD1, U 0x98, + U 0x64, U 0xCE, U 0x0D, U 0x60, + U 0x02, U 0x8E, U 0x88, U 0x34, + U 0x1B, U 0xED, U 0xCF, U 0x98, U 0xDA, U 0x8F, U 0x33, U 0x1E, - U 0xED, U 0xCA, U 0x0F, U 0x4F, + U 0xED, U 0xC8, U 0x0F, U 0x4F, U 0x54, U 0x2F, U 0xD4, U 0x2C, U 0x8C, U 0x2A, U 0x8A, U 0x32, U 0x0E, U 0xCC, U 0x02, U 0x0B, U 0xAB, U 0x01, U 0x0C, U 0xBB, - U 0x0C, U 0x65, U 0xBF, U 0x0E, + U 0x0C, U 0x65, U 0xBF, U 0x0A, U 0x0A, U 0x49, U 0x51, U 0x6E, U 0x92, U 0x02, U 0x63, U 0xFF, - U 0x05, U 0x8A, U 0x33, U 0x0A, + U 0x01, U 0x8A, U 0x33, U 0x0A, U 0xAB, U 0x50, U 0x64, U 0xBE, - U 0xFD, U 0x2C, U 0xD0, U 0x13, + U 0xF9, U 0x2C, U 0xD0, U 0x13, U 0x0A, U 0xEE, U 0x51, U 0x0E, U 0xCE, U 0x01, U 0x0E, U 0x0E, U 0x41, U 0x0C, U 0x0C, U 0x41, U 0x0E, U 0xCC, U 0x0C, U 0x65, - U 0xCE, U 0xE8, U 0x2F, U 0xD0, + U 0xCE, U 0xE4, U 0x2F, U 0xD0, U 0x12, U 0xB0, U 0xFF, U 0x65, U 0xF2, U 0x6E, U 0xC0, U 0xB0, U 0x8E, U 0x37, U 0x8C, U 0xD8, @@ -1248,7 +1251,7 @@ static unsigned char t3fw[30136] = { U 0x09, U 0x7C, U 0xA3, U 0x07, U 0x7A, U 0xC9, U 0x02, U 0x7E, U 0xFB, U 0x01, U 0xC0, U 0xB1, - U 0x65, U 0xBE, U 0xC7, U 0x88, + U 0x65, U 0xBE, U 0xC3, U 0x88, U 0x35, U 0xDB, U 0xA0, U 0xAE, U 0x8E, U 0x78, U 0xEB, U 0x01, U 0xB1, U 0xAB, U 0x89, U 0xD7, @@ -1258,7 +1261,7 @@ static unsigned char t3fw[30136] = { U 0xA3, U 0x07, U 0x7A, U 0xB9, U 0x02, U 0x7D, U 0xEB, U 0x01, U 0xC0, U 0xC1, U 0x65, U 0xCE, - U 0xA1, U 0xC0, U 0x90, U 0x29, + U 0x9D, U 0xC0, U 0x90, U 0x29, U 0x24, U 0x67, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x88, U 0x37, U 0x8C, U 0x36, U 0x98, U 0x14, @@ -1276,7 +1279,7 @@ static unsigned char t3fw[30136] = { U 0x7A, U 0xE9, U 0x06, U 0x88, U 0x15, U 0x8E, U 0x16, U 0x78, U 0xEB, U 0x01, U 0xC0, U 0xF1, - U 0x65, U 0xF1, U 0xB9, U 0x29, + U 0x65, U 0xF1, U 0xBA, U 0x29, U 0x12, U 0x1A, U 0x2F, U 0x12, U 0x11, U 0x8A, U 0x35, U 0x2E, U 0x12, U 0x1B, U 0x9A, U 0x1A, @@ -1290,7 +1293,7 @@ static unsigned char t3fw[30136] = { U 0x2A, U 0x12, U 0x01, U 0x7A, U 0x8B, U 0x01, U 0xC0, U 0xF1, U 0x64, U 0xF0, U 0x81, U 0x60, - U 0x01, U 0x82, U 0x89, U 0x36, + U 0x01, U 0x83, U 0x89, U 0x36, U 0x8B, U 0x37, U 0x99, U 0x17, U 0x0B, U 0xE8, U 0x0C, U 0x98, U 0x1F, U 0x09, U 0xC9, U 0x0C, @@ -1307,7 +1310,7 @@ static unsigned char t3fw[30136] = { U 0x7F, U 0xA9, U 0x06, U 0x88, U 0x18, U 0x8F, U 0x19, U 0x78, U 0xFB, U 0x01, U 0xC0, U 0xE1, - U 0x65, U 0xE1, U 0x3D, U 0x29, + U 0x65, U 0xE1, U 0x3E, U 0x29, U 0x12, U 0x1A, U 0x2F, U 0x12, U 0x13, U 0x8A, U 0x35, U 0x2E, U 0x12, U 0x1B, U 0x9A, U 0x1B, @@ -1320,7 +1323,7 @@ static unsigned char t3fw[30136] = { U 0x0A, U 0x7E, U 0xA9, U 0x05, U 0x2A, U 0x12, U 0x03, U 0x7A, U 0x8B, U 0x01, U 0xC0, U 0xF1, - U 0x65, U 0xF1, U 0x09, U 0x2E, + U 0x65, U 0xF1, U 0x0A, U 0x2E, U 0x12, U 0x16, U 0x2E, U 0x16, U 0x19, U 0x2A, U 0x12, U 0x1B, U 0x00, U 0x51, U 0x04, U 0xC0, @@ -1334,74 +1337,74 @@ static unsigned char t3fw[30136] = { U 0x7F, U 0xCB, U 0x01, U 0xB1, U 0xAA, U 0x2A, U 0x16, U 0x1B, U 0x2C, U 0x16, U 0x1A, U 0x63, - U 0xFC, U 0x62, U 0x00, U 0x00, + U 0xFC, U 0x5E, U 0x00, U 0x00, U 0x7F, U 0xB3, U 0x02, U 0x63, U 0xFE, U 0x31, U 0x63, U 0xFE, U 0x2B, U 0x7E, U 0xB3, U 0x02, - U 0x63, U 0xFC, U 0x34, U 0x63, - U 0xFC, U 0x2E, U 0x00, U 0x00, + U 0x63, U 0xFC, U 0x30, U 0x63, + U 0xFC, U 0x2A, U 0x00, U 0x00, U 0x64, U 0x50, U 0xC0, U 0xDA, - U 0x20, U 0xDB, U 0xF0, U 0x58, - U 0x15, U 0xDE, U 0xC0, U 0x20, + U 0x20, U 0xDB, U 0xC0, U 0x58, + U 0x16, U 0x65, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xC0, U 0x91, - U 0x63, U 0xFD, U 0x7E, U 0x00, + U 0x63, U 0xFD, U 0x7A, U 0x00, U 0xC0, U 0x91, U 0x63, U 0xFA, - U 0x4C, U 0xDA, U 0x20, U 0xDB, + U 0x44, U 0xDA, U 0x20, U 0xDB, U 0x70, U 0xC0, U 0xD1, U 0x2E, U 0x0A, U 0x80, U 0xC0, U 0x9A, U 0x29, U 0x24, U 0x68, U 0x2C, - U 0x70, U 0x07, U 0x58, U 0x14, - U 0xCE, U 0xD2, U 0xA0, U 0xD1, - U 0x0F, U 0x03, U 0x4C, U 0x0B, - U 0x18, U 0xED, U 0x51, U 0xDB, - U 0xC0, U 0xA8, U 0x28, U 0x78, - U 0xC3, U 0x02, U 0x2B, U 0xCD, + U 0x70, U 0x07, U 0x58, U 0x15, + U 0x55, U 0xD2, U 0xA0, U 0xD1, + U 0x0F, U 0x03, U 0x47, U 0x0B, + U 0x18, U 0xED, U 0x4F, U 0xDB, + U 0x70, U 0xA8, U 0x28, U 0x78, + U 0x73, U 0x02, U 0x2B, U 0x7D, U 0xF8, U 0xD9, U 0xB0, U 0x63, - U 0xFA, U 0x65, U 0x00, U 0x00, + U 0xFA, U 0x61, U 0x00, U 0x00, U 0x2A, U 0x2C, U 0x74, U 0xDB, - U 0x40, U 0x58, U 0x0E, U 0x50, - U 0x63, U 0xFA, U 0xE8, U 0x00, - U 0x00, U 0x00, U 0x2D, U 0x25, - U 0x02, U 0x7B, U 0xC9, U 0x01, - U 0xC0, U 0xB0, U 0x64, U 0xB0, - U 0x17, U 0x2C, U 0xB0, U 0x07, - U 0x28, U 0xB0, U 0x00, U 0xDA, - U 0x20, U 0x06, U 0x88, U 0x0A, - U 0x28, U 0x82, U 0x4C, U 0xC0, - U 0xD1, U 0x0B, U 0x80, U 0x00, - U 0xDB, U 0xA0, U 0x65, U 0xAF, - U 0xE7, U 0xC0, U 0x20, U 0xD1, - U 0x0F, U 0xC0, U 0x91, U 0x63, - U 0xFC, U 0x04, U 0x02, U 0x2A, - U 0x02, U 0x58, U 0x02, U 0x50, - U 0x0A, U 0xA2, U 0x02, U 0x06, - U 0x00, U 0x00, U 0x02, U 0x2A, - U 0x02, U 0x58, U 0x02, U 0x4D, - U 0x0A, U 0xA2, U 0x02, U 0x06, - U 0x00, U 0x00, U 0xDB, U 0x70, - U 0xDA, U 0x20, U 0xC0, U 0xD1, - U 0x2E, U 0x0A, U 0x80, U 0xC0, - U 0x9E, U 0x29, U 0x24, U 0x68, - U 0x2C, U 0x70, U 0x07, U 0x58, - U 0x14, U 0xAE, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0xC0, U 0x94, - U 0x63, U 0xFB, U 0xCF, U 0x00, - U 0xC0, U 0x96, U 0x63, U 0xFB, + U 0x40, U 0x58, U 0x0E, U 0xD1, + U 0x63, U 0xFA, U 0xE4, U 0x00, + U 0x00, U 0x29, U 0x22, U 0x1D, + U 0x2D, U 0x25, U 0x02, U 0x7B, + U 0x99, U 0x01, U 0xC0, U 0xB0, + U 0xC9, U 0xB6, U 0x2C, U 0xB0, + U 0x07, U 0x28, U 0xB0, U 0x00, + U 0xDA, U 0x20, U 0x06, U 0x88, + U 0x0A, U 0x28, U 0x82, U 0x4C, + U 0xC0, U 0xD1, U 0x0B, U 0x80, + U 0x00, U 0xDB, U 0xA0, U 0x65, + U 0xAF, U 0xE7, U 0xC0, U 0x20, + U 0xD1, U 0x0F, U 0xC0, U 0x91, + U 0x63, U 0xFB, U 0xFF, U 0x00, + U 0x02, U 0x2A, U 0x02, U 0x58, + U 0x02, U 0x4C, U 0x0A, U 0xA2, + U 0x02, U 0x06, U 0x00, U 0x00, + U 0x02, U 0x2A, U 0x02, U 0x58, + U 0x02, U 0x49, U 0x0A, U 0xA2, + U 0x02, U 0x06, U 0x00, U 0x00, + U 0xDB, U 0x70, U 0xDA, U 0x20, + U 0xC0, U 0xD1, U 0x2E, U 0x0A, + U 0x80, U 0xC0, U 0x9E, U 0x29, + U 0x24, U 0x68, U 0x2C, U 0x70, + U 0x07, U 0x58, U 0x15, U 0x34, + U 0xC0, U 0x20, U 0xD1, U 0x0F, + U 0xC0, U 0x94, U 0x63, U 0xFB, U 0xC9, U 0xC0, U 0x96, U 0x63, - U 0xFB, U 0xC4, U 0x00, U 0x00, + U 0xFB, U 0xC4, U 0xC0, U 0x96, + U 0x63, U 0xFB, U 0xBF, U 0x00, U 0x2A, U 0x2C, U 0x74, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x5B, - U 0xFE, U 0x13, U 0xDB, U 0xA0, + U 0xFE, U 0x11, U 0xDB, U 0xA0, U 0xC2, U 0xA0, U 0x2A, U 0xB4, - U 0x00, U 0x2F, U 0x20, U 0x0C, + U 0x00, U 0x2C, U 0x20, U 0x0C, U 0x63, U 0xFF, U 0x27, U 0x00, U 0x8D, U 0x35, U 0x8C, U 0xB7, U 0x7D, U 0xCB, U 0x02, U 0x63, U 0xFD, U 0xD2, U 0x63, U 0xFC, - U 0x71, U 0x8F, U 0x35, U 0x8E, + U 0x6D, U 0x8F, U 0x35, U 0x8E, U 0xD7, U 0x7F, U 0xEB, U 0x02, U 0x63, U 0xFD, U 0xC5, U 0x63, - U 0xFC, U 0x64, U 0x00, U 0x00, + U 0xFC, U 0x60, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, @@ -1413,7 +1416,7 @@ static unsigned char t3fw[30136] = { U 0x2A, U 0x25, U 0x02, U 0x7B, U 0x89, U 0x01, U 0xDB, U 0xA0, U 0xC9, U 0xB9, U 0x13, U 0xED, - U 0x08, U 0xDA, U 0x20, U 0x28, + U 0x06, U 0xDA, U 0x20, U 0x28, U 0xB0, U 0x00, U 0x2C, U 0xB0, U 0x07, U 0x03, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xC0, @@ -1421,35 +1424,39 @@ static unsigned char t3fw[30136] = { U 0xDB, U 0xA0, U 0x65, U 0xAF, U 0xE7, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, - U 0x6C, U 0x10, U 0x04, U 0x29, + U 0x6C, U 0x10, U 0x04, U 0x2C, U 0x20, U 0x06, U 0x2A, U 0x21, - U 0x02, U 0x68, U 0x98, U 0x05, - U 0x28, U 0x9C, U 0xF9, U 0x65, - U 0x81, U 0x1A, U 0x0A, U 0x0A, - U 0x4C, U 0x65, U 0xA0, U 0xF0, - U 0x16, U 0xEC, U 0xFB, U 0x2B, - U 0x62, U 0x9E, U 0x1A, U 0xEC, - U 0xF8, U 0x6F, U 0xB8, U 0x02, - U 0x60, U 0x00, U 0xF1, U 0x2A, - U 0xA2, U 0x26, U 0x68, U 0xA0, - U 0x07, U 0x8B, U 0x20, U 0x0A, - U 0xBB, U 0x0C, U 0x65, U 0xB0, - U 0xE3, U 0x2A, U 0x62, U 0x9D, - U 0x64, U 0xA0, U 0xDD, U 0x2B, - U 0x20, U 0x0C, U 0x0C, U 0xBC, - U 0x11, U 0xA6, U 0xCC, U 0x2D, - U 0xC2, U 0x86, U 0x6F, U 0xD9, - U 0x02, U 0x60, U 0x00, U 0xD7, - U 0x1D, U 0xEC, U 0xEF, U 0x0D, + U 0x02, U 0x68, U 0xC8, U 0x05, + U 0x28, U 0xCC, U 0xF9, U 0x65, + U 0x81, U 0x2E, U 0x0A, U 0x09, + U 0x4C, U 0x65, U 0x91, U 0x04, + U 0x8F, U 0x30, U 0xC1, U 0xB8, + U 0x0F, U 0x8F, U 0x14, U 0x7F, + U 0xB0, U 0x05, U 0x28, U 0x21, + U 0x23, U 0x65, U 0x81, U 0x27, + U 0x16, U 0xEC, U 0xF5, U 0x29, + U 0x62, U 0x9E, U 0x6F, U 0x98, + U 0x02, U 0x60, U 0x00, U 0xF8, + U 0x19, U 0xEC, U 0xF1, U 0x29, + U 0x92, U 0x26, U 0x68, U 0x90, + U 0x07, U 0x8A, U 0x20, U 0x09, + U 0xAA, U 0x0C, U 0x65, U 0xA0, + U 0xE7, U 0x2A, U 0x62, U 0x9D, + U 0x64, U 0xA0, U 0xE1, U 0x2B, + U 0x20, U 0x0C, U 0x0C, U 0xB9, + U 0x11, U 0xA6, U 0x99, U 0x2D, + U 0x92, U 0x86, U 0x6F, U 0xD9, + U 0x02, U 0x60, U 0x00, U 0xDB, + U 0x1D, U 0xEC, U 0xE9, U 0x0D, U 0xBD, U 0x0A, U 0x2D, U 0xD2, U 0xA3, U 0x68, U 0xD0, U 0x07, U 0x8E, U 0x20, U 0x0D, U 0xEE, - U 0x0C, U 0x65, U 0xE0, U 0xC3, - U 0x27, U 0xC2, U 0x85, U 0xC0, - U 0xE0, U 0x64, U 0x70, U 0xBB, - U 0x1D, U 0xEC, U 0xF4, U 0x68, - U 0x43, U 0x4D, U 0x1C, U 0xEC, - U 0xF3, U 0x8A, U 0x2B, U 0x0C, + U 0x0C, U 0x65, U 0xE0, U 0xC7, + U 0x27, U 0x92, U 0x85, U 0xC0, + U 0xE0, U 0x64, U 0x70, U 0xBF, + U 0x1D, U 0xEC, U 0xEE, U 0x68, + U 0x43, U 0x4E, U 0x1C, U 0xEC, + U 0xED, U 0x8A, U 0x2B, U 0x0C, U 0xAA, U 0x02, U 0x9A, U 0x70, U 0x89, U 0x20, U 0x08, U 0x99, U 0x11, U 0x0D, U 0x99, U 0x02, @@ -1458,75 +1465,93 @@ static unsigned char t3fw[30136] = { U 0x9F, U 0x75, U 0x28, U 0x21, U 0x04, U 0x08, U 0x88, U 0x11, U 0x98, U 0x77, U 0x18, U 0xEC, - U 0xE4, U 0x0C, U 0xBF, U 0x11, + U 0xDE, U 0x0C, U 0xBF, U 0x11, U 0xA6, U 0xFF, U 0x2D, U 0xF2, U 0x85, U 0xA8, U 0xB8, U 0x2E, U 0x84, U 0xCF, U 0x2D, U 0xDC, U 0x28, U 0x2D, U 0xF6, U 0x85, U 0xC8, U 0x5A, U 0x2A, U 0x2C, U 0x74, U 0xDB, U 0x40, U 0x58, - U 0x0D, U 0xE7, U 0xD2, U 0xA0, + U 0x0E, U 0x64, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, - U 0x2C, U 0x9C, U 0xF9, U 0x64, - U 0xC0, U 0x8D, U 0x2C, U 0x20, - U 0x66, U 0x89, U 0x31, U 0xB1, - U 0xCC, U 0x0C, U 0x0C, U 0x47, - U 0x2C, U 0x24, U 0x66, U 0x6F, - U 0xC6, U 0x69, U 0x70, U 0x9E, - U 0x66, U 0x18, U 0xEC, U 0xDA, - U 0x89, U 0x30, U 0x8F, U 0x2B, - U 0x09, U 0x89, U 0x40, U 0x0B, - U 0x99, U 0x10, U 0x09, U 0xFF, - U 0x02, U 0x08, U 0xFF, U 0x02, - U 0x9F, U 0x70, U 0x8C, U 0x20, - U 0x08, U 0xCC, U 0x11, U 0x0D, - U 0xCC, U 0x02, U 0x9C, U 0x71, - U 0x8A, U 0x33, U 0x9A, U 0x73, - U 0x89, U 0x32, U 0x99, U 0x72, - U 0x88, U 0x2A, U 0x98, U 0x74, - U 0x8F, U 0x34, U 0x9F, U 0x75, - U 0x63, U 0xFF, U 0x82, U 0x00, + U 0x00, U 0x29, U 0xCC, U 0xF9, + U 0x64, U 0x90, U 0xB1, U 0x2C, + U 0x20, U 0x66, U 0x89, U 0x31, + U 0xB1, U 0xCC, U 0x0C, U 0x0C, + U 0x47, U 0x2C, U 0x24, U 0x66, + U 0x6E, U 0xC6, U 0x02, U 0x60, + U 0x00, U 0x85, U 0x09, U 0xF8, + U 0x50, U 0x65, U 0x80, U 0x7F, + U 0x1C, U 0xEC, U 0xD3, U 0x8A, + U 0x2B, U 0x0F, U 0x08, U 0x40, + U 0x0B, U 0x88, U 0x10, U 0x08, + U 0xAA, U 0x02, U 0x0C, U 0xAA, + U 0x02, U 0x9A, U 0x70, U 0x89, + U 0x20, U 0x08, U 0x99, U 0x11, + U 0x0D, U 0x99, U 0x02, U 0x99, + U 0x71, U 0x88, U 0x33, U 0x98, + U 0x73, U 0x8C, U 0x32, U 0x9C, + U 0x72, U 0x8A, U 0x2A, U 0x9A, + U 0x74, U 0x89, U 0x34, U 0x99, + U 0x75, U 0x63, U 0xFF, U 0x7D, U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x14, U 0xB8, + U 0x40, U 0x58, U 0x15, U 0x3A, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x15, U 0x47, + U 0xB6, U 0x58, U 0x15, U 0xC9, U 0x63, U 0xFF, U 0xE5, U 0x00, U 0xDA, U 0x20, U 0x58, U 0x15, - U 0x45, U 0x63, U 0xFF, U 0xDC, + U 0xC7, U 0x63, U 0xFF, U 0xDC, U 0x00, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, - U 0x50, U 0x58, U 0x15, U 0xC7, + U 0x50, U 0x58, U 0x16, U 0x55, U 0xD2, U 0xA0, U 0xD1, U 0x0F, + U 0xC8, U 0x58, U 0xDA, U 0x20, + U 0xDB, U 0x30, U 0x58, U 0x14, + U 0xA7, U 0x2A, U 0x21, U 0x02, + U 0x65, U 0xAF, U 0xBD, U 0xC0, + U 0x94, U 0x09, U 0xA9, U 0x02, + U 0x29, U 0x25, U 0x02, U 0x63, + U 0xFF, U 0xB2, U 0x00, U 0x00, U 0x2B, U 0x21, U 0x04, U 0x58, - U 0x13, U 0xDA, U 0x1D, U 0xEC, - U 0xBD, U 0x2B, U 0x20, U 0x0C, - U 0xC0, U 0xE0, U 0x2E, U 0x24, - U 0x66, U 0x63, U 0xFF, U 0x84, - U 0x2F, U 0x21, U 0x23, U 0xC0, - U 0xC8, U 0x7F, U 0xC3, U 0x02, - U 0x63, U 0xFF, U 0x79, U 0x2C, - U 0x20, U 0x66, U 0x2B, U 0x21, - U 0x04, U 0xB1, U 0xCC, U 0x0C, - U 0x0C, U 0x47, U 0x2C, U 0x24, - U 0x66, U 0x58, U 0x13, U 0xCF, - U 0x1D, U 0xEC, U 0xB3, U 0x2B, - U 0x20, U 0x0C, U 0xC0, U 0xE0, - U 0x2E, U 0x24, U 0x66, U 0x63, - U 0xFF, U 0x5A, U 0x00, U 0x00, + U 0x14, U 0x53, U 0x1D, U 0xEC, + U 0xAF, U 0xC0, U 0xE0, U 0x2E, + U 0x24, U 0x66, U 0x8F, U 0x30, + U 0x2B, U 0x20, U 0x0C, U 0x0F, + U 0x8F, U 0x14, U 0x63, U 0xFF, + U 0x66, U 0x29, U 0x21, U 0x38, + U 0xC0, U 0x88, U 0x79, U 0x83, + U 0x1F, U 0x8C, U 0x31, U 0x0C, + U 0xFC, U 0x50, U 0x64, U 0xCF, + U 0x56, U 0x2B, U 0x21, U 0x04, + U 0xC0, U 0xC0, U 0x58, U 0x14, + U 0x48, U 0x1D, U 0xEC, U 0xA4, + U 0xC0, U 0xE0, U 0x8F, U 0x30, + U 0x2B, U 0x20, U 0x0C, U 0x0F, + U 0x8F, U 0x14, U 0x63, U 0xFF, + U 0x3E, U 0x2C, U 0x20, U 0x66, + U 0x2B, U 0x21, U 0x04, U 0xB1, + U 0xCC, U 0x0C, U 0x0C, U 0x47, + U 0x2C, U 0x24, U 0x66, U 0x58, + U 0x14, U 0x40, U 0x1D, U 0xEC, + U 0x9C, U 0xC0, U 0xE0, U 0x2E, + U 0x24, U 0x66, U 0x8F, U 0x30, + U 0x2B, U 0x20, U 0x0C, U 0x0F, + U 0x8F, U 0x14, U 0x63, U 0xFF, + U 0x1A, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0xB7, U 0xC0, U 0xA1, U 0x16, - U 0xEC, U 0xB0, U 0x15, U 0xEC, - U 0xA2, U 0xD7, U 0x20, U 0xD8, + U 0xEC, U 0x98, U 0x15, U 0xEC, + U 0x8A, U 0xD7, U 0x20, U 0xD8, U 0x40, U 0xB8, U 0x22, U 0xC0, U 0x40, U 0x05, U 0x35, U 0x02, U 0x96, U 0x71, U 0x95, U 0x70, U 0x02, U 0xA4, U 0x38, U 0x04, U 0x04, U 0x42, U 0xC9, U 0x4B, - U 0x1A, U 0xEC, U 0x95, U 0x19, - U 0xEC, U 0x96, U 0x29, U 0xA6, + U 0x1A, U 0xEC, U 0x7D, U 0x19, + U 0xEC, U 0x7E, U 0x29, U 0xA6, U 0x7E, U 0xC1, U 0x40, U 0xD3, U 0x0F, U 0x6D, U 0x4A, U 0x05, U 0x00, U 0x80, U 0x88, U 0x00, @@ -1535,34 +1560,34 @@ static unsigned char t3fw[30136] = { U 0x0F, U 0xC0, U 0x50, U 0x08, U 0xA5, U 0x38, U 0x75, U 0xB0, U 0xE3, U 0x63, U 0xFF, U 0xD7, - U 0x6C, U 0x10, U 0x08, U 0x93, - U 0x14, U 0x94, U 0x12, U 0x29, + U 0x6C, U 0x10, U 0x06, U 0x93, + U 0x13, U 0x94, U 0x11, U 0x29, U 0x20, U 0x06, U 0x65, U 0x52, U 0x88, U 0xC0, U 0x71, U 0x68, U 0x98, U 0x05, U 0x2A, U 0x9C, U 0xF9, U 0x65, U 0xA2, U 0x98, - U 0x16, U 0xEC, U 0x89, U 0x29, - U 0x21, U 0x02, U 0x8A, U 0x14, + U 0x16, U 0xEC, U 0x71, U 0x29, + U 0x21, U 0x02, U 0x8A, U 0x13, U 0x09, U 0x09, U 0x4C, U 0x65, - U 0x90, U 0xC7, U 0x8A, U 0xA0, + U 0x90, U 0xCD, U 0x8A, U 0xA0, U 0x0A, U 0x6A, U 0x51, U 0x2A, U 0xAC, U 0xFD, U 0x65, U 0xA0, - U 0xBC, U 0xCC, U 0x5F, U 0xDB, + U 0xC2, U 0xCC, U 0x5F, U 0xDB, U 0x30, U 0xDA, U 0x20, U 0x8C, - U 0x12, U 0x58, U 0x14, U 0x7C, - U 0xC0, U 0x51, U 0x9A, U 0x14, + U 0x11, U 0x58, U 0x14, U 0xED, + U 0xC0, U 0x51, U 0x9A, U 0x13, U 0xC7, U 0xBF, U 0x9B, U 0xA9, - U 0x8E, U 0x14, U 0x2E, U 0xE2, + U 0x8E, U 0x13, U 0x2E, U 0xE2, U 0x09, U 0x68, U 0xE0, U 0x60, U 0x2F, U 0x62, U 0x9E, U 0x1D, - U 0xEC, U 0x7A, U 0x6F, U 0xF8, - U 0x02, U 0x60, U 0x00, U 0x81, + U 0xEC, U 0x62, U 0x6F, U 0xF8, + U 0x02, U 0x60, U 0x00, U 0x84, U 0x2D, U 0xD2, U 0x26, U 0x68, U 0xD0, U 0x05, U 0x2F, U 0x22, - U 0x00, U 0x7D, U 0xF9, U 0x75, + U 0x00, U 0x7D, U 0xF9, U 0x78, U 0x2C, U 0x62, U 0x9D, U 0xC7, - U 0x90, U 0x64, U 0xC0, U 0x6D, - U 0x9C, U 0x11, U 0x8A, U 0x14, + U 0x90, U 0x64, U 0xC0, U 0x70, + U 0x9C, U 0x10, U 0x8A, U 0x13, U 0x2B, U 0x20, U 0x0C, U 0x2A, U 0xA0, U 0x20, U 0x0C, U 0xBD, U 0x11, U 0xA6, U 0xDD, U 0x0A, @@ -1570,16 +1595,16 @@ static unsigned char t3fw[30136] = { U 0x09, U 0x88, U 0x01, U 0x29, U 0xD2, U 0x86, U 0xAF, U 0x88, U 0x28, U 0x8C, U 0x09, U 0x79, - U 0x8B, U 0x55, U 0x1F, U 0xEC, - U 0x6C, U 0x0F, U 0xBF, U 0x0A, + U 0x8B, U 0x59, U 0x1F, U 0xEC, + U 0x54, U 0x0F, U 0xBF, U 0x0A, U 0x2F, U 0xF2, U 0xA3, U 0x68, U 0xF0, U 0x05, U 0x28, U 0x22, - U 0x00, U 0x7F, U 0x89, U 0x43, + U 0x00, U 0x7F, U 0x89, U 0x47, U 0x29, U 0xD2, U 0x85, U 0xD4, - U 0x90, U 0x65, U 0x90, U 0x77, - U 0x60, U 0x00, U 0x3D, U 0x00, + U 0x90, U 0x65, U 0x90, U 0x75, + U 0x60, U 0x00, U 0x43, U 0x00, U 0x00, U 0x2B, U 0x20, U 0x0C, - U 0x1F, U 0xEC, U 0x64, U 0x0C, + U 0x1F, U 0xEC, U 0x4C, U 0x0C, U 0xBD, U 0x11, U 0xA6, U 0xDD, U 0x29, U 0xD2, U 0x86, U 0x0F, U 0xBF, U 0x0A, U 0x6E, U 0x96, @@ -1588,47 +1613,47 @@ static unsigned char t3fw[30136] = { U 0x20, U 0x7F, U 0x89, U 0x05, U 0x29, U 0xD2, U 0x85, U 0x65, U 0x91, U 0x65, U 0xDA, U 0x20, - U 0x58, U 0x14, U 0xE7, U 0x60, - U 0x00, U 0x13, U 0xDA, U 0x20, - U 0xC0, U 0xB6, U 0x58, U 0x14, - U 0xE5, U 0x60, U 0x00, U 0x09, + U 0x58, U 0x15, U 0x58, U 0xC9, + U 0x5C, U 0x60, U 0x01, U 0xFF, + U 0x00, U 0xDA, U 0x20, U 0xC0, + U 0xB6, U 0x58, U 0x15, U 0x55, + U 0x60, U 0x00, U 0x0C, U 0x00, U 0xC0, U 0x90, U 0x63, U 0xFF, - U 0xB9, U 0xDA, U 0x20, U 0x58, - U 0x14, U 0xE2, U 0x89, U 0x14, - U 0x89, U 0x91, U 0x09, U 0xFE, - U 0x50, U 0x65, U 0x51, U 0xE4, - U 0x8C, U 0x12, U 0x8D, U 0x14, - U 0xDA, U 0x20, U 0xDB, U 0xD0, - U 0x8D, U 0xD0, U 0x9E, U 0x10, - U 0x0D, U 0x6D, U 0x51, U 0x58, - U 0x13, U 0x54, U 0x9A, U 0x14, - U 0x64, U 0xA2, U 0x08, U 0xC7, - U 0x5F, U 0x8F, U 0xA1, U 0x95, - U 0xA9, U 0xC0, U 0x51, U 0x0F, - U 0x0F, U 0x47, U 0x9F, U 0x12, - U 0x63, U 0xFE, U 0xFB, U 0x00, - U 0xC0, U 0x91, U 0xC0, U 0xF1, - U 0x28, U 0x20, U 0x06, U 0x2C, - U 0x20, U 0x66, U 0x28, U 0x8C, - U 0xF9, U 0xA7, U 0xCC, U 0x0C, - U 0x0C, U 0x47, U 0x2C, U 0x24, - U 0x66, U 0x6F, U 0xC6, U 0x08, - U 0x8D, U 0x14, U 0x8D, U 0xD1, - U 0x70, U 0xDE, U 0x01, U 0xC0, - U 0x90, U 0xDD, U 0x90, U 0x64, + U 0xB5, U 0x00, U 0x00, U 0xDA, + U 0x20, U 0x58, U 0x15, U 0x51, + U 0x65, U 0x51, U 0xE4, U 0x8D, + U 0x13, U 0x8C, U 0x11, U 0xDB, + U 0xD0, U 0x8D, U 0xD0, U 0x02, + U 0x2A, U 0x02, U 0x0D, U 0x6D, + U 0x51, U 0x58, U 0x13, U 0xC3, + U 0x9A, U 0x13, U 0x64, U 0xA1, + U 0xCE, U 0xC7, U 0x5F, U 0x8F, + U 0xA1, U 0x95, U 0xA9, U 0xC0, + U 0x51, U 0x0F, U 0x0F, U 0x47, + U 0x9F, U 0x11, U 0x63, U 0xFE, + U 0xFD, U 0x00, U 0xC0, U 0x91, + U 0xC0, U 0xF1, U 0x28, U 0x20, + U 0x06, U 0x2C, U 0x20, U 0x66, + U 0x28, U 0x8C, U 0xF9, U 0xA7, + U 0xCC, U 0x0C, U 0x0C, U 0x47, + U 0x2C, U 0x24, U 0x66, U 0x6F, + U 0xC6, U 0x09, U 0x8D, U 0x13, + U 0x8D, U 0xD1, U 0x70, U 0xDE, + U 0x02, U 0x29, U 0x0A, U 0x00, + U 0x09, U 0x9D, U 0x02, U 0x64, U 0x81, U 0x59, U 0xC9, U 0xD3, - U 0x2A, U 0x12, U 0x01, U 0x2B, - U 0x21, U 0x04, U 0x58, U 0x13, - U 0x64, U 0x8A, U 0x14, U 0xC0, - U 0xB0, U 0x2B, U 0x24, U 0x66, - U 0x8E, U 0xA9, U 0x2A, U 0xA0, + U 0x8A, U 0x10, U 0x2B, U 0x21, + U 0x04, U 0x58, U 0x13, U 0xD3, + U 0x8A, U 0x13, U 0xC0, U 0xB0, + U 0x2B, U 0x24, U 0x66, U 0x2E, + U 0xA2, U 0x09, U 0x2A, U 0xA0, U 0x20, U 0x0E, U 0x28, U 0x14, - U 0x1C, U 0xEC, U 0x43, U 0x8D, - U 0x14, U 0x15, U 0xEC, U 0x37, + U 0x1C, U 0xEC, U 0x2B, U 0x8D, + U 0x13, U 0x15, U 0xEC, U 0x1F, U 0xC1, U 0x70, U 0x0A, U 0x77, U 0x36, U 0x85, U 0x56, U 0x2D, U 0xDC, U 0x28, U 0xAC, U 0x2C, - U 0x9C, U 0x13, U 0xDE, U 0xD0, + U 0x9C, U 0x12, U 0xDE, U 0xD0, U 0xA8, U 0x55, U 0x7C, U 0xD3, U 0x02, U 0x2E, U 0xDD, U 0xF8, U 0xD3, U 0xE0, U 0xDA, U 0x40, @@ -1642,22 +1667,22 @@ static unsigned char t3fw[30136] = { U 0x29, U 0xC2, U 0x85, U 0xAF, U 0x3F, U 0xAB, U 0x99, U 0x29, U 0xC6, U 0x85, U 0x1C, U 0xEC, - U 0x2C, U 0xDE, U 0xF0, U 0xAC, + U 0x14, U 0xDE, U 0xF0, U 0xAC, U 0x88, U 0x2D, U 0x84, U 0xCF, - U 0x28, U 0x12, U 0x03, U 0x29, - U 0x12, U 0x04, U 0x78, U 0xF3, + U 0x28, U 0x12, U 0x02, U 0x29, + U 0x12, U 0x03, U 0x78, U 0xF3, U 0x02, U 0x2E, U 0xFD, U 0xF8, U 0x28, U 0x90, U 0x20, U 0xD3, U 0xE0, U 0x07, U 0x88, U 0x0C, U 0xC1, U 0x70, U 0x08, U 0x08, U 0x47, U 0x28, U 0x94, U 0x20, U 0x08, U 0x77, U 0x36, U 0x65, - U 0x7F, U 0xAB, U 0x89, U 0x14, - U 0x13, U 0xEC, U 0x2A, U 0x89, + U 0x7F, U 0xAB, U 0x89, U 0x13, + U 0x13, U 0xEC, U 0x12, U 0x89, U 0x90, U 0xC0, U 0xF4, U 0x77, U 0x97, U 0x49, U 0x1B, U 0xEC, - U 0x28, U 0xC1, U 0xCA, U 0x28, - U 0x21, U 0x04, U 0x85, U 0x14, + U 0x10, U 0xC1, U 0xCA, U 0x28, + U 0x21, U 0x04, U 0x85, U 0x13, U 0x09, U 0x9E, U 0x40, U 0x06, U 0xEE, U 0x11, U 0x87, U 0x53, U 0x04, U 0x88, U 0x11, U 0x85, @@ -1668,83 +1693,57 @@ static unsigned char t3fw[30136] = { U 0xA4, U 0x97, U 0xA7, U 0x95, U 0xA6, U 0x03, U 0xFF, U 0x02, U 0x9F, U 0xA2, U 0x2C, U 0x20, - U 0x0C, U 0x1E, U 0xEC, U 0x11, + U 0x0C, U 0x1E, U 0xEB, U 0xF9, U 0xAE, U 0xCE, U 0x0C, U 0xCC, U 0x11, U 0x06, U 0xCC, U 0x08, U 0x2B, U 0xC2, U 0x85, U 0x2D, U 0xE4, U 0xCF, U 0x2B, U 0xBC, U 0x20, U 0x2B, U 0xC6, U 0x85, U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x12, U 0x58, U 0x0D, U 0x14, + U 0x11, U 0x58, U 0x0D, U 0x7F, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x28, U 0x20, U 0x3D, U 0xC0, U 0xE0, U 0x7C, U 0x87, U 0x7F, U 0x2E, U 0x24, U 0x67, U 0x0E, U 0x0A, U 0x47, U 0x65, U 0xA0, - U 0x7B, U 0x1A, U 0xEC, U 0x0F, + U 0x7B, U 0x1A, U 0xEB, U 0xF7, U 0x88, U 0x20, U 0x1E, U 0xEB, - U 0xFD, U 0x8F, U 0x14, U 0x8E, + U 0xE5, U 0x8F, U 0x13, U 0x8E, U 0xE4, U 0x8F, U 0xF4, U 0x08, U 0x88, U 0x11, U 0x0A, U 0x88, U 0x02, U 0x0F, U 0x8F, U 0x14, - U 0xAF, U 0xEE, U 0x1F, U 0xEC, - U 0x0A, U 0x98, U 0x91, U 0x0F, + U 0xAF, U 0xEE, U 0x1F, U 0xEB, + U 0xF2, U 0x98, U 0x91, U 0x0F, U 0xEE, U 0x02, U 0x9E, U 0x90, - U 0x1E, U 0xEC, U 0x09, U 0xC0, - U 0x80, U 0x1A, U 0xEB, U 0xFA, + U 0x1E, U 0xEB, U 0xF1, U 0xC0, + U 0x80, U 0x1A, U 0xEB, U 0xE2, U 0x2C, U 0xD2, U 0x85, U 0xAA, U 0xBA, U 0xB8, U 0xCC, U 0x28, U 0xA4, U 0xCF, U 0x2C, U 0xD6, U 0x85, U 0x2C, U 0x21, U 0x02, - U 0x2F, U 0x20, U 0x70, U 0x0E, + U 0x2F, U 0x20, U 0x72, U 0x0E, U 0xCC, U 0x02, U 0xB1, U 0xFF, - U 0x2F, U 0x24, U 0x70, U 0x2C, + U 0x2F, U 0x24, U 0x72, U 0x2C, U 0x25, U 0x02, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0x87, U 0x14, + U 0xD1, U 0x0F, U 0x87, U 0x13, U 0x87, U 0x70, U 0x07, U 0x07, U 0x47, U 0x63, U 0xFD, U 0x6E, - U 0x28, U 0x21, U 0x23, U 0xC0, + U 0x28, U 0x21, U 0x38, U 0xC0, U 0x99, U 0x79, U 0x8B, U 0x02, U 0x63, U 0xFE, U 0x9A, U 0xDD, U 0xF0, U 0x63, U 0xFE, U 0x95, U 0x00, U 0xDA, U 0x20, U 0xDB, - U 0x30, U 0x8C, U 0x12, U 0xDD, - U 0x50, U 0x58, U 0x14, U 0xF4, + U 0x30, U 0x8C, U 0x11, U 0xDD, + U 0x50, U 0x58, U 0x15, U 0x71, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0xE1, U 0x63, U 0xFF, - U 0x7A, U 0x8B, U 0x14, U 0x8C, - U 0x12, U 0xDD, U 0x50, U 0xC0, + U 0x7A, U 0x8B, U 0x13, U 0x8C, + U 0x11, U 0xDD, U 0x50, U 0xC0, U 0xAA, U 0x2E, U 0x0A, U 0x80, U 0x2A, U 0x24, U 0x68, U 0xDA, - U 0x20, U 0x58, U 0x13, U 0x60, + U 0x20, U 0x58, U 0x13, U 0xD1, U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x00, U 0x70, U 0x96, U 0x55, - U 0x2B, U 0x62, U 0x9E, U 0x6E, - U 0xB8, U 0x53, U 0x1D, U 0xEB, - U 0xD4, U 0x2D, U 0xD2, U 0x26, - U 0x68, U 0xD0, U 0x04, U 0x8E, - U 0x20, U 0x7D, U 0xE9, U 0x45, - U 0x2A, U 0x62, U 0x9D, U 0xCB, - U 0xAF, U 0x2B, U 0x21, U 0x04, - U 0x2C, U 0x20, U 0x66, U 0x58, - U 0x12, U 0xF8, U 0xC0, U 0x90, - U 0x29, U 0x24, U 0x66, U 0x82, - U 0x14, U 0x18, U 0xEB, U 0xE2, - U 0x8F, U 0x21, U 0x08, U 0xFF, - U 0x01, U 0x9F, U 0x21, U 0xC0, - U 0x20, U 0xD1, U 0x0F, U 0x00, - U 0x8B, U 0x10, U 0xC9, U 0xB8, - U 0x8C, U 0xA0, U 0x0C, U 0x6C, - U 0x51, U 0xCC, U 0xCC, U 0x8E, - U 0x24, U 0x1F, U 0xEB, U 0xD0, - U 0x8D, U 0xE1, U 0x9E, U 0x14, - U 0x0F, U 0xDD, U 0x02, U 0x9D, - U 0xE1, U 0x88, U 0x10, U 0x65, - U 0x8F, U 0xA9, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0xDA, U 0x20, - U 0xC0, U 0xB6, U 0x58, U 0x14, - U 0x4D, U 0xC0, U 0x20, U 0xD1, - U 0x0F, U 0x00, U 0x00, U 0x00, + U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x29, U 0x21, U 0x02, U 0xC0, U 0xD0, U 0x75, U 0x97, U 0x10, U 0x2A, @@ -1754,7 +1753,7 @@ static unsigned char t3fw[30136] = { U 0x02, U 0x0D, U 0xD9, U 0x02, U 0x09, U 0x0C, U 0x4C, U 0x65, U 0xC1, U 0x82, U 0x16, U 0xEB, - U 0xB4, U 0x1E, U 0xEB, U 0xB2, + U 0xB6, U 0x1E, U 0xEB, U 0xB4, U 0x28, U 0x62, U 0x9E, U 0xC0, U 0xFA, U 0x78, U 0xF3, U 0x02, U 0x60, U 0x01, U 0x88, U 0x29, @@ -1768,13 +1767,13 @@ static unsigned char t3fw[30136] = { U 0xCC, U 0x29, U 0xC2, U 0x86, U 0xC0, U 0x8C, U 0x79, U 0x83, U 0x02, U 0x60, U 0x01, U 0x57, - U 0x19, U 0xEB, U 0xA7, U 0x09, + U 0x19, U 0xEB, U 0xA9, U 0x09, U 0xB9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x07, U 0x88, U 0x20, U 0x09, U 0x88, U 0x0C, U 0x65, U 0x81, U 0x43, U 0x27, U 0xC2, U 0x85, U 0x1C, - U 0xEB, U 0xA9, U 0x64, U 0x71, + U 0xEB, U 0xAB, U 0x64, U 0x71, U 0x3A, U 0x89, U 0x31, U 0x09, U 0x8B, U 0x14, U 0x0C, U 0xBB, U 0x01, U 0x6F, U 0xB1, U 0x1D, @@ -1787,14 +1786,14 @@ static unsigned char t3fw[30136] = { U 0x3A, U 0x8A, U 0x10, U 0x2A, U 0xAC, U 0x18, U 0x89, U 0x34, U 0xC0, U 0xC4, U 0x7F, U 0x97, - U 0x3C, U 0x18, U 0xEB, U 0xAA, - U 0x1B, U 0xEB, U 0xA9, U 0x8F, + U 0x3C, U 0x18, U 0xEB, U 0xAB, + U 0x1B, U 0xEB, U 0xAA, U 0x8F, U 0x35, U 0x9C, U 0x71, U 0x9B, U 0x70, U 0x8B, U 0x20, U 0x9D, U 0x74, U 0x08, U 0xBB, U 0x02, U 0x9B, U 0x72, U 0xC0, U 0x82, U 0x98, U 0x75, U 0x1B, U 0xEB, - U 0xA5, U 0x0F, U 0x08, U 0x40, + U 0xA6, U 0x0F, U 0x08, U 0x40, U 0x9B, U 0x73, U 0x0F, U 0x88, U 0x11, U 0x98, U 0x77, U 0x7F, U 0xF7, U 0x0B, U 0x2F, U 0x21, @@ -1812,8 +1811,8 @@ static unsigned char t3fw[30136] = { U 0xF9, U 0x38, U 0x2F, U 0x3C, U 0x20, U 0x09, U 0x09, U 0x42, U 0x64, U 0x90, U 0x86, U 0x19, - U 0xEB, U 0x76, U 0x18, U 0xEB, - U 0x77, U 0x28, U 0x96, U 0x7E, + U 0xEB, U 0x78, U 0x18, U 0xEB, + U 0x79, U 0x28, U 0x96, U 0x7E, U 0x00, U 0xF0, U 0x88, U 0x00, U 0xA0, U 0x8C, U 0x00, U 0xF0, U 0x88, U 0x00, U 0xA0, U 0x8C, @@ -1824,21 +1823,21 @@ static unsigned char t3fw[30136] = { U 0x66, U 0x9D, U 0x89, U 0x30, U 0x77, U 0x97, U 0x38, U 0x8F, U 0x33, U 0x8A, U 0x32, U 0x18, - U 0xEB, U 0x80, U 0x07, U 0xBE, + U 0xEB, U 0x82, U 0x07, U 0xBE, U 0x0B, U 0x2C, U 0x21, U 0x04, U 0xB4, U 0xBB, U 0x04, U 0xCC, U 0x11, U 0x98, U 0xE0, U 0xC0, U 0x84, U 0x98, U 0xE1, U 0x88, U 0x2B, U 0x9D, U 0xE5, U 0x9A, U 0xE6, U 0x9F, U 0xE7, U 0x1A, - U 0xEB, U 0x78, U 0x09, U 0x9F, + U 0xEB, U 0x7A, U 0x09, U 0x9F, U 0x40, U 0x06, U 0xFF, U 0x11, U 0x0F, U 0xCC, U 0x02, U 0x0A, U 0x88, U 0x02, U 0x98, U 0xE2, U 0xC1, U 0xFC, U 0x0F, U 0xCC, U 0x02, U 0x2C, U 0xE6, U 0x04, U 0xC9, U 0xB8, U 0x2C, U 0x20, - U 0x0C, U 0x1E, U 0xEB, U 0x67, + U 0x0C, U 0x1E, U 0xEB, U 0x69, U 0x0C, U 0xCA, U 0x11, U 0xAE, U 0xCC, U 0x06, U 0xAA, U 0x08, U 0x29, U 0xA2, U 0x85, U 0x2D, @@ -1852,27 +1851,27 @@ static unsigned char t3fw[30136] = { U 0x72, U 0x63, U 0xFF, U 0x66, U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x13, U 0x4D, + U 0x40, U 0x58, U 0x13, U 0xD8, U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0xDA, U 0x20, U 0x58, U 0x13, - U 0xDD, U 0x63, U 0xFF, U 0xE8, + U 0xDA, U 0x20, U 0x58, U 0x14, + U 0x68, U 0x63, U 0xFF, U 0xE8, U 0xC0, U 0xA0, U 0x63, U 0xFE, U 0x82, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x13, U 0xD9, + U 0xB6, U 0x58, U 0x14, U 0x64, U 0x63, U 0xFF, U 0xD9, U 0x00, U 0xDB, U 0x40, U 0x2A, U 0x2C, - U 0x74, U 0x58, U 0x0C, U 0x5A, + U 0x74, U 0x58, U 0x0C, U 0xDF, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x10, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x12, U 0x6E, - U 0x1E, U 0xEB, U 0x44, U 0xC0, + U 0x04, U 0x58, U 0x12, U 0xF7, + U 0x1E, U 0xEB, U 0x46, U 0xC0, U 0xD0, U 0x2D, U 0x24, U 0x66, U 0x63, U 0xFE, U 0xB1, U 0x00, U 0x6C, U 0x10, U 0x06, U 0xD6, - U 0x20, U 0x19, U 0xEB, U 0x3F, - U 0x1E, U 0xEB, U 0x41, U 0x28, + U 0x20, U 0x19, U 0xEB, U 0x41, + U 0x1E, U 0xEB, U 0x43, U 0x28, U 0x61, U 0x02, U 0x17, U 0xEB, - U 0x3E, U 0x08, U 0x08, U 0x4C, + U 0x40, U 0x08, U 0x08, U 0x4C, U 0x65, U 0x80, U 0x5F, U 0x8A, U 0x30, U 0x0A, U 0x6A, U 0x51, U 0x69, U 0xA3, U 0x57, U 0x2B, @@ -1894,14 +1893,14 @@ static unsigned char t3fw[30136] = { U 0x22, U 0xD2, U 0x85, U 0xCF, U 0x25, U 0x60, U 0x00, U 0x0D, U 0x00, U 0xDA, U 0x60, U 0xC0, - U 0xB6, U 0x58, U 0x13, U 0xB5, + U 0xB6, U 0x58, U 0x14, U 0x40, U 0xC8, U 0x5A, U 0x60, U 0x01, U 0x0F, U 0x00, U 0xDA, U 0x60, - U 0x58, U 0x13, U 0xB2, U 0x65, + U 0x58, U 0x14, U 0x3D, U 0x65, U 0x51, U 0x06, U 0xDC, U 0x40, U 0xDB, U 0x30, U 0x8D, U 0x30, U 0xDA, U 0x60, U 0x0D, U 0x6D, - U 0x51, U 0x58, U 0x12, U 0x27, + U 0x51, U 0x58, U 0x12, U 0xB0, U 0xD3, U 0xA0, U 0x64, U 0xA0, U 0xF3, U 0x84, U 0xA1, U 0xC0, U 0x51, U 0x04, U 0x04, U 0x47, @@ -1912,7 +1911,7 @@ static unsigned char t3fw[30136] = { U 0x2C, U 0x64, U 0x66, U 0x6F, U 0xC6, U 0x02, U 0x70, U 0x96, U 0x0A, U 0x2B, U 0x61, U 0x04, - U 0x58, U 0x12, U 0x3E, U 0xC0, + U 0x58, U 0x12, U 0xC7, U 0xC0, U 0xB0, U 0x2B, U 0x64, U 0x66, U 0x65, U 0x50, U 0xB4, U 0x2A, U 0x3C, U 0x10, U 0xC0, U 0xE7, @@ -1920,13 +1919,13 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0xF0, U 0x02, U 0xDF, U 0x38, U 0x0F, U 0x0F, U 0x42, U 0x64, U 0xF0, U 0x90, U 0x19, - U 0xEB, U 0x0A, U 0x18, U 0xEB, - U 0x0B, U 0x28, U 0x96, U 0x7E, + U 0xEB, U 0x0C, U 0x18, U 0xEB, + U 0x0D, U 0x28, U 0x96, U 0x7E, U 0x8D, U 0x10, U 0x6D, U 0xDA, U 0x05, U 0x00, U 0xA0, U 0x88, U 0x00, U 0xC0, U 0x8C, U 0xC0, U 0xA0, U 0x89, U 0x30, U 0x1D, - U 0xEB, U 0x1A, U 0x77, U 0x97, + U 0xEB, U 0x1C, U 0x77, U 0x97, U 0x53, U 0x88, U 0x32, U 0x8C, U 0x10, U 0x8F, U 0x33, U 0x02, U 0xCE, U 0x0B, U 0xC0, U 0x24, @@ -1935,14 +1934,14 @@ static unsigned char t3fw[30136] = { U 0x22, U 0x11, U 0x8D, U 0x6B, U 0x9B, U 0xE5, U 0x9F, U 0xE7, U 0x98, U 0xE6, U 0x1F, U 0xEB, - U 0x10, U 0x09, U 0x98, U 0x40, + U 0x12, U 0x09, U 0x98, U 0x40, U 0x06, U 0x88, U 0x11, U 0x08, U 0x22, U 0x02, U 0x0F, U 0xDD, U 0x02, U 0xC1, U 0x8D, U 0x9D, U 0xE2, U 0x08, U 0x22, U 0x02, U 0x92, U 0xE4, U 0xB4, U 0xC2, U 0x2E, U 0x60, U 0x0C, U 0x1F, - U 0xEB, U 0x00, U 0x0C, U 0xE8, + U 0xEB, U 0x02, U 0x0C, U 0xE8, U 0x11, U 0xA7, U 0x88, U 0x2C, U 0x82, U 0x85, U 0xAF, U 0xEE, U 0x0C, U 0x22, U 0x0B, U 0x2B, @@ -1950,7 +1949,7 @@ static unsigned char t3fw[30136] = { U 0x85, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x28, U 0x60, U 0x0C, U 0xD2, U 0xA0, U 0x8C, U 0x11, - U 0x19, U 0xEA, U 0xF8, U 0x0C, + U 0x19, U 0xEA, U 0xFA, U 0x0C, U 0x8D, U 0x11, U 0xA9, U 0x88, U 0xA7, U 0xDD, U 0x2E, U 0xD2, U 0x85, U 0x2B, U 0x84, U 0xCF, @@ -1962,7 +1961,7 @@ static unsigned char t3fw[30136] = { U 0xFF, U 0x60, U 0x00, U 0x00, U 0x2A, U 0x6C, U 0x74, U 0xC0, U 0xB2, U 0xDC, U 0x20, U 0xDD, - U 0x40, U 0x58, U 0x12, U 0x1C, + U 0x40, U 0x58, U 0x12, U 0xA5, U 0xC0, U 0xB0, U 0x63, U 0xFF, U 0x63, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, @@ -1985,15 +1984,15 @@ static unsigned char t3fw[30136] = { U 0x40, U 0x7A, U 0xC1, U 0x0E, U 0xC8, U 0xAB, U 0xDB, U 0xD0, U 0xDA, U 0x30, U 0x2C, U 0x0A, - U 0x00, U 0x58, U 0x0A, U 0x76, + U 0x00, U 0x58, U 0x0A, U 0xFB, U 0x2E, U 0x31, U 0x02, U 0x0E, U 0x0F, U 0x4C, U 0xC8, U 0xFE, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x68, U 0x95, U 0xF8, U 0x28, U 0x31, U 0x02, U 0x08, U 0x08, U 0x4C, U 0x65, U 0x8F, U 0xEF, - U 0x1A, U 0xEA, U 0xC6, U 0x1C, - U 0xEA, U 0xC4, U 0x2B, U 0xA2, + U 0x1A, U 0xEA, U 0xC8, U 0x1C, + U 0xEA, U 0xC6, U 0x2B, U 0xA2, U 0x9E, U 0xC0, U 0x9A, U 0x7B, U 0x9B, U 0x46, U 0x2B, U 0xC2, U 0x26, U 0x68, U 0xB0, U 0x04, @@ -2001,11 +2000,11 @@ static unsigned char t3fw[30136] = { U 0x3B, U 0x29, U 0xA2, U 0x9D, U 0xC0, U 0xE3, U 0xCB, U 0x93, U 0x94, U 0x90, U 0x1B, U 0xEA, - U 0xD7, U 0x2D, U 0x31, U 0x04, + U 0xD8, U 0x2D, U 0x31, U 0x04, U 0x9B, U 0x96, U 0x08, U 0xDD, U 0x11, U 0x0E, U 0xDD, U 0x02, U 0x9D, U 0x97, U 0x9D, U 0x91, - U 0x12, U 0xEA, U 0xD4, U 0xC0, + U 0x12, U 0xEA, U 0xD5, U 0xC0, U 0xE5, U 0x24, U 0xC4, U 0xA2, U 0x2E, U 0x34, U 0x06, U 0x2F, U 0x31, U 0x02, U 0x28, U 0xA2, @@ -2014,227 +2013,229 @@ static unsigned char t3fw[30136] = { U 0xA6, U 0x9D, U 0x2F, U 0x35, U 0x02, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x30, U 0xC0, - U 0xB6, U 0x58, U 0x13, U 0x3D, + U 0xB6, U 0x58, U 0x13, U 0xC8, U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0x6C, U 0x10, U 0x06, U 0x29, - U 0x20, U 0x06, U 0x68, U 0x98, - U 0x05, U 0x28, U 0x9C, U 0xF9, - U 0x65, U 0x82, U 0x5D, U 0x29, - U 0x21, U 0x02, U 0x09, U 0x09, - U 0x4C, U 0x65, U 0x92, U 0x10, - U 0xCD, U 0x51, U 0xDB, U 0x30, - U 0xDA, U 0x20, U 0x04, U 0x4C, - U 0x02, U 0x58, U 0x12, U 0xA1, - U 0xC0, U 0x51, U 0xD3, U 0xA0, - U 0xC7, U 0xAF, U 0x2A, U 0x36, - U 0x0A, U 0xC0, U 0xE0, U 0x19, - U 0xEA, U 0xA3, U 0x1D, U 0xEA, - U 0xA9, U 0x1F, U 0xEA, U 0xA2, - U 0x8A, U 0x3A, U 0x16, U 0xEA, - U 0x9F, U 0xB1, U 0xAC, U 0x64, - U 0xC1, U 0x35, U 0x28, U 0x62, + U 0x6C, U 0x10, U 0x06, U 0x2A, + U 0x20, U 0x06, U 0x94, U 0x10, + U 0x68, U 0xA8, U 0x05, U 0x28, + U 0xAC, U 0xF9, U 0x65, U 0x82, + U 0x50, U 0x29, U 0x21, U 0x02, + U 0x09, U 0x09, U 0x4C, U 0x65, + U 0x92, U 0x0A, U 0xCC, U 0x5F, + U 0xDB, U 0x30, U 0xDA, U 0x20, + U 0x8C, U 0x10, U 0x58, U 0x13, + U 0x2C, U 0xC0, U 0x51, U 0xD3, + U 0xA0, U 0xC7, U 0xAF, U 0x9A, + U 0x3A, U 0xC0, U 0xD0, U 0x1C, + U 0xEA, U 0xA5, U 0x14, U 0xEA, + U 0xAB, U 0x1E, U 0xEA, U 0xA4, + U 0x8F, U 0x3A, U 0x16, U 0xEA, + U 0xA1, U 0xB1, U 0xFB, U 0x64, + U 0xB1, U 0x31, U 0x28, U 0x62, U 0x9E, U 0x6F, U 0x88, U 0x02, - U 0x60, U 0x01, U 0xF1, U 0x29, - U 0xDC, U 0x33, U 0x29, U 0x92, + U 0x60, U 0x01, U 0xED, U 0x29, + U 0x4C, U 0x33, U 0x29, U 0x92, U 0x26, U 0x68, U 0x90, U 0x07, - U 0x8B, U 0x20, U 0x09, U 0xBB, - U 0x0C, U 0x65, U 0xB1, U 0xE0, - U 0x27, U 0x62, U 0x9D, U 0xC0, - U 0x8E, U 0x64, U 0x71, U 0xD8, + U 0x8A, U 0x20, U 0x09, U 0xAA, + U 0x0C, U 0x65, U 0xA1, U 0xDC, + U 0x2A, U 0x62, U 0x9D, U 0xC0, + U 0x8E, U 0x64, U 0xA1, U 0xD4, U 0x2B, U 0x20, U 0x0C, U 0x0C, - U 0xBC, U 0x11, U 0xA6, U 0xCC, - U 0x29, U 0xC2, U 0x86, U 0x79, - U 0x83, U 0x02, U 0x60, U 0x01, - U 0xD2, U 0x19, U 0xEA, U 0x91, - U 0x09, U 0xB9, U 0x0A, U 0x29, - U 0x92, U 0xA3, U 0x97, U 0x10, - U 0x68, U 0x90, U 0x08, U 0x28, - U 0x22, U 0x00, U 0x09, U 0x88, - U 0x0C, U 0x65, U 0x81, U 0xBB, - U 0x27, U 0xC2, U 0x85, U 0x64, - U 0x71, U 0xB5, U 0x29, U 0x20, - U 0x06, U 0x29, U 0x9C, U 0xF9, - U 0x64, U 0x91, U 0xEC, U 0x2C, + U 0xB7, U 0x11, U 0x06, U 0x77, + U 0x08, U 0x29, U 0x72, U 0x86, + U 0x79, U 0x83, U 0x02, U 0x60, + U 0x01, U 0xCD, U 0x0C, U 0xB9, + U 0x0A, U 0x29, U 0x92, U 0xA3, + U 0x68, U 0x90, U 0x08, U 0x2C, + U 0x22, U 0x00, U 0x09, U 0xCC, + U 0x0C, U 0x65, U 0xC1, U 0xBB, + U 0x27, U 0x72, U 0x85, U 0x64, + U 0x71, U 0xB5, U 0x28, U 0x20, + U 0x06, U 0x28, U 0x8C, U 0xF9, + U 0x64, U 0x81, U 0xE5, U 0x2C, U 0x20, U 0x66, U 0x89, U 0x31, U 0xB1, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0x6E, U 0xC6, U 0x02, U 0x60, U 0x01, U 0xA1, U 0x09, U 0xF8, U 0x50, U 0x65, U 0x81, U 0x9B, - U 0x88, U 0x36, U 0x89, U 0xF4, - U 0x08, U 0x8C, U 0x14, U 0xAC, - U 0x99, U 0x1C, U 0xEA, U 0x81, - U 0x0C, U 0x99, U 0x02, U 0x2C, - U 0x21, U 0x04, U 0x99, U 0x70, - U 0x19, U 0xEA, U 0x98, U 0x08, - U 0x08, U 0x47, U 0x99, U 0x71, - U 0x89, U 0x2A, U 0x09, U 0x88, - U 0x10, U 0x08, U 0x99, U 0x02, - U 0x18, U 0xEA, U 0x95, U 0x08, - U 0x99, U 0x02, U 0x99, U 0x72, - U 0x28, U 0x30, U 0x13, U 0x29, - U 0x30, U 0x12, U 0x04, U 0x88, - U 0x10, U 0x06, U 0x99, U 0x10, - U 0x08, U 0x99, U 0x02, U 0x28, - U 0x30, U 0x2C, U 0x9A, U 0x74, - U 0x0C, U 0x88, U 0x10, U 0x08, - U 0xC8, U 0x02, U 0x09, U 0x88, - U 0x02, U 0x98, U 0x73, U 0x89, - U 0x37, U 0x99, U 0x75, U 0x88, - U 0x38, U 0x98, U 0x76, U 0x8A, - U 0x39, U 0xC0, U 0x81, U 0x9A, - U 0x77, U 0x1A, U 0xEA, U 0x88, - U 0x89, U 0x35, U 0x98, U 0x7B, - U 0x99, U 0x78, U 0x09, U 0x89, - U 0x14, U 0x0A, U 0x99, U 0x02, - U 0x99, U 0x7A, U 0x8A, U 0x30, - U 0x89, U 0x32, U 0x77, U 0xA7, - U 0x36, U 0x18, U 0xEA, U 0x76, - U 0x8F, U 0x33, U 0x98, U 0x7C, - U 0xC0, U 0x84, U 0x98, U 0x7D, - U 0x88, U 0x2B, U 0x2E, U 0x76, - U 0x11, U 0x29, U 0x76, U 0x12, - U 0x2F, U 0x76, U 0x13, U 0x19, - U 0xEA, U 0x70, U 0x0A, U 0x9F, - U 0x40, U 0x06, U 0xFF, U 0x11, - U 0x04, U 0xCA, U 0x11, U 0x09, - U 0x88, U 0x02, U 0x0F, U 0xAA, - U 0x02, U 0x98, U 0x7E, U 0xC1, - U 0xF9, U 0x0F, U 0xAA, U 0x02, - U 0x2A, U 0x76, U 0x10, U 0xC0, + U 0x2A, U 0x21, U 0x04, U 0x8C, + U 0xE4, U 0x88, U 0x36, U 0x1E, + U 0xEA, U 0x85, U 0x08, U 0x89, + U 0x14, U 0xA9, U 0xCC, U 0x08, + U 0x08, U 0x47, U 0x09, U 0x88, + U 0x10, U 0x19, U 0xEA, U 0x99, + U 0x0E, U 0xCC, U 0x02, U 0x9C, + U 0x70, U 0x99, U 0x71, U 0x8C, + U 0x2A, U 0x1E, U 0xEA, U 0x97, + U 0x08, U 0xCC, U 0x02, U 0x0E, + U 0xCC, U 0x02, U 0x9C, U 0x72, + U 0x2E, U 0x30, U 0x2C, U 0x29, + U 0x30, U 0x13, U 0x28, U 0x30, + U 0x12, U 0x04, U 0x99, U 0x10, + U 0x06, U 0x88, U 0x10, U 0x0C, + U 0xEE, U 0x10, U 0x9F, U 0x74, + U 0x0E, U 0xAE, U 0x02, U 0x09, + U 0x88, U 0x02, U 0x08, U 0xEE, + U 0x02, U 0x9E, U 0x73, U 0x8C, + U 0x37, U 0x04, U 0xAA, U 0x11, + U 0x9C, U 0x75, U 0x89, U 0x38, + U 0xC0, U 0xF4, U 0x99, U 0x76, + U 0x88, U 0x39, U 0xC0, U 0xC1, + U 0x98, U 0x77, U 0x18, U 0xEA, + U 0x89, U 0x8E, U 0x35, U 0x9C, + U 0x7B, U 0x9E, U 0x78, U 0x0E, + U 0x8E, U 0x14, U 0x08, U 0xEE, + U 0x02, U 0x9E, U 0x7A, U 0x8E, + U 0x30, U 0x1C, U 0xEA, U 0x79, + U 0x77, U 0xE7, U 0x30, U 0x88, + U 0x32, U 0x89, U 0x33, U 0x9C, + U 0x7C, U 0x9F, U 0x7D, U 0x0E, + U 0x9C, U 0x40, U 0x06, U 0xCC, + U 0x11, U 0x8F, U 0x2B, U 0x29, + U 0x76, U 0x13, U 0x2D, U 0x76, + U 0x11, U 0x28, U 0x76, U 0x12, + U 0x0C, U 0xAA, U 0x02, U 0x18, + U 0xEA, U 0x70, U 0xC1, U 0xC9, + U 0x0C, U 0xAA, U 0x02, U 0x2A, + U 0x76, U 0x10, U 0x08, U 0xFF, + U 0x02, U 0x9F, U 0x7E, U 0xC0, U 0xAA, U 0x60, U 0x00, U 0x01, - U 0xC0, U 0xA6, U 0xAD, U 0xBF, - U 0x0C, U 0xBC, U 0x11, U 0xA6, - U 0xCC, U 0x29, U 0xC2, U 0x85, - U 0x2E, U 0xF4, U 0xCF, U 0x09, - U 0xA9, U 0x0B, U 0x29, U 0xC6, - U 0x85, U 0x65, U 0x51, U 0x07, + U 0xC0, U 0xA6, U 0xA4, U 0xBC, + U 0x0C, U 0xB9, U 0x11, U 0xA6, + U 0x99, U 0x28, U 0x92, U 0x85, + U 0x2D, U 0xC4, U 0xCF, U 0x08, + U 0xA8, U 0x0B, U 0x28, U 0x96, + U 0x85, U 0x65, U 0x51, U 0x00, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x2B, U 0x20, U 0x0C, U 0x0C, - U 0xBC, U 0x11, U 0x06, U 0xCC, - U 0x08, U 0x28, U 0xC2, U 0x86, - U 0x09, U 0xB9, U 0x0A, U 0x6F, - U 0x89, U 0x02, U 0x60, U 0x01, - U 0x2E, U 0x29, U 0x92, U 0xA3, + U 0xB7, U 0x11, U 0x06, U 0x77, + U 0x08, U 0x2A, U 0x72, U 0x86, + U 0x0C, U 0xB9, U 0x0A, U 0x6F, + U 0xA9, U 0x02, U 0x60, U 0x01, + U 0x18, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x08, U 0x2A, U 0x22, U 0x00, U 0x09, U 0xAA, - U 0x0C, U 0x65, U 0xA1, U 0x1F, - U 0x2A, U 0xC2, U 0x85, U 0x64, - U 0xA1, U 0x19, U 0x28, U 0x20, - U 0x3D, U 0x08, U 0x28, U 0x40, - U 0x64, U 0x80, U 0x8C, U 0x84, - U 0x35, U 0x04, U 0x84, U 0x14, - U 0x64, U 0x40, U 0x84, U 0x85, - U 0xF5, U 0x74, U 0x53, U 0x7F, - U 0x84, U 0x36, U 0x04, U 0x84, - U 0x14, U 0x64, U 0x40, U 0x77, - U 0x74, U 0x53, U 0x74, U 0x29, - U 0x30, U 0x13, U 0xC0, U 0x8C, - U 0x79, U 0x88, U 0x6C, U 0xC0, + U 0x0C, U 0x65, U 0xA1, U 0x09, + U 0x2A, U 0x72, U 0x85, U 0x64, + U 0xA1, U 0x03, U 0x2C, U 0x20, + U 0x3D, U 0x0C, U 0x2C, U 0x40, + U 0x64, U 0xC0, U 0x8C, U 0x8C, + U 0x35, U 0x0C, U 0x8C, U 0x14, + U 0x64, U 0xC0, U 0x84, U 0x8F, + U 0xE5, U 0x7C, U 0xF3, U 0x7F, + U 0x8C, U 0x36, U 0x0C, U 0x8C, + U 0x14, U 0x64, U 0xC0, U 0x77, + U 0x7C, U 0xF3, U 0x74, U 0x28, + U 0x30, U 0x13, U 0xC0, U 0xFC, + U 0x78, U 0xF8, U 0x6C, U 0xC0, U 0x90, U 0x29, U 0x24, U 0x67, - U 0x09, U 0x08, U 0x47, U 0x65, - U 0x80, U 0xED, U 0x88, U 0x20, - U 0x89, U 0xF4, U 0x84, U 0x35, - U 0x1F, U 0xEA, U 0x4B, U 0x04, - U 0x84, U 0x14, U 0xA4, U 0x94, - U 0x0F, U 0x44, U 0x02, U 0x94, - U 0xA0, U 0x14, U 0xEA, U 0x46, - U 0x08, U 0x88, U 0x11, U 0x04, - U 0x88, U 0x02, U 0x98, U 0xA1, - U 0x84, U 0x36, U 0x98, U 0xA3, - U 0x04, U 0x84, U 0x14, U 0xA4, - U 0x99, U 0x0F, U 0x99, U 0x02, - U 0x99, U 0xA2, U 0x19, U 0xEA, - U 0x42, U 0xAD, U 0xB4, U 0x28, - U 0xC2, U 0x85, U 0x2E, U 0x44, - U 0xCF, U 0x28, U 0x8C, U 0x10, - U 0x28, U 0xC6, U 0x85, U 0x28, - U 0x21, U 0x02, U 0x2F, U 0x20, - U 0x70, U 0x09, U 0x88, U 0x02, - U 0xB2, U 0xFF, U 0x2F, U 0x24, - U 0x70, U 0x28, U 0x25, U 0x02, + U 0x09, U 0x0C, U 0x47, U 0x65, + U 0xC0, U 0xD7, U 0x19, U 0xEA, + U 0x4F, U 0x18, U 0xEA, U 0x4D, + U 0x8F, U 0x20, U 0x8C, U 0x35, + U 0x08, U 0xFF, U 0x11, U 0x0C, + U 0x8C, U 0x14, U 0x08, U 0xFF, + U 0x02, U 0x88, U 0xE4, U 0x9F, + U 0xA1, U 0xAC, U 0x8C, U 0x09, + U 0xCC, U 0x02, U 0x9C, U 0xA0, + U 0x8C, U 0x36, U 0x9F, U 0xA3, + U 0x0C, U 0x8C, U 0x14, U 0xAC, + U 0x88, U 0x09, U 0x88, U 0x02, + U 0x98, U 0xA2, U 0x18, U 0xEA, + U 0x45, U 0xA4, U 0xBC, U 0x2F, + U 0x72, U 0x85, U 0x2D, U 0xC4, + U 0xCF, U 0x2F, U 0xFC, U 0x10, + U 0x2F, U 0x76, U 0x85, U 0x2F, + U 0x21, U 0x02, U 0x29, U 0x20, + U 0x72, U 0x08, U 0xFF, U 0x02, + U 0xB2, U 0x99, U 0x29, U 0x24, + U 0x72, U 0x2F, U 0x25, U 0x02, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xCC, U 0x57, U 0xDA, - U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x12, U 0x1D, + U 0x20, U 0xDB, U 0x30, U 0x8C, + U 0x10, U 0x58, U 0x12, U 0xA9, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xC0, U 0x91, U 0x63, U 0xFF, U 0x8F, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x12, U 0xAB, + U 0xB6, U 0x58, U 0x13, U 0x37, U 0x63, U 0xFF, U 0xE1, U 0x00, - U 0xDA, U 0x20, U 0x58, U 0x12, - U 0xA9, U 0x63, U 0xFF, U 0xD8, - U 0x8A, U 0x10, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x11, U 0x41, - U 0x1D, U 0xEA, U 0x20, U 0x1F, - U 0xEA, U 0x19, U 0x2B, U 0x20, - U 0x0C, U 0xC0, U 0xE0, U 0x2E, - U 0x24, U 0x66, U 0x8A, U 0x3A, - U 0x63, U 0xFE, U 0x48, U 0x00, - U 0x00, U 0xDA, U 0x20, U 0xDB, - U 0x30, U 0xDC, U 0x40, U 0xDD, - U 0x50, U 0x58, U 0x13, U 0x24, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x2A, U 0x2C, U 0x74, U 0xDB, - U 0x40, U 0x58, U 0x0B, U 0x1F, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x29, U 0x21, U 0x23, U 0xC0, - U 0x88, U 0x79, U 0x83, U 0x02, - U 0x63, U 0xFE, U 0x20, U 0x2A, - U 0x12, U 0x00, U 0x2C, U 0x20, - U 0x66, U 0x2B, U 0x21, U 0x04, - U 0x2C, U 0xCC, U 0x01, U 0x0C, - U 0x0C, U 0x47, U 0x2C, U 0x24, - U 0x66, U 0x58, U 0x11, U 0x2D, - U 0x1D, U 0xEA, U 0x0C, U 0x1F, - U 0xEA, U 0x05, U 0x2B, U 0x20, - U 0x0C, U 0xC0, U 0xE0, U 0x2E, - U 0x24, U 0x66, U 0x8A, U 0x3A, - U 0x63, U 0xFD, U 0xF8, U 0x00, - U 0xDA, U 0x20, U 0x58, U 0x12, - U 0x8C, U 0x63, U 0xFF, U 0x64, - U 0xDA, U 0x20, U 0x5B, U 0xFF, - U 0x1C, U 0xD2, U 0xA0, U 0xD1, - U 0x0F, U 0x00, U 0x00, U 0x00, + U 0xDA, U 0x20, U 0x58, U 0x13, + U 0x35, U 0x63, U 0xFF, U 0xD8, + U 0x2B, U 0x21, U 0x04, U 0x58, + U 0x11, U 0xCC, U 0x1E, U 0xEA, + U 0x1D, U 0x2B, U 0x20, U 0x0C, + U 0xC0, U 0xD0, U 0x2D, U 0x24, + U 0x66, U 0x8F, U 0x3A, U 0x63, + U 0xFE, U 0x4D, U 0xDA, U 0x20, + U 0xDB, U 0x30, U 0xDC, U 0x40, + U 0xDD, U 0x50, U 0x58, U 0x13, + U 0xBE, U 0xD2, U 0xA0, U 0xD1, + U 0x0F, U 0x2A, U 0x2C, U 0x74, + U 0x8B, U 0x10, U 0x58, U 0x0B, + U 0xA7, U 0xD2, U 0xA0, U 0xD1, + U 0x0F, U 0x29, U 0x21, U 0x38, + U 0xC0, U 0x88, U 0x79, U 0x83, + U 0x2E, U 0x8C, U 0x31, U 0x0C, + U 0xFC, U 0x50, U 0x64, U 0xCE, + U 0x22, U 0x2B, U 0x21, U 0x04, + U 0xC0, U 0xC0, U 0x58, U 0x11, + U 0xBB, U 0xC0, U 0xD0, U 0x1E, + U 0xEA, U 0x0C, U 0x8F, U 0x3A, + U 0x2B, U 0x20, U 0x0C, U 0x63, + U 0xFE, U 0x0D, U 0xDA, U 0x20, + U 0x58, U 0x13, U 0x1D, U 0x63, + U 0xFF, U 0x7A, U 0xDA, U 0x20, + U 0x5B, U 0xFF, U 0x22, U 0xD2, + U 0xA0, U 0xD1, U 0x0F, U 0x00, + U 0x2C, U 0x20, U 0x66, U 0x2B, + U 0x21, U 0x04, U 0xB1, U 0xCC, + U 0x0C, U 0x0C, U 0x47, U 0x2C, + U 0x24, U 0x66, U 0x58, U 0x11, + U 0xAF, U 0x1E, U 0xEA, U 0x00, + U 0x2B, U 0x20, U 0x0C, U 0xC0, + U 0xD0, U 0x2D, U 0x24, U 0x66, + U 0x8F, U 0x3A, U 0x63, U 0xFD, + U 0xDA, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x08, U 0x95, - U 0x15, U 0xC0, U 0x61, U 0xC1, + U 0x14, U 0xC0, U 0x61, U 0xC1, U 0xB0, U 0xD9, U 0x40, U 0x2A, U 0x20, U 0x3D, U 0xC0, U 0x40, U 0x0B, U 0xAA, U 0x01, U 0x0A, U 0x64, U 0x38, U 0x2A, U 0x20, - U 0x06, U 0x29, U 0x16, U 0x06, + U 0x06, U 0x29, U 0x16, U 0x05, U 0x68, U 0xA8, U 0x05, U 0x2C, U 0xAC, U 0xF9, U 0x65, U 0xC3, - U 0x3B, U 0x1D, U 0xE9, U 0xF2, + U 0x3F, U 0x1D, U 0xE9, U 0xF2, U 0x64, U 0x40, U 0x05, U 0x2F, - U 0x12, U 0x05, U 0x64, U 0xF2, - U 0x9C, U 0x26, U 0x21, U 0x02, + U 0x12, U 0x04, U 0x64, U 0xF2, + U 0xA0, U 0x26, U 0x21, U 0x02, U 0x1E, U 0xE9, U 0xEE, U 0x06, U 0x06, U 0x4C, U 0x65, U 0x62, - U 0xE3, U 0x15, U 0xE9, U 0xEA, + U 0xE6, U 0x15, U 0xE9, U 0xEA, U 0x64, U 0x40, U 0xD9, U 0x8A, U 0x35, U 0x29, U 0x30, U 0x03, - U 0x9A, U 0x14, U 0x0A, U 0x99, + U 0x9A, U 0x13, U 0x0A, U 0x99, U 0x0C, U 0x64, U 0x90, U 0xCC, U 0x2C, U 0x20, U 0x0C, U 0x8B, - U 0x14, U 0x9C, U 0x11, U 0x0C, + U 0x13, U 0x9C, U 0x10, U 0x0C, U 0xCC, U 0x11, U 0xA5, U 0xCC, - U 0x9C, U 0x12, U 0x2C, U 0xC2, + U 0x9C, U 0x11, U 0x2C, U 0xC2, U 0x86, U 0xB4, U 0xBB, U 0x7C, U 0xB3, U 0x02, U 0x60, U 0x02, - U 0xD3, U 0x8F, U 0x11, U 0x0E, + U 0xD7, U 0x8F, U 0x10, U 0x0E, U 0xFE, U 0x0A, U 0x2E, U 0xE2, U 0xA3, U 0x68, U 0xE0, U 0x09, U 0x86, U 0x20, U 0xD3, U 0x0F, U 0x0E, U 0x66, U 0x0C, U 0x65, - U 0x62, U 0xBE, U 0x88, U 0x12, + U 0x62, U 0xC2, U 0x88, U 0x11, U 0x28, U 0x82, U 0x85, U 0x64, - U 0x82, U 0xB6, U 0x89, U 0x14, + U 0x82, U 0xBA, U 0x89, U 0x13, U 0x64, U 0x90, U 0x5E, U 0xDA, U 0x80, U 0xD9, U 0x30, U 0x8C, U 0x20, U 0x1E, U 0xE9, U 0xE8, U 0x1F, U 0xE9, U 0xE9, U 0x1D, - U 0xE9, U 0xD6, U 0x8B, U 0x14, + U 0xE9, U 0xD6, U 0x8B, U 0x13, U 0x8D, U 0xD4, U 0xD4, U 0xB0, U 0x7F, U 0xB7, U 0x18, U 0xB8, U 0x8A, U 0x29, U 0x3C, U 0x10, @@ -2256,78 +2257,79 @@ static unsigned char t3fw[30136] = { U 0x02, U 0x98, U 0xA2, U 0x2A, U 0xAC, U 0x10, U 0x19, U 0xE9, U 0xD4, U 0xC0, U 0xC0, U 0x8F, - U 0x14, U 0x1E, U 0xE9, U 0xC5, - U 0x86, U 0x12, U 0x8D, U 0x11, + U 0x13, U 0x1E, U 0xE9, U 0xC5, + U 0x86, U 0x11, U 0x8D, U 0x10, U 0x28, U 0x62, U 0x85, U 0xAE, U 0xDD, U 0x08, U 0xFF, U 0x0B, U 0x2C, U 0xD4, U 0xCF, U 0x28, U 0x21, U 0x02, U 0x2F, U 0x66, U 0x85, U 0x8B, U 0x35, U 0x2A, - U 0x20, U 0x70, U 0x09, U 0x88, + U 0x20, U 0x72, U 0x09, U 0x88, U 0x02, U 0xAB, U 0xAA, U 0x28, U 0x25, U 0x02, U 0x2A, U 0x24, - U 0x70, U 0xC0, U 0x20, U 0xD1, + U 0x72, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x29, U 0x52, U 0x9E, U 0x18, U 0xE9, U 0xB1, U 0x6F, U 0x98, U 0x02, U 0x60, U 0x02, - U 0x08, U 0x28, U 0x82, U 0x26, + U 0x0B, U 0x28, U 0x82, U 0x26, U 0x68, U 0x80, U 0x08, U 0x29, U 0x22, U 0x00, U 0x08, U 0x99, - U 0x0C, U 0x65, U 0x91, U 0xF9, + U 0x0C, U 0x65, U 0x91, U 0xFC, U 0x2A, U 0x52, U 0x9D, U 0xC1, - U 0xCA, U 0x9A, U 0x13, U 0x64, - U 0xA1, U 0xEF, U 0x2B, U 0x20, + U 0xCE, U 0x9A, U 0x12, U 0x64, + U 0xA1, U 0xF2, U 0x2B, U 0x20, U 0x0C, U 0x26, U 0x20, U 0x06, - U 0x0C, U 0xB8, U 0x11, U 0xA5, - U 0x88, U 0x2D, U 0x82, U 0x86, - U 0x0E, U 0xBE, U 0x0A, U 0x7D, - U 0xC3, U 0x02, U 0x60, U 0x02, - U 0x02, U 0x2E, U 0xE2, U 0xA3, - U 0x68, U 0xE0, U 0x08, U 0x2F, - U 0x22, U 0x00, U 0x0E, U 0xFF, - U 0x0C, U 0x65, U 0xF1, U 0xF3, - U 0x28, U 0x82, U 0x85, U 0xDE, - U 0x80, U 0x64, U 0x81, U 0xFF, - U 0x98, U 0x10, U 0x26, U 0x6C, - U 0xF9, U 0x64, U 0x61, U 0xFF, - U 0x2C, U 0x20, U 0x66, U 0x88, - U 0x31, U 0xB1, U 0xCC, U 0x0C, + U 0x0C, U 0xB8, U 0x11, U 0x05, + U 0x88, U 0x08, U 0x2D, U 0x82, + U 0x86, U 0x0E, U 0xBE, U 0x0A, + U 0x7D, U 0xC3, U 0x02, U 0x60, + U 0x02, U 0x05, U 0x2E, U 0xE2, + U 0xA3, U 0x68, U 0xE0, U 0x08, + U 0x2F, U 0x22, U 0x00, U 0x0E, + U 0xFF, U 0x0C, U 0x65, U 0xF1, + U 0xF6, U 0x28, U 0x82, U 0x85, + U 0xD7, U 0x80, U 0xDE, U 0x80, + U 0x64, U 0x82, U 0x00, U 0x98, + U 0x16, U 0x26, U 0x6C, U 0xF9, + U 0x64, U 0x62, U 0x01, U 0x2C, + U 0x20, U 0x66, U 0x88, U 0x31, + U 0x2C, U 0xCC, U 0x01, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0x6E, U 0xC6, U 0x02, U 0x60, U 0x01, U 0xBC, U 0x08, U 0xFD, U 0x50, U 0x65, U 0xD1, - U 0xB6, U 0x17, U 0xE9, U 0xB4, - U 0x19, U 0xE9, U 0x98, U 0x1A, - U 0xE9, U 0x9F, U 0x2C, U 0x21, + U 0xB6, U 0x1D, U 0xE9, U 0xB2, + U 0x1C, U 0xE9, U 0x97, U 0x19, + U 0xE9, U 0x9E, U 0x2A, U 0x21, U 0x04, U 0x8B, U 0x2D, U 0x28, U 0x30, U 0x10, U 0x2F, U 0x21, U 0x1D, U 0x0C, U 0x88, U 0x10, - U 0x0B, U 0xFB, U 0x09, U 0x0C, - U 0x88, U 0x02, U 0x0A, U 0x88, - U 0x02, U 0x09, U 0xBB, U 0x02, - U 0x64, U 0x41, U 0x52, U 0x89, - U 0x10, U 0xC0, U 0x4D, U 0x9B, - U 0x90, U 0x97, U 0x91, U 0x98, - U 0x92, U 0x8D, U 0x35, U 0xD9, - U 0xE0, U 0x64, U 0xD0, U 0x6C, - U 0xD7, U 0x30, U 0xDB, U 0xD0, - U 0xD8, U 0x30, U 0x7F, U 0xD7, - U 0x13, U 0x27, U 0x3C, U 0x10, - U 0xBC, U 0xE9, U 0x26, U 0x32, - U 0x16, U 0x8C, U 0x39, U 0x96, - U 0xE6, U 0x9C, U 0xE7, U 0x8A, - U 0x37, U 0xB4, U 0x38, U 0x9A, - U 0xE8, U 0x0B, U 0x13, U 0x14, - U 0x64, U 0x30, U 0x49, U 0x2A, - U 0x82, U 0x16, U 0x86, U 0x79, - U 0x9A, U 0x96, U 0x96, U 0x97, - U 0x8C, U 0x77, U 0x8A, U 0x7D, - U 0x9C, U 0x98, U 0x2B, U 0x82, - U 0x17, U 0x2C, U 0x7C, U 0x20, - U 0x9A, U 0x9A, U 0x2A, U 0x9C, - U 0x18, U 0x9B, U 0x99, U 0x86, - U 0x7B, U 0xB0, U 0x3B, U 0xB8, - U 0x89, U 0x6D, U 0xB9, U 0x21, + U 0x0B, U 0xFB, U 0x09, U 0x0A, + U 0x88, U 0x02, U 0x09, U 0x88, + U 0x02, U 0x0C, U 0xBB, U 0x02, + U 0x64, U 0x41, U 0x52, U 0x9B, + U 0x70, U 0x9D, U 0x71, U 0x98, + U 0x72, U 0xC0, U 0x4D, U 0x8D, + U 0x35, U 0xD9, U 0xE0, U 0x64, + U 0xD0, U 0x6E, U 0xD7, U 0x30, + U 0xDB, U 0xD0, U 0xD8, U 0x30, + U 0x7F, U 0xD7, U 0x14, U 0x27, + U 0x3C, U 0x10, U 0xBC, U 0xE9, + U 0x26, U 0x32, U 0x16, U 0x8C, + U 0x39, U 0x96, U 0xE6, U 0x9C, + U 0xE7, U 0x8A, U 0x37, U 0xB4, + U 0x38, U 0x2A, U 0xE6, U 0x08, + U 0x0B, U 0x13, U 0x14, U 0x64, + U 0x30, U 0x4A, U 0x2A, U 0x82, + U 0x16, U 0x86, U 0x79, U 0x9A, + U 0x96, U 0x96, U 0x97, U 0x8C, + U 0x77, U 0x8A, U 0x7D, U 0x9C, + U 0x98, U 0x2B, U 0x82, U 0x17, + U 0x2C, U 0x7C, U 0x20, U 0x9A, + U 0x9A, U 0x2A, U 0x9C, U 0x18, + U 0x9B, U 0x99, U 0x86, U 0x7B, + U 0xB0, U 0x3B, U 0x29, U 0x8C, + U 0x08, U 0x6D, U 0xB9, U 0x21, U 0x8B, U 0xC9, U 0x96, U 0xA5, U 0x26, U 0x92, U 0x16, U 0x2A, U 0xAC, U 0x18, U 0xB8, U 0x99, @@ -2347,9 +2349,9 @@ static unsigned char t3fw[30136] = { U 0x12, U 0x6D, U 0xAA, U 0x06, U 0x99, U 0x88, U 0x99, U 0x8B, U 0x28, U 0x8C, U 0x18, U 0xC0, - U 0xD0, U 0x1B, U 0xE9, U 0x83, - U 0x1C, U 0xE9, U 0x82, U 0x16, - U 0xE9, U 0x78, U 0xB1, U 0xFF, + U 0xD0, U 0x1B, U 0xE9, U 0x81, + U 0x1C, U 0xE9, U 0x80, U 0x16, + U 0xE9, U 0x76, U 0xB1, U 0xFF, U 0x2A, U 0x21, U 0x1C, U 0x23, U 0xE6, U 0x13, U 0x0F, U 0x0F, U 0x4F, U 0x26, U 0xE6, U 0x12, @@ -2357,187 +2359,193 @@ static unsigned char t3fw[30136] = { U 0xA9, U 0x06, U 0xC0, U 0xF0, U 0xC0, U 0x80, U 0x28, U 0x25, U 0x1D, U 0x05, U 0xF6, U 0x11, - U 0x1A, U 0xE9, U 0x71, U 0x8F, + U 0x1A, U 0xE9, U 0x6F, U 0x8F, U 0x20, U 0x2B, U 0xE6, U 0x15, U 0x2C, U 0xE6, U 0x16, U 0x2D, U 0xE6, U 0x17, U 0x26, U 0xE6, U 0x18, U 0x0A, U 0xFA, U 0x02, U 0x2A, U 0xE6, U 0x14, U 0x29, U 0x20, U 0x06, U 0x29, U 0x9C, - U 0xF9, U 0x64, U 0x90, U 0xFF, + U 0xF9, U 0x64, U 0x90, U 0xF8, U 0x29, U 0x20, U 0x0C, U 0x8D, - U 0x15, U 0xC0, U 0x80, U 0x1A, - U 0xE9, U 0x57, U 0x0C, U 0x9C, + U 0x14, U 0xC0, U 0x80, U 0x1A, + U 0xE9, U 0x56, U 0x0C, U 0x9C, U 0x11, U 0xAA, U 0x99, U 0xA5, U 0xCC, U 0xDA, U 0x20, U 0x2B, U 0xC2, U 0x85, U 0x28, U 0x94, U 0xCF, U 0x0B, U 0x4B, U 0x0B, U 0x2B, U 0xC6, U 0x85, U 0xC0, - U 0xB0, U 0x8C, U 0x16, U 0x58, - U 0x11, U 0x14, U 0xD2, U 0xA0, + U 0xB0, U 0x8C, U 0x15, U 0x58, + U 0x11, U 0x9C, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x35, - U 0x6F, U 0xA5, U 0x48, U 0xD8, + U 0x6F, U 0xA5, U 0x46, U 0xD8, U 0x30, U 0x8B, U 0xD5, U 0x6D, U 0xA9, U 0x0C, U 0x8A, U 0x86, U 0x0A, U 0x8A, U 0x14, U 0xCB, - U 0xA9, U 0x7A, U 0xB3, U 0x37, + U 0xA7, U 0x7A, U 0xB3, U 0x35, U 0x28, U 0x8C, U 0x10, U 0xC0, U 0x80, U 0x28, U 0x24, U 0x67, U 0x08, U 0x0B, U 0x47, U 0x65, - U 0xB1, U 0x12, U 0xDA, U 0x20, + U 0xB1, U 0x0B, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x2C, U 0x12, - U 0x06, U 0x58, U 0x11, U 0x37, + U 0x05, U 0x58, U 0x11, U 0xBF, U 0xD3, U 0xA0, U 0xC0, U 0xC1, U 0xC0, U 0xD0, U 0x2D, U 0xA4, - U 0x03, U 0x9C, U 0x15, U 0x63, - U 0xFD, U 0x26, U 0x86, U 0x36, - U 0x64, U 0x61, U 0x0C, U 0x89, - U 0x10, U 0xC0, U 0x4D, U 0x9B, - U 0x90, U 0x97, U 0x91, U 0x98, - U 0x92, U 0x63, U 0xFE, U 0xA4, - U 0xC0, U 0x81, U 0x63, U 0xFF, - U 0xC7, U 0x8A, U 0x15, U 0xCC, - U 0xA7, U 0xDA, U 0x20, U 0xDB, - U 0x30, U 0x8C, U 0x16, U 0x58, - U 0x11, U 0x2B, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0xDA, U 0x20, - U 0xC0, U 0xB6, U 0x58, U 0x11, - U 0xBA, U 0x63, U 0xFF, U 0xE4, + U 0x03, U 0x9C, U 0x14, U 0x63, + U 0xFD, U 0x22, U 0x86, U 0x36, + U 0x64, U 0x61, U 0x05, U 0x9B, + U 0x70, U 0x9D, U 0x71, U 0x98, + U 0x72, U 0xC0, U 0x4D, U 0x63, + U 0xFE, U 0xA4, U 0xC0, U 0x81, + U 0x63, U 0xFF, U 0xC9, U 0x00, + U 0x88, U 0x14, U 0xCC, U 0x87, + U 0xDA, U 0x20, U 0xDB, U 0x30, + U 0x8C, U 0x15, U 0x58, U 0x11, + U 0xB3, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0xDA, U 0x20, U 0xC0, + U 0xB6, U 0x58, U 0x12, U 0x42, + U 0x63, U 0xFF, U 0xE4, U 0x00, U 0x00, U 0xDA, U 0x20, U 0x8B, - U 0x11, U 0x58, U 0x11, U 0xB7, - U 0x63, U 0xFF, U 0xD9, U 0x00, - U 0x9E, U 0x17, U 0x8A, U 0x13, + U 0x10, U 0x58, U 0x12, U 0x3F, + U 0x63, U 0xFF, U 0xD8, U 0x00, + U 0x9E, U 0x17, U 0x8A, U 0x12, U 0x2B, U 0x21, U 0x04, U 0x58, - U 0x10, U 0x4F, U 0x8E, U 0x17, - U 0xC0, U 0xB0, U 0x2B, U 0x24, + U 0x10, U 0xD5, U 0x8E, U 0x17, + U 0xC0, U 0x90, U 0x29, U 0x24, U 0x66, U 0x63, U 0xFE, U 0x34, U 0xC0, U 0x80, U 0x63, U 0xFE, - U 0x09, U 0xDA, U 0x20, U 0xDB, - U 0x30, U 0x8C, U 0x16, U 0xDD, - U 0x50, U 0x58, U 0x12, U 0x33, + U 0x06, U 0xDA, U 0x20, U 0xDB, + U 0x30, U 0x8C, U 0x15, U 0xDD, + U 0x50, U 0x58, U 0x12, U 0xC7, U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0xDA, U 0x20, U 0x58, U 0x11, - U 0xAB, U 0x63, U 0xFF, U 0xA8, - U 0x2D, U 0x21, U 0x23, U 0xC0, - U 0xC8, U 0x7D, U 0xC3, U 0x02, - U 0x63, U 0xFE, U 0x0D, U 0x8A, - U 0x13, U 0x2B, U 0x21, U 0x04, - U 0x2C, U 0x20, U 0x66, U 0x98, - U 0x17, U 0xB1, U 0xCC, U 0x0C, - U 0x0C, U 0x47, U 0x2C, U 0x24, - U 0x66, U 0x58, U 0x10, U 0x3D, - U 0x8E, U 0x17, U 0xC0, U 0xD0, - U 0x2D, U 0x24, U 0x66, U 0x63, - U 0xFD, U 0xEE, U 0x00, U 0x00, - U 0x26, U 0x21, U 0x23, U 0xB0, - U 0x66, U 0x06, U 0x06, U 0x4F, - U 0x26, U 0x25, U 0x23, U 0x65, - U 0x6E, U 0xF1, U 0x28, U 0x20, - U 0x6A, U 0x7F, U 0x87, U 0x05, - U 0x08, U 0x29, U 0x41, U 0x64, - U 0x90, U 0xA5, U 0xC0, U 0xD0, - U 0x1B, U 0xE9, U 0x1C, U 0x19, - U 0xE9, U 0x2B, U 0x26, U 0x20, - U 0x07, U 0x23, U 0xE6, U 0x1B, - U 0xB1, U 0x66, U 0x09, U 0xFA, - U 0x02, U 0x2B, U 0xE6, U 0x1A, - U 0x28, U 0x20, U 0x0A, U 0x2D, - U 0xE6, U 0x1D, U 0x2A, U 0xE6, - U 0x1E, U 0x09, U 0x88, U 0x02, - U 0x28, U 0xE6, U 0x1C, U 0x88, - U 0x26, U 0x06, U 0x06, U 0x47, - U 0x28, U 0xE6, U 0x20, U 0x2B, - U 0x22, U 0x08, U 0x26, U 0xE5, - U 0x3E, U 0x2B, U 0xE6, U 0x21, - U 0x2D, U 0x24, U 0x07, U 0x2C, - U 0x20, U 0x06, U 0x2A, U 0x20, - U 0x64, U 0x68, U 0xC3, U 0x47, - U 0xB4, U 0x44, U 0x63, U 0xFE, - U 0x9E, U 0xDB, U 0x30, U 0xDA, - U 0x20, U 0x8D, U 0x15, U 0xC0, - U 0xCE, U 0x2E, U 0x0A, U 0x80, - U 0x2C, U 0x24, U 0x68, U 0x8C, - U 0x16, U 0x58, U 0x10, U 0x7B, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x8E, U 0x10, U 0x2A, U 0x32, - U 0x16, U 0x16, U 0xE8, U 0xF3, - U 0x0A, U 0x2A, U 0x14, U 0x86, - U 0x66, U 0x2B, U 0xE6, U 0x12, - U 0x97, U 0xE1, U 0x27, U 0xE6, - U 0x13, U 0x28, U 0xE6, U 0x14, - U 0xAA, U 0x66, U 0x09, U 0x66, - U 0x02, U 0x96, U 0xE0, U 0x2E, - U 0xEC, U 0x48, U 0x69, U 0xED, - U 0x50, U 0xC1, U 0x46, U 0x63, - U 0xFD, U 0x7A, U 0x00, U 0x00, - U 0x64, U 0xAF, U 0xB4, U 0x19, - U 0xE8, U 0xE9, U 0x28, U 0x20, - U 0x16, U 0x89, U 0x92, U 0x0A, - U 0x88, U 0x0C, U 0x00, U 0x91, - U 0x04, U 0x00, U 0x88, U 0x1A, - U 0xA8, U 0xB8, U 0x98, U 0x29, - U 0x63, U 0xFF, U 0x9C, U 0x00, + U 0xDA, U 0x20, U 0x58, U 0x12, + U 0x33, U 0x63, U 0xFF, U 0xA7, + U 0x00, U 0x2B, U 0x21, U 0x38, + U 0xC0, U 0xA8, U 0x7B, U 0xAB, + U 0x02, U 0x60, U 0x01, U 0x04, + U 0x8C, U 0x31, U 0x0C, U 0xFC, + U 0x50, U 0x64, U 0xCE, U 0x04, + U 0x8A, U 0x12, U 0x2B, U 0x21, + U 0x04, U 0xC0, U 0xC0, U 0x98, + U 0x17, U 0x58, U 0x10, U 0xC3, + U 0x8E, U 0x17, U 0x63, U 0xFD, + U 0xF3, U 0x2D, U 0x21, U 0x38, + U 0x2D, U 0xDC, U 0xFF, U 0x0D, + U 0x0D, U 0x4F, U 0x2D, U 0x25, + U 0x38, U 0x65, U 0xDE, U 0xF7, + U 0x28, U 0x20, U 0x6A, U 0x7F, + U 0x87, U 0x05, U 0x08, U 0x26, + U 0x41, U 0x64, U 0x60, U 0xA3, + U 0xC0, U 0x90, U 0x16, U 0xE9, + U 0x1C, U 0x1C, U 0xE9, U 0x2A, + U 0x2A, U 0x20, U 0x07, U 0x23, + U 0xE6, U 0x1B, U 0xB1, U 0xAA, + U 0x0C, U 0xFD, U 0x02, U 0x26, + U 0xE6, U 0x1A, U 0x2B, U 0x20, + U 0x0A, U 0x29, U 0xE6, U 0x1D, + U 0x2D, U 0xE6, U 0x1E, U 0x0C, + U 0xBB, U 0x02, U 0x2B, U 0xE6, + U 0x1C, U 0x8B, U 0x26, U 0x0A, + U 0x0A, U 0x47, U 0x2B, U 0xE6, + U 0x20, U 0x8B, U 0x28, U 0x2A, + U 0xE5, U 0x3E, U 0x2B, U 0xE6, + U 0x21, U 0x29, U 0x24, U 0x07, + U 0x28, U 0x20, U 0x06, U 0x2A, + U 0x20, U 0x64, U 0x68, U 0x83, + U 0x46, U 0xB4, U 0x44, U 0x63, + U 0xFE, U 0xA5, U 0xDB, U 0x30, + U 0xDA, U 0x20, U 0x8C, U 0x15, + U 0x8D, U 0x14, U 0x2E, U 0x0A, + U 0x80, U 0xC0, U 0x8E, U 0x28, + U 0x24, U 0x68, U 0x58, U 0x11, + U 0x05, U 0xD2, U 0xA0, U 0xD1, + U 0x0F, U 0x2E, U 0x7C, U 0x48, + U 0x19, U 0xE8, U 0xF5, U 0x2A, + U 0x32, U 0x16, U 0x2B, U 0x76, + U 0x12, U 0x9D, U 0x71, U 0x2D, + U 0x76, U 0x13, U 0x28, U 0x76, + U 0x14, U 0x89, U 0x96, U 0x0A, + U 0x2A, U 0x14, U 0xAA, U 0x99, + U 0x0C, U 0x99, U 0x02, U 0x99, + U 0x70, U 0x69, U 0xED, U 0x71, + U 0xC1, U 0x46, U 0x63, U 0xFD, + U 0x81, U 0x00, U 0x00, U 0x00, + U 0x64, U 0xAF, U 0xB5, U 0x1D, + U 0xE8, U 0xEA, U 0x2C, U 0x20, + U 0x16, U 0x8D, U 0xD2, U 0x0A, + U 0xCC, U 0x0C, U 0x00, U 0xD1, + U 0x04, U 0x00, U 0xCC, U 0x1A, + U 0xAC, U 0xBC, U 0x9C, U 0x29, + U 0x63, U 0xFF, U 0x9D, U 0x00, U 0x2B, U 0x21, U 0x04, U 0x6E, U 0xB8, U 0x1E, U 0x2C, U 0x20, U 0x66, U 0xB8, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0xC9, U 0xC0, U 0x9E, - U 0x17, U 0x8A, U 0x13, U 0x58, - U 0x10, U 0x04, U 0x8E, U 0x17, + U 0x17, U 0x8A, U 0x12, U 0x58, + U 0x10, U 0x8C, U 0x8E, U 0x17, U 0xC0, U 0x34, U 0x8F, U 0x20, U 0xC0, U 0xD0, U 0x2D, U 0x24, U 0x66, U 0xC0, U 0x68, U 0x26, U 0x24, U 0x06, U 0x63, U 0xFF, - U 0x2C, U 0x00, U 0x8D, U 0x35, + U 0x2E, U 0x8A, U 0x12, U 0x2B, + U 0x21, U 0x04, U 0x2C, U 0x20, + U 0x66, U 0x98, U 0x17, U 0xB1, + U 0xCC, U 0x0C, U 0x0C, U 0x47, + U 0x2C, U 0x24, U 0x66, U 0x58, + U 0x10, U 0x82, U 0x8E, U 0x17, + U 0x87, U 0x16, U 0xC0, U 0xD0, + U 0x2D, U 0x24, U 0x66, U 0x63, + U 0xFC, U 0xE6, U 0x8D, U 0x35, U 0xC0, U 0x80, U 0x64, U 0xD0, U 0x4A, U 0xD9, U 0xE0, U 0xDC, U 0x30, U 0xDB, U 0xE0, U 0xDF, - U 0x30, U 0x1A, U 0xE8, U 0xF4, + U 0x30, U 0x1A, U 0xE8, U 0xEC, U 0xB1, U 0x88, U 0xB4, U 0xFF, - U 0x17, U 0xE8, U 0xF4, U 0x86, - U 0xC9, U 0x24, U 0x9D, U 0xFF, - U 0x8D, U 0xC8, U 0x2C, U 0xCC, - U 0x10, U 0x2D, U 0x46, U 0x30, - U 0x07, U 0x67, U 0x01, U 0x2D, - U 0x46, U 0x32, U 0x0A, U 0x66, - U 0x01, U 0x1D, U 0xE8, U 0xEE, - U 0x26, U 0x46, U 0x31, U 0xAD, - U 0x6D, U 0x2D, U 0x46, U 0x33, - U 0x26, U 0xF2, U 0x15, U 0x97, - U 0xB7, U 0x96, U 0xB6, U 0x84, - U 0xC3, U 0xBC, U 0xBB, U 0x94, + U 0x16, U 0xE8, U 0xEC, U 0x84, + U 0xC9, U 0x2D, U 0x9D, U 0xFF, + U 0x87, U 0xC8, U 0x2C, U 0xCC, + U 0x10, U 0x27, U 0xD6, U 0x30, + U 0x06, U 0x46, U 0x01, U 0x27, + U 0xD6, U 0x32, U 0x0A, U 0x44, + U 0x01, U 0x17, U 0xE8, U 0xE6, + U 0x24, U 0xD6, U 0x31, U 0xA7, + U 0x47, U 0x27, U 0xD6, U 0x33, + U 0x24, U 0xF2, U 0x15, U 0x96, + U 0xB7, U 0x94, U 0xB6, U 0x8D, + U 0xC3, U 0xBC, U 0xBB, U 0x9D, U 0xB5, U 0x8D, U 0x35, U 0x29, U 0x9C, U 0x10, U 0x7D, U 0x83, U 0xC2, U 0x2F, U 0x21, U 0x1D, U 0xC1, U 0x46, U 0x63, U 0xFD, - U 0x4B, U 0x00, U 0x00, U 0x00, + U 0x33, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x29, U 0x20, U 0x06, U 0x28, U 0x9C, - U 0xF8, U 0x65, U 0x82, U 0xC3, + U 0xF8, U 0x65, U 0x82, U 0xBF, U 0x29, U 0x21, U 0x02, U 0x2B, U 0x20, U 0x0C, U 0x09, U 0x09, U 0x4C, U 0x65, U 0x90, U 0xE1, - U 0x16, U 0xE8, U 0xB9, U 0x0C, + U 0x16, U 0xE8, U 0xB2, U 0x0C, U 0xBA, U 0x11, U 0xA6, U 0xAA, U 0x2D, U 0xA2, U 0x86, U 0x2C, U 0x0A, U 0x12, U 0x7D, U 0xC3, - U 0x02, U 0x60, U 0x02, U 0x90, - U 0x19, U 0xE8, U 0xB5, U 0x09, + U 0x02, U 0x60, U 0x02, U 0x8C, + U 0x19, U 0xE8, U 0xAE, U 0x09, U 0xB9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x07, U 0x8C, U 0x20, U 0x09, U 0xCC, - U 0x0C, U 0x65, U 0xC2, U 0x7C, + U 0x0C, U 0x65, U 0xC2, U 0x78, U 0x29, U 0xA2, U 0x85, U 0x64, - U 0x92, U 0x76, U 0x2D, U 0x62, - U 0x9E, U 0x1A, U 0xE8, U 0xAB, + U 0x92, U 0x72, U 0x2D, U 0x62, + U 0x9E, U 0x1A, U 0xE8, U 0xA4, U 0x6F, U 0xD8, U 0x02, U 0x60, - U 0x02, U 0x72, U 0x2A, U 0xA2, + U 0x02, U 0x6E, U 0x2A, U 0xA2, U 0x26, U 0x29, U 0x16, U 0x01, U 0x68, U 0xA0, U 0x08, U 0x2B, U 0x22, U 0x00, U 0x0A, U 0xBB, - U 0x0C, U 0x65, U 0xB2, U 0x60, + U 0x0C, U 0x65, U 0xB2, U 0x5C, U 0x29, U 0x62, U 0x9D, U 0xC1, - U 0x8C, U 0x64, U 0x92, U 0x58, + U 0x8C, U 0x64, U 0x92, U 0x54, U 0x2A, U 0x21, U 0x20, U 0x0A, U 0x80, U 0x60, U 0x99, U 0x10, U 0x2C, U 0x20, U 0x3C, U 0xC7, @@ -2569,14 +2577,14 @@ static unsigned char t3fw[30136] = { U 0x7C, U 0x8B, U 0x29, U 0xB0, U 0xCD, U 0x2D, U 0x25, U 0x23, U 0xC8, U 0x55, U 0xDA, U 0x20, - U 0xDB, U 0x30, U 0x58, U 0x0F, - U 0xFA, U 0x29, U 0x21, U 0x02, + U 0xDB, U 0x30, U 0x58, U 0x10, + U 0x7B, U 0x29, U 0x21, U 0x02, U 0xCC, U 0x96, U 0xC0, U 0xE8, U 0x0E, U 0x9E, U 0x02, U 0x2E, U 0x25, U 0x02, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x58, U 0x10, - U 0x7A, U 0xC0, U 0x20, U 0xD1, + U 0xFC, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x2C, U 0x20, U 0x66, U 0x89, U 0x31, U 0xB1, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, @@ -2592,88 +2600,87 @@ static unsigned char t3fw[30136] = { U 0xFA, U 0x1A, U 0x0A, U 0x88, U 0x02, U 0x28, U 0x26, U 0x1B, U 0x2E, U 0x30, U 0x10, U 0xC0, - U 0xA0, U 0xC0, U 0xB0, U 0x88, - U 0x30, U 0x1C, U 0xE8, U 0x6E, - U 0x94, U 0x12, U 0x95, U 0x13, - U 0xC0, U 0x41, U 0x25, U 0x20, - U 0x3C, U 0x2C, U 0xC0, U 0x22, - U 0x08, U 0x8D, U 0x14, U 0x77, - U 0x87, U 0x05, U 0x2F, U 0x0A, - U 0x01, U 0x0C, U 0xFA, U 0x38, - U 0xC0, U 0xF2, U 0xC0, U 0x84, - U 0x08, U 0x58, U 0x01, U 0x0F, - U 0x5F, U 0x01, U 0x0F, U 0x4B, - U 0x38, U 0x05, U 0x35, U 0x40, - U 0x07, U 0xBB, U 0x10, U 0xC0, - U 0xF0, U 0x08, U 0x4F, U 0x38, - U 0x08, U 0xFF, U 0x10, U 0x0F, - U 0xBB, U 0x02, U 0x28, U 0xEC, - U 0xFE, U 0xC0, U 0xF0, U 0x08, - U 0x4F, U 0x38, U 0x84, U 0x2B, - U 0x0B, U 0xA8, U 0x10, U 0x0A, - U 0xFF, U 0x10, U 0x2A, U 0x21, - U 0x20, U 0x0F, U 0x88, U 0x02, - U 0x0B, U 0x88, U 0x02, U 0x08, - U 0x44, U 0x02, U 0x18, U 0xE8, - U 0x7D, U 0x8F, U 0x11, U 0x08, - U 0x44, U 0x02, U 0x28, U 0x21, - U 0x25, U 0x0A, U 0x2A, U 0x14, - U 0x08, U 0x28, U 0x14, U 0x04, - U 0x88, U 0x11, U 0x0A, U 0x88, - U 0x02, U 0x2A, U 0x21, U 0x04, - U 0x94, U 0xF0, U 0x8B, U 0x20, - U 0x04, U 0xE4, U 0x10, U 0x08, - U 0xBB, U 0x11, U 0x04, U 0xBB, - U 0x02, U 0xC0, U 0x4A, U 0x04, - U 0xBB, U 0x02, U 0x9B, U 0xF1, - U 0x84, U 0x2A, U 0x08, U 0xAB, - U 0x11, U 0x0B, U 0xEB, U 0x02, - U 0x94, U 0xF4, U 0x0A, U 0x54, - U 0x11, U 0x0B, U 0x44, U 0x02, - U 0x05, U 0x55, U 0x10, U 0x0D, - U 0x1B, U 0x40, U 0x94, U 0xF7, - U 0x07, U 0xBB, U 0x10, U 0x0B, - U 0x55, U 0x02, U 0x08, U 0x55, - U 0x02, U 0xC0, U 0x81, U 0x95, - U 0xF6, U 0x84, U 0x33, U 0xC0, - U 0x50, U 0x94, U 0xF3, U 0xB1, - U 0x94, U 0x8B, U 0x32, U 0x95, - U 0xF8, U 0x98, U 0xF9, U 0x9B, - U 0xF2, U 0xC0, U 0x80, U 0xC1, - U 0xBC, U 0x24, U 0x26, U 0x14, - U 0x98, U 0xFB, U 0x9B, U 0xF5, - U 0x99, U 0xFA, U 0x85, U 0x38, - U 0x95, U 0xFC, U 0x84, U 0x3A, - U 0x94, U 0xFD, U 0x8B, U 0x3B, - U 0x9B, U 0xFE, U 0x88, U 0x39, - U 0x98, U 0xFF, U 0x85, U 0x35, - U 0x25, U 0xF6, U 0x10, U 0x84, - U 0x36, U 0x85, U 0x13, U 0x24, - U 0xF6, U 0x11, U 0x8B, U 0x37, - U 0x84, U 0x12, U 0x2B, U 0xF6, - U 0x12, U 0xC0, U 0xB0, U 0x64, - U 0xC0, U 0x81, U 0x89, U 0x30, - U 0x77, U 0x97, U 0x46, U 0x8D, - U 0x32, U 0x88, U 0x33, U 0x2E, - U 0x30, U 0x10, U 0x8F, U 0x11, - U 0x1C, U 0xE8, U 0x40, U 0x09, - U 0x99, U 0x40, U 0x06, U 0x99, - U 0x11, U 0x2C, U 0xF6, U 0x14, - U 0xC0, U 0xC4, U 0x2C, U 0xF6, - U 0x15, U 0x8C, U 0x2B, U 0x2D, - U 0xF6, U 0x1A, U 0x28, U 0xF6, - U 0x1B, U 0x2B, U 0xF6, U 0x19, - U 0x04, U 0xA8, U 0x11, U 0x09, - U 0x88, U 0x02, U 0x08, U 0xEE, - U 0x02, U 0x19, U 0xE8, U 0x35, - U 0xC1, U 0x80, U 0x08, U 0xEE, - U 0x02, U 0x09, U 0xC9, U 0x02, - U 0x29, U 0xF6, U 0x16, U 0x2E, - U 0xF6, U 0x18, U 0xC0, U 0x9E, - U 0x60, U 0x00, U 0x04, U 0x00, - U 0x00, U 0x00, U 0xC0, U 0x9A, + U 0xA0, U 0xC0, U 0xB0, U 0x94, + U 0x12, U 0x95, U 0x13, U 0x1C, + U 0xE8, U 0x67, U 0x88, U 0x30, + U 0x2C, U 0xC0, U 0x22, U 0x08, + U 0x8D, U 0x14, U 0x77, U 0x87, + U 0x04, U 0xC0, U 0xF1, U 0x0C, + U 0xFA, U 0x38, U 0xC0, U 0x41, + U 0xC0, U 0xF2, U 0x25, U 0x20, + U 0x3C, U 0xC0, U 0x84, U 0x08, + U 0x58, U 0x01, U 0x0F, U 0x5F, + U 0x01, U 0x0F, U 0x4B, U 0x38, + U 0x05, U 0x35, U 0x40, U 0x07, + U 0xBB, U 0x10, U 0xC0, U 0xF0, + U 0x08, U 0x4F, U 0x38, U 0x08, + U 0xFF, U 0x10, U 0x0F, U 0xBB, + U 0x02, U 0x28, U 0xEC, U 0xFE, + U 0xC0, U 0xF0, U 0x08, U 0x4F, + U 0x38, U 0x84, U 0x2B, U 0x0B, + U 0xA8, U 0x10, U 0x0A, U 0xFF, + U 0x10, U 0x2A, U 0x21, U 0x20, + U 0x0F, U 0x88, U 0x02, U 0x0B, + U 0x88, U 0x02, U 0x08, U 0x44, + U 0x02, U 0x18, U 0xE8, U 0x75, + U 0x8F, U 0x11, U 0x08, U 0x44, + U 0x02, U 0x28, U 0x21, U 0x25, + U 0x0A, U 0x2A, U 0x14, U 0x08, + U 0x28, U 0x14, U 0x04, U 0x88, + U 0x11, U 0x0A, U 0x88, U 0x02, + U 0x2A, U 0x21, U 0x04, U 0x94, + U 0xF0, U 0x8B, U 0x20, U 0x04, + U 0xE4, U 0x10, U 0x08, U 0xBB, + U 0x11, U 0x04, U 0xBB, U 0x02, + U 0xC0, U 0x4A, U 0x04, U 0xBB, + U 0x02, U 0x9B, U 0xF1, U 0x84, + U 0x2A, U 0x08, U 0xAB, U 0x11, + U 0x0B, U 0xEB, U 0x02, U 0x94, + U 0xF4, U 0x0A, U 0x54, U 0x11, + U 0x0B, U 0x44, U 0x02, U 0x05, + U 0x55, U 0x10, U 0x0D, U 0x1B, + U 0x40, U 0x94, U 0xF7, U 0x07, + U 0xBB, U 0x10, U 0x0B, U 0x55, + U 0x02, U 0x08, U 0x55, U 0x02, + U 0xC0, U 0x81, U 0x95, U 0xF6, + U 0x84, U 0x33, U 0xC0, U 0x50, + U 0x94, U 0xF3, U 0xB1, U 0x94, + U 0x8B, U 0x32, U 0x95, U 0xF8, + U 0x98, U 0xF9, U 0x9B, U 0xF2, + U 0xC0, U 0x80, U 0xC1, U 0xBC, + U 0x24, U 0x26, U 0x14, U 0x99, + U 0xFA, U 0x9B, U 0xF5, U 0x98, + U 0xFB, U 0x85, U 0x38, U 0x95, + U 0xFC, U 0x84, U 0x3A, U 0x94, + U 0xFD, U 0x8B, U 0x3B, U 0x9B, + U 0xFE, U 0x88, U 0x39, U 0x98, + U 0xFF, U 0x85, U 0x35, U 0x25, + U 0xF6, U 0x10, U 0x84, U 0x36, + U 0x85, U 0x13, U 0x24, U 0xF6, + U 0x11, U 0x8B, U 0x37, U 0x84, + U 0x12, U 0x2B, U 0xF6, U 0x12, + U 0xC0, U 0xB0, U 0x64, U 0xC0, + U 0x7E, U 0x89, U 0x30, U 0x77, + U 0x97, U 0x43, U 0x8D, U 0x32, + U 0x88, U 0x33, U 0x2E, U 0x30, + U 0x10, U 0x8F, U 0x11, U 0x1C, + U 0xE8, U 0x39, U 0x09, U 0x99, + U 0x40, U 0x06, U 0x99, U 0x11, + U 0x2C, U 0xF6, U 0x14, U 0xC0, + U 0xC4, U 0x2C, U 0xF6, U 0x15, + U 0x8C, U 0x2B, U 0x2D, U 0xF6, + U 0x1A, U 0x28, U 0xF6, U 0x1B, + U 0x2B, U 0xF6, U 0x19, U 0x04, + U 0xA8, U 0x11, U 0x09, U 0x88, + U 0x02, U 0x08, U 0xEE, U 0x02, + U 0x19, U 0xE8, U 0x2F, U 0xC1, + U 0x80, U 0x08, U 0xEE, U 0x02, + U 0x09, U 0xC9, U 0x02, U 0x29, + U 0xF6, U 0x16, U 0x2E, U 0xF6, + U 0x18, U 0xC0, U 0x9E, U 0x60, + U 0x00, U 0x01, U 0xC0, U 0x9A, U 0x2F, U 0x20, U 0x0C, U 0x18, - U 0xE8, U 0x25, U 0x0C, U 0xFE, + U 0xE8, U 0x1F, U 0x0C, U 0xFE, U 0x11, U 0xA8, U 0xFF, U 0xA6, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0x2B, U 0xF4, U 0xCF, U 0x0D, @@ -2683,45 +2690,46 @@ static unsigned char t3fw[30136] = { U 0xAA, U 0x9A, U 0x26, U 0x0A, U 0x99, U 0x0C, U 0x09, U 0x09, U 0x48, U 0x29, U 0x25, U 0x25, - U 0x65, U 0x50, U 0x4C, U 0xC0, + U 0x65, U 0x50, U 0x50, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xC0, U 0x9A, U 0x63, U 0xFF, U 0xC6, U 0xDA, U 0x20, U 0x58, - U 0x10, U 0x9D, U 0x63, U 0xFE, - U 0x34, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x10, U 0x9A, - U 0x63, U 0xFE, U 0x2A, U 0x00, - U 0x68, U 0x97, U 0x38, U 0xC0, - U 0x20, U 0xD1, U 0x0F, U 0x00, - U 0x00, U 0xDA, U 0x20, U 0xDB, - U 0x70, U 0x58, U 0x10, U 0x57, - U 0xC0, U 0xB0, U 0xC0, U 0xC1, - U 0x0A, U 0xCA, U 0x39, U 0x0A, - U 0xCB, U 0x38, U 0x65, U 0xBD, + U 0x11, U 0x20, U 0x63, U 0xFE, + U 0x38, U 0xDA, U 0x20, U 0xC0, + U 0xB6, U 0x58, U 0x11, U 0x1D, + U 0x63, U 0xFE, U 0x2E, U 0x00, + U 0x68, U 0x97, U 0x3C, U 0x2B, + U 0x9C, U 0xFD, U 0x64, U 0xBE, + U 0x24, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0xDA, U 0x20, U 0xDB, + U 0x70, U 0x58, U 0x10, U 0xD9, + U 0xC0, U 0xC0, U 0xC0, U 0xD1, + U 0x0A, U 0xDA, U 0x39, U 0x0A, + U 0xDC, U 0x38, U 0x65, U 0xCD, U 0xE0, U 0x63, U 0xFE, U 0x09, U 0x8A, U 0x10, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x0F, U 0x2A, + U 0x04, U 0x58, U 0x0F, U 0xAA, U 0xC0, U 0xB0, U 0x2B, U 0x24, U 0x66, U 0x63, U 0xFE, U 0x21, U 0xDB, U 0x40, U 0x2A, U 0x2C, - U 0x74, U 0x58, U 0x09, U 0x0F, + U 0x74, U 0x58, U 0x09, U 0x8B, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x58, U 0x0F, - U 0x2F, U 0x63, U 0xFC, U 0xF7, + U 0xAF, U 0x63, U 0xFC, U 0xF7, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x29, U 0x0A, U 0x80, U 0x1E, U 0xE8, - U 0x1D, U 0x1F, U 0xE8, U 0x1D, - U 0x1C, U 0xE7, U 0xF5, U 0x0C, + U 0x15, U 0x1F, U 0xE8, U 0x15, + U 0x1C, U 0xE7, U 0xEE, U 0x0C, U 0x2B, U 0x11, U 0xAC, U 0xBB, U 0x2C, U 0x2C, U 0xFC, U 0x2D, U 0xB2, U 0x85, U 0x0F, U 0xCC, U 0x02, U 0x9E, U 0xD1, U 0x9C, U 0xD0, U 0xC0, U 0x51, U 0xC0, - U 0x70, U 0x13, U 0xE8, U 0x19, - U 0x14, U 0xE8, U 0x18, U 0x18, - U 0xE8, U 0x16, U 0x2A, U 0xB2, + U 0x70, U 0x13, U 0xE8, U 0x11, + U 0x14, U 0xE8, U 0x10, U 0x18, + U 0xE8, U 0x0E, U 0x2A, U 0xB2, U 0x85, U 0xA8, U 0x28, U 0x04, U 0x24, U 0x0A, U 0x23, U 0x46, U 0x91, U 0xA9, U 0x86, U 0xB8, @@ -2736,17 +2744,17 @@ static unsigned char t3fw[30136] = { U 0x9B, U 0x68, U 0x98, U 0x0B, U 0x2A, U 0x9C, U 0xF9, U 0x65, U 0xA1, U 0xB2, U 0x02, U 0x2A, - U 0x02, U 0x58, U 0x0F, U 0x11, + U 0x02, U 0x58, U 0x0F, U 0x91, U 0x89, U 0x37, U 0x1B, U 0xE7, - U 0xDE, U 0xC8, U 0x91, U 0x64, + U 0xD7, U 0xC8, U 0x91, U 0x64, U 0x52, U 0x0E, U 0x2A, U 0x21, U 0x02, U 0x0A, U 0x0C, U 0x4C, U 0x65, U 0xC2, U 0x58, U 0x8D, - U 0x30, U 0x19, U 0xE7, U 0xD7, + U 0x30, U 0x19, U 0xE7, U 0xD0, U 0x74, U 0xD7, U 0x05, U 0x2E, U 0x21, U 0x23, U 0x65, U 0xE2, U 0x9E, U 0x2F, U 0x92, U 0x9E, - U 0x1A, U 0xE7, U 0xD3, U 0x6F, + U 0x1A, U 0xE7, U 0xCC, U 0x6F, U 0xF8, U 0x02, U 0x60, U 0x02, U 0x53, U 0x2A, U 0xA2, U 0x26, U 0x68, U 0xA0, U 0x08, U 0x2C, @@ -2754,20 +2762,20 @@ static unsigned char t3fw[30136] = { U 0x0C, U 0x65, U 0xC2, U 0x44, U 0x2A, U 0x92, U 0x9D, U 0x64, U 0xA2, U 0x3E, U 0x9A, U 0x15, - U 0x1F, U 0xE7, U 0xCD, U 0x8D, - U 0x67, U 0xC1, U 0xE6, U 0x64, - U 0xD0, U 0x0E, U 0x2B, U 0x62, - U 0x06, U 0x18, U 0xE7, U 0xCA, - U 0x64, U 0xB0, U 0x05, U 0x28, - U 0x80, U 0x21, U 0x7B, U 0x8B, - U 0x42, U 0x2B, U 0x20, U 0x0C, - U 0x18, U 0xE7, U 0xC5, U 0x0C, - U 0xBC, U 0x11, U 0xA8, U 0xCC, - U 0x29, U 0xC2, U 0x86, U 0x79, - U 0xEB, U 0x45, U 0x0F, U 0xBE, - U 0x0A, U 0x2E, U 0xE2, U 0xA3, - U 0x68, U 0xE0, U 0x04, U 0x8F, - U 0x20, U 0x7E, U 0xF9, U 0x37, + U 0x1F, U 0xE7, U 0xC6, U 0x8D, + U 0x67, U 0xC1, U 0xE6, U 0xC8, + U 0xDD, U 0x2B, U 0x62, U 0x06, + U 0x18, U 0xE7, U 0xC4, U 0x64, + U 0xB0, U 0x05, U 0x28, U 0x80, + U 0x21, U 0x7B, U 0x8B, U 0x43, + U 0x2B, U 0x20, U 0x0C, U 0x18, + U 0xE7, U 0xBE, U 0x0C, U 0xBC, + U 0x11, U 0xA8, U 0xCC, U 0x29, + U 0xC2, U 0x86, U 0x79, U 0xEB, + U 0x46, U 0x0F, U 0xBE, U 0x0A, + U 0x2E, U 0xE2, U 0xA3, U 0x68, + U 0xE0, U 0x05, U 0x2F, U 0x22, + U 0x00, U 0x7E, U 0xF9, U 0x37, U 0x2C, U 0xC2, U 0x85, U 0x9C, U 0x18, U 0x64, U 0xC2, U 0x33, U 0x2B, U 0x21, U 0x2F, U 0x87, @@ -2779,7 +2787,7 @@ static unsigned char t3fw[30136] = { U 0x55, U 0x60, U 0x00, U 0x1E, U 0x2A, U 0x20, U 0x0C, U 0xC1, U 0xB2, U 0x8C, U 0x20, U 0x58, - U 0x10, U 0x75, U 0x9A, U 0x18, + U 0x11, U 0x03, U 0x9A, U 0x18, U 0x64, U 0xA2, U 0x45, U 0x8D, U 0x67, U 0x63, U 0xFF, U 0xCF, U 0xC0, U 0xC0, U 0x63, U 0xFF, @@ -2794,7 +2802,7 @@ static unsigned char t3fw[30136] = { U 0x01, U 0x99, U 0xD7, U 0xA0, U 0xDA, U 0x20, U 0xDB, U 0x70, U 0xC1, U 0xC8, U 0x2D, U 0x21, - U 0x20, U 0x58, U 0x10, U 0x1B, + U 0x20, U 0x58, U 0x10, U 0x9D, U 0x8C, U 0x26, U 0x8B, U 0x27, U 0x9A, U 0x16, U 0x0C, U 0xBB, U 0x0C, U 0x7A, U 0xB3, U 0x34, @@ -2812,7 +2820,7 @@ static unsigned char t3fw[30136] = { U 0x02, U 0x60, U 0x00, U 0x97, U 0xCF, U 0x58, U 0x60, U 0x00, U 0x1F, U 0xDA, U 0x20, U 0x8B, - U 0x16, U 0x58, U 0x0F, U 0xE1, + U 0x16, U 0x58, U 0x10, U 0x63, U 0x65, U 0xA1, U 0x38, U 0x63, U 0xFF, U 0xBD, U 0xC0, U 0x81, U 0xC0, U 0x90, U 0x8F, U 0x18, @@ -2821,7 +2829,7 @@ static unsigned char t3fw[30136] = { U 0x97, U 0xF5, U 0x63, U 0xFF, U 0xD2, U 0xDB, U 0x30, U 0xDA, U 0x20, U 0xDC, U 0x40, U 0x58, - U 0x0F, U 0x85, U 0xC0, U 0x51, + U 0x10, U 0x07, U 0xC0, U 0x51, U 0xD6, U 0xA0, U 0xC0, U 0xC0, U 0x2B, U 0xA0, U 0x10, U 0x2C, U 0xA4, U 0x03, U 0x9B, U 0x17, @@ -2846,7 +2854,7 @@ static unsigned char t3fw[30136] = { U 0x26, U 0x18, U 0x63, U 0xFE, U 0x96, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, - U 0x50, U 0x58, U 0x10, U 0x83, + U 0x50, U 0x58, U 0x11, U 0x11, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x30, U 0x2C, U 0x20, U 0x66, U 0x89, U 0x61, U 0xB1, @@ -2863,13 +2871,13 @@ static unsigned char t3fw[30136] = { U 0x8E, U 0x17, U 0x0C, U 0xDD, U 0x11, U 0x9E, U 0x10, U 0xAD, U 0x6D, U 0x2D, U 0xDC, U 0x20, - U 0x1E, U 0xE7, U 0x84, U 0x58, + U 0x1E, U 0xE7, U 0x7C, U 0x58, U 0x00, U 0xF9, U 0x23, U 0x26, U 0x18, U 0xDA, U 0x20, U 0x8B, U 0x16, U 0xDC, U 0x40, U 0x2F, U 0x22, U 0x13, U 0xDD, U 0x50, U 0xB1, U 0xFF, U 0x2F, U 0x26, - U 0x13, U 0x58, U 0x0F, U 0x24, + U 0x13, U 0x58, U 0x0F, U 0xA6, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x28, U 0x20, U 0x3D, U 0x08, U 0x48, U 0x40, U 0x65, @@ -2888,34 +2896,34 @@ static unsigned char t3fw[30136] = { U 0x20, U 0x07, U 0x7F, U 0x02, U 0x8E, U 0x17, U 0xDA, U 0x20, U 0x9E, U 0x10, U 0x1E, U 0xE7, - U 0x6B, U 0x58, U 0x00, U 0x7D, + U 0x63, U 0x58, U 0x00, U 0x7D, U 0x63, U 0xFF, U 0x9A, U 0x00, U 0xC0, U 0x91, U 0x63, U 0xFF, U 0xD1, U 0x00, U 0x00, U 0x00, U 0x65, U 0x50, U 0x81, U 0xDA, U 0x20, U 0xDB, U 0x60, U 0xDC, - U 0x40, U 0x58, U 0x0F, U 0x3B, + U 0x40, U 0x58, U 0x0F, U 0xBD, U 0xC0, U 0x20, U 0xC0, U 0xF0, U 0x2F, U 0xA4, U 0x03, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x0F, U 0xC9, + U 0xB6, U 0x58, U 0x10, U 0x4B, U 0x63, U 0xFF, U 0xE0, U 0x00, U 0x00, U 0x6F, U 0x95, U 0x02, U 0x63, U 0xFD, U 0x6C, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0xC4, - U 0xE0, U 0x58, U 0x0E, U 0xBC, + U 0xE0, U 0x58, U 0x0F, U 0x3E, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x15, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x0E, U 0x5B, + U 0x04, U 0x58, U 0x0E, U 0xDB, U 0x23, U 0x24, U 0x66, U 0x28, U 0x60, U 0x10, U 0x98, U 0x17, U 0x63, U 0xFF, U 0x21, U 0x00, - U 0xDA, U 0x20, U 0x58, U 0x0F, - U 0xBC, U 0x63, U 0xFF, U 0xAB, + U 0xDA, U 0x20, U 0x58, U 0x10, + U 0x3E, U 0x63, U 0xFF, U 0xAB, U 0xC8, U 0x58, U 0xDB, U 0x30, - U 0xDA, U 0x20, U 0x58, U 0x0E, - U 0xA1, U 0x2A, U 0x21, U 0x02, + U 0xDA, U 0x20, U 0x58, U 0x0F, + U 0x22, U 0x2A, U 0x21, U 0x02, U 0x65, U 0xAF, U 0x9C, U 0xC0, U 0x94, U 0x09, U 0xA9, U 0x02, U 0x29, U 0x25, U 0x02, U 0x63, @@ -2923,12 +2931,12 @@ static unsigned char t3fw[30136] = { U 0xDC, U 0x40, U 0xDD, U 0x50, U 0xC0, U 0xA3, U 0x2E, U 0x0A, U 0x80, U 0x2A, U 0x24, U 0x68, - U 0xDA, U 0x20, U 0x58, U 0x0E, - U 0xA9, U 0xD2, U 0xA0, U 0xD1, + U 0xDA, U 0x20, U 0x58, U 0x0F, + U 0x2B, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x2B, - U 0x20, U 0x0C, U 0x58, U 0x0F, - U 0xC5, U 0x63, U 0xFF, U 0x6B, + U 0x20, U 0x0C, U 0x58, U 0x10, + U 0x53, U 0x63, U 0xFF, U 0x6B, U 0x6C, U 0x10, U 0x04, U 0x28, U 0x20, U 0x06, U 0xC0, U 0x62, U 0x28, U 0x8C, U 0xF8, U 0x65, @@ -2946,10 +2954,10 @@ static unsigned char t3fw[30136] = { U 0x03, U 0x0C, U 0xBB, U 0x01, U 0x2B, U 0x26, U 0x1B, U 0x64, U 0x40, U 0x69, U 0x29, U 0x20, - U 0x0C, U 0x1B, U 0xE7, U 0x0B, + U 0x0C, U 0x1B, U 0xE7, U 0x04, U 0x0C, U 0x9A, U 0x11, U 0x0B, U 0xAA, U 0x08, U 0x2F, U 0xA2, - U 0x86, U 0x1B, U 0xE7, U 0x09, + U 0x86, U 0x1B, U 0xE7, U 0x02, U 0x6F, U 0xF9, U 0x02, U 0x60, U 0x00, U 0xB6, U 0x0B, U 0x9B, U 0x0A, U 0x2B, U 0xB2, U 0xA3, @@ -2957,7 +2965,7 @@ static unsigned char t3fw[30136] = { U 0x22, U 0x00, U 0x0B, U 0xCC, U 0x0C, U 0x65, U 0xC0, U 0xA4, U 0x2B, U 0xA2, U 0x85, U 0x1D, - U 0xE7, U 0x2D, U 0x64, U 0xB0, + U 0xE7, U 0x25, U 0x64, U 0xB0, U 0x9B, U 0x8C, U 0x2B, U 0x24, U 0x21, U 0x04, U 0x0D, U 0xCC, U 0x02, U 0x9C, U 0xB0, U 0x88, @@ -2968,7 +2976,7 @@ static unsigned char t3fw[30136] = { U 0x98, U 0xB4, U 0x8F, U 0x34, U 0x94, U 0xB7, U 0x9F, U 0xB5, U 0xC0, U 0x40, U 0x1E, U 0xE6, - U 0xFE, U 0x2D, U 0xA2, U 0x85, + U 0xF7, U 0x2D, U 0xA2, U 0x85, U 0x0E, U 0x9E, U 0x08, U 0x25, U 0xE4, U 0xCF, U 0x2D, U 0xDC, U 0x28, U 0x2D, U 0xA6, U 0x85, @@ -2990,7 +2998,7 @@ static unsigned char t3fw[30136] = { U 0x25, U 0x25, U 0x02, U 0x7B, U 0xF9, U 0x01, U 0xC0, U 0xB0, U 0x64, U 0xBF, U 0xC4, U 0x13, - U 0xE6, U 0xDF, U 0x2C, U 0xB0, + U 0xE6, U 0xD8, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x03, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, @@ -2999,8 +3007,8 @@ static unsigned char t3fw[30136] = { U 0xAF, U 0xE7, U 0x63, U 0xFF, U 0xA6, U 0x2A, U 0x2C, U 0x74, U 0xC0, U 0xB0, U 0x2C, U 0x0A, - U 0x02, U 0x58, U 0x0D, U 0x95, - U 0x1C, U 0xE7, U 0x03, U 0x9C, + U 0x02, U 0x58, U 0x0E, U 0x15, + U 0x1C, U 0xE6, U 0xFB, U 0x9C, U 0xA0, U 0x8B, U 0x20, U 0x08, U 0xBB, U 0x11, U 0x06, U 0xBB, U 0x02, U 0x9B, U 0xA1, U 0x89, @@ -3009,10 +3017,10 @@ static unsigned char t3fw[30136] = { U 0x26, U 0x24, U 0x68, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0x58, - U 0x0F, U 0xE1, U 0xD2, U 0xA0, + U 0x10, U 0x6F, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x2B, U 0x20, U 0x0C, U 0x58, - U 0x0F, U 0x58, U 0xC0, U 0x20, + U 0x0F, U 0xDA, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x07, U 0x3D, U 0x14, U 0xC0, U 0x80, @@ -3023,14 +3031,14 @@ static unsigned char t3fw[30136] = { U 0x08, U 0x08, U 0x42, U 0x77, U 0x40, U 0x01, U 0xB1, U 0xDD, U 0x64, U 0x81, U 0x5A, U 0x1E, - U 0xE6, U 0xBB, U 0x19, U 0xE6, - U 0xBC, U 0x29, U 0xE6, U 0x7E, + U 0xE6, U 0xB4, U 0x19, U 0xE6, + U 0xB5, U 0x29, U 0xE6, U 0x7E, U 0xD3, U 0x0F, U 0x6D, U 0xDA, U 0x05, U 0x00, U 0x50, U 0x88, U 0x00, U 0x30, U 0x8C, U 0xC0, U 0xE0, U 0xC0, U 0x20, U 0x25, U 0xA0, U 0x3C, U 0x14, U 0xE6, - U 0xBA, U 0xB6, U 0xD3, U 0x8F, + U 0xB3, U 0xB6, U 0xD3, U 0x8F, U 0xC0, U 0xC0, U 0xD0, U 0x0F, U 0x87, U 0x14, U 0x24, U 0x40, U 0x22, U 0x0F, U 0x89, U 0x40, @@ -3050,7 +3058,7 @@ static unsigned char t3fw[30136] = { U 0x38, U 0x0A, U 0xEE, U 0x10, U 0x0E, U 0x88, U 0x02, U 0x0D, U 0x88, U 0x02, U 0x8D, U 0xAB, - U 0x1E, U 0xE6, U 0xAA, U 0x08, + U 0x1E, U 0xE6, U 0xA3, U 0x08, U 0xD8, U 0x02, U 0x0E, U 0x88, U 0x02, U 0x98, U 0xB0, U 0xC0, U 0xE8, U 0x04, U 0x28, U 0x10, @@ -3086,9 +3094,9 @@ static unsigned char t3fw[30136] = { U 0xC3, U 0x0B, U 0x34, U 0x0B, U 0x96, U 0x45, U 0x98, U 0x47, U 0x99, U 0x46, U 0x18, U 0xE6, - U 0x91, U 0x9F, U 0x41, U 0x04, + U 0x8A, U 0x9F, U 0x41, U 0x04, U 0x59, U 0x11, U 0x0E, U 0x99, - U 0x02, U 0x1F, U 0xE6, U 0x8F, + U 0x02, U 0x1F, U 0xE6, U 0x88, U 0x02, U 0x0E, U 0x47, U 0x08, U 0xD8, U 0x02, U 0x98, U 0x42, U 0x0E, U 0x99, U 0x02, U 0x9F, @@ -3096,15 +3104,15 @@ static unsigned char t3fw[30136] = { U 0x99, U 0x02, U 0x99, U 0x44, U 0x2F, U 0xA0, U 0x0C, U 0xB4, U 0x38, U 0x0C, U 0xF9, U 0x11, - U 0x14, U 0xE6, U 0x7E, U 0x1E, - U 0xE6, U 0x75, U 0xA4, U 0xFF, + U 0x14, U 0xE6, U 0x77, U 0x1E, + U 0xE6, U 0x6E, U 0xA4, U 0xFF, U 0xAE, U 0x99, U 0x2E, U 0x92, U 0x85, U 0x26, U 0xF4, U 0xCF, U 0x0E, U 0x88, U 0x0B, U 0x28, U 0x96, U 0x85, U 0xD1, U 0x0F, U 0x2B, U 0xA0, U 0x0C, U 0x1F, - U 0xE6, U 0x6F, U 0x1C, U 0xE6, - U 0x76, U 0x0C, U 0xBE, U 0x11, + U 0xE6, U 0x68, U 0x1C, U 0xE6, + U 0x6F, U 0x0C, U 0xBE, U 0x11, U 0xAC, U 0xBB, U 0xAF, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0x26, U 0xB4, U 0xCF, U 0x0D, U 0x3D, @@ -3119,7 +3127,7 @@ static unsigned char t3fw[30136] = { U 0x08, U 0x87, U 0x14, U 0x77, U 0x87, U 0x12, U 0xC0, U 0xB0, U 0xC0, U 0xA6, U 0x19, U 0xE6, - U 0x61, U 0x29, U 0x90, U 0x22, + U 0x5A, U 0x29, U 0x90, U 0x22, U 0xC0, U 0x30, U 0xCC, U 0x97, U 0xC0, U 0x31, U 0x60, U 0x00, U 0x03, U 0xC0, U 0xB0, U 0xC0, @@ -3170,7 +3178,7 @@ static unsigned char t3fw[30136] = { U 0x29, U 0x20, U 0x0C, U 0xD2, U 0xC0, U 0xC0, U 0x80, U 0x0C, U 0x9E, U 0x11, U 0x1B, U 0xE6, - U 0x34, U 0x1F, U 0xE6, U 0x2B, + U 0x2D, U 0x1F, U 0xE6, U 0x24, U 0xAB, U 0x99, U 0xAF, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0x28, U 0x94, U 0xCF, U 0x0D, U 0xAD, @@ -3214,492 +3222,609 @@ static unsigned char t3fw[30136] = { U 0x64, U 0x9F, U 0xEC, U 0xD1, U 0x0F, U 0xD2, U 0x40, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, - U 0x6C, U 0x10, U 0x08, U 0xD6, - U 0x30, U 0xC0, U 0x70, U 0x95, - U 0x15, U 0xDA, U 0x40, U 0x8E, - U 0x39, U 0x14, U 0xE5, U 0xFE, - U 0x9A, U 0x14, U 0x64, U 0xE0, - U 0x02, U 0x64, U 0x51, U 0xFC, - U 0x29, U 0x20, U 0x06, U 0x2A, - U 0x9C, U 0xF8, U 0x65, U 0xA2, - U 0x5F, U 0x2A, U 0x21, U 0x02, + U 0x6C, U 0x10, U 0x0A, U 0xD6, + U 0x30, U 0x2E, U 0x30, U 0x27, + U 0xD9, U 0x50, U 0xDA, U 0x40, + U 0x15, U 0xE5, U 0xF8, U 0x24, + U 0x30, U 0x26, U 0x9A, U 0x15, + U 0x29, U 0x16, U 0x04, U 0x64, + U 0xE0, U 0x02, U 0x64, U 0x93, + U 0x73, U 0x29, U 0x20, U 0x06, + U 0x2A, U 0x9C, U 0xF8, U 0x65, + U 0xA3, U 0xCE, U 0x2A, U 0x21, + U 0x02, U 0x27, U 0x0A, U 0x04, U 0x0A, U 0x0B, U 0x4C, U 0x65, - U 0xB2, U 0x1F, U 0x2C, U 0x32, - U 0x00, U 0x15, U 0xE5, U 0xF4, + U 0xB3, U 0x97, U 0x8C, U 0x30, U 0x74, U 0xC7, U 0x05, U 0x2D, - U 0x21, U 0x23, U 0x65, U 0xD3, - U 0x24, U 0x2E, U 0x52, U 0x9E, - U 0x1A, U 0xE5, U 0xF0, U 0x6F, - U 0xE8, U 0x02, U 0x60, U 0x02, - U 0x1B, U 0x2A, U 0xA2, U 0x26, - U 0x68, U 0xA0, U 0x08, U 0x2B, - U 0x22, U 0x00, U 0x0A, U 0xBB, - U 0x0C, U 0x65, U 0xB2, U 0x0C, - U 0x2E, U 0x52, U 0x9D, U 0x1D, - U 0xE5, U 0xEB, U 0x64, U 0xE2, - U 0x03, U 0x8B, U 0x38, U 0x64, - U 0xB2, U 0x2D, U 0x9E, U 0x16, - U 0xC8, U 0xBC, U 0x8D, U 0x69, - U 0x1E, U 0xE5, U 0xE8, U 0x64, - U 0xD0, U 0x05, U 0x2E, U 0xE0, - U 0x21, U 0x7B, U 0xEB, U 0x49, - U 0x2E, U 0x20, U 0x0C, U 0x18, - U 0xE5, U 0xE2, U 0x0C, U 0xEF, - U 0x11, U 0xA8, U 0xFF, U 0x29, - U 0xF2, U 0x86, U 0xC1, U 0x86, - U 0x79, U 0x8B, U 0x4A, U 0x17, - U 0xE5, U 0xDF, U 0x07, U 0xE7, - U 0x0A, U 0x27, U 0x72, U 0xA3, - U 0x68, U 0x70, U 0x04, U 0x88, - U 0x20, U 0x77, U 0x89, U 0x39, - U 0x25, U 0xF2, U 0x85, U 0x64, - U 0x52, U 0xA2, U 0x27, U 0x21, - U 0x2E, U 0x07, U 0xB7, U 0x36, - U 0x07, U 0xB9, U 0x0C, U 0x6F, - U 0x9D, U 0x01, U 0xD7, U 0xB0, - U 0x89, U 0x69, U 0x6E, U 0x92, - U 0x42, U 0x28, U 0x20, U 0x3D, - U 0x7B, U 0x87, U 0x3C, U 0x8A, - U 0x15, U 0xCD, U 0xAF, U 0x60, - U 0x00, U 0x18, U 0xC1, U 0xB2, + U 0x21, U 0x23, U 0x65, U 0xD4, + U 0xA0, U 0xC0, U 0xA6, U 0x2B, + U 0x0A, U 0x03, U 0x2C, U 0x22, + U 0x00, U 0x58, U 0x0F, U 0x17, + U 0x64, U 0xA3, U 0xB9, U 0x17, + U 0xE5, U 0xE6, U 0x8E, U 0x38, + U 0x9A, U 0x16, U 0x64, U 0xE3, + U 0xBA, U 0x2F, U 0x60, U 0x27, + U 0x28, U 0x50, U 0x21, U 0xC9, + U 0xF3, U 0x7E, U 0x83, U 0x11, + U 0xC2, U 0xB0, U 0x8C, U 0x20, + U 0x2A, U 0x20, U 0x0C, U 0x58, + U 0x0F, U 0x36, U 0xD7, U 0xA0, + U 0xCD, U 0xA1, U 0x60, U 0x04, + U 0xA2, U 0x00, U 0xC2, U 0xB0, U 0x8C, U 0x20, U 0x2A, U 0x20, - U 0x0C, U 0x58, U 0x0E, U 0x90, - U 0xD5, U 0xA0, U 0x64, U 0xA2, - U 0xAC, U 0x8B, U 0x68, U 0x63, - U 0xFF, U 0xCB, U 0xC0, U 0x50, - U 0x63, U 0xFF, U 0xC3, U 0xC0, - U 0xE0, U 0x60, U 0x00, U 0x02, - U 0x2E, U 0x60, U 0x03, U 0x0E, - U 0x9B, U 0x0C, U 0x6E, U 0xB2, - U 0x0E, U 0xDC, U 0x70, U 0x0C, - U 0xEA, U 0x11, U 0xAA, U 0x6A, - U 0x2A, U 0xAC, U 0x28, U 0x5B, - U 0xFF, U 0xB6, U 0xD7, U 0xA0, - U 0xDA, U 0x20, U 0xDB, U 0x70, - U 0xC1, U 0xC4, U 0x2D, U 0x21, - U 0x1F, U 0x58, U 0x0E, U 0x38, - U 0x8C, U 0x26, U 0x8B, U 0x27, - U 0xD4, U 0xA0, U 0x0C, U 0xBB, - U 0x0C, U 0x7A, U 0xB3, U 0x25, - U 0x8A, U 0x63, U 0xC0, U 0x90, - U 0x9A, U 0x53, U 0x88, U 0x62, - U 0x99, U 0x58, U 0x98, U 0x52, - U 0x8F, U 0x65, U 0x9F, U 0x59, - U 0x8E, U 0x67, U 0x9E, U 0x5B, - U 0x8D, U 0x66, U 0x97, U 0x55, - U 0x9D, U 0x5A, U 0x8B, U 0x68, - U 0x7B, U 0x7B, U 0x74, U 0x8B, - U 0x15, U 0xCE, U 0xB3, U 0x60, - U 0x00, U 0x0D, U 0xDA, U 0x20, - U 0xDB, U 0x40, U 0x58, U 0x0E, - U 0x02, U 0x65, U 0xA1, U 0x0D, - U 0x63, U 0xFF, U 0xCC, U 0x00, - U 0xDA, U 0x20, U 0xDB, U 0x30, - U 0x8C, U 0x14, U 0x58, U 0x0D, - U 0xAA, U 0xD6, U 0xA0, U 0xC0, - U 0xC0, U 0xC0, U 0xD1, U 0x9D, - U 0x15, U 0x2C, U 0xA4, U 0x03, + U 0x0C, U 0x58, U 0x0F, U 0x0A, + U 0xD7, U 0xA0, U 0x64, U 0xA4, + U 0x86, U 0x2F, U 0x21, U 0x2E, + U 0x8B, U 0x68, U 0x0F, U 0xBF, + U 0x36, U 0x0F, U 0xB9, U 0x0C, + U 0x6F, U 0x9D, U 0x54, U 0x29, + U 0x60, U 0x27, U 0xD5, U 0xB0, + U 0x6E, U 0x92, U 0x05, U 0x28, + U 0x20, U 0x3D, U 0x7B, U 0x8F, + U 0x4C, U 0xDA, U 0x20, U 0xDB, + U 0x50, U 0xC1, U 0xC4, U 0x2D, + U 0x21, U 0x1F, U 0x58, U 0x0E, + U 0xD0, U 0x8B, U 0x26, U 0x9A, + U 0x18, U 0x9A, U 0x19, U 0x89, + U 0x27, U 0x2A, U 0xAC, U 0x38, + U 0x0B, U 0x99, U 0x0C, U 0x7A, + U 0x93, U 0x53, U 0x89, U 0x63, + U 0xC0, U 0x80, U 0x99, U 0x73, + U 0x8F, U 0x62, U 0x98, U 0x78, + U 0x9F, U 0x72, U 0x8E, U 0x65, + U 0x9E, U 0x79, U 0x8D, U 0x67, + U 0x9D, U 0x7B, U 0x8C, U 0x66, + U 0x95, U 0x75, U 0x9C, U 0x7A, + U 0x8E, U 0x68, U 0x7E, U 0x53, + U 0x02, U 0x60, U 0x00, U 0xB1, + U 0x8B, U 0x14, U 0x65, U 0xB0, + U 0x50, U 0x60, U 0x00, U 0x38, + U 0xDB, U 0xF0, U 0x63, U 0xFF, + U 0xA5, U 0x00, U 0x8A, U 0x14, + U 0xC9, U 0xA9, U 0x2E, U 0x60, + U 0x03, U 0x0E, U 0x9B, U 0x0C, + U 0x6E, U 0xB2, U 0xA5, U 0xDC, + U 0x50, U 0x0C, U 0xEA, U 0x11, + U 0xAA, U 0x6A, U 0x2A, U 0xAC, + U 0x28, U 0x5B, U 0xFF, U 0xB1, + U 0xD5, U 0xA0, U 0x63, U 0xFF, + U 0x93, U 0xC0, U 0xE0, U 0x63, + U 0xFF, U 0xE2, U 0xDA, U 0x20, + U 0x8B, U 0x18, U 0x58, U 0x0E, + U 0x8D, U 0x65, U 0xA2, U 0xB1, + U 0x63, U 0xFF, U 0x9E, U 0x00, + U 0x00, U 0xDA, U 0x20, U 0xDB, + U 0x30, U 0x8C, U 0x15, U 0x58, + U 0x0E, U 0x35, U 0xD6, U 0xA0, + U 0xC0, U 0xC0, U 0xC0, U 0xD1, + U 0x2D, U 0x16, U 0x04, U 0x2C, + U 0xA4, U 0x03, U 0xDC, U 0x70, U 0xDA, U 0x20, U 0xDB, U 0x60, - U 0xDF, U 0x70, U 0xDC, U 0x50, - U 0xC0, U 0xE0, U 0x25, U 0x60, - U 0x03, U 0x9E, U 0x10, U 0x1E, - U 0xE5, U 0xC1, U 0x0C, U 0x5D, - U 0x11, U 0xAD, U 0x6D, U 0x2D, - U 0xDC, U 0x28, U 0x5B, U 0xFF, - U 0x3F, U 0x8E, U 0x66, U 0xA5, - U 0xA8, U 0x8F, U 0x67, U 0x28, - U 0x64, U 0x03, U 0xAF, U 0x7F, - U 0x77, U 0xFB, U 0x01, U 0xB1, - U 0xEE, U 0x9E, U 0x66, U 0x9F, - U 0x67, U 0x8D, U 0x26, U 0x8C, - U 0x29, U 0xA4, U 0xDD, U 0x0D, - U 0xCC, U 0x0C, U 0x9D, U 0x26, - U 0x8B, U 0x68, U 0x0C, U 0x0C, - U 0x48, U 0x2C, U 0x25, U 0x25, - U 0x07, U 0xBB, U 0x0C, U 0x9B, - U 0x68, U 0x63, U 0xFE, U 0xC3, - U 0x2C, U 0x20, U 0x66, U 0x89, - U 0x61, U 0xB1, U 0xCC, U 0x0C, - U 0x0C, U 0x47, U 0x2C, U 0x24, - U 0x66, U 0x6E, U 0xC6, U 0x02, - U 0x60, U 0x00, U 0xB8, U 0x09, - U 0xFD, U 0x50, U 0x65, U 0xD0, - U 0xB2, U 0xCB, U 0xBF, U 0x8E, - U 0x69, U 0xCB, U 0xEB, U 0xDB, - U 0x60, U 0xDC, U 0x50, U 0xDF, - U 0x70, U 0xDA, U 0x20, U 0x1E, - U 0xE5, U 0xBC, U 0x2D, U 0x60, + U 0xDF, U 0x50, U 0x2D, U 0x60, + U 0x03, U 0xC0, U 0xE0, U 0x9E, + U 0x10, U 0x9D, U 0x17, U 0x1E, + U 0xE5, U 0xC1, U 0x0C, U 0xDD, + U 0x11, U 0x0D, U 0x6D, U 0x08, + U 0x2D, U 0xDC, U 0x28, U 0x5B, + U 0xFF, U 0x47, U 0x8E, U 0x66, + U 0x8F, U 0x67, U 0x88, U 0x17, + U 0xAF, U 0x5F, U 0xA8, U 0xA8, + U 0x28, U 0x64, U 0x03, U 0x75, + U 0xFB, U 0x01, U 0xB1, U 0xEE, + U 0x8A, U 0x18, U 0x9E, U 0x66, + U 0x9F, U 0x67, U 0x89, U 0x26, + U 0x88, U 0x29, U 0xAA, U 0x99, + U 0x09, U 0x88, U 0x0C, U 0x99, + U 0x26, U 0x8E, U 0x68, U 0x08, + U 0x08, U 0x48, U 0x05, U 0xEE, + U 0x0C, U 0x28, U 0x25, U 0x25, + U 0x15, U 0xE5, U 0x9B, U 0x9E, + U 0x68, U 0x65, U 0xEE, U 0xCC, + U 0x63, U 0xFE, U 0xE6, U 0x00, + U 0x00, U 0x00, U 0xC9, U 0x43, + U 0x2F, U 0x21, U 0x23, U 0x2B, + U 0x21, U 0x21, U 0x2F, U 0xFC, + U 0x01, U 0x0F, U 0x0F, U 0x4F, + U 0x2F, U 0x25, U 0x23, U 0x7F, + U 0xBB, U 0x02, U 0x60, U 0x03, + U 0x14, U 0x2C, U 0x20, U 0x66, + U 0x89, U 0x61, U 0xB1, U 0xCC, + U 0x0C, U 0x0C, U 0x47, U 0x2C, + U 0x24, U 0x66, U 0x6E, U 0xC6, + U 0x02, U 0x60, U 0x02, U 0x28, + U 0x09, U 0xFD, U 0x50, U 0x65, + U 0xD2, U 0x22, U 0x64, U 0xE1, + U 0xB6, U 0x2E, U 0x60, U 0x27, + U 0x64, U 0xE1, U 0xB0, U 0xDC, + U 0x70, U 0xDF, U 0x50, U 0xDA, + U 0x20, U 0xDB, U 0x60, U 0x1E, + U 0xE5, U 0xB2, U 0x2D, U 0x60, U 0x03, U 0xC0, U 0x80, U 0x98, U 0x10, U 0x0C, U 0xDD, U 0x11, U 0xAD, U 0x6D, U 0x2D, U 0xDC, - U 0x28, U 0x5B, U 0xFF, U 0x24, - U 0x8B, U 0x15, U 0xC9, U 0x42, - U 0x8A, U 0x26, U 0x29, U 0x22, - U 0x09, U 0x04, U 0xAA, U 0x08, - U 0x2A, U 0x26, U 0x06, U 0x0A, - U 0x99, U 0x0C, U 0x09, U 0x09, - U 0x48, U 0x29, U 0x25, U 0x25, - U 0x65, U 0xB1, U 0x3C, U 0xC0, - U 0x20, U 0xD1, U 0x0F, U 0x00, + U 0x28, U 0x5B, U 0xFF, U 0x22, + U 0x64, U 0x41, U 0x81, U 0xC0, + U 0x44, U 0x2B, U 0x0A, U 0x00, + U 0x8C, U 0x20, U 0x2A, U 0x20, + U 0x0C, U 0x58, U 0x0E, U 0xAC, + U 0x0A, U 0xA7, U 0x02, U 0x65, + U 0xA0, U 0x0F, U 0xC0, U 0xB0, + U 0x2C, U 0x22, U 0x00, U 0x2A, + U 0x20, U 0x0C, U 0x58, U 0x0E, + U 0xA8, U 0xD7, U 0xA0, U 0x64, + U 0xAF, U 0xEF, U 0xDA, U 0x20, + U 0xC1, U 0xBC, U 0xC1, U 0xC8, + U 0x2D, U 0x21, U 0x20, U 0x8F, + U 0x18, U 0x8E, U 0x26, U 0x89, + U 0x29, U 0xAF, U 0xEE, U 0x9E, + U 0x26, U 0x0E, U 0x99, U 0x0C, + U 0x09, U 0x09, U 0x48, U 0x29, + U 0x25, U 0x25, U 0x58, U 0x0E, + U 0x70, U 0xC0, U 0x90, U 0xC0, + U 0x50, U 0xC0, U 0xC2, U 0x88, + U 0x60, U 0x9A, U 0x19, U 0x1E, + U 0xE5, U 0x6E, U 0xC0, U 0xA1, + U 0x2E, U 0xE0, U 0x22, U 0x08, + U 0x8F, U 0x14, U 0x77, U 0x87, + U 0x04, U 0xC0, U 0x81, U 0x0E, + U 0x89, U 0x38, U 0xC0, U 0x80, + U 0x0B, U 0x93, U 0x10, U 0x2D, + U 0x20, U 0x3C, U 0x29, U 0x21, + U 0x20, U 0x0C, U 0xDC, U 0x01, + U 0x04, U 0xDB, U 0x01, U 0x09, + U 0x29, U 0x14, U 0x0B, U 0xA8, + U 0x38, U 0x0C, U 0xA5, U 0x38, + U 0x0D, U 0x3D, U 0x40, U 0x1C, + U 0xE5, U 0x85, U 0x8B, U 0x2B, + U 0x08, U 0x88, U 0x10, U 0x07, + U 0x55, U 0x10, U 0x08, U 0x55, + U 0x02, U 0x05, U 0x33, U 0x02, + U 0x28, U 0x21, U 0x25, U 0x0F, + U 0x15, U 0x40, U 0x03, U 0xBB, + U 0x02, U 0x0C, U 0xBB, U 0x02, + U 0x07, U 0x55, U 0x10, U 0x05, + U 0xD3, U 0x10, U 0x08, U 0x28, + U 0x14, U 0x0A, U 0xDD, U 0x11, + U 0x04, U 0x88, U 0x11, U 0x09, + U 0x88, U 0x02, U 0x05, U 0x33, + U 0x02, U 0x29, U 0x21, U 0x04, + U 0x08, U 0x33, U 0x02, U 0x9B, + U 0x70, U 0xC0, U 0x80, U 0x8A, + U 0x20, U 0x1B, U 0xE5, U 0x7E, + U 0x08, U 0xAA, U 0x11, U 0x0B, + U 0xAA, U 0x02, U 0x9A, U 0x71, + U 0xC0, U 0xA1, U 0x85, U 0x2A, + U 0x93, U 0x76, U 0x95, U 0x74, + U 0x08, U 0x93, U 0x11, U 0x03, + U 0xDD, U 0x02, U 0x0A, U 0xDD, + U 0x02, U 0x9D, U 0x77, U 0x8C, + U 0x63, U 0xC1, U 0xDC, U 0x9C, + U 0x73, U 0x8B, U 0x62, U 0x98, + U 0x78, U 0x9A, U 0x79, U 0x9B, + U 0x72, U 0x23, U 0x22, U 0x14, + U 0xC0, U 0xC0, U 0xB1, U 0x35, + U 0x25, U 0x26, U 0x14, U 0x9C, + U 0x7B, U 0x9D, U 0x75, U 0x93, + U 0x7A, U 0x2B, U 0x62, U 0x1A, + U 0x9B, U 0x7C, U 0x2A, U 0x62, + U 0x1C, U 0x9A, U 0x7D, U 0x28, + U 0x62, U 0x1D, U 0x98, U 0x7E, + U 0x25, U 0x62, U 0x1B, U 0x95, + U 0x7F, U 0x23, U 0x62, U 0x17, + U 0x23, U 0x76, U 0x10, U 0x2D, + U 0x62, U 0x18, U 0x2D, U 0x76, + U 0x11, U 0x2C, U 0x62, U 0x19, + U 0x2C, U 0x76, U 0x12, U 0x64, + U 0xE0, U 0xB9, U 0x8E, U 0x60, + U 0x77, U 0xE7, U 0x3D, U 0xC0, + U 0xFE, U 0x13, U 0xE5, U 0x46, + U 0x1D, U 0xE5, U 0x47, U 0xC1, + U 0x81, U 0x8A, U 0x62, U 0x8B, + U 0x63, U 0x04, U 0x95, U 0x11, + U 0x0E, U 0x9C, U 0x40, U 0x06, + U 0xCC, U 0x11, U 0x0C, U 0x55, + U 0x02, U 0x24, U 0x76, U 0x15, + U 0x08, U 0x55, U 0x02, U 0xC0, + U 0x80, U 0x2D, U 0x76, U 0x14, + U 0x8D, U 0x2B, U 0x2B, U 0x76, + U 0x1B, U 0x2A, U 0x76, U 0x1A, + U 0x28, U 0x76, U 0x19, U 0x25, + U 0x76, U 0x18, U 0x03, U 0xDD, + U 0x02, U 0x2D, U 0x76, U 0x16, + U 0x60, U 0x00, U 0x03, U 0x00, + U 0x00, U 0xC0, U 0xFA, U 0x2E, + U 0x20, U 0x0C, U 0x19, U 0xE5, + U 0x2D, U 0x18, U 0xE5, U 0x24, + U 0xA9, U 0xE9, U 0x0C, U 0xEE, + U 0x11, U 0xA8, U 0xEE, U 0xC0, + U 0x80, U 0x2D, U 0xE2, U 0x85, + U 0x28, U 0x94, U 0xCF, U 0x0D, + U 0xFD, U 0x0B, U 0x2D, U 0xE6, + U 0x85, U 0xDA, U 0x20, U 0x8B, + U 0x19, U 0x8C, U 0x15, U 0x8D, + U 0x14, U 0x58, U 0x0D, U 0x71, + U 0xD2, U 0xA0, U 0xD1, U 0x0F, + U 0xDC, U 0x70, U 0xDF, U 0x50, U 0xDB, U 0x60, U 0x2D, U 0x6C, - U 0x28, U 0xDF, U 0x70, U 0xDA, - U 0x20, U 0xC0, U 0xC0, U 0x1E, - U 0xE5, U 0xAC, U 0x9C, U 0x10, - U 0xDC, U 0x50, U 0x5B, U 0xFE, - U 0xB4, U 0x63, U 0xFF, U 0xC7, - U 0x00, U 0x2D, U 0x20, U 0x3D, - U 0x0D, U 0x4D, U 0x40, U 0x65, - U 0xDD, U 0xF9, U 0x6F, U 0xE5, - U 0x22, U 0xDA, U 0x30, U 0x8F, - U 0x45, U 0x6D, U 0xE9, U 0x0C, + U 0x28, U 0xC0, U 0xA0, U 0x1E, + U 0xE5, U 0x45, U 0x9A, U 0x10, + U 0xDA, U 0x20, U 0x5B, U 0xFE, + U 0x55, U 0x63, U 0xFE, U 0x53, + U 0x00, U 0x2B, U 0x20, U 0x3D, + U 0x0B, U 0x4B, U 0x40, U 0x65, + U 0xBC, U 0x82, U 0x6F, U 0xE5, + U 0x27, U 0xDA, U 0x30, U 0x8F, + U 0x55, U 0x6D, U 0xE9, U 0x0C, U 0x8E, U 0xAA, U 0x0E, U 0x8E, - U 0x14, U 0xC9, U 0xE3, U 0x7E, - U 0xF3, U 0x11, U 0x2A, U 0xAC, + U 0x14, U 0xC9, U 0xE8, U 0x7E, + U 0xF3, U 0x16, U 0x2A, U 0xAC, U 0x10, U 0xC0, U 0x90, U 0x29, U 0x24, U 0x67, U 0x09, U 0x0F, - U 0x47, U 0x64, U 0xFD, U 0xD7, - U 0x60, U 0x01, U 0x41, U 0x00, - U 0xC0, U 0x91, U 0x63, U 0xFF, - U 0xED, U 0x00, U 0x88, U 0x15, - U 0x65, U 0x81, U 0x4C, U 0xDA, + U 0x47, U 0x64, U 0xFC, U 0x60, + U 0x60, U 0x01, U 0x5F, U 0x00, + U 0xC0, U 0xFA, U 0x63, U 0xFF, + U 0x85, U 0xC0, U 0x91, U 0x63, + U 0xFF, U 0xE8, U 0x88, U 0x14, + U 0x65, U 0x81, U 0x68, U 0xDA, U 0x20, U 0xDB, U 0x60, U 0x8C, - U 0x14, U 0x58, U 0x0D, U 0x66, + U 0x15, U 0x58, U 0x0D, U 0x88, U 0xC0, U 0x20, U 0xC0, U 0x90, U 0x29, U 0xA4, U 0x03, U 0xD1, - U 0x0F, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x0D, U 0xF4, - U 0x63, U 0xFF, U 0xDE, U 0x00, - U 0x8A, U 0x16, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x0C, U 0x8C, - U 0xC0, U 0xA0, U 0x2A, U 0x24, - U 0x66, U 0x8B, U 0x68, U 0x63, - U 0xFF, U 0x3A, U 0x00, U 0x00, + U 0x0F, U 0x8A, U 0x16, U 0x2B, + U 0x21, U 0x04, U 0x58, U 0x0C, + U 0xAF, U 0xC0, U 0xA0, U 0x2A, + U 0x24, U 0x66, U 0x8E, U 0x68, + U 0x63, U 0xFD, U 0xCA, U 0x00, U 0x00, U 0x2B, U 0x9C, U 0xF9, - U 0x65, U 0xB0, U 0xC5, U 0xDA, - U 0x20, U 0x58, U 0x0C, U 0x91, - U 0x63, U 0xFD, U 0x91, U 0x00, + U 0x65, U 0xB0, U 0xFD, U 0xDA, + U 0x20, U 0x58, U 0x0C, U 0xB4, + U 0x63, U 0xFC, U 0x22, U 0x00, + U 0x00, U 0xDA, U 0x20, U 0xC0, + U 0xB6, U 0x58, U 0x0E, U 0x0D, + U 0x63, U 0xFF, U 0xBA, U 0x00, U 0x2B, U 0x20, U 0x0C, U 0x0C, - U 0xBA, U 0x11, U 0xA5, U 0xAA, - U 0x2F, U 0xA2, U 0x86, U 0xC1, - U 0xC2, U 0x7F, U 0xC3, U 0x02, - U 0x60, U 0x00, U 0xFC, U 0x0D, - U 0xB9, U 0x0A, U 0x29, U 0x92, - U 0xA3, U 0x68, U 0x90, U 0x07, - U 0x8C, U 0x20, U 0x09, U 0xCC, - U 0x0C, U 0x65, U 0xC0, U 0xEB, - U 0x26, U 0xA2, U 0x85, U 0x64, - U 0x60, U 0xE5, U 0x2C, U 0x20, + U 0xBE, U 0x11, U 0xA7, U 0xEE, + U 0x2D, U 0xE2, U 0x86, U 0xC1, + U 0xC2, U 0x7D, U 0xC3, U 0x02, + U 0x60, U 0x01, U 0x18, U 0x19, + U 0xE4, U 0xF1, U 0x09, U 0xB9, + U 0x0A, U 0x29, U 0x92, U 0xA3, + U 0x68, U 0x90, U 0x08, U 0x2A, + U 0x22, U 0x00, U 0x09, U 0xAA, + U 0x0C, U 0x65, U 0xA1, U 0x03, + U 0x26, U 0xE2, U 0x85, U 0x64, + U 0x60, U 0xFD, U 0x2C, U 0x20, U 0x66, U 0x89, U 0x31, U 0xB1, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0x6F, U 0xC6, U 0x02, U 0x70, U 0x96, - U 0x0A, U 0xDA, U 0xE0, U 0x2B, + U 0x0C, U 0x8A, U 0x16, U 0x2B, U 0x21, U 0x04, U 0x58, U 0x0C, - U 0x74, U 0x27, U 0x24, U 0x66, - U 0x89, U 0x30, U 0x77, U 0x97, - U 0x4B, U 0x18, U 0xE5, U 0x59, - U 0x1D, U 0xE5, U 0x5A, U 0x8A, - U 0x32, U 0x8B, U 0x33, U 0xC0, - U 0xF4, U 0x2C, U 0x21, U 0x04, - U 0x09, U 0x9E, U 0x40, U 0x06, - U 0xEE, U 0x11, U 0x04, U 0xCC, - U 0x11, U 0x0E, U 0xCC, U 0x02, - U 0x9F, U 0x61, U 0xC1, U 0xE0, - U 0x0E, U 0xCC, U 0x02, U 0x9D, - U 0x60, U 0x8F, U 0x2B, U 0x9A, - U 0x66, U 0x9B, U 0x67, U 0x9C, - U 0x64, U 0x97, U 0x65, U 0x08, - U 0xFF, U 0x02, U 0x9F, U 0x62, - U 0x2F, U 0x20, U 0x0C, U 0x18, - U 0xE5, U 0x43, U 0x0C, U 0xFE, - U 0x11, U 0xA5, U 0xEE, U 0x2D, - U 0xE2, U 0x85, U 0xA8, U 0xFF, - U 0x27, U 0xF4, U 0xCF, U 0x2D, - U 0xDC, U 0x20, U 0x2D, U 0xE6, - U 0x85, U 0x8F, U 0x15, U 0x65, - U 0xF0, U 0x91, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0x00, U 0x00, - U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x14, U 0x58, U 0x06, U 0x43, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x00, U 0xDA, U 0x20, U 0xDB, - U 0xE0, U 0x58, U 0x0D, U 0xBC, - U 0x63, U 0xFE, U 0xFE, U 0x00, - U 0x00, U 0xDA, U 0x20, U 0xDB, - U 0x30, U 0x8C, U 0x14, U 0x8D, - U 0x15, U 0x58, U 0x0E, U 0x3E, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x00, U 0x00, U 0x88, U 0x15, - U 0xC8, U 0x88, U 0xDA, U 0x20, + U 0x93, U 0xC0, U 0xD0, U 0x2D, + U 0x24, U 0x66, U 0x8E, U 0x30, + U 0x77, U 0xE7, U 0x4D, U 0x1C, + U 0xE4, U 0xF1, U 0x1B, U 0xE4, + U 0xF1, U 0x8F, U 0x32, U 0x88, + U 0x33, U 0xC0, U 0xA4, U 0x2D, + U 0x21, U 0x04, U 0x0E, U 0x99, + U 0x40, U 0x06, U 0x99, U 0x11, + U 0x04, U 0xDD, U 0x11, U 0x09, + U 0xDD, U 0x02, U 0x9A, U 0x61, + U 0xC1, U 0x90, U 0x09, U 0xDD, + U 0x02, U 0x9B, U 0x60, U 0xC0, + U 0x90, U 0x8B, U 0x2B, U 0x9D, + U 0x64, U 0x9F, U 0x66, U 0x98, + U 0x67, U 0x99, U 0x65, U 0x0C, + U 0xBB, U 0x02, U 0x9B, U 0x62, + U 0x28, U 0x20, U 0x0C, U 0x1A, + U 0xE4, U 0xDA, U 0xAA, U 0x8A, + U 0x0C, U 0x88, U 0x11, U 0xA7, + U 0x88, U 0x2F, U 0x82, U 0x85, + U 0x29, U 0xA4, U 0xCF, U 0x2F, + U 0xFC, U 0x20, U 0x2F, U 0x86, + U 0x85, U 0x8A, U 0x14, U 0x65, + U 0xA0, U 0xA6, U 0xC0, U 0x20, + U 0xD1, U 0x0F, U 0xB0, U 0xFC, + U 0x8B, U 0x14, U 0x2C, U 0x25, + U 0x23, U 0xC8, U 0xB7, U 0x02, + U 0x2A, U 0x02, U 0x06, U 0x6B, + U 0x02, U 0x58, U 0x0C, U 0xC4, + U 0x2A, U 0x21, U 0x02, U 0x65, + U 0xAE, U 0xF7, U 0xC0, U 0xD8, + U 0x0D, U 0xAD, U 0x02, U 0x2D, + U 0x25, U 0x02, U 0x63, U 0xFE, + U 0xEC, U 0x00, U 0x8E, U 0x14, + U 0xC8, U 0xE8, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x58, U 0x0C, - U 0x9C, U 0x2A, U 0x21, U 0x02, - U 0x65, U 0xAE, U 0xDA, U 0xC0, - U 0x94, U 0x09, U 0xA9, U 0x02, - U 0x29, U 0x25, U 0x02, U 0x63, - U 0xFE, U 0xCF, U 0xDA, U 0x20, - U 0x2B, U 0x20, U 0x0C, U 0x58, - U 0x0D, U 0xC7, U 0x63, U 0xFE, - U 0xC4, U 0x27, U 0x24, U 0x68, - U 0xDA, U 0x20, U 0xDB, U 0x30, - U 0x2C, U 0x12, U 0x04, U 0x2D, - U 0x12, U 0x05, U 0x2E, U 0x0A, - U 0x80, U 0x58, U 0x0C, U 0xA1, - U 0x63, U 0xFC, U 0x7C, U 0x00, + U 0xBD, U 0x2A, U 0x21, U 0x02, + U 0x65, U 0xAE, U 0xDA, U 0x07, + U 0xAF, U 0x02, U 0x2F, U 0x25, + U 0x02, U 0x63, U 0xFE, U 0xD1, + U 0x00, U 0xDA, U 0x20, U 0xDB, + U 0x30, U 0x8C, U 0x15, U 0x8D, + U 0x14, U 0x58, U 0x0E, U 0x61, + U 0xD2, U 0xA0, U 0xD1, U 0x0F, + U 0xDA, U 0x20, U 0x2B, U 0x20, + U 0x0C, U 0x58, U 0x0D, U 0xCC, + U 0x63, U 0xFE, U 0xB6, U 0x00, + U 0xDA, U 0x20, U 0x2B, U 0x20, + U 0x0C, U 0x58, U 0x0D, U 0xEE, + U 0x63, U 0xFE, U 0xAA, U 0xDA, + U 0x20, U 0xDB, U 0x30, U 0x8C, + U 0x15, U 0x2D, U 0x12, U 0x04, + U 0x2E, U 0x0A, U 0x80, U 0x28, + U 0x0A, U 0x00, U 0x28, U 0x24, + U 0x68, U 0x58, U 0x0C, U 0xBC, + U 0x63, U 0xFA, U 0xE5, U 0x00, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x58, U 0x0D, - U 0xA5, U 0x8A, U 0x15, U 0xCD, - U 0xA1, U 0xDA, U 0x20, U 0x03, - U 0x3B, U 0x02, U 0x2C, U 0x12, - U 0x04, U 0x58, U 0x0D, U 0x0F, - U 0x27, U 0xA4, U 0x03, U 0xC0, - U 0x20, U 0xD1, U 0x0F, U 0x00, - U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x14, U 0x58, U 0x06, U 0x20, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x6C, U 0x10, U 0x0C, U 0x28, - U 0x21, U 0x02, U 0x94, U 0x10, - U 0x08, U 0x08, U 0x4C, U 0x65, - U 0x83, U 0x62, U 0x1F, U 0xE5, - U 0x09, U 0x29, U 0xF2, U 0x9E, - U 0x6F, U 0x98, U 0x02, U 0x60, - U 0x03, U 0x66, U 0x1D, U 0xE5, - U 0x05, U 0x29, U 0xD2, U 0x26, - U 0x68, U 0x90, U 0x08, U 0x2A, - U 0x22, U 0x00, U 0x09, U 0xAA, - U 0x0C, U 0x65, U 0xA3, U 0x54, - U 0x2C, U 0xF2, U 0x9D, U 0x64, - U 0xC3, U 0x4E, U 0x2B, U 0x20, - U 0x0C, U 0x0C, U 0xB6, U 0x11, - U 0xAF, U 0x66, U 0x28, U 0x62, - U 0x86, U 0xC1, U 0xEC, U 0x78, - U 0xE3, U 0x02, U 0x60, U 0x03, - U 0x46, U 0x19, U 0xE4, U 0xFC, - U 0x09, U 0xB9, U 0x0A, U 0x29, - U 0x92, U 0xA3, U 0x68, U 0x90, - U 0x07, U 0x8A, U 0x20, U 0x09, + U 0xC0, U 0x89, U 0x14, U 0xCD, + U 0x92, U 0xDA, U 0x20, U 0xDB, + U 0x30, U 0x8C, U 0x15, U 0x58, + U 0x0D, U 0x2B, U 0xDB, U 0xA0, + U 0xC0, U 0x20, U 0xC0, U 0xA0, + U 0x2A, U 0xB4, U 0x03, U 0xD1, + U 0x0F, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0x2A, U 0x2C, U 0x74, + U 0x8B, U 0x15, U 0x58, U 0x06, + U 0x35, U 0xD2, U 0xA0, U 0xD1, + U 0x0F, U 0x00, U 0x00, U 0x00, + U 0x6C, U 0x10, U 0x0E, U 0x28, + U 0x21, U 0x02, U 0x24, U 0x16, + U 0x01, U 0x08, U 0x08, U 0x4C, + U 0x65, U 0x83, U 0x95, U 0x1F, + U 0xE4, U 0x9A, U 0x29, U 0xF2, + U 0x9E, U 0x6F, U 0x98, U 0x02, + U 0x60, U 0x03, U 0x99, U 0x1E, + U 0xE4, U 0x96, U 0x29, U 0xE2, + U 0x26, U 0x68, U 0x90, U 0x08, + U 0x2A, U 0x22, U 0x00, U 0x09, U 0xAA, U 0x0C, U 0x65, U 0xA3, - U 0x32, U 0x24, U 0x62, U 0x85, - U 0x64, U 0x43, U 0x2C, U 0xC0, - U 0xE1, U 0x2A, U 0x31, U 0x09, - U 0xC0, U 0x70, U 0x27, U 0x24, - U 0x66, U 0x89, U 0x35, U 0x9A, - U 0x11, U 0x99, U 0x2A, U 0x88, - U 0x36, U 0x99, U 0x12, U 0x98, - U 0x2B, U 0x89, U 0x37, U 0x98, - U 0x13, U 0x99, U 0x2C, U 0x88, - U 0x38, U 0x99, U 0x14, U 0x08, - U 0x58, U 0x14, U 0x98, U 0x15, - U 0x98, U 0x2D, U 0x89, U 0x39, - U 0x2A, U 0x25, U 0x04, U 0x2E, - U 0x25, U 0x1D, U 0x29, U 0x25, - U 0x1C, U 0x28, U 0x30, U 0x28, - U 0xC0, U 0x92, U 0x28, U 0x24, - U 0x3C, U 0x2A, U 0x30, U 0x29, - U 0x08, U 0x08, U 0x47, U 0x98, - U 0x16, U 0x09, U 0x89, U 0x01, - U 0x2A, U 0x24, U 0x3D, U 0x2A, - U 0x31, U 0x15, U 0x99, U 0x17, - U 0x0A, U 0x09, U 0x41, U 0x09, - U 0xA9, U 0x0C, U 0x29, U 0x9C, - U 0xEC, U 0x29, U 0x25, U 0x1F, - U 0x7E, U 0x87, U 0x19, U 0x2D, - U 0x2A, U 0x00, U 0x0D, U 0xA0, - U 0x60, U 0x00, U 0x08, U 0x3E, - U 0x01, U 0x0A, U 0x3E, U 0xB1, - U 0xAD, U 0x08, U 0xDA, U 0x39, - U 0x0E, U 0xAA, U 0x11, U 0x0A, - U 0x99, U 0x0C, U 0x29, U 0x25, - U 0x1F, U 0x2A, U 0x21, U 0x1F, - U 0x18, U 0xE5, U 0x06, U 0x0A, - U 0x81, U 0x60, U 0xC1, U 0xD0, - U 0x94, U 0x1A, U 0x95, U 0x1B, - U 0x01, U 0x08, U 0x3E, U 0x00, - U 0x05, U 0x3E, U 0xB1, U 0x84, - U 0x05, U 0x48, U 0x39, U 0x84, - U 0x3C, U 0x25, U 0x9C, U 0xFC, - U 0x0D, U 0x88, U 0x36, U 0x29, - U 0x20, U 0x14, U 0x08, U 0xAA, - U 0x1C, U 0x8D, U 0x3D, U 0x27, - U 0x26, U 0x18, U 0x2E, U 0x26, - U 0x13, U 0x2E, U 0x26, U 0x14, - U 0x2E, U 0x26, U 0x15, U 0x27, - U 0x26, U 0x1B, U 0x2E, U 0x24, - U 0x6B, U 0x27, U 0x24, U 0x67, - U 0x27, U 0x24, U 0x68, U 0x08, - U 0x58, U 0x1C, U 0x09, U 0x09, - U 0x43, U 0x29, U 0x24, U 0x14, - U 0x29, U 0x32, U 0x11, U 0x2A, - U 0x25, U 0x2E, U 0x28, U 0x25, - U 0x2F, U 0x27, U 0x25, U 0x24, - U 0x27, U 0x25, U 0x25, U 0x27, - U 0x25, U 0x2C, U 0x27, U 0x25, - U 0x23, U 0x25, U 0x25, U 0x20, - U 0x24, U 0x25, U 0x21, U 0x2D, - U 0x25, U 0x22, U 0x84, U 0x1A, - U 0x2D, U 0x21, U 0x1C, U 0x85, - U 0x1B, U 0x6F, U 0xD2, U 0x02, - U 0x60, U 0x02, U 0x09, U 0xC0, - U 0xA0, U 0x99, U 0x18, U 0x6D, + U 0x87, U 0x24, U 0xF2, U 0x9D, + U 0x64, U 0x43, U 0x81, U 0x2A, + U 0x31, U 0x16, U 0x0A, U 0x4B, + U 0x41, U 0x2B, U 0x24, U 0x0B, + U 0xB4, U 0xBB, U 0x0B, U 0x0B, + U 0x47, U 0x2B, U 0x24, U 0x0C, + U 0x0C, U 0xB6, U 0x11, U 0xAF, + U 0x66, U 0x28, U 0x62, U 0x86, + U 0xC1, U 0xCC, U 0x78, U 0xC3, + U 0x02, U 0x60, U 0x03, U 0x6B, + U 0x19, U 0xE4, U 0x8A, U 0x09, + U 0xB9, U 0x0A, U 0x29, U 0x92, + U 0xA3, U 0x68, U 0x90, U 0x07, + U 0x8C, U 0x20, U 0x09, U 0xCC, + U 0x0C, U 0x65, U 0xC3, U 0x57, + U 0x27, U 0x62, U 0x85, U 0x64, + U 0x73, U 0x51, U 0x29, U 0x31, + U 0x09, U 0xC0, U 0xD0, U 0x2D, + U 0x24, U 0x66, U 0x8C, U 0x35, + U 0x99, U 0x13, U 0x9C, U 0x2A, + U 0x88, U 0x36, U 0x9C, U 0x14, + U 0x98, U 0x2B, U 0x8E, U 0x37, + U 0x98, U 0x15, U 0x9E, U 0x16, + U 0x9E, U 0x2C, U 0x8C, U 0x38, + U 0xC0, U 0xE1, U 0x0C, U 0x5C, + U 0x14, U 0x9C, U 0x17, U 0x9C, + U 0x2D, U 0x88, U 0x39, U 0x29, + U 0x25, U 0x04, U 0x2E, U 0x25, + U 0x1D, U 0x28, U 0x25, U 0x1C, + U 0x2C, U 0x30, U 0x28, U 0xC0, + U 0x82, U 0x2C, U 0x24, U 0x3C, + U 0x29, U 0x30, U 0x29, U 0x0C, + U 0x0C, U 0x47, U 0x08, U 0xC8, + U 0x01, U 0x29, U 0x24, U 0x3D, + U 0x29, U 0x31, U 0x15, U 0x98, + U 0x18, U 0x99, U 0x12, U 0x09, + U 0x08, U 0x41, U 0x08, U 0x99, + U 0x0C, U 0x29, U 0x9C, U 0xEC, + U 0x29, U 0x25, U 0x1F, U 0x7E, + U 0xC7, U 0x25, U 0x92, U 0x1C, + U 0x82, U 0x12, U 0x28, U 0x2A, + U 0x00, U 0x08, U 0x20, U 0x60, + U 0x99, U 0x1B, U 0x01, U 0x02, + U 0x3E, U 0x00, U 0x09, U 0x3E, + U 0xB1, U 0x28, U 0x09, U 0x82, + U 0x39, U 0x89, U 0x1B, U 0x0E, + U 0x22, U 0x11, U 0x02, U 0x99, + U 0x0C, U 0x82, U 0x1C, U 0x29, + U 0x25, U 0x1F, U 0x82, U 0x1C, + U 0x94, U 0x1D, U 0x95, U 0x1E, + U 0x24, U 0x21, U 0x1F, U 0x15, + U 0xE4, U 0x8F, U 0x04, U 0x51, + U 0x60, U 0x9A, U 0x10, U 0xC1, + U 0x80, U 0x2B, U 0x16, U 0x10, + U 0x25, U 0x20, U 0x14, U 0x96, + U 0x1F, U 0x05, U 0x05, U 0x43, + U 0x01, U 0x06, U 0x3E, U 0x00, + U 0x0D, U 0x3E, U 0xB1, U 0x6B, + U 0x0D, U 0xB6, U 0x39, U 0x8B, + U 0x3C, U 0x2D, U 0x9C, U 0xFC, + U 0x08, U 0x66, U 0x36, U 0x06, + U 0x44, U 0x1C, U 0x89, U 0x3D, + U 0x2E, U 0x26, U 0x13, U 0x2E, + U 0x26, U 0x14, U 0x2E, U 0x26, + U 0x15, U 0x2E, U 0x24, U 0x6B, + U 0x25, U 0x24, U 0x14, U 0x06, + U 0xD6, U 0x1C, U 0xC0, U 0x50, + U 0x25, U 0x26, U 0x18, U 0x25, + U 0x26, U 0x1B, U 0x25, U 0x24, + U 0x67, U 0x25, U 0x24, U 0x68, + U 0x28, U 0x32, U 0x11, U 0x25, + U 0x25, U 0x23, U 0x25, U 0x25, + U 0x24, U 0x25, U 0x25, U 0x25, + U 0x25, U 0x25, U 0x2C, U 0x29, + U 0x25, U 0x22, U 0x2D, U 0x25, + U 0x20, U 0x2B, U 0x25, U 0x21, + U 0x24, U 0x25, U 0x2E, U 0x26, + U 0x25, U 0x2F, U 0x14, U 0xE4, + U 0x76, U 0x16, U 0xE4, U 0x74, + U 0x1B, U 0xE4, U 0x5A, U 0x98, + U 0x19, U 0x2D, U 0x21, U 0x1C, + U 0xC0, U 0x84, U 0x98, U 0x71, + U 0x9B, U 0x70, U 0x89, U 0x20, + U 0x95, U 0x75, U 0x95, U 0x77, + U 0x95, U 0x7F, U 0x96, U 0x7C, + U 0x96, U 0x7E, U 0x98, U 0x79, + U 0x9B, U 0x78, U 0x94, U 0x73, + U 0x1B, U 0xE4, U 0x6E, U 0x14, + U 0xE4, U 0x6F, U 0x0C, U 0x38, + U 0x40, U 0x02, U 0x88, U 0x10, + U 0x0C, U 0x06, U 0x40, U 0x15, + U 0xE4, U 0x6B, U 0x01, U 0x66, + U 0x10, U 0x94, U 0x7D, U 0x9B, + U 0x74, U 0x84, U 0x1D, U 0x1B, + U 0xE4, U 0x4C, U 0x08, U 0x66, + U 0x02, U 0x95, U 0x7B, U 0x18, + U 0xE4, U 0x39, U 0x85, U 0x1E, + U 0x0B, U 0x99, U 0x02, U 0x99, + U 0x72, U 0x99, U 0x7A, U 0x08, + U 0x66, U 0x02, U 0x2B, U 0x12, + U 0x10, U 0x96, U 0x76, U 0x86, + U 0x1F, U 0x6F, U 0xD2, U 0x02, + U 0x60, U 0x01, U 0xC0, U 0xC0, + U 0xA0, U 0x99, U 0x1A, U 0x6D, U 0x08, U 0x0A, U 0xB1, U 0xAA, U 0x00, U 0xA1, U 0x04, U 0x00, - U 0xE9, U 0x1A, U 0x7D, U 0x9B, + U 0xE8, U 0x1A, U 0x7D, U 0x8B, U 0x02, U 0x63, U 0xFF, U 0xEE, - U 0x89, U 0x18, U 0xC0, U 0x80, - U 0xC0, U 0xE1, U 0xC0, U 0x70, - U 0xC0, U 0xD2, U 0x9B, U 0x1D, - U 0x95, U 0x1B, U 0x96, U 0x1C, - U 0x9C, U 0x1E, U 0x16, U 0xE4, - U 0xD1, U 0x2C, U 0x20, U 0x3D, - U 0x15, U 0xE4, U 0xE0, U 0x0C, - U 0x0B, U 0x40, U 0x0D, U 0xCC, - U 0x01, U 0x0B, U 0xE7, U 0x38, - U 0x1D, U 0xE4, U 0xC3, U 0x0A, - U 0x77, U 0x10, U 0x0C, U 0xE8, - U 0x38, U 0x0B, U 0x88, U 0x10, - U 0xC0, U 0xC4, U 0x9C, U 0x41, - U 0x08, U 0x77, U 0x02, U 0x9D, - U 0x40, U 0xB0, U 0xA8, U 0x09, - U 0x88, U 0x11, U 0x8B, U 0x20, - U 0x9C, U 0x49, U 0x9D, U 0x48, - U 0x95, U 0x4B, U 0x96, U 0x43, - U 0x08, U 0x77, U 0x02, U 0x86, - U 0x14, U 0x18, U 0xE4, U 0xD1, - U 0x15, U 0xE4, U 0xB9, U 0x08, - U 0x77, U 0x02, U 0x05, U 0xBB, - U 0x02, U 0x9B, U 0x4A, U 0x9B, - U 0x42, U 0x97, U 0x46, U 0x88, - U 0x12, U 0x87, U 0x11, U 0x08, - U 0xDA, U 0x14, U 0x9A, U 0x4E, - U 0x0D, U 0x88, U 0x10, U 0x0D, - U 0x77, U 0x11, U 0x08, U 0x77, - U 0x02, U 0x1A, U 0xE4, U 0xAC, - U 0x06, U 0xD8, U 0x14, U 0x0D, - U 0x66, U 0x10, U 0x08, U 0x77, - U 0x02, U 0x97, U 0x4F, U 0xC7, - U 0x8F, U 0x98, U 0x4D, U 0x98, - U 0x4C, U 0x98, U 0x45, U 0x87, - U 0x15, U 0x98, U 0x44, U 0x07, - U 0x15, U 0x14, U 0x0D, U 0x55, - U 0x11, U 0x0A, U 0x55, U 0x02, - U 0x95, U 0x47, U 0x15, U 0xE4, - U 0xC1, U 0x8A, U 0x26, U 0x2D, - U 0x46, U 0x10, U 0x2D, U 0x46, - U 0x18, U 0x2D, U 0x46, U 0x20, - U 0x2C, U 0x46, U 0x11, U 0x2C, - U 0x46, U 0x19, U 0x2C, U 0x46, - U 0x21, U 0x2B, U 0x46, U 0x12, - U 0x2B, U 0x46, U 0x1A, U 0x28, - U 0x46, U 0x14, U 0x28, U 0x46, - U 0x15, U 0x2B, U 0x46, U 0x22, - U 0x88, U 0x16, U 0x25, U 0x46, - U 0x24, U 0x25, U 0x46, U 0x26, - U 0x8B, U 0x17, U 0x0A, U 0x0C, - U 0x48, U 0x09, U 0x0D, U 0x48, - U 0x85, U 0x13, U 0x0E, U 0xDD, - U 0x11, U 0x05, U 0xCC, U 0x11, - U 0x08, U 0x39, U 0x40, U 0x0B, - U 0xEB, U 0x39, U 0x02, U 0x99, - U 0x10, U 0x1E, U 0xE4, U 0xB0, - U 0x0D, U 0xCC, U 0x02, U 0x0D, - U 0x55, U 0x11, U 0x08, U 0x2D, - U 0x40, U 0x06, U 0x55, U 0x02, - U 0x2E, U 0x46, U 0x13, U 0x16, - U 0xE4, U 0x7B, U 0x0F, U 0xDD, - U 0x11, U 0x25, U 0x46, U 0x16, - U 0x08, U 0x08, U 0x40, U 0x85, - U 0x1B, U 0x01, U 0x88, U 0x10, - U 0x0D, U 0xBB, U 0x02, U 0x86, - U 0x67, U 0x1D, U 0xE4, U 0xA7, - U 0x09, U 0x88, U 0x02, U 0x0C, - U 0xBB, U 0x02, U 0x19, U 0xE4, - U 0x77, U 0x1C, U 0xE4, U 0xA5, - U 0x2B, U 0x46, U 0x17, U 0x2D, - U 0x46, U 0x1B, U 0xA7, U 0x66, - U 0x1B, U 0xE4, U 0xA4, U 0xC0, - U 0x70, U 0x2C, U 0x46, U 0x1C, - U 0x09, U 0x88, U 0x02, U 0x8C, - U 0x1E, U 0x28, U 0x46, U 0x1E, - U 0x2B, U 0x46, U 0x23, U 0xC0, - U 0x90, U 0x8B, U 0x1D, U 0x29, - U 0x46, U 0x1D, U 0x29, U 0x46, - U 0x1F, U 0x18, U 0xE4, U 0x9D, - U 0x29, U 0x46, U 0x27, U 0x28, - U 0x46, U 0x25, U 0x29, U 0x31, - U 0x16, U 0x2E, U 0x20, U 0x06, - U 0x29, U 0x24, U 0x6A, U 0x24, - U 0x31, U 0x17, U 0x96, U 0x2D, - U 0x24, U 0x25, U 0x23, U 0x86, - U 0x1C, U 0xCC, U 0xE1, U 0x27, - U 0x24, U 0x07, U 0xC0, U 0xD7, - U 0x09, U 0x0E, U 0x40, U 0x64, - U 0xE0, U 0x82, U 0x9A, U 0x29, - U 0x09, U 0x28, U 0x41, U 0x64, - U 0x80, U 0x91, U 0x64, U 0x40, - U 0x9B, U 0x2D, U 0x24, U 0x06, - U 0xC0, U 0x98, U 0x09, U 0x49, - U 0x36, U 0x28, U 0x0A, U 0xA0, - U 0x24, U 0x62, U 0x85, U 0x01, - U 0xC4, U 0x04, U 0xA8, U 0x44, - U 0x28, U 0x21, U 0x04, U 0x24, - U 0x66, U 0x85, U 0x08, U 0x88, - U 0x11, U 0x8E, U 0x3F, U 0x8A, - U 0x3E, U 0x2D, U 0x32, U 0x10, - U 0x0E, U 0xA4, U 0x18, U 0x00, - U 0xC4, U 0x04, U 0x0E, U 0xAE, - U 0x18, U 0x00, U 0xEE, U 0x11, - U 0x0A, U 0xCA, U 0x53, U 0x0E, - U 0xDD, U 0x02, U 0xC0, U 0xE3, - U 0x0E, U 0x88, U 0x02, U 0x98, - U 0xC1, U 0x1E, U 0xE4, U 0x82, - U 0x09, U 0x08, U 0x4E, U 0x9E, - U 0xC0, U 0x8E, U 0x20, U 0x94, - U 0xC3, U 0x98, U 0xC5, U 0x9D, - U 0xC4, U 0x18, U 0xE4, U 0x4E, - U 0x1D, U 0xE4, U 0x7F, U 0x05, - U 0xEE, U 0x11, U 0x0E, U 0xAA, - U 0x02, U 0x0D, U 0xAA, U 0x02, - U 0xA8, U 0xB8, U 0x27, U 0x84, - U 0xCF, U 0x9A, U 0xC2, U 0x1E, - U 0xE4, U 0x40, U 0x24, U 0xF2, - U 0x9D, U 0x27, U 0xE4, U 0xA2, - U 0x24, U 0x4C, U 0x18, U 0x24, - U 0xF6, U 0x9D, U 0x65, U 0x50, - U 0x52, U 0xC0, U 0x20, U 0xD1, - U 0x0F, U 0x2D, U 0x24, U 0x06, - U 0xC0, U 0xA0, U 0xC0, U 0x98, - U 0x09, U 0x49, U 0x36, U 0x04, - U 0xA9, U 0x38, U 0x63, U 0xFF, - U 0x7F, U 0xC0, U 0xA0, U 0x63, - U 0xFE, U 0x07, U 0x00, U 0x00, - U 0x65, U 0x4F, U 0x6D, U 0xC0, + U 0x89, U 0x1A, U 0xC0, U 0xE2, + U 0xC0, U 0x81, U 0x2B, U 0x16, + U 0x10, U 0x95, U 0x1E, U 0x94, + U 0x1D, U 0x96, U 0x1F, U 0x2D, + U 0x20, U 0x3D, U 0x29, U 0x76, + U 0x1A, U 0x29, U 0x76, U 0x12, + U 0xC0, U 0x60, U 0x14, U 0xE4, + U 0x40, U 0xC0, U 0x50, U 0x24, + U 0x76, U 0x13, U 0x0D, U 0x0B, + U 0x40, U 0x84, U 0x17, U 0x0B, + U 0x85, U 0x38, U 0x0E, U 0xDD, + U 0x01, U 0x8B, U 0x14, U 0x1E, + U 0xE4, U 0x51, U 0x0A, U 0x55, + U 0x10, U 0x0D, U 0x86, U 0x38, + U 0x0B, U 0x66, U 0x10, U 0x06, + U 0x55, U 0x02, U 0x2E, U 0x76, + U 0x1B, U 0xB0, U 0xA6, U 0x0B, + U 0xDD, U 0x14, U 0xC0, U 0xE4, + U 0x2E, U 0x76, U 0x19, U 0x2E, + U 0x76, U 0x11, U 0x0D, U 0xBB, + U 0x10, U 0x8A, U 0x13, U 0x2D, + U 0x76, U 0x1E, U 0x09, U 0x66, + U 0x11, U 0x8D, U 0x16, U 0x06, + U 0x55, U 0x02, U 0x0D, U 0xAA, + U 0x11, U 0x16, U 0xE4, U 0x43, + U 0x0B, U 0xAA, U 0x02, U 0x0D, + U 0xDB, U 0x14, U 0x06, U 0x55, + U 0x02, U 0x0D, U 0xDD, U 0x10, + U 0x0B, U 0xAA, U 0x02, U 0x25, + U 0x76, U 0x16, U 0x04, U 0x16, + U 0x14, U 0x0D, U 0x66, U 0x11, + U 0x15, U 0xE4, U 0x1E, U 0x2A, + U 0x76, U 0x1F, U 0xC7, U 0xBF, + U 0x2B, U 0x76, U 0x1D, U 0x2B, + U 0x76, U 0x1C, U 0x2B, U 0x76, + U 0x15, U 0x2B, U 0x76, U 0x14, + U 0x1A, U 0xE4, U 0x17, U 0x25, + U 0x76, U 0x18, U 0x25, U 0x76, + U 0x10, U 0x0A, U 0x66, U 0x02, + U 0x26, U 0x76, U 0x17, U 0x0C, + U 0x26, U 0x40, U 0x0F, U 0x66, + U 0x11, U 0x8A, U 0x26, U 0x2B, + U 0x76, U 0x24, U 0x2B, U 0x76, + U 0x25, U 0x2E, U 0x76, U 0x21, + U 0x25, U 0x76, U 0x20, U 0x29, + U 0x76, U 0x22, U 0x85, U 0x18, + U 0x19, U 0xE4, U 0x30, U 0x1E, + U 0xE3, U 0xFA, U 0x8B, U 0x15, + U 0x8E, U 0xE7, U 0x29, U 0x76, + U 0x23, U 0x05, U 0x85, U 0x39, + U 0x89, U 0x10, U 0x88, U 0x19, + U 0x06, U 0x55, U 0x02, U 0x0D, + U 0xBB, U 0x11, U 0x0D, U 0xBB, + U 0x02, U 0xA4, U 0xEE, U 0x0A, + U 0x06, U 0x48, U 0x84, U 0x1D, + U 0x05, U 0x66, U 0x11, U 0x2B, + U 0x76, U 0x26, U 0x08, U 0x08, + U 0x48, U 0x0E, U 0x88, U 0x11, + U 0x2B, U 0x12, U 0x10, U 0x08, + U 0x66, U 0x02, U 0x06, U 0x55, + U 0x02, U 0x86, U 0x1F, U 0x25, + U 0x76, U 0x27, U 0x9E, U 0x2D, + U 0x85, U 0x1E, U 0x29, U 0x24, + U 0x6A, U 0x27, U 0x31, U 0x17, + U 0x2D, U 0x20, U 0x06, U 0x27, + U 0x25, U 0x38, U 0xCC, U 0xD3, + U 0xC0, U 0x80, U 0x28, U 0x24, + U 0x07, U 0xC0, U 0xD7, U 0x09, + U 0x0C, U 0x40, U 0x64, U 0xC0, + U 0x86, U 0x9A, U 0x29, U 0x09, + U 0x2E, U 0x41, U 0x64, U 0xE0, + U 0x96, U 0x64, U 0x70, U 0xA0, + U 0x2D, U 0x24, U 0x06, U 0xC0, + U 0x98, U 0x09, U 0x79, U 0x36, + U 0x01, U 0xC4, U 0x04, U 0x2E, + U 0x21, U 0x04, U 0x27, U 0x62, + U 0x85, U 0x28, U 0x0A, U 0xA0, + U 0xA8, U 0x77, U 0x08, U 0xEE, + U 0x11, U 0xC0, U 0x83, U 0x27, + U 0x66, U 0x85, U 0x2A, U 0x32, + U 0x10, U 0x8D, U 0x3F, U 0x08, + U 0xEE, U 0x02, U 0x8C, U 0x3E, + U 0x09, U 0x08, U 0x4E, U 0x0D, + U 0xC7, U 0x18, U 0x00, U 0xC4, + U 0x04, U 0x9E, U 0x41, U 0x0D, + U 0xCD, U 0x18, U 0x00, U 0xDD, + U 0x11, U 0x0D, U 0xAA, U 0x02, + U 0x1D, U 0xE4, U 0x08, U 0x0C, + U 0xCC, U 0x53, U 0x9D, U 0x40, + U 0x1D, U 0xE4, U 0x07, U 0x8E, + U 0x20, U 0x97, U 0x43, U 0x9A, + U 0x44, U 0x98, U 0x45, U 0x1A, + U 0xE3, U 0xD3, U 0x05, U 0xEE, + U 0x11, U 0x0E, U 0xCC, U 0x02, + U 0xAA, U 0xBA, U 0xC0, U 0xE0, + U 0x0D, U 0xCC, U 0x02, U 0x9C, + U 0x42, U 0x2E, U 0xA4, U 0xCF, + U 0x17, U 0xE3, U 0xC5, U 0x28, + U 0xF2, U 0x9D, U 0x2E, U 0x74, + U 0xA2, U 0x28, U 0x8C, U 0x18, + U 0x28, U 0xF6, U 0x9D, U 0x65, + U 0x50, U 0x55, U 0xC0, U 0x20, + U 0xD1, U 0x0F, U 0x00, U 0x00, + U 0x2D, U 0x24, U 0x06, U 0xC0, + U 0xA0, U 0xC0, U 0x98, U 0x09, + U 0x79, U 0x36, U 0x07, U 0xA9, + U 0x38, U 0x63, U 0xFF, U 0x7B, + U 0xC0, U 0xA0, U 0x63, U 0xFE, + U 0x50, U 0x00, U 0x00, U 0x00, + U 0x65, U 0x7F, U 0x68, U 0xC0, U 0x98, U 0xC0, U 0xA8, U 0x2A, U 0x24, U 0x06, U 0x63, U 0xFF, - U 0x6B, U 0x2D, U 0x24, U 0x06, + U 0x66, U 0x2D, U 0x24, U 0x06, U 0xC0, U 0x90, U 0x63, U 0xFF, - U 0x63, U 0xCC, U 0x57, U 0xDA, + U 0x5E, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x8C, - U 0x10, U 0x58, U 0x0C, U 0x2A, + U 0x11, U 0x58, U 0x0C, U 0x37, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x0C, U 0xB9, + U 0xB6, U 0x58, U 0x0C, U 0xC6, U 0x63, U 0xFF, U 0xE5, U 0x00, U 0xDA, U 0x20, U 0x58, U 0x0C, - U 0xB7, U 0x63, U 0xFF, U 0xDC, + U 0xC4, U 0x63, U 0xFF, U 0xDC, U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x10, U 0x58, U 0x05, U 0x38, + U 0x11, U 0x58, U 0x05, U 0x3F, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x28, U 0x20, U 0x06, U 0x8A, U 0x33, U 0x6F, U 0x82, U 0x02, U 0x60, U 0x01, U 0x61, U 0xC0, U 0x50, - U 0x13, U 0xE4, U 0x20, U 0x29, - U 0x21, U 0x02, U 0x16, U 0xE4, - U 0x1F, U 0x69, U 0x92, U 0x04, + U 0x13, U 0xE3, U 0xA4, U 0x29, + U 0x21, U 0x02, U 0x16, U 0xE3, + U 0xA3, U 0x69, U 0x92, U 0x04, U 0x25, U 0x25, U 0x02, U 0xD9, U 0x50, U 0x2C, U 0x20, U 0x15, - U 0x9A, U 0x28, U 0x14, U 0xE4, - U 0x1D, U 0x8F, U 0x26, U 0x27, + U 0x9A, U 0x28, U 0x14, U 0xE3, + U 0xA1, U 0x8F, U 0x26, U 0x27, U 0x20, U 0x0B, U 0x0A, U 0xFE, U 0x0C, U 0x04, U 0x77, U 0x09, U 0x2B, U 0x71, U 0x1C, U 0x64, @@ -3732,13 +3857,13 @@ static unsigned char t3fw[30136] = { U 0xCC, U 0x28, U 0xC2, U 0x86, U 0x2E, U 0x0A, U 0x08, U 0x78, U 0xEB, U 0x61, U 0x1E, U 0xE3, - U 0xFB, U 0x0E, U 0xBE, U 0x0A, + U 0x7F, U 0x0E, U 0xBE, U 0x0A, U 0x2E, U 0xE2, U 0xA3, U 0x68, U 0xE0, U 0x05, U 0x28, U 0x22, U 0x00, U 0x7E, U 0x89, U 0x4F, U 0x29, U 0xC2, U 0x85, U 0x1E, - U 0xE4, U 0x07, U 0x64, U 0x90, - U 0x46, U 0x1F, U 0xE4, U 0x15, + U 0xE3, U 0x8B, U 0x64, U 0x90, + U 0x46, U 0x1F, U 0xE3, U 0x98, U 0x9E, U 0x90, U 0xC0, U 0x84, U 0x98, U 0x91, U 0x28, U 0x20, U 0x0A, U 0x95, U 0x93, U 0x0F, @@ -3752,7 +3877,7 @@ static unsigned char t3fw[30136] = { U 0x07, U 0x68, U 0xE3, U 0x43, U 0x29, U 0x21, U 0x02, U 0x2A, U 0xC2, U 0x85, U 0x1D, U 0xE3, - U 0xEE, U 0x2A, U 0xAC, U 0x20, + U 0x72, U 0x2A, U 0xAC, U 0x20, U 0xAD, U 0xBD, U 0x25, U 0xD4, U 0xCF, U 0x2A, U 0xC6, U 0x85, U 0x63, U 0xFF, U 0x4E, U 0x00, @@ -3761,7 +3886,7 @@ static unsigned char t3fw[30136] = { U 0x24, U 0x65, U 0xC9, U 0xF6, U 0x05, U 0xE4, U 0x31, U 0x00, U 0x02, U 0x00, U 0x2A, U 0x62, - U 0x82, U 0x1B, U 0xE3, U 0xF7, + U 0x82, U 0x1B, U 0xE3, U 0x7A, U 0x29, U 0x41, U 0x02, U 0x0B, U 0xAA, U 0x02, U 0x2A, U 0x66, U 0x82, U 0x09, U 0xE4, U 0x31, @@ -3821,7 +3946,7 @@ static unsigned char t3fw[30136] = { U 0x2D, U 0x20, U 0x6A, U 0x0D, U 0x2D, U 0x41, U 0x65, U 0xDF, U 0x7E, U 0xDA, U 0x20, U 0xC0, - U 0xB0, U 0x58, U 0x0C, U 0x75, + U 0xB0, U 0x58, U 0x0C, U 0x8E, U 0x64, U 0xAF, U 0x18, U 0xC0, U 0xF1, U 0x63, U 0xFE, U 0xEF, U 0x9F, U 0x27, U 0x63, U 0xFF, @@ -3831,8 +3956,8 @@ static unsigned char t3fw[30136] = { U 0x28, U 0x22, U 0x1F, U 0x65, U 0x8E, U 0x27, U 0x63, U 0xFF, U 0x6E, U 0x25, U 0x24, U 0x06, - U 0x25, U 0x25, U 0x02, U 0xC0, - U 0x90, U 0x63, U 0xFE, U 0x19, + U 0x29, U 0x21, U 0x02, U 0x63, + U 0xFE, U 0x1B, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x65, U 0x71, U 0x33, U 0x2B, U 0x4C, U 0x18, U 0xC0, U 0xC7, U 0x29, @@ -3840,14 +3965,14 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x80, U 0x09, U 0xA8, U 0x38, U 0x08, U 0x08, U 0x42, U 0x64, U 0x81, U 0x10, U 0x1C, - U 0xE3, U 0x8A, U 0x1A, U 0xE3, - U 0x8B, U 0x2A, U 0xC6, U 0x7E, + U 0xE3, U 0x0E, U 0x1A, U 0xE3, + U 0x0F, U 0x2A, U 0xC6, U 0x7E, U 0x2A, U 0x5C, U 0xFD, U 0xD3, U 0x0F, U 0x6D, U 0xAA, U 0x05, U 0x00, U 0xB0, U 0x88, U 0x00, U 0x90, U 0x8C, U 0x89, U 0x40, U 0xC0, U 0xA0, U 0x09, U 0x88, - U 0x47, U 0x1F, U 0xE3, U 0xB4, + U 0x47, U 0x1F, U 0xE3, U 0x37, U 0x08, U 0x0B, U 0x47, U 0x09, U 0x4C, U 0x50, U 0x09, U 0x0D, U 0x53, U 0x04, U 0xDD, U 0x10, @@ -3862,8 +3987,8 @@ static unsigned char t3fw[30136] = { U 0x9D, U 0x26, U 0x8E, U 0x40, U 0xC0, U 0x90, U 0x0E, U 0x5E, U 0x50, U 0x64, U 0xE0, U 0x97, - U 0x1C, U 0xE3, U 0x9A, U 0x1E, - U 0xE3, U 0x89, U 0x03, U 0x8B, + U 0x1C, U 0xE3, U 0x1D, U 0x1E, + U 0xE3, U 0x0D, U 0x03, U 0x8B, U 0x0B, U 0xC0, U 0xF4, U 0x9F, U 0xB1, U 0x9E, U 0xB0, U 0x2D, U 0x20, U 0x0A, U 0x99, U 0xB3, @@ -3877,14 +4002,14 @@ static unsigned char t3fw[30136] = { U 0x07, U 0x2F, U 0x20, U 0x06, U 0x2B, U 0x20, U 0x64, U 0x69, U 0xF3, U 0x39, U 0xCB, U 0xB6, - U 0x1D, U 0xE3, U 0x6B, U 0x23, + U 0x1D, U 0xE2, U 0xEF, U 0x23, U 0x20, U 0x16, U 0x8D, U 0xD2, U 0x0B, U 0x33, U 0x0C, U 0x00, U 0xD1, U 0x04, U 0x00, U 0x33, U 0x1A, U 0xB4, U 0x8D, U 0xA3, U 0xC3, U 0x93, U 0x29, U 0x22, - U 0x20, U 0x0C, U 0x13, U 0xE3, - U 0x6A, U 0x1F, U 0xE3, U 0x61, + U 0x20, U 0x0C, U 0x13, U 0xE2, + U 0xEE, U 0x1F, U 0xE2, U 0xE5, U 0x0C, U 0x2E, U 0x11, U 0xAF, U 0xEE, U 0xA3, U 0x22, U 0x29, U 0x24, U 0xCF, U 0x2F, U 0xE2, @@ -3893,16 +4018,16 @@ static unsigned char t3fw[30136] = { U 0x85, U 0xD1, U 0x0F, U 0x00, U 0x2E, U 0x20, U 0x0C, U 0xB4, U 0x8C, U 0x0C, U 0xEB, U 0x11, - U 0x1F, U 0xE3, U 0x61, U 0x1D, - U 0xE3, U 0x58, U 0xAF, U 0xEE, + U 0x1F, U 0xE2, U 0xE5, U 0x1D, + U 0xE2, U 0xDC, U 0xAF, U 0xEE, U 0xAD, U 0xBB, U 0x22, U 0xB2, U 0x85, U 0x29, U 0xE4, U 0xCF, U 0x02, U 0xC2, U 0x0B, U 0x22, U 0xB6, U 0x85, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x2E, U 0x20, U 0x0C, U 0x1C, - U 0xE3, U 0x51, U 0x1F, U 0xE3, - U 0x58, U 0x0C, U 0xEB, U 0x11, + U 0xE2, U 0xD5, U 0x1F, U 0xE2, + U 0xDC, U 0x0C, U 0xEB, U 0x11, U 0xAF, U 0xEE, U 0xAC, U 0xBB, U 0x22, U 0xB2, U 0x85, U 0x29, U 0xE4, U 0xCF, U 0x02, U 0x82, @@ -3916,18 +4041,18 @@ static unsigned char t3fw[30136] = { U 0xEE, U 0x12, U 0xDA, U 0x70, U 0xC0, U 0xB3, U 0x2C, U 0x3C, U 0x18, U 0xDD, U 0x50, U 0x58, - U 0x0A, U 0x7B, U 0x89, U 0x40, + U 0x0A, U 0x86, U 0x89, U 0x40, U 0xC0, U 0x80, U 0x63, U 0xFE, - U 0xE3, U 0xDE, U 0x60, U 0xDA, - U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0xDD, U 0x50, U 0x58, - U 0x00, U 0x05, U 0x9A, U 0x10, - U 0xDB, U 0x50, U 0x07, U 0x7A, - U 0x02, U 0x58, U 0x04, U 0x4C, - U 0x88, U 0x10, U 0x63, U 0xFE, - U 0xF8, U 0x00, U 0x00, U 0x00, + U 0xE3, U 0x06, U 0x6E, U 0x02, + U 0x02, U 0x2A, U 0x02, U 0xDB, + U 0x30, U 0xDC, U 0x40, U 0xDD, + U 0x50, U 0x58, U 0x00, U 0x04, + U 0x9A, U 0x10, U 0xDB, U 0x50, + U 0xDA, U 0x70, U 0x58, U 0x04, + U 0x53, U 0x88, U 0x10, U 0x63, + U 0xFE, U 0xF7, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x92, - U 0x12, U 0x1E, U 0xE3, U 0x42, + U 0x12, U 0x1E, U 0xE2, U 0xC6, U 0x8C, U 0x40, U 0xAE, U 0x2D, U 0x0C, U 0x8C, U 0x47, U 0x2E, U 0x3C, U 0x18, U 0x04, U 0xCA, @@ -3969,14 +4094,14 @@ static unsigned char t3fw[30136] = { U 0xC7, U 0x29, U 0xDD, U 0xF8, U 0x63, U 0xFF, U 0xC1, U 0x00, U 0xC0, U 0x23, U 0x8A, U 0x42, - U 0x1B, U 0xE3, U 0x47, U 0x00, + U 0x1B, U 0xE2, U 0xCB, U 0x00, U 0xCD, U 0x32, U 0x2D, U 0x44, U 0x02, U 0x9B, U 0x30, U 0x92, U 0x31, U 0x89, U 0x42, U 0x85, U 0x43, U 0x79, U 0xA1, U 0x05, - U 0x1E, U 0xE3, U 0x43, U 0x0E, + U 0x1E, U 0xE2, U 0xC7, U 0x0E, U 0x55, U 0x01, U 0x87, U 0x12, - U 0x1B, U 0xE3, U 0x34, U 0x89, + U 0x1B, U 0xE2, U 0xB7, U 0x89, U 0x70, U 0x95, U 0x35, U 0x0B, U 0x99, U 0x02, U 0x99, U 0x32, U 0x88, U 0x42, U 0x0A, U 0x88, @@ -4004,35 +4129,35 @@ static unsigned char t3fw[30136] = { U 0x5A, U 0x7F, U 0xE0, U 0x02, U 0x60, U 0x02, U 0x15, U 0x89, U 0x28, U 0x88, U 0x26, U 0x1F, - U 0xE3, U 0x26, U 0x09, U 0x88, + U 0xE2, U 0xAA, U 0x09, U 0x88, U 0x0C, U 0x65, U 0x82, U 0x0F, U 0x2E, U 0x20, U 0x0B, U 0x0F, U 0xEE, U 0x0B, U 0x2D, U 0xE0, U 0xFE, U 0x2E, U 0xE0, U 0xFF, U 0x08, U 0xDD, U 0x11, U 0x0E, - U 0xDD, U 0x02, U 0x1E, U 0xE3, - U 0x20, U 0xAE, U 0xDD, U 0x1E, - U 0xE3, U 0x20, U 0x1C, U 0xE3, - U 0x20, U 0x0E, U 0xDD, U 0x01, + U 0xDD, U 0x02, U 0x1E, U 0xE2, + U 0xA4, U 0xAE, U 0xDD, U 0x1E, + U 0xE2, U 0xA4, U 0x1C, U 0xE2, + U 0xA4, U 0x0E, U 0xDD, U 0x01, U 0x0D, U 0xCC, U 0x37, U 0xC1, U 0x80, U 0x08, U 0x48, U 0x37, U 0xB8, U 0x8D, U 0xB4, U 0x88, U 0x98, U 0x10, U 0x89, U 0x60, - U 0x1A, U 0xE2, U 0xDE, U 0x7B, + U 0x1A, U 0xE2, U 0x62, U 0x7B, U 0x96, U 0x21, U 0x8B, U 0x62, U 0x2A, U 0xA0, U 0x21, U 0x9C, U 0x14, U 0x7B, U 0xA3, U 0x17, U 0x9D, U 0x13, U 0x2A, U 0x20, U 0x0C, U 0x8B, U 0x10, U 0x8C, - U 0x20, U 0x58, U 0x0B, U 0x97, + U 0x20, U 0x58, U 0x0B, U 0xB0, U 0x8C, U 0x14, U 0x8D, U 0x13, U 0xDB, U 0xA0, U 0xCE, U 0xAC, U 0x60, U 0x01, U 0xC4, U 0x00, U 0x2E, U 0x20, U 0x0C, U 0x1B, - U 0xE2, U 0xD1, U 0x0C, U 0xEA, + U 0xE2, U 0x55, U 0x0C, U 0xEA, U 0x11, U 0x0B, U 0xAA, U 0x08, U 0x2B, U 0xA2, U 0x86, U 0x1F, - U 0xE2, U 0xCF, U 0x7B, U 0xDB, + U 0xE2, U 0x53, U 0x7B, U 0xDB, U 0x3B, U 0x0F, U 0xEF, U 0x0A, U 0x2F, U 0xF2, U 0xA3, U 0x68, U 0xF0, U 0x05, U 0x28, U 0x22, @@ -4053,13 +4178,13 @@ static unsigned char t3fw[30136] = { U 0x63, U 0xFF, U 0xDD, U 0x00, U 0x00, U 0x9D, U 0x13, U 0x9C, U 0x14, U 0xDA, U 0x20, U 0xDB, - U 0x70, U 0x58, U 0x0B, U 0x08, + U 0x70, U 0x58, U 0x0B, U 0x15, U 0x8B, U 0x15, U 0x8C, U 0x14, U 0x8D, U 0x13, U 0x65, U 0xA0, U 0x6A, U 0x8E, U 0x62, U 0x63, U 0xFF, U 0xCC, U 0x00, U 0xDA, U 0x20, U 0x8B, U 0x11, U 0xDC, - U 0x40, U 0x58, U 0x0A, U 0xAE, + U 0x40, U 0x58, U 0x0A, U 0xBB, U 0xD6, U 0xA0, U 0x8B, U 0x15, U 0xC0, U 0x51, U 0xDE, U 0x70, U 0xDA, U 0x20, U 0xDC, U 0x60, @@ -4067,7 +4192,7 @@ static unsigned char t3fw[30136] = { U 0x76, U 0x8D, U 0x13, U 0x8C, U 0x14, U 0xD9, U 0xA0, U 0x2E, U 0x20, U 0x0C, U 0x1B, U 0xE2, - U 0xAB, U 0x1F, U 0xE2, U 0xB2, + U 0x2F, U 0x1F, U 0xE2, U 0x36, U 0x0C, U 0xEA, U 0x11, U 0xAF, U 0xEF, U 0xC0, U 0xE0, U 0xAB, U 0xAA, U 0x2B, U 0xA2, U 0x85, @@ -4082,13 +4207,13 @@ static unsigned char t3fw[30136] = { U 0x07, U 0x5B, U 0xFF, U 0x09, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0xDB, U 0xE0, U 0xDA, - U 0x20, U 0x58, U 0x0B, U 0x29, + U 0x20, U 0x58, U 0x0B, U 0x36, U 0x65, U 0x50, U 0xEF, U 0x2A, U 0x20, U 0x14, U 0x0A, U 0x3A, U 0x40, U 0x65, U 0xA0, U 0xEB, U 0xDB, U 0x60, U 0xDC, U 0x40, U 0xDD, U 0x30, U 0x02, U 0x2A, - U 0x02, U 0x58, U 0x09, U 0x9C, + U 0x02, U 0x58, U 0x09, U 0xA7, U 0xD6, U 0xA0, U 0x64, U 0xA0, U 0xD5, U 0x84, U 0xA1, U 0x83, U 0xA0, U 0x04, U 0x04, U 0x47, @@ -4102,7 +4227,7 @@ static unsigned char t3fw[30136] = { U 0x93, U 0x29, U 0x24, U 0x06, U 0x2C, U 0x20, U 0x06, U 0xC0, U 0xB1, U 0x8D, U 0x64, U 0x1F, - U 0xE2, U 0x8A, U 0x9D, U 0x27, + U 0xE2, U 0x0E, U 0x9D, U 0x27, U 0x9D, U 0x28, U 0x9D, U 0x29, U 0x8F, U 0xF2, U 0x9D, U 0x26, U 0x00, U 0xF1, U 0x04, U 0x00, @@ -4118,7 +4243,7 @@ static unsigned char t3fw[30136] = { U 0xBB, U 0x36, U 0xC0, U 0xE2, U 0x0B, U 0x0B, U 0x47, U 0x0E, U 0xBB, U 0x37, U 0x2B, U 0x24, - U 0x16, U 0x18, U 0xE2, U 0x82, + U 0x16, U 0x18, U 0xE2, U 0x06, U 0x0A, U 0x09, U 0x45, U 0x0D, U 0x0B, U 0x42, U 0x2B, U 0x24, U 0x0B, U 0x29, U 0x24, U 0x0A, @@ -4130,19 +4255,19 @@ static unsigned char t3fw[30136] = { U 0xCC, U 0x36, U 0x2C, U 0x24, U 0x64, U 0x65, U 0xFD, U 0xEC, U 0x0C, U 0x0C, U 0x47, U 0x64, - U 0xCD, U 0xE6, U 0x18, U 0xE2, - U 0x6D, U 0x8E, U 0x28, U 0x88, + U 0xCD, U 0xE6, U 0x18, U 0xE1, + U 0xF1, U 0x8E, U 0x28, U 0x88, U 0x82, U 0x0C, U 0x9F, U 0x0C, U 0x00, U 0x81, U 0x04, U 0x00, U 0xFF, U 0x1A, U 0xAF, U 0xEE, U 0x9E, U 0x29, U 0x63, U 0xFD, - U 0xCF, U 0x1C, U 0xE2, U 0x9C, + U 0xCF, U 0x1C, U 0xE2, U 0x1D, U 0x63, U 0xFE, U 0x13, U 0x00, - U 0x1C, U 0xE2, U 0x93, U 0x63, + U 0x1C, U 0xE2, U 0x17, U 0x63, U 0xFE, U 0x0C, U 0x8D, U 0x65, U 0x63, U 0xFF, U 0xA5, U 0x00, U 0xDA, U 0x20, U 0x2B, U 0x20, - U 0x0C, U 0x58, U 0x0B, U 0x06, + U 0x0C, U 0x58, U 0x0B, U 0x1F, U 0x64, U 0x5F, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xC0, U 0x20, U 0xD1, U 0x0F, @@ -4150,8 +4275,8 @@ static unsigned char t3fw[30136] = { U 0x16, U 0xC0, U 0x93, U 0x63, U 0xFF, U 0xA0, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, - U 0x60, U 0x17, U 0xE2, U 0x56, - U 0x1D, U 0xE2, U 0x59, U 0xC3, + U 0x60, U 0x17, U 0xE1, U 0xDA, + U 0x1D, U 0xE1, U 0xDD, U 0xC3, U 0x81, U 0x29, U 0x31, U 0x01, U 0x2A, U 0x30, U 0x08, U 0x29, U 0x24, U 0x0A, U 0x78, U 0xA1, @@ -4168,7 +4293,7 @@ static unsigned char t3fw[30136] = { U 0xFF, U 0x09, U 0x28, U 0xF1, U 0x1C, U 0x2B, U 0x24, U 0x14, U 0xA8, U 0xEE, U 0x2E, U 0xF5, - U 0x1C, U 0x64, U 0xA0, U 0xB5, + U 0x1C, U 0x64, U 0xA0, U 0xA9, U 0x2B, U 0x22, U 0x1E, U 0x28, U 0x22, U 0x1D, U 0x01, U 0x11, U 0x02, U 0x7B, U 0x89, U 0x01, @@ -4181,7 +4306,7 @@ static unsigned char t3fw[30136] = { U 0xDB, U 0xA0, U 0x65, U 0xAF, U 0xE7, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0xDA, - U 0x20, U 0x58, U 0x00, U 0xD8, + U 0x20, U 0x58, U 0x00, U 0xDE, U 0x29, U 0x21, U 0x02, U 0x09, U 0x0B, U 0x4C, U 0xCA, U 0xB2, U 0xD2, U 0xA0, U 0xD1, U 0x0F, @@ -4191,138 +4316,144 @@ static unsigned char t3fw[30136] = { U 0x64, U 0xE0, U 0x2D, U 0x02, U 0x2A, U 0x02, U 0x03, U 0x3B, U 0x02, U 0xDC, U 0x40, U 0xDD, - U 0x50, U 0x58, U 0x00, U 0xCE, + U 0x50, U 0x58, U 0x00, U 0xD4, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x2B, U 0x20, U 0x14, U 0xB0, U 0xBB, U 0x2B, U 0x24, U 0x14, U 0x0B, U 0x0F, U 0x41, U 0x64, - U 0xF0, U 0x82, U 0x7C, U 0xB7, + U 0xF0, U 0x79, U 0x7C, U 0xB7, U 0xCA, U 0xC0, U 0xC1, U 0x0C, U 0x9C, U 0x02, U 0x2C, U 0x25, U 0x02, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x2E, U 0x20, U 0x06, - U 0x69, U 0xE2, U 0xC1, U 0x2F, - U 0x21, U 0x02, U 0x0F, U 0x0F, - U 0x4C, U 0x69, U 0xF1, U 0xB8, - U 0x26, U 0x24, U 0x06, U 0x26, - U 0x25, U 0x02, U 0x2B, U 0x22, - U 0x1E, U 0x28, U 0x22, U 0x1D, - U 0x2A, U 0x20, U 0x0B, U 0x29, - U 0x20, U 0x15, U 0x0D, U 0xAA, - U 0x09, U 0x2C, U 0xA1, U 0x1C, - U 0x26, U 0x24, U 0x15, U 0xAC, - U 0x99, U 0x29, U 0xA5, U 0x1C, - U 0x7B, U 0x81, U 0x4A, U 0x60, - U 0x00, U 0x49, U 0xB0, U 0xBB, + U 0x69, U 0xE2, U 0xC1, U 0x26, + U 0x24, U 0x06, U 0x2B, U 0x22, + U 0x1E, U 0x2F, U 0x22, U 0x1D, + U 0x29, U 0x20, U 0x0B, U 0x28, + U 0x20, U 0x15, U 0x0D, U 0x99, + U 0x09, U 0x2A, U 0x91, U 0x1C, + U 0x26, U 0x24, U 0x15, U 0xAA, + U 0x88, U 0x28, U 0x95, U 0x1C, + U 0x7B, U 0xF1, U 0x49, U 0x60, + U 0x00, U 0x48, U 0xB0, U 0xBB, U 0x2B, U 0x24, U 0x14, U 0x0B, - U 0x0D, U 0x41, U 0xCB, U 0xD6, - U 0x7C, U 0xB7, U 0x02, U 0x2C, - U 0x25, U 0x02, U 0x2B, U 0x22, - U 0x1E, U 0x2E, U 0x22, U 0x1D, - U 0x7B, U 0xE9, U 0x02, U 0x2B, - U 0x0A, U 0x00, U 0x64, U 0xB0, - U 0x17, U 0x2C, U 0xB0, U 0x07, - U 0x28, U 0xB0, U 0x00, U 0xDA, - U 0x20, U 0x07, U 0x88, U 0x0A, - U 0x28, U 0x82, U 0x4C, U 0xC0, - U 0xD1, U 0x0B, U 0x80, U 0x00, - U 0xDB, U 0xA0, U 0x65, U 0xAF, - U 0xE7, U 0xC0, U 0x20, U 0xD1, - U 0x0F, U 0x26, U 0x24, U 0x06, - U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0x26, U 0x24, U 0x06, U 0x63, - U 0xFF, U 0xC7, U 0xDB, U 0x60, - U 0x1D, U 0xE2, U 0x07, U 0x64, - U 0xBF, U 0x42, U 0x2C, U 0xB0, + U 0x0A, U 0x41, U 0x64, U 0xA0, + U 0x62, U 0x7C, U 0xB7, U 0x02, + U 0x2C, U 0x25, U 0x02, U 0x2B, + U 0x22, U 0x1E, U 0x2C, U 0x22, + U 0x1D, U 0xD3, U 0x0F, U 0x7B, + U 0xC9, U 0x01, U 0xC0, U 0xB0, + U 0xC9, U 0xB6, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x07, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xC0, U 0xD1, U 0x0B, U 0x80, U 0x00, U 0xDB, U 0xA0, U 0x65, - U 0xAF, U 0xE7, U 0x1D, U 0xE1, - U 0xFF, U 0x63, U 0xFF, U 0x24, + U 0xAF, U 0xE7, U 0xC0, U 0x20, + U 0xD1, U 0x0F, U 0x00, U 0x00, + U 0x26, U 0x24, U 0x06, U 0xD2, + U 0xA0, U 0xD1, U 0x0F, U 0x00, + U 0x00, U 0xDB, U 0x60, U 0x1D, + U 0xE1, U 0x8E, U 0x64, U 0xBF, + U 0x4F, U 0x2C, U 0xB0, U 0x07, + U 0x28, U 0xB0, U 0x00, U 0xDA, + U 0x20, U 0x07, U 0x88, U 0x0A, + U 0x28, U 0x82, U 0x4C, U 0xC0, + U 0xD1, U 0x0B, U 0x80, U 0x00, + U 0xDB, U 0xA0, U 0x65, U 0xAF, + U 0xE7, U 0x1D, U 0xE1, U 0x86, + U 0x63, U 0xFF, U 0x31, U 0x00, + U 0x26, U 0x24, U 0x06, U 0x63, + U 0xFF, U 0x9C, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x28, - U 0x20, U 0x06, U 0xC0, U 0x64, - U 0x6F, U 0x85, U 0x64, U 0xCA, - U 0x5B, U 0x29, U 0x20, U 0x14, - U 0x7D, U 0x97, U 0x26, U 0xDA, - U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x05, U 0x5D, U 0x02, - U 0x58, U 0x00, U 0x19, U 0x29, - U 0x21, U 0x02, U 0x09, U 0x0A, - U 0x4C, U 0xC8, U 0xA3, U 0xC0, - U 0x20, U 0xD1, U 0x0F, U 0x00, - U 0xC0, U 0xB1, U 0x0B, U 0x9B, - U 0x02, U 0x2B, U 0x25, U 0x02, - U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0x00, U 0x00, U 0x02, U 0x2A, + U 0x20, U 0x06, U 0x26, U 0x0A, + U 0x04, U 0x6F, U 0x85, U 0x63, + U 0x64, U 0x50, U 0x2A, U 0x29, + U 0x20, U 0x14, U 0x7D, U 0x97, + U 0x24, U 0x02, U 0x2A, U 0x02, + U 0xDB, U 0x30, U 0xDC, U 0x40, + U 0xDD, U 0x50, U 0x58, U 0x00, + U 0x19, U 0x29, U 0x21, U 0x02, + U 0x09, U 0x0A, U 0x4C, U 0xC8, + U 0xA2, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0xC0, U 0xB1, U 0x0B, + U 0x9B, U 0x02, U 0x2B, U 0x25, + U 0x02, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0x00, U 0x02, U 0x2A, U 0x02, U 0x03, U 0x3B, U 0x02, U 0x2C, U 0x0A, U 0x01, U 0x58, - U 0x00, U 0xCA, U 0xC9, U 0xAA, + U 0x00, U 0xD1, U 0xC9, U 0xAA, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x58, U 0x09, - U 0xE4, U 0x29, U 0xA0, U 0x11, + U 0xF2, U 0x29, U 0xA0, U 0x11, U 0xD3, U 0xA0, U 0x7E, U 0x97, U 0x08, U 0x2C, U 0x0A, U 0xFD, U 0x0C, U 0x9C, U 0x01, U 0x2C, U 0xA4, U 0x11, U 0xC0, U 0x51, U 0x2D, U 0x20, U 0x14, U 0x06, U 0xDD, U 0x02, U 0x2D, U 0x24, - U 0x14, U 0x63, U 0xFF, U 0xA2, + U 0x14, U 0x63, U 0xFF, U 0xA4, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0xC0, U 0xE0, U 0x58, U 0x09, - U 0x64, U 0xD2, U 0xA0, U 0xD1, + U 0x72, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x16, - U 0xE1, U 0xDA, U 0x1C, U 0xE1, - U 0xDA, U 0x65, U 0x51, U 0x3B, + U 0xE1, U 0x5F, U 0x1C, U 0xE1, + U 0x5F, U 0x65, U 0x51, U 0x57, U 0xC0, U 0xE1, U 0x17, U 0xE1, - U 0xD6, U 0x28, U 0x21, U 0x02, - U 0x8B, U 0x20, U 0x08, U 0x08, - U 0x4C, U 0x65, U 0x80, U 0x7B, - U 0x29, U 0x32, U 0x00, U 0x09, - U 0x69, U 0x51, U 0x69, U 0x93, - U 0x72, U 0x2A, U 0x62, U 0x9E, - U 0x6E, U 0xA8, U 0x48, U 0x2A, + U 0x5B, U 0x28, U 0x21, U 0x02, + U 0x2D, U 0x22, U 0x00, U 0x08, + U 0x08, U 0x4C, U 0x65, U 0x80, + U 0x93, U 0x2B, U 0x32, U 0x00, + U 0x0B, U 0x69, U 0x51, U 0x29, + U 0x9C, U 0xFD, U 0x65, U 0x90, + U 0x87, U 0x2A, U 0x62, U 0x9E, + U 0x6E, U 0xA8, U 0x4C, U 0x2A, U 0x72, U 0x26, U 0x68, U 0xA0, - U 0x02, U 0x7A, U 0xB9, U 0x3F, - U 0x2A, U 0x62, U 0x9D, U 0xB4, - U 0x4F, U 0xCB, U 0xA7, U 0x2B, - U 0x20, U 0x0C, U 0x0C, U 0xBD, - U 0x11, U 0x06, U 0xDD, U 0x08, - U 0x28, U 0xD2, U 0x86, U 0x78, - U 0xFB, U 0x15, U 0x0C, U 0xBF, - U 0x0A, U 0x2F, U 0xF2, U 0xA3, - U 0x68, U 0xF0, U 0x04, U 0x88, - U 0x20, U 0x7F, U 0x89, U 0x07, + U 0x02, U 0x7A, U 0xD9, U 0x43, + U 0x2A, U 0x62, U 0x9D, U 0xCB, + U 0xAD, U 0x7C, U 0xBE, U 0x50, + U 0x2B, U 0x20, U 0x0C, U 0x0C, + U 0xBD, U 0x11, U 0xA6, U 0xDD, + U 0x28, U 0xD2, U 0x86, U 0x2F, + U 0x4C, U 0x04, U 0x78, U 0xFB, + U 0x16, U 0x0C, U 0xBF, U 0x0A, + U 0x2F, U 0xF2, U 0xA3, U 0x68, + U 0xF0, U 0x05, U 0x28, U 0x22, + U 0x00, U 0x7F, U 0x89, U 0x07, U 0x2D, U 0xD2, U 0x85, U 0xD3, - U 0x0F, U 0x65, U 0xD0, U 0x60, + U 0x0F, U 0x65, U 0xD0, U 0x74, U 0x2A, U 0x21, U 0x04, U 0x19, - U 0xE2, U 0x02, U 0xD3, U 0x0F, - U 0x7A, U 0x9B, U 0x1D, U 0xDA, - U 0x20, U 0x58, U 0x08, U 0x64, - U 0x60, U 0x00, U 0x24, U 0x00, - U 0x2C, U 0x21, U 0x04, U 0x1B, - U 0xE1, U 0xFD, U 0x7C, U 0xBB, - U 0x13, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x08, U 0x5F, - U 0xC9, U 0x53, U 0x60, U 0x00, - U 0xEF, U 0xDA, U 0x20, U 0x58, - U 0x0A, U 0x46, U 0x60, U 0x00, - U 0x06, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x0A, U 0x43, - U 0x65, U 0x50, U 0xDD, U 0xDC, - U 0x40, U 0xDB, U 0x30, U 0x8D, - U 0x30, U 0xDA, U 0x20, U 0x0D, - U 0x6D, U 0x51, U 0x58, U 0x08, - U 0xB8, U 0xD3, U 0xA0, U 0x64, - U 0xA0, U 0xCA, U 0x1C, U 0xE1, - U 0xB0, U 0xC0, U 0x51, U 0x84, - U 0xA1, U 0x8E, U 0xA0, U 0x04, - U 0x04, U 0x47, U 0x0E, U 0x0E, - U 0x47, U 0x63, U 0xFF, U 0x50, + U 0xE1, U 0x85, U 0xD3, U 0x0F, + U 0x7A, U 0x9B, U 0x2E, U 0xDA, + U 0x20, U 0x58, U 0x08, U 0x6E, + U 0x60, U 0x00, U 0x35, U 0x00, + U 0x2D, U 0x21, U 0x04, U 0x1B, + U 0xE1, U 0x80, U 0x7D, U 0xBB, + U 0x24, U 0xDA, U 0x20, U 0xC0, + U 0xB6, U 0x58, U 0x08, U 0x69, + U 0xCA, U 0x54, U 0x60, U 0x01, + U 0x03, U 0x0B, U 0x2B, U 0x50, + U 0x2B, U 0x24, U 0x0B, U 0xB4, + U 0xBB, U 0x0B, U 0x0B, U 0x47, + U 0x2B, U 0x24, U 0x0C, U 0x63, + U 0xFF, U 0xA0, U 0xDA, U 0x20, + U 0x58, U 0x0A, U 0x4D, U 0x60, + U 0x00, U 0x06, U 0xDA, U 0x20, + U 0xC0, U 0xB6, U 0x58, U 0x0A, + U 0x4B, U 0x65, U 0x50, U 0xE0, + U 0xDC, U 0x40, U 0xDB, U 0x30, + U 0x2D, U 0x32, U 0x00, U 0x02, + U 0x2A, U 0x02, U 0x0D, U 0x6D, + U 0x51, U 0x58, U 0x08, U 0xBD, + U 0x1C, U 0xE1, U 0x30, U 0xD3, + U 0xA0, U 0x64, U 0xA0, U 0xC8, + U 0xC0, U 0x51, U 0x84, U 0xA1, + U 0x8E, U 0xA0, U 0x04, U 0x04, + U 0x47, U 0x0E, U 0x0E, U 0x47, + U 0x63, U 0xFF, U 0x35, U 0x00, U 0x00, U 0x2B, U 0x21, U 0x04, U 0xC0, U 0x8C, U 0x89, U 0x31, U 0xC0, U 0x70, U 0xDF, U 0x70, @@ -4332,23 +4463,23 @@ static unsigned char t3fw[30136] = { U 0xAE, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0x7C, U 0xFB, U 0x09, U 0x9D, - U 0x10, U 0x58, U 0x08, U 0xCA, + U 0x10, U 0x58, U 0x08, U 0xCF, U 0x8D, U 0x10, U 0x27, U 0x24, U 0x66, U 0x94, U 0xD1, U 0x1E, - U 0xE1, U 0xB6, U 0xB8, U 0xDC, + U 0xE1, U 0x33, U 0xB8, U 0xDC, U 0x9E, U 0xD0, U 0x65, U 0x50, U 0x56, U 0xC0, U 0xD7, U 0xB8, U 0x3A, U 0xC0, U 0xB1, U 0xC0, U 0xF0, U 0x0C, U 0xBF, U 0x38, U 0x0F, U 0x0F, U 0x42, U 0xCB, - U 0xF1, U 0x19, U 0xE1, U 0x94, - U 0x18, U 0xE1, U 0x96, U 0x28, + U 0xF1, U 0x19, U 0xE1, U 0x12, + U 0x18, U 0xE1, U 0x14, U 0x28, U 0x96, U 0x7E, U 0xB0, U 0x4B, U 0xD3, U 0x0F, U 0x6D, U 0xBA, U 0x05, U 0x00, U 0xA0, U 0x88, U 0x00, U 0xC0, U 0x8C, U 0x2C, U 0x20, U 0x0C, U 0xC0, U 0x20, - U 0x1D, U 0xE1, U 0x9A, U 0x0C, + U 0x1D, U 0xE1, U 0x18, U 0x0C, U 0xCF, U 0x11, U 0xA6, U 0xFF, U 0x2E, U 0xF2, U 0x85, U 0xAD, U 0xCC, U 0x27, U 0xC4, U 0xCF, @@ -4358,12 +4489,12 @@ static unsigned char t3fw[30136] = { U 0x38, U 0x78, U 0xD0, U 0xCD, U 0x63, U 0xFF, U 0xC1, U 0x00, U 0x8E, U 0x30, U 0x0E, U 0x0E, - U 0x47, U 0x63, U 0xFE, U 0xBD, + U 0x47, U 0x63, U 0xFE, U 0xA1, U 0x2A, U 0x2C, U 0x74, U 0x2B, U 0x0A, U 0x01, U 0x04, U 0x4D, - U 0x02, U 0x58, U 0x08, U 0xBD, + U 0x02, U 0x58, U 0x08, U 0xC2, U 0x2F, U 0x20, U 0x0C, U 0x12, - U 0xE1, U 0x8B, U 0x0C, U 0xF9, + U 0xE1, U 0x09, U 0x0C, U 0xF9, U 0x11, U 0xA6, U 0x99, U 0xA2, U 0xFF, U 0x27, U 0xF4, U 0xCF, U 0x28, U 0x92, U 0x85, U 0xD2, @@ -4375,7 +4506,7 @@ static unsigned char t3fw[30136] = { U 0x60, U 0xCB, U 0x55, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x05, U 0x5D, U 0x02, U 0x02, U 0x2A, - U 0x02, U 0x5B, U 0xFF, U 0x9B, + U 0x02, U 0x5B, U 0xFF, U 0x94, U 0x29, U 0x21, U 0x02, U 0x09, U 0x08, U 0x4C, U 0xC8, U 0x82, U 0xD2, U 0xA0, U 0xD1, U 0x0F, @@ -4394,7 +4525,7 @@ static unsigned char t3fw[30136] = { U 0x01, U 0x26, U 0x25, U 0x02, U 0x28, U 0x24, U 0x0A, U 0x0F, U 0xEE, U 0x01, U 0x2E, U 0x24, - U 0x14, U 0x58, U 0x01, U 0x0D, + U 0x14, U 0x58, U 0x01, U 0x0E, U 0x63, U 0xFF, U 0xA3, U 0x00, U 0x26, U 0x24, U 0x06, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, @@ -4402,18 +4533,18 @@ static unsigned char t3fw[30136] = { U 0x21, U 0x02, U 0xD6, U 0x20, U 0x08, U 0x08, U 0x4C, U 0x65, U 0x80, U 0x9D, U 0x2B, U 0x20, - U 0x0C, U 0x12, U 0xE1, U 0x5B, + U 0x0C, U 0x12, U 0xE0, U 0xD9, U 0x0C, U 0xB8, U 0x11, U 0xA2, U 0x88, U 0x2A, U 0x82, U 0x86, U 0xB5, U 0x49, U 0x7A, U 0x93, U 0x02, U 0x60, U 0x00, U 0x97, - U 0x19, U 0xE1, U 0x58, U 0x09, + U 0x19, U 0xE0, U 0xD6, U 0x09, U 0xB9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x08, U 0x2A, U 0x62, U 0x00, U 0x09, U 0xAA, U 0x0C, U 0x65, U 0xA0, U 0x82, U 0x28, U 0x82, U 0x85, - U 0x1C, U 0xE1, U 0x63, U 0x64, + U 0x1C, U 0xE0, U 0xE1, U 0x64, U 0x80, U 0x79, U 0x9C, U 0x80, U 0xB8, U 0x87, U 0xB1, U 0x4B, U 0x9B, U 0x81, U 0x9B, U 0x10, @@ -4422,8 +4553,8 @@ static unsigned char t3fw[30136] = { U 0x0A, U 0x01, U 0xC0, U 0xD0, U 0x07, U 0x8D, U 0x38, U 0x0D, U 0x0D, U 0x42, U 0xCB, U 0xDE, - U 0x1F, U 0xE1, U 0x44, U 0x1E, - U 0xE1, U 0x45, U 0x2E, U 0xF6, + U 0x1F, U 0xE0, U 0xC2, U 0x1E, + U 0xE0, U 0xC3, U 0x2E, U 0xF6, U 0x7E, U 0xD8, U 0x30, U 0xD3, U 0x0F, U 0x6D, U 0x4A, U 0x05, U 0x00, U 0x80, U 0x88, U 0x00, @@ -4431,7 +4562,7 @@ static unsigned char t3fw[30136] = { U 0x08, U 0xC0, U 0xA0, U 0x00, U 0xEE, U 0x32, U 0x2E, U 0x74, U 0x00, U 0x28, U 0x60, U 0x0C, - U 0x19, U 0xE1, U 0x47, U 0x0C, + U 0x19, U 0xE0, U 0xC5, U 0x0C, U 0x8D, U 0x11, U 0xA2, U 0xDD, U 0xA9, U 0x88, U 0xC0, U 0x20, U 0x2C, U 0xD2, U 0x85, U 0x22, @@ -4443,18 +4574,18 @@ static unsigned char t3fw[30136] = { U 0x63, U 0xFF, U 0xB4, U 0x00, U 0xCC, U 0x58, U 0x2A, U 0x6C, U 0x74, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x07, U 0xF1, + U 0x40, U 0x58, U 0x07, U 0xF6, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x60, U 0x58, U 0x09, - U 0xBE, U 0x63, U 0xFF, U 0xE7, + U 0xC5, U 0x63, U 0xFF, U 0xE7, U 0xDD, U 0x40, U 0x2A, U 0x6C, U 0x74, U 0xC0, U 0xB0, U 0xDC, - U 0x70, U 0x58, U 0x08, U 0x65, + U 0x70, U 0x58, U 0x08, U 0x6A, U 0x2E, U 0x30, U 0x08, U 0x8B, U 0x10, U 0x00, U 0xEE, U 0x32, U 0x2E, U 0x74, U 0x00, U 0x28, - U 0x60, U 0x0C, U 0x19, U 0xE1, - U 0x30, U 0x0C, U 0x8D, U 0x11, + U 0x60, U 0x0C, U 0x19, U 0xE0, + U 0xAE, U 0x0C, U 0x8D, U 0x11, U 0xA2, U 0xDD, U 0xA9, U 0x88, U 0xC0, U 0x20, U 0x2C, U 0xD2, U 0x85, U 0x22, U 0x84, U 0xCF, @@ -4473,7 +4604,7 @@ static unsigned char t3fw[30136] = { U 0x02, U 0x2A, U 0x02, U 0x03, U 0x3B, U 0x02, U 0x04, U 0x4C, U 0x02, U 0xC0, U 0xD0, U 0x58, - U 0x00, U 0xBF, U 0xD2, U 0xA0, + U 0x00, U 0xC0, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x29, @@ -4501,7 +4632,7 @@ static unsigned char t3fw[30136] = { U 0x06, U 0x88, U 0x02, U 0x28, U 0x24, U 0x14, U 0x63, U 0xFF, U 0xC7, U 0x29, U 0x20, U 0x15, - U 0x1B, U 0xE0, U 0xFB, U 0x2A, + U 0x1B, U 0xE0, U 0x79, U 0x2A, U 0x20, U 0x0B, U 0xC0, U 0xC0, U 0x9C, U 0x24, U 0x0B, U 0xAA, U 0x09, U 0x2B, U 0xA1, U 0x1C, @@ -4512,10 +4643,10 @@ static unsigned char t3fw[30136] = { U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0xC0, U 0xE0, U 0x58, U 0x08, - U 0x75, U 0xD2, U 0xA0, U 0xD1, + U 0x7C, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xCB, - U 0x55, U 0x13, U 0xE0, U 0xF6, + U 0x55, U 0x13, U 0xE0, U 0x74, U 0x25, U 0x22, U 0x1F, U 0x0D, U 0x46, U 0x11, U 0x06, U 0x55, U 0x0C, U 0xA3, U 0x23, U 0x26, @@ -4533,144 +4664,145 @@ static unsigned char t3fw[30136] = { U 0x24, U 0x4D, U 0xF8, U 0x24, U 0x26, U 0x1E, U 0x63, U 0xFF, U 0xD8, U 0x00, U 0x00, U 0x00, - U 0x6C, U 0x10, U 0x04, U 0x28, - U 0x20, U 0x06, U 0xD6, U 0x20, - U 0x6E, U 0x85, U 0x02, U 0x60, - U 0x00, U 0xDE, U 0x17, U 0xE0, - U 0xD5, U 0x1D, U 0xE0, U 0xDC, - U 0x19, U 0xE0, U 0xD5, U 0xC0, - U 0xC1, U 0xC0, U 0x20, U 0x2A, - U 0x8C, U 0xFC, U 0x64, U 0xA1, - U 0x32, U 0x2B, U 0x61, U 0x02, - U 0xB4, U 0x4E, U 0x0B, U 0x0B, - U 0x4C, U 0x65, U 0xB0, U 0xA8, - U 0x2B, U 0x60, U 0x0C, U 0x2A, - U 0x62, U 0x00, U 0x0C, U 0xB8, - U 0x11, U 0x07, U 0x88, U 0x08, - U 0x2F, U 0x82, U 0x86, U 0x09, - U 0xB9, U 0x0A, U 0x7F, U 0xE3, - U 0x02, U 0x60, U 0x00, U 0x9F, - U 0x29, U 0x92, U 0xA3, U 0x68, - U 0x90, U 0x05, U 0x09, U 0xAA, - U 0x0C, U 0x65, U 0xA0, U 0x93, - U 0x28, U 0x82, U 0x85, U 0x64, - U 0x80, U 0x8D, U 0xB8, U 0x89, - U 0x1B, U 0xE0, U 0xDA, U 0x94, - U 0x81, U 0x9B, U 0x80, U 0x65, - U 0x51, U 0x4D, U 0xC0, U 0xB7, - U 0xB8, U 0x38, U 0xC0, U 0xA1, - U 0xC0, U 0xE0, U 0x09, U 0xAE, - U 0x38, U 0x0E, U 0x0E, U 0x42, - U 0x64, U 0xE0, U 0x48, U 0x1A, - U 0xE0, U 0xB8, U 0x1F, U 0xE0, - U 0xB9, U 0x2F, U 0xA6, U 0x7E, - U 0xB0, U 0x4A, U 0x6D, U 0xAA, + U 0x6C, U 0x10, U 0x04, U 0xD6, + U 0x20, U 0x28, U 0x20, U 0x06, + U 0xC0, U 0x70, U 0x6E, U 0x85, + U 0x02, U 0x60, U 0x00, U 0xD4, + U 0x1D, U 0xE0, U 0x5B, U 0x19, + U 0xE0, U 0x53, U 0x12, U 0xE0, + U 0x51, U 0x2A, U 0x8C, U 0xFC, + U 0x64, U 0xA1, U 0x30, U 0x2B, + U 0x61, U 0x02, U 0xB4, U 0x4C, + U 0x0B, U 0x0B, U 0x4C, U 0x65, + U 0xB0, U 0xA2, U 0x2B, U 0x60, + U 0x0C, U 0x8A, U 0x60, U 0x0C, + U 0xB8, U 0x11, U 0x02, U 0x88, + U 0x08, U 0x2E, U 0x82, U 0x86, + U 0x09, U 0xB9, U 0x0A, U 0x7E, + U 0xC3, U 0x02, U 0x60, U 0x00, + U 0x9A, U 0x29, U 0x92, U 0xA3, + U 0x68, U 0x90, U 0x05, U 0x09, + U 0xAA, U 0x0C, U 0x65, U 0xA0, + U 0x8E, U 0x28, U 0x82, U 0x85, + U 0x64, U 0x80, U 0x88, U 0xB8, + U 0x89, U 0x1B, U 0xE0, U 0x57, + U 0x94, U 0x81, U 0x9B, U 0x80, + U 0x65, U 0x51, U 0x55, U 0xC0, + U 0xB7, U 0xB8, U 0x38, U 0x2A, + U 0x0A, U 0x01, U 0xC0, U 0xC0, + U 0x09, U 0xAC, U 0x38, U 0x0C, + U 0x0C, U 0x42, U 0x64, U 0xC0, + U 0x42, U 0x1F, U 0xE0, U 0x36, + U 0x1E, U 0xE0, U 0x38, U 0x2E, + U 0xF6, U 0x7E, U 0xB0, U 0x4A, + U 0xD3, U 0x0F, U 0x6D, U 0xAA, U 0x05, U 0x00, U 0x80, U 0x88, U 0x00, U 0x90, U 0x8C, U 0xC0, - U 0xA0, U 0x2E, U 0x60, U 0x0C, - U 0x0C, U 0xE8, U 0x11, U 0xA7, - U 0x88, U 0x2F, U 0x82, U 0x85, - U 0xAD, U 0xEE, U 0x0F, U 0x4F, - U 0x0B, U 0x2F, U 0x86, U 0x85, - U 0x2B, U 0x60, U 0x06, U 0x22, - U 0xE4, U 0xCF, U 0x68, U 0xB1, - U 0x2A, U 0x29, U 0x60, U 0x15, - U 0xC0, U 0xB2, U 0xC9, U 0x9A, - U 0xD2, U 0xA0, U 0x2D, U 0x61, - U 0x02, U 0x2B, U 0x64, U 0x06, - U 0x0C, U 0xDD, U 0x02, U 0x2D, - U 0x65, U 0x02, U 0xD1, U 0x0F, - U 0xC0, U 0xE0, U 0x08, U 0xAE, - U 0x38, U 0x7E, U 0xB0, U 0xB7, - U 0x63, U 0xFF, U 0xAB, U 0x00, - U 0x22, U 0x64, U 0x06, U 0xD2, + U 0xA0, U 0x29, U 0x60, U 0x0C, + U 0x0C, U 0x9C, U 0x11, U 0xA2, + U 0xCC, U 0x2B, U 0xC2, U 0x85, + U 0xAD, U 0x99, U 0x0B, U 0x4B, + U 0x0B, U 0x2B, U 0xC6, U 0x85, + U 0x28, U 0x60, U 0x06, U 0x27, + U 0x94, U 0xCF, U 0x68, U 0x81, + U 0x22, U 0x2D, U 0x60, U 0x15, + U 0xD2, U 0xA0, U 0xC9, U 0xD2, + U 0xC0, U 0xE2, U 0x2E, U 0x64, + U 0x06, U 0xD1, U 0x0F, U 0x00, + U 0xC0, U 0xF0, U 0x08, U 0xAF, + U 0x38, U 0x7F, U 0xB0, U 0xBD, + U 0x63, U 0xFF, U 0xB1, U 0x00, + U 0x27, U 0x64, U 0x06, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x60, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x08, U 0x9D, + U 0x40, U 0x58, U 0x08, U 0xA6, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x60, U 0x58, U 0x09, - U 0x2D, U 0x63, U 0xFF, U 0xE8, + U 0x36, U 0x63, U 0xFF, U 0xE8, U 0x00, U 0x28, U 0x22, U 0x1E, - U 0x29, U 0x22, U 0x1D, U 0x78, - U 0x99, U 0x02, U 0x28, U 0x0A, - U 0x00, U 0xC1, U 0x76, U 0xC1, - U 0xC1, U 0xC1, U 0xD2, U 0x1B, - U 0xE0, U 0xA5, U 0xC1, U 0x24, - U 0xAB, U 0x6B, U 0x64, U 0x80, - U 0x43, U 0x78, U 0x91, U 0x40, - U 0x2A, U 0x80, U 0x00, U 0x0C, - U 0xAF, U 0x0C, U 0x64, U 0xF0, - U 0xAE, U 0x0D, U 0xAE, U 0x0C, - U 0x64, U 0xE0, U 0xA8, U 0x02, - U 0xAF, U 0x0C, U 0x64, U 0xF0, - U 0xA2, U 0x07, U 0xAE, U 0x0C, - U 0x64, U 0xE0, U 0x9C, U 0x2F, - U 0xAC, U 0xE8, U 0x64, U 0xF0, - U 0x96, U 0x2E, U 0xAC, U 0xE7, - U 0x64, U 0xE0, U 0x90, U 0x2F, - U 0xAC, U 0xE6, U 0x64, U 0xF0, - U 0x8A, U 0x2A, U 0x80, U 0x07, - U 0x08, U 0xA8, U 0x0B, U 0x08, - U 0x8A, U 0x02, U 0x7B, U 0x83, - U 0x02, U 0x2A, U 0x8D, U 0xF8, - U 0xD8, U 0xA0, U 0x65, U 0xAF, - U 0xBB, U 0xC0, U 0x90, U 0x60, - U 0x00, U 0x73, U 0x00, U 0x00, + U 0x29, U 0x22, U 0x1D, U 0xD3, + U 0x0F, U 0x78, U 0x99, U 0x01, + U 0xC0, U 0x80, U 0xC1, U 0xD6, + U 0xC1, U 0xC1, U 0x1B, U 0xE0, + U 0x25, U 0xC1, U 0x22, U 0xAB, + U 0x6B, U 0x64, U 0x80, U 0x42, + U 0x78, U 0x91, U 0x3F, U 0x2A, + U 0x80, U 0x00, U 0x0C, U 0xAE, + U 0x0C, U 0x64, U 0xE0, U 0xBB, + U 0x02, U 0xAF, U 0x0C, U 0x64, + U 0xF0, U 0xB5, U 0x2E, U 0xAC, + U 0xEC, U 0x64, U 0xE0, U 0xAF, + U 0x0D, U 0xAF, U 0x0C, U 0x64, + U 0xF0, U 0xA9, U 0x2E, U 0xAC, + U 0xE8, U 0x64, U 0xE0, U 0xA3, + U 0x2F, U 0xAC, U 0xE7, U 0x64, + U 0xF0, U 0x9D, U 0x2E, U 0xAC, + U 0xE6, U 0x64, U 0xE0, U 0x97, + U 0x2F, U 0x80, U 0x07, U 0x08, + U 0xF8, U 0x0B, U 0xDA, U 0x80, + U 0x7B, U 0x83, U 0x02, U 0x2A, + U 0x8D, U 0xF8, U 0xD8, U 0xA0, + U 0x65, U 0xAF, U 0xBC, U 0x28, + U 0x61, U 0x23, U 0x08, U 0xD7, + U 0x39, U 0xD9, U 0x70, U 0x60, + U 0x00, U 0x7B, U 0x00, U 0x00, U 0x2B, U 0x60, U 0x0C, U 0x0C, - U 0xB8, U 0x11, U 0xA7, U 0x88, - U 0x2E, U 0x82, U 0x86, U 0x6E, - U 0xE8, U 0x79, U 0x09, U 0xBA, - U 0x0A, U 0x2A, U 0xA2, U 0xA3, - U 0x68, U 0xA0, U 0x04, U 0x8E, - U 0x60, U 0x7A, U 0xE9, U 0x6B, + U 0xB8, U 0x11, U 0xA2, U 0x88, + U 0x2C, U 0x82, U 0x86, U 0x2A, + U 0x0A, U 0x08, U 0x7C, U 0xAB, + U 0x7E, U 0x09, U 0xBA, U 0x0A, + U 0x2A, U 0xA2, U 0xA3, U 0x68, + U 0xA0, U 0x05, U 0x2C, U 0x62, + U 0x00, U 0x7A, U 0xC9, U 0x6F, U 0x2A, U 0x82, U 0x85, U 0x64, - U 0xA0, U 0x65, U 0x1F, U 0xE0, - U 0x8D, U 0xC0, U 0xE3, U 0x2E, - U 0x64, U 0x06, U 0x9E, U 0xA1, - U 0x9F, U 0xA0, U 0x1F, U 0xE0, - U 0xB9, U 0x2E, U 0x60, U 0x0A, - U 0x92, U 0xA3, U 0x0F, U 0xEE, - U 0x02, U 0x9E, U 0xA2, U 0x8E, - U 0x60, U 0x0F, U 0xEE, U 0x02, - U 0x9E, U 0xA4, U 0x2F, U 0x60, - U 0x14, U 0x7A, U 0xFF, U 0x47, - U 0x22, U 0xA4, U 0x17, U 0xAD, - U 0xBE, U 0x2F, U 0x82, U 0x85, - U 0x22, U 0xE4, U 0xCF, U 0x2F, - U 0xFC, U 0x18, U 0x2F, U 0x86, - U 0x85, U 0x63, U 0xFE, U 0x70, - U 0x2A, U 0x6C, U 0x74, U 0xC0, - U 0xB1, U 0xDC, U 0x90, U 0xDD, - U 0x40, U 0x58, U 0x07, U 0xA3, - U 0x1D, U 0xE0, U 0x72, U 0xC0, - U 0xC1, U 0x63, U 0xFE, U 0xC4, + U 0xA0, U 0x69, U 0x1F, U 0xE0, + U 0x0B, U 0x27, U 0x65, U 0x04, + U 0xC0, U 0xE3, U 0xC0, U 0xC4, + U 0x2E, U 0x64, U 0x06, U 0x9C, + U 0xA1, U 0x1C, U 0xE0, U 0x36, + U 0x9F, U 0xA0, U 0x2E, U 0x60, + U 0x0A, U 0x97, U 0xA3, U 0x0C, + U 0xEE, U 0x02, U 0x9E, U 0xA2, + U 0x8F, U 0x60, U 0x0C, U 0xFF, + U 0x02, U 0x9F, U 0xA4, U 0x2E, + U 0x60, U 0x14, U 0x7A, U 0xEF, + U 0x46, U 0x27, U 0xA4, U 0x17, + U 0xAD, U 0xBC, U 0x2F, U 0x82, + U 0x85, U 0x27, U 0xC4, U 0xCF, + U 0x2F, U 0xFC, U 0x20, U 0x2F, + U 0x86, U 0x85, U 0x63, U 0xFE, + U 0x69, U 0x2A, U 0x6C, U 0x74, + U 0xC0, U 0xB1, U 0xDC, U 0x90, + U 0xDD, U 0x40, U 0x58, U 0x07, + U 0xA7, U 0x1D, U 0xDF, U 0xEE, + U 0x63, U 0xFE, U 0xC1, U 0x00, U 0xD9, U 0xA0, U 0xDA, U 0x60, - U 0xDB, U 0x30, U 0xDC, U 0x40, - U 0xDD, U 0x50, U 0xC2, U 0xF0, - U 0xC1, U 0xE0, U 0x09, U 0xFE, - U 0x39, U 0x58, U 0x07, U 0xEA, + U 0xDB, U 0x30, U 0xC2, U 0xD0, + U 0xC1, U 0xE0, U 0xDC, U 0x40, + U 0x09, U 0xDE, U 0x39, U 0xDD, + U 0x50, U 0x58, U 0x07, U 0xF0, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x60, U 0x58, U 0x08, - U 0xEF, U 0x63, U 0xFE, U 0xF0, - U 0x2C, U 0xA4, U 0x17, U 0x0D, - U 0xBE, U 0x08, U 0x29, U 0x82, - U 0x85, U 0x22, U 0xE4, U 0xCF, - U 0x29, U 0x9C, U 0x18, U 0x29, - U 0x86, U 0x85, U 0x64, U 0x50, - U 0x0C, U 0x2A, U 0x6C, U 0x74, - U 0x04, U 0x4B, U 0x02, U 0x58, - U 0x01, U 0x6B, U 0xD2, U 0xA0, - U 0xD1, U 0x0F, U 0xC0, U 0x20, - U 0xD1, U 0x0F, U 0x00, U 0x00, + U 0xF5, U 0x63, U 0xFE, U 0xE4, + U 0x29, U 0x0A, U 0x01, U 0x29, + U 0xA4, U 0x17, U 0x0D, U 0xBF, + U 0x08, U 0x2E, U 0x82, U 0x85, + U 0x27, U 0xF4, U 0xCF, U 0x2E, + U 0xEC, U 0x20, U 0x2E, U 0x86, + U 0x85, U 0x64, U 0x50, U 0x0B, + U 0x2A, U 0x6C, U 0x74, U 0xDB, + U 0x40, U 0x58, U 0x01, U 0x6A, + U 0xD2, U 0xA0, U 0xD1, U 0x0F, + U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x2B, U 0x22, U 0x1E, U 0x28, U 0x22, U 0x1D, U 0x93, U 0x10, U 0x7B, U 0x89, U 0x01, U 0xC0, U 0xB0, U 0xC0, U 0xC9, U 0xC0, U 0x3B, U 0xC1, U 0xF2, U 0x04, U 0x06, - U 0x40, U 0x1D, U 0xE0, U 0x5B, + U 0x40, U 0x1D, U 0xDF, U 0xD8, U 0xC0, U 0xE2, U 0xC0, U 0x74, U 0x07, U 0x47, U 0x01, U 0x0E, U 0x4E, U 0x01, U 0xAD, U 0x2D, @@ -4711,7 +4843,7 @@ static unsigned char t3fw[30136] = { U 0x10, U 0x7C, U 0xB1, U 0x21, U 0x7A, U 0xB9, U 0x01, U 0xC0, U 0xB0, U 0xC9, U 0xB9, U 0x13, - U 0xE0, U 0x26, U 0xDA, U 0x20, + U 0xDF, U 0xA3, U 0xDA, U 0x20, U 0x28, U 0xB0, U 0x00, U 0x2C, U 0xB0, U 0x07, U 0x03, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, @@ -4729,13 +4861,13 @@ static unsigned char t3fw[30136] = { U 0x0E, U 0x1E, U 0x50, U 0x65, U 0xE1, U 0x9E, U 0x29, U 0x21, U 0x02, U 0xC0, U 0xC1, U 0x16, - U 0xE0, U 0x15, U 0x09, U 0x0B, + U 0xDF, U 0x92, U 0x09, U 0x0B, U 0x4C, U 0x65, U 0xB0, U 0x90, U 0x8A, U 0x30, U 0x0A, U 0x6E, U 0x51, U 0x68, U 0xE3, U 0x02, U 0x60, U 0x00, U 0x85, U 0x2F, - U 0x62, U 0x9E, U 0x1B, U 0xE0, - U 0x0E, U 0x6E, U 0xF8, U 0x53, + U 0x62, U 0x9E, U 0x1B, U 0xDF, + U 0x8B, U 0x6E, U 0xF8, U 0x53, U 0x2B, U 0xB2, U 0x26, U 0x68, U 0xB0, U 0x05, U 0x2E, U 0x22, U 0x00, U 0x7B, U 0xE9, U 0x47, @@ -4746,32 +4878,32 @@ static unsigned char t3fw[30136] = { U 0x11, U 0xA6, U 0xFF, U 0x29, U 0xF2, U 0x86, U 0x9E, U 0x12, U 0x79, U 0x8B, U 0x41, U 0x17, - U 0xE0, U 0x05, U 0x07, U 0xB7, + U 0xDF, U 0x82, U 0x07, U 0xB7, U 0x0A, U 0x27, U 0x72, U 0xA3, U 0x68, U 0x70, U 0x04, U 0x88, U 0x20, U 0x77, U 0x89, U 0x30, U 0x29, U 0xF2, U 0x85, U 0xDF, U 0x90, U 0xD7, U 0x90, U 0x65, U 0x90, U 0x65, U 0x2A, U 0x21, - U 0x04, U 0x19, U 0xE0, U 0x3C, + U 0x04, U 0x19, U 0xDF, U 0xB9, U 0x7A, U 0x9B, U 0x22, U 0xDA, - U 0x20, U 0x58, U 0x06, U 0x9F, + U 0x20, U 0x58, U 0x06, U 0xA3, U 0x60, U 0x00, U 0x29, U 0x00, U 0x2C, U 0x21, U 0x04, U 0x1B, - U 0xE0, U 0x38, U 0x7C, U 0xBB, + U 0xDF, U 0xB5, U 0x7C, U 0xBB, U 0x18, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x06, U 0x9A, + U 0xB6, U 0x58, U 0x06, U 0x9E, U 0xC9, U 0x58, U 0x60, U 0x01, U 0x4C, U 0xC0, U 0x90, U 0x63, U 0xFF, U 0xCC, U 0xDA, U 0x20, - U 0x58, U 0x08, U 0x7F, U 0x60, + U 0x58, U 0x08, U 0x85, U 0x60, U 0x00, U 0x06, U 0xDA, U 0x20, U 0xC0, U 0xB6, U 0x58, U 0x08, - U 0x7D, U 0x65, U 0x51, U 0x35, + U 0x83, U 0x65, U 0x51, U 0x35, U 0xDC, U 0x40, U 0xDB, U 0x30, U 0x8D, U 0x30, U 0xDA, U 0x20, U 0x0D, U 0x6D, U 0x51, U 0x58, - U 0x06, U 0xF2, U 0xC0, U 0xD0, + U 0x06, U 0xF6, U 0xC0, U 0xD0, U 0xD3, U 0xA0, U 0x64, U 0xA1, U 0x20, U 0x29, U 0x21, U 0x02, U 0xC0, U 0x51, U 0x84, U 0xA1, @@ -4789,11 +4921,11 @@ static unsigned char t3fw[30136] = { U 0xBB, U 0x15, U 0x9F, U 0x13, U 0x9E, U 0x14, U 0x8A, U 0x10, U 0x8B, U 0x11, U 0x58, U 0x07, - U 0x02, U 0x8E, U 0x14, U 0x8F, + U 0x06, U 0x8E, U 0x14, U 0x8F, U 0x13, U 0xC0, U 0xD0, U 0x2D, U 0x24, U 0x66, U 0x8A, U 0x30, U 0xC0, U 0x92, U 0xC1, U 0xC8, - U 0x1B, U 0xDF, U 0xEC, U 0x7F, + U 0x1B, U 0xDF, U 0x68, U 0x7F, U 0xA6, U 0x09, U 0x9B, U 0xF0, U 0x99, U 0xF1, U 0x2C, U 0xF4, U 0x08, U 0x27, U 0xFC, U 0x10, @@ -4802,8 +4934,8 @@ static unsigned char t3fw[30136] = { U 0x51, U 0xC0, U 0x80, U 0x07, U 0x58, U 0x38, U 0x08, U 0x08, U 0x42, U 0x64, U 0x80, U 0x67, - U 0x18, U 0xDF, U 0xC8, U 0x19, - U 0xDF, U 0xC9, U 0x29, U 0x86, + U 0x18, U 0xDF, U 0x45, U 0x19, + U 0xDF, U 0x46, U 0x29, U 0x86, U 0x7E, U 0x6A, U 0x42, U 0x0A, U 0xD3, U 0x0F, U 0x6D, U 0xE9, U 0x05, U 0x00, U 0xA0, U 0x88, @@ -4814,7 +4946,7 @@ static unsigned char t3fw[30136] = { U 0x0B, U 0x2C, U 0x94, U 0x08, U 0x9B, U 0x90, U 0x9F, U 0x91, U 0x2F, U 0x20, U 0x0C, U 0x12, - U 0xDF, U 0xC8, U 0x0C, U 0xF8, + U 0xDF, U 0x45, U 0x0C, U 0xF8, U 0x11, U 0xA6, U 0x88, U 0x29, U 0x82, U 0x85, U 0xA2, U 0xFF, U 0x2D, U 0xF4, U 0xCF, U 0xD2, @@ -4822,7 +4954,7 @@ static unsigned char t3fw[30136] = { U 0x23, U 0x86, U 0x85, U 0xD1, U 0x0F, U 0x22, U 0x20, U 0x0C, U 0x89, U 0x12, U 0x18, U 0xDF, - U 0xC0, U 0x0C, U 0x2B, U 0x11, + U 0x3D, U 0x0C, U 0x2B, U 0x11, U 0xA6, U 0xBB, U 0xA8, U 0x22, U 0x2D, U 0x24, U 0xCF, U 0x2C, U 0xB2, U 0x85, U 0xD2, U 0xA0, @@ -4842,18 +4974,18 @@ static unsigned char t3fw[30136] = { U 0x9E, U 0x14, U 0x2A, U 0x2C, U 0x74, U 0xC0, U 0xB1, U 0xDC, U 0x70, U 0xDD, U 0x40, U 0x58, - U 0x06, U 0xDD, U 0x8E, U 0x14, + U 0x06, U 0xE1, U 0x8E, U 0x14, U 0xC0, U 0xD0, U 0x1B, U 0xDF, - U 0xB9, U 0xC1, U 0xC8, U 0x63, + U 0x35, U 0xC1, U 0xC8, U 0x63, U 0xFF, U 0x6A, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x28, U 0x21, U 0x02, U 0x16, U 0xDF, - U 0x9D, U 0x08, U 0x08, U 0x4C, + U 0x1A, U 0x08, U 0x08, U 0x4C, U 0x65, U 0x82, U 0x19, U 0x29, U 0x62, U 0x9E, U 0x6F, U 0x98, U 0x02, U 0x60, U 0x02, U 0x20, - U 0x19, U 0xDF, U 0x98, U 0x29, + U 0x19, U 0xDF, U 0x15, U 0x29, U 0x92, U 0x26, U 0x68, U 0x90, U 0x07, U 0x8A, U 0x20, U 0x09, U 0xAA, U 0x0C, U 0x65, U 0xA2, @@ -4869,7 +5001,7 @@ static unsigned char t3fw[30136] = { U 0x24, U 0x66, U 0x7C, U 0xDB, U 0x02, U 0x60, U 0x01, U 0xEF, U 0xC0, U 0xC1, U 0x29, U 0x30, - U 0x08, U 0x1B, U 0xDF, U 0x8A, + U 0x08, U 0x1B, U 0xDF, U 0x07, U 0x64, U 0x90, U 0x9C, U 0x2F, U 0x0A, U 0xFF, U 0xC0, U 0xD3, U 0xB0, U 0x9E, U 0x64, U 0xE1, @@ -4885,18 +5017,18 @@ static unsigned char t3fw[30136] = { U 0xC2, U 0x86, U 0x28, U 0x0A, U 0x08, U 0x79, U 0x83, U 0x02, U 0x60, U 0x01, U 0xB9, U 0x19, - U 0xDF, U 0x7A, U 0x09, U 0xB9, + U 0xDE, U 0xF7, U 0x09, U 0xB9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x08, U 0x2E, U 0x22, U 0x00, U 0x09, U 0xEE, U 0x0C, U 0x65, U 0xE1, U 0xA4, U 0x2E, U 0xC2, U 0x85, U 0x64, U 0xE1, U 0x9E, U 0x26, U 0x20, - U 0x07, U 0x13, U 0xDF, U 0x83, + U 0x07, U 0x13, U 0xDF, U 0x00, U 0x6E, U 0x7B, U 0x02, U 0x60, - U 0x01, U 0x9A, U 0x17, U 0xDF, - U 0x7A, U 0x1F, U 0xDF, U 0x83, - U 0x19, U 0xDF, U 0xB0, U 0xC0, + U 0x01, U 0x9A, U 0x17, U 0xDE, + U 0xF7, U 0x1F, U 0xDF, U 0x00, + U 0x19, U 0xDF, U 0x2D, U 0xC0, U 0xD2, U 0x28, U 0x20, U 0x0A, U 0x93, U 0xE0, U 0x9D, U 0xE1, U 0xA9, U 0x69, U 0x0F, U 0x88, @@ -4905,7 +5037,7 @@ static unsigned char t3fw[30136] = { U 0x80, U 0xB1, U 0xFF, U 0x07, U 0xFF, U 0x02, U 0x9F, U 0xE3, U 0x2E, U 0xC2, U 0x85, U 0x1F, - U 0xDF, U 0x6D, U 0x0E, U 0xDE, + U 0xDE, U 0xEA, U 0x0E, U 0xDE, U 0x0B, U 0xAF, U 0xBF, U 0x2A, U 0xF4, U 0xCF, U 0x2E, U 0xC6, U 0x85, U 0x65, U 0x5F, U 0x76, @@ -4915,21 +5047,21 @@ static unsigned char t3fw[30136] = { U 0x13, U 0x00, U 0x99, U 0x32, U 0x00, U 0xED, U 0x32, U 0x64, U 0x80, U 0xEE, U 0x2A, U 0x30, - U 0x14, U 0x1F, U 0xDF, U 0x9D, + U 0x14, U 0x1F, U 0xDF, U 0x1A, U 0x00, U 0xAA, U 0x32, U 0x78, U 0xEF, U 0x05, U 0x0F, U 0x9E, U 0x09, U 0x2D, U 0xE4, U 0x7F, - U 0x1E, U 0xDF, U 0x9B, U 0x66, + U 0x1E, U 0xDF, U 0x18, U 0x66, U 0xA0, U 0x05, U 0x0F, U 0x98, U 0x09, U 0x2A, U 0x84, U 0x80, U 0xB4, U 0xA7, U 0x18, U 0xDF, - U 0x98, U 0xC7, U 0x6F, U 0x00, + U 0x15, U 0xC7, U 0x6F, U 0x00, U 0x91, U 0x04, U 0xAE, U 0x9E, U 0xDD, U 0xE0, U 0x00, U 0xAF, U 0x1A, U 0x00, U 0xC3, U 0x1A, U 0x6E, U 0xE1, U 0x05, U 0x2D, U 0xB2, U 0x00, U 0x0D, U 0xED, - U 0x0C, U 0x1E, U 0xDF, U 0x92, + U 0x0C, U 0x1E, U 0xDF, U 0x0F, U 0x08, U 0xD8, U 0x1C, U 0x06, U 0x33, U 0x03, U 0xAE, U 0x88, U 0x2A, U 0x84, U 0x8B, U 0x2E, @@ -4960,22 +5092,22 @@ static unsigned char t3fw[30136] = { U 0x00, U 0xEE, U 0x11, U 0x0E, U 0xDD, U 0x02, U 0xC0, U 0xE3, U 0x0E, U 0xFF, U 0x02, U 0x1E, - U 0xDF, U 0x66, U 0x9F, U 0x71, - U 0x9E, U 0x70, U 0x1E, U 0xDF, - U 0x65, U 0x8F, U 0x20, U 0x98, + U 0xDE, U 0xE3, U 0x9F, U 0x71, + U 0x9E, U 0x70, U 0x1E, U 0xDE, + U 0xE2, U 0x8F, U 0x20, U 0x98, U 0x73, U 0x9D, U 0x74, U 0x05, U 0xFF, U 0x11, U 0x0B, U 0xCD, U 0x53, U 0xC1, U 0x80, U 0x98, U 0x75, U 0x0F, U 0xDD, U 0x02, U 0x0E, U 0xDD, U 0x02, U 0x9D, - U 0x72, U 0x1E, U 0xDF, U 0x24, + U 0x72, U 0x1E, U 0xDE, U 0xA1, U 0x2A, U 0x24, U 0x66, U 0x2F, U 0x62, U 0x9D, U 0x2A, U 0xE4, U 0xA2, U 0x2F, U 0xFC, U 0x18, U 0x2F, U 0x66, U 0x9D, U 0x63, U 0xFE, U 0x71, U 0x00, U 0x00, U 0x00, U 0x2F, U 0x30, U 0x12, - U 0x1B, U 0xDF, U 0x66, U 0x00, + U 0x1B, U 0xDE, U 0xE3, U 0x00, U 0xFA, U 0x32, U 0x78, U 0xFF, U 0x05, U 0x0B, U 0x98, U 0x0B, U 0x2A, U 0x84, U 0x7F, U 0x66, @@ -4987,16 +5119,16 @@ static unsigned char t3fw[30136] = { U 0x9E, U 0x2B, U 0x63, U 0xFF, U 0x56, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x07, U 0x0E, + U 0x40, U 0x58, U 0x07, U 0x14, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x07, U 0x9D, + U 0xB6, U 0x58, U 0x07, U 0xA3, U 0x63, U 0xFF, U 0xE5, U 0x00, U 0xDA, U 0x70, U 0x58, U 0x06, - U 0x36, U 0xC0, U 0xA0, U 0x2A, + U 0x3A, U 0xC0, U 0xA0, U 0x2A, U 0x24, U 0x66, U 0x63, U 0xFE, U 0x02, U 0xDA, U 0x20, U 0x58, - U 0x07, U 0x98, U 0x63, U 0xFF, + U 0x07, U 0x9E, U 0x63, U 0xFF, U 0xCF, U 0xB1, U 0x69, U 0x28, U 0x20, U 0x0A, U 0x86, U 0x20, U 0x09, U 0x09, U 0x47, U 0x99, @@ -5005,14 +5137,14 @@ static unsigned char t3fw[30136] = { U 0x26, U 0x93, U 0xE0, U 0x27, U 0xE5, U 0x0A, U 0x9A, U 0xE3, U 0x88, U 0x10, U 0x9D, U 0xE1, - U 0x19, U 0xDF, U 0x42, U 0x8D, + U 0x19, U 0xDE, U 0xBF, U 0x8D, U 0x11, U 0x09, U 0x6F, U 0x02, U 0x9F, U 0xE4, U 0x2D, U 0xE4, U 0x16, U 0x09, U 0x88, U 0x02, U 0xC0, U 0xD3, U 0x98, U 0xE2, U 0x2A, U 0x24, U 0x07, U 0x63, U 0xFE, U 0x51, U 0x00, U 0x00, - U 0x1D, U 0xDF, U 0x0B, U 0x08, + U 0x1D, U 0xDE, U 0x88, U 0x08, U 0x68, U 0x11, U 0x8F, U 0x11, U 0x89, U 0x2B, U 0x93, U 0xE0, U 0x08, U 0xFF, U 0x02, U 0xC0, @@ -5026,7 +5158,7 @@ static unsigned char t3fw[30136] = { U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x85, U 0x21, U 0x0D, U 0x38, U 0x11, - U 0x14, U 0xDE, U 0xE9, U 0x86, + U 0x14, U 0xDE, U 0x66, U 0x86, U 0x22, U 0xA4, U 0x24, U 0x08, U 0x66, U 0x0C, U 0x96, U 0x22, U 0x05, U 0x33, U 0x0B, U 0x93, @@ -5040,12 +5172,12 @@ static unsigned char t3fw[30136] = { U 0x21, U 0x63, U 0xFF, U 0xE3, U 0x6C, U 0x10, U 0x0A, U 0xD6, U 0x20, U 0x94, U 0x18, U 0x17, - U 0xDE, U 0xDE, U 0xD9, U 0x30, + U 0xDE, U 0x5B, U 0xD9, U 0x30, U 0xB8, U 0x38, U 0x98, U 0x19, U 0x99, U 0x14, U 0x65, U 0x52, U 0x52, U 0xC0, U 0xE1, U 0xD2, U 0xE0, U 0x2E, U 0x61, U 0x02, - U 0x1D, U 0xDE, U 0xDB, U 0x0E, + U 0x1D, U 0xDE, U 0x58, U 0x0E, U 0x0E, U 0x4C, U 0x65, U 0xE1, U 0x62, U 0x8F, U 0x30, U 0x8E, U 0x19, U 0x0F, U 0x6F, U 0x51, @@ -5054,19 +5186,19 @@ static unsigned char t3fw[30136] = { U 0x29, U 0xD0, U 0x23, U 0x0E, U 0x8F, U 0x50, U 0x77, U 0xE6, U 0x6B, U 0x8F, U 0x18, U 0x1E, - U 0xDF, U 0x18, U 0xB0, U 0xFF, + U 0xDE, U 0x95, U 0xB0, U 0xFF, U 0x0F, U 0xF4, U 0x11, U 0x0F, U 0x1F, U 0x14, U 0x65, U 0x90, - U 0xCE, U 0x18, U 0xDF, U 0x15, + U 0xCE, U 0x18, U 0xDE, U 0x92, U 0x8C, U 0x60, U 0xA8, U 0xCC, U 0xC0, U 0xB1, U 0x19, U 0xDE, - U 0xC9, U 0x28, U 0x60, U 0x0B, + U 0x46, U 0x28, U 0x60, U 0x0B, U 0x09, U 0xCC, U 0x0B, U 0x0D, U 0x88, U 0x09, U 0x29, U 0x81, U 0x1C, U 0x28, U 0x81, U 0x1A, U 0x2A, U 0x0A, U 0x00, U 0x09, U 0x88, U 0x0C, U 0x08, U 0xBA, - U 0x38, U 0x1B, U 0xDF, U 0x0B, + U 0x38, U 0x1B, U 0xDE, U 0x88, U 0x0C, U 0xA9, U 0x0A, U 0x29, U 0x92, U 0x94, U 0x7B, U 0x9B, U 0x02, U 0x60, U 0x00, U 0x8C, @@ -5075,28 +5207,28 @@ static unsigned char t3fw[30136] = { U 0xA7, U 0xDD, U 0x29, U 0xD2, U 0x86, U 0xB8, U 0x48, U 0x79, U 0x83, U 0x02, U 0x60, U 0x00, - U 0xD2, U 0x19, U 0xDE, U 0xBB, + U 0xD2, U 0x19, U 0xDE, U 0x38, U 0x09, U 0xB8, U 0x0A, U 0x28, U 0x82, U 0xA3, U 0x98, U 0x17, U 0x68, U 0x80, U 0x02, U 0x60, U 0x00, U 0xA3, U 0x60, U 0x00, - U 0xA5, U 0x1A, U 0xDE, U 0xFF, + U 0xA5, U 0x1A, U 0xDE, U 0x7C, U 0x84, U 0x18, U 0x0A, U 0xEE, U 0x01, U 0xCA, U 0x98, U 0x1B, - U 0xDE, U 0xB2, U 0x8C, U 0x19, + U 0xDE, U 0x2F, U 0x8C, U 0x19, U 0x2B, U 0xB0, U 0x00, U 0x8C, U 0xC0, U 0x6E, U 0xB3, U 0x13, - U 0x1D, U 0xDE, U 0xAF, U 0x0C, + U 0x1D, U 0xDE, U 0x2C, U 0x0C, U 0x1C, U 0x52, U 0x0D, U 0xCC, U 0x0B, U 0x2D, U 0xC2, U 0x95, U 0xC0, U 0xA1, U 0x7E, U 0xDB, U 0xAE, U 0x60, U 0x00, U 0x38, U 0x0C, U 0x0C, U 0x53, U 0x60, U 0x00, U 0x09, U 0x00, U 0x00, - U 0x00, U 0x18, U 0xDE, U 0xF1, + U 0x00, U 0x18, U 0xDE, U 0x6E, U 0x8C, U 0x60, U 0xA8, U 0xCC, U 0xC0, U 0xB1, U 0x19, U 0xDE, - U 0xA5, U 0x28, U 0x60, U 0x0B, + U 0x22, U 0x28, U 0x60, U 0x0B, U 0x09, U 0xCC, U 0x0B, U 0x0D, U 0x88, U 0x09, U 0x29, U 0x81, U 0x1C, U 0x28, U 0x81, U 0x1A, @@ -5106,16 +5238,16 @@ static unsigned char t3fw[30136] = { U 0x29, U 0x92, U 0x94, U 0x7E, U 0x93, U 0x02, U 0x63, U 0xFF, U 0x72, U 0xDA, U 0x60, U 0xC0, - U 0xBA, U 0x58, U 0x07, U 0x29, + U 0xBA, U 0x58, U 0x07, U 0x2F, U 0x64, U 0x50, U 0x73, U 0x60, U 0x02, U 0x66, U 0x00, U 0x00, - U 0x1A, U 0xDE, U 0x98, U 0x8C, + U 0x1A, U 0xDE, U 0x15, U 0x8C, U 0x19, U 0x2A, U 0xA0, U 0x00, U 0x8C, U 0xC0, U 0x6E, U 0xA3, - U 0x1A, U 0x18, U 0xDE, U 0x94, + U 0x1A, U 0x18, U 0xDE, U 0x11, U 0x0C, U 0x1C, U 0x52, U 0x08, U 0xCC, U 0x0B, U 0x18, U 0xDE, - U 0xDB, U 0x2B, U 0xC2, U 0x95, + U 0x58, U 0x2B, U 0xC2, U 0x95, U 0xC0, U 0xA1, U 0x78, U 0xB3, U 0x02, U 0x63, U 0xFF, U 0x3F, U 0x63, U 0xFF, U 0xC9, U 0x00, @@ -5124,23 +5256,23 @@ static unsigned char t3fw[30136] = { U 0x78, U 0x99, U 0x18, U 0x29, U 0xD2, U 0x85, U 0xC9, U 0x92, U 0x2B, U 0x72, U 0x9E, U 0x1D, - U 0xDE, U 0x89, U 0x6E, U 0xB8, + U 0xDE, U 0x06, U 0x6E, U 0xB8, U 0x23, U 0x2D, U 0xD2, U 0x26, U 0x99, U 0x13, U 0x69, U 0xD0, U 0x0B, U 0x60, U 0x00, U 0x0D, U 0xDA, U 0x60, U 0x58, U 0x07, - U 0x13, U 0x60, U 0x00, U 0x17, + U 0x19, U 0x60, U 0x00, U 0x17, U 0x00, U 0x88, U 0x60, U 0x7D, U 0x89, U 0x0A, U 0x9A, U 0x1A, U 0x29, U 0x72, U 0x9D, U 0x9C, U 0x12, U 0x99, U 0x15, U 0xCF, U 0x95, U 0xDA, U 0x60, U 0xC0, - U 0xB6, U 0x58, U 0x07, U 0x0C, + U 0xB6, U 0x58, U 0x07, U 0x12, U 0x65, U 0x51, U 0xF5, U 0x8D, U 0x14, U 0x8C, U 0x18, U 0xDB, U 0xD0, U 0x8D, U 0xD0, U 0x06, U 0x6A, U 0x02, U 0x0D, U 0x6D, - U 0x51, U 0x58, U 0x05, U 0x80, + U 0x51, U 0x58, U 0x05, U 0x84, U 0xD3, U 0xA0, U 0x9A, U 0x14, U 0x64, U 0xA1, U 0xDD, U 0x82, U 0xA0, U 0x85, U 0xA1, U 0xB8, @@ -5158,7 +5290,7 @@ static unsigned char t3fw[30136] = { U 0x66, U 0x7C, U 0xAB, U 0x11, U 0x9F, U 0x11, U 0x9E, U 0x1B, U 0x8A, U 0x15, U 0x58, U 0x05, - U 0x91, U 0x8E, U 0x1B, U 0x8F, + U 0x95, U 0x8E, U 0x1B, U 0x8F, U 0x11, U 0xC0, U 0xA0, U 0x2A, U 0x64, U 0x66, U 0x9F, U 0x11, U 0x64, U 0xF0, U 0xE1, U 0x29, @@ -5172,21 +5304,21 @@ static unsigned char t3fw[30136] = { U 0x99, U 0x00, U 0x90, U 0x8C, U 0x65, U 0x51, U 0x4E, U 0x8A, U 0x10, U 0x85, U 0x1A, U 0x8B, - U 0x30, U 0x1F, U 0xDE, U 0x6B, + U 0x30, U 0x1F, U 0xDD, U 0xE8, U 0x88, U 0x12, U 0x29, U 0x60, U 0x07, U 0x08, U 0x58, U 0x0A, U 0x2C, U 0x82, U 0x94, U 0x2D, U 0x61, U 0x04, U 0x0E, U 0xCC, U 0x0C, U 0x2C, U 0x86, U 0x94, U 0x6F, U 0xDB, U 0x3C, U 0x1C, - U 0xDE, U 0x95, U 0xAC, U 0x9C, + U 0xDE, U 0x12, U 0xAC, U 0x9C, U 0x29, U 0xC0, U 0x80, U 0x0B, U 0x5D, U 0x50, U 0xA2, U 0x99, U 0x09, U 0x09, U 0x47, U 0x29, U 0xC4, U 0x80, U 0x65, U 0xD0, U 0xDA, U 0x2E, U 0x60, U 0x0C, - U 0xC0, U 0xD0, U 0x1F, U 0xDE, - U 0x54, U 0x0C, U 0xE8, U 0x11, + U 0xC0, U 0xD0, U 0x1F, U 0xDD, + U 0xD1, U 0x0C, U 0xE8, U 0x11, U 0xAF, U 0xEE, U 0xA7, U 0x88, U 0x22, U 0x82, U 0x85, U 0x2D, U 0xE4, U 0xCF, U 0x02, U 0x42, @@ -5200,7 +5332,7 @@ static unsigned char t3fw[30136] = { U 0x60, U 0x2E, U 0x60, U 0x0A, U 0x28, U 0x0A, U 0xFF, U 0x08, U 0xE8, U 0x0C, U 0x64, U 0x81, - U 0x0E, U 0x18, U 0xDE, U 0x7E, + U 0x0E, U 0x18, U 0xDD, U 0xFB, U 0x83, U 0x16, U 0x82, U 0x13, U 0xB3, U 0x39, U 0x02, U 0x33, U 0x0B, U 0x2C, U 0x34, U 0x16, @@ -5212,7 +5344,7 @@ static unsigned char t3fw[30136] = { U 0x34, U 0x98, U 0x32, U 0xC0, U 0x80, U 0x28, U 0x64, U 0x07, U 0x2B, U 0x60, U 0x0C, U 0xD2, - U 0xA0, U 0x1C, U 0xDE, U 0x39, + U 0xA0, U 0x1C, U 0xDD, U 0xB6, U 0x0C, U 0xBE, U 0x11, U 0xA7, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0xAC, U 0xBB, U 0x28, U 0xB4, @@ -5232,15 +5364,15 @@ static unsigned char t3fw[30136] = { U 0xF1, U 0xC0, U 0x80, U 0x0C, U 0xF8, U 0x38, U 0x08, U 0x08, U 0x42, U 0x64, U 0x80, U 0x6B, - U 0x1B, U 0xDE, U 0x1A, U 0x19, - U 0xDE, U 0x1B, U 0x29, U 0xB6, + U 0x1B, U 0xDD, U 0x97, U 0x19, + U 0xDD, U 0x98, U 0x29, U 0xB6, U 0x7E, U 0x8D, U 0x18, U 0xB0, U 0xDD, U 0x6D, U 0xDA, U 0x05, U 0x00, U 0xA0, U 0x88, U 0x00, U 0xC0, U 0x8C, U 0xC0, U 0xA0, U 0x63, U 0xFE, U 0xF3, U 0x00, U 0x82, U 0x13, U 0x8B, U 0x16, - U 0x1D, U 0xDE, U 0x2B, U 0x28, + U 0x1D, U 0xDD, U 0xA8, U 0x28, U 0x60, U 0x0A, U 0xC0, U 0xE0, U 0x2E, U 0xC4, U 0x80, U 0x0D, U 0x88, U 0x02, U 0x02, U 0xB2, @@ -5251,7 +5383,7 @@ static unsigned char t3fw[30136] = { U 0x0C, U 0x2D, U 0x11, U 0xA7, U 0xDD, U 0x28, U 0xD2, U 0x85, U 0x08, U 0xBB, U 0x0B, U 0x18, - U 0xDE, U 0x13, U 0x2B, U 0xD6, + U 0xDD, U 0x90, U 0x2B, U 0xD6, U 0x85, U 0xA8, U 0x22, U 0x2E, U 0x24, U 0xCF, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x9E, U 0x1B, @@ -5266,14 +5398,14 @@ static unsigned char t3fw[30136] = { U 0x0F, U 0x9E, U 0x1B, U 0x2A, U 0x6C, U 0x74, U 0xC0, U 0xB1, U 0x8D, U 0x18, U 0x58, U 0x05, - U 0x35, U 0x8E, U 0x1B, U 0x85, + U 0x39, U 0x8E, U 0x1B, U 0x85, U 0x1A, U 0x63, U 0xFE, U 0x7E, U 0x88, U 0x6B, U 0x82, U 0x13, U 0x89, U 0x16, U 0x08, U 0xBE, U 0x11, U 0x0E, U 0xCE, U 0x02, U 0x02, U 0x92, U 0x0B, U 0x9E, U 0x25, U 0xB4, U 0x99, U 0x1E, - U 0xDE, U 0x06, U 0x9F, U 0x20, + U 0xDD, U 0x83, U 0x9F, U 0x20, U 0x0E, U 0x88, U 0x02, U 0x98, U 0x22, U 0xC0, U 0xEF, U 0x04, U 0xD8, U 0x11, U 0x0E, U 0x88, @@ -5281,7 +5413,7 @@ static unsigned char t3fw[30136] = { U 0xE4, U 0x9E, U 0x21, U 0xC0, U 0x80, U 0xD2, U 0xA0, U 0x2B, U 0x60, U 0x0C, U 0x28, U 0x64, - U 0x07, U 0x1C, U 0xDD, U 0xF4, + U 0x07, U 0x1C, U 0xDD, U 0x71, U 0x0C, U 0xBE, U 0x11, U 0xA7, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0xAC, U 0xBB, U 0x28, U 0xB4, @@ -5300,16 +5432,16 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x04, U 0x02, U 0x2A, U 0x02, U 0x03, U 0x3B, U 0x02, U 0x5B, U 0xFF, U 0xF6, - U 0x1C, U 0xDD, U 0xDC, U 0x1B, - U 0xDE, U 0x24, U 0xC7, U 0x9F, + U 0x1C, U 0xDD, U 0x59, U 0x1B, + U 0xDD, U 0xA1, U 0xC7, U 0x9F, U 0x88, U 0xB0, U 0x09, U 0xA9, U 0x03, U 0x09, U 0x8A, U 0x01, U 0x9A, U 0xB0, U 0x79, U 0x80, U 0x1E, U 0xC0, U 0xF0, U 0x0F, U 0xE4, U 0x31, U 0x1D, U 0xDD, - U 0xD3, U 0x00, U 0x02, U 0x00, + U 0x50, U 0x00, U 0x02, U 0x00, U 0x2B, U 0xD2, U 0x82, U 0x1E, - U 0xDE, U 0x1D, U 0x2A, U 0xC1, + U 0xDD, U 0x9A, U 0x2A, U 0xC1, U 0x02, U 0x0E, U 0xBB, U 0x02, U 0x2B, U 0xD6, U 0x82, U 0x0A, U 0xE4, U 0x31, U 0xD1, U 0x0F, @@ -5320,17 +5452,17 @@ static unsigned char t3fw[30136] = { U 0x31, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0xC0, U 0x0C, U 0xE4, U 0x31, - U 0x12, U 0xDD, U 0xC8, U 0x1A, - U 0xDD, U 0xC5, U 0x00, U 0x02, + U 0x12, U 0xDD, U 0x45, U 0x1A, + U 0xDD, U 0x42, U 0x00, U 0x02, U 0x00, U 0x29, U 0xA2, U 0x82, - U 0x18, U 0xDE, U 0x11, U 0x1B, - U 0xDE, U 0x0F, U 0x26, U 0x21, + U 0x18, U 0xDD, U 0x8E, U 0x1B, + U 0xDD, U 0x8C, U 0x26, U 0x21, U 0x02, U 0x0B, U 0x99, U 0x01, U 0x08, U 0x66, U 0x01, U 0x29, U 0xA6, U 0x82, U 0x26, U 0x25, U 0x02, U 0x06, U 0xE4, U 0x31, - U 0x14, U 0xDE, U 0x0C, U 0x15, - U 0xDE, U 0x07, U 0x23, U 0x6A, + U 0x14, U 0xDD, U 0x89, U 0x15, + U 0xDD, U 0x84, U 0x23, U 0x6A, U 0x90, U 0x23, U 0x26, U 0x12, U 0x85, U 0x50, U 0x24, U 0x26, U 0x11, U 0x25, U 0x26, U 0x13, @@ -5339,12 +5471,12 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x08, U 0xD6, U 0x10, U 0x2B, U 0x0A, U 0x64, U 0x29, U 0x1A, U 0xB4, U 0x1A, - U 0xDD, U 0xB2, U 0x0D, U 0x23, - U 0x11, U 0x1C, U 0xDD, U 0xB3, + U 0xDD, U 0x2F, U 0x0D, U 0x23, + U 0x11, U 0x1C, U 0xDD, U 0x30, U 0x0F, U 0x25, U 0x11, U 0xB8, U 0x18, U 0x98, U 0x13, U 0x0E, U 0x55, U 0x11, U 0x18, U 0xDD, - U 0xFE, U 0xAC, U 0x55, U 0xA8, + U 0x7B, U 0xAC, U 0x55, U 0xA8, U 0x38, U 0xAA, U 0x33, U 0x2C, U 0x80, U 0xFF, U 0x2A, U 0x80, U 0xFE, U 0xA9, U 0x33, U 0x28, @@ -5355,20 +5487,20 @@ static unsigned char t3fw[30136] = { U 0x11, U 0x09, U 0x88, U 0x02, U 0x08, U 0xAA, U 0x1C, U 0x28, U 0x8C, U 0x08, U 0x28, U 0x16, - U 0x04, U 0x58, U 0x08, U 0x4C, - U 0x14, U 0xDD, U 0xA4, U 0x0A, + U 0x04, U 0x58, U 0x08, U 0x61, + U 0x14, U 0xDD, U 0x21, U 0x0A, U 0xA7, U 0x02, U 0x24, U 0x41, U 0x16, U 0x2A, U 0x30, U 0x80, U 0x2B, U 0x12, U 0x04, U 0x07, U 0xAA, U 0x28, U 0x58, U 0x08, - U 0x47, U 0xB1, U 0x33, U 0x8B, + U 0x5C, U 0xB1, U 0x33, U 0x8B, U 0x13, U 0xB4, U 0x55, U 0x9A, U 0x60, U 0x04, U 0xAC, U 0x28, U 0xB4, U 0x66, U 0x2C, U 0x56, U 0x27, U 0x7B, U 0x69, U 0xE0, - U 0x16, U 0xDD, U 0xDB, U 0x94, + U 0x16, U 0xDD, U 0x58, U 0x94, U 0x12, U 0xC0, U 0x50, U 0xC0, - U 0xD0, U 0x17, U 0xDD, U 0x97, + U 0xD0, U 0x17, U 0xDD, U 0x14, U 0x9D, U 0x15, U 0xD3, U 0x70, U 0xD4, U 0x10, U 0x2F, U 0x60, U 0x80, U 0x2E, U 0x60, U 0x82, @@ -5378,7 +5510,7 @@ static unsigned char t3fw[30136] = { U 0x40, U 0x2A, U 0x60, U 0x7F, U 0x0D, U 0xCC, U 0x28, U 0x2B, U 0x3A, U 0x20, U 0x0C, U 0xAA, - U 0x28, U 0x58, U 0x08, U 0x35, + U 0x28, U 0x58, U 0x08, U 0x4A, U 0xC0, U 0xB1, U 0x0A, U 0xBE, U 0x37, U 0x2E, U 0x35, U 0x40, U 0x8F, U 0x17, U 0x72, U 0xF9, @@ -5386,7 +5518,7 @@ static unsigned char t3fw[30136] = { U 0x40, U 0x2A, U 0x60, U 0x81, U 0x0D, U 0xCC, U 0x28, U 0x2B, U 0x3A, U 0x20, U 0x0C, U 0xAA, - U 0x28, U 0x58, U 0x08, U 0x2D, + U 0x28, U 0x58, U 0x08, U 0x42, U 0xC0, U 0xB1, U 0x0A, U 0xBE, U 0x37, U 0x2E, U 0x35, U 0x42, U 0xB2, U 0x33, U 0xB4, U 0x44, @@ -5399,17 +5531,17 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x21, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x27, - U 0x0A, U 0x00, U 0x1C, U 0xDD, - U 0x76, U 0x1F, U 0xDD, U 0x87, - U 0x1E, U 0xDD, U 0x8A, U 0x1D, - U 0xDD, U 0x73, U 0x1A, U 0xDD, - U 0xB5, U 0x1B, U 0xDD, U 0xC3, + U 0x0A, U 0x00, U 0x1C, U 0xDC, + U 0xF3, U 0x1F, U 0xDD, U 0x04, + U 0x1E, U 0xDD, U 0x07, U 0x1D, + U 0xDC, U 0xF0, U 0x1A, U 0xDD, + U 0x32, U 0x1B, U 0xDD, U 0x40, U 0xC0, U 0x28, U 0x24, U 0xB0, U 0x00, U 0x6D, U 0x2A, U 0x75, U 0xAA, U 0x48, U 0x28, U 0x80, U 0x80, U 0xC0, U 0x91, U 0x64, U 0x80, U 0x61, U 0x00, U 0x41, - U 0x04, U 0x15, U 0xDD, U 0x6E, + U 0x04, U 0x15, U 0xDC, U 0xEB, U 0xC0, U 0x31, U 0x25, U 0x50, U 0x2E, U 0x00, U 0x36, U 0x1A, U 0x06, U 0x55, U 0x01, U 0x05, @@ -5419,10 +5551,10 @@ static unsigned char t3fw[30136] = { U 0x97, U 0x4D, U 0x0D, U 0x59, U 0x0A, U 0x29, U 0x92, U 0x24, U 0x68, U 0x90, U 0x08, U 0x12, - U 0xDD, U 0xA7, U 0x02, U 0x42, + U 0xDD, U 0x24, U 0x02, U 0x42, U 0x08, U 0x72, U 0x99, U 0x3B, U 0x23, U 0x62, U 0x95, U 0x12, - U 0xDD, U 0x6B, U 0xCB, U 0x34, + U 0xDC, U 0xE8, U 0xCB, U 0x34, U 0x9F, U 0x30, U 0x02, U 0x82, U 0x02, U 0x0E, U 0x44, U 0x02, U 0xC0, U 0x92, U 0x99, U 0x31, @@ -5438,41 +5570,41 @@ static unsigned char t3fw[30136] = { U 0xB4, U 0x00, U 0xD1, U 0x0F, U 0xD1, U 0x0F, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0x1A, - U 0xDD, U 0x4F, U 0x2A, U 0xA0, + U 0xDC, U 0xCC, U 0x2A, U 0xA0, U 0x00, U 0x58, U 0x02, U 0x1C, U 0x5B, U 0xFF, U 0xD5, U 0x02, U 0x2A, U 0x02, U 0x03, U 0x3B, U 0x02, U 0x5B, U 0xFF, U 0xD1, - U 0x1B, U 0xDD, U 0x4D, U 0xC9, + U 0x1B, U 0xDC, U 0xCA, U 0xC9, U 0xA1, U 0x2C, U 0xB1, U 0x02, U 0xC0, U 0xD4, U 0x0D, U 0xCC, U 0x02, U 0x0C, U 0x0C, U 0x4F, U 0x2C, U 0xB5, U 0x02, U 0x0C, U 0xE4, U 0x31, U 0xD1, U 0x0F, U 0xC0, U 0xA0, U 0x0A, U 0xE4, - U 0x31, U 0x18, U 0xDD, U 0x43, + U 0x31, U 0x18, U 0xDC, U 0xC0, U 0x00, U 0x02, U 0x00, U 0x2F, - U 0x82, U 0x82, U 0x19, U 0xDD, - U 0x56, U 0x2E, U 0xB1, U 0x02, + U 0x82, U 0x82, U 0x19, U 0xDC, + U 0xD3, U 0x2E, U 0xB1, U 0x02, U 0x09, U 0xFF, U 0x02, U 0x2F, U 0x86, U 0x82, U 0x0E, U 0xE4, U 0x31, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x20, U 0x02, U 0xE4, U 0x31, - U 0x14, U 0xDD, U 0x3D, U 0x16, - U 0xDD, U 0x3A, U 0x00, U 0x02, + U 0x14, U 0xDC, U 0xBA, U 0x16, + U 0xDC, U 0xB7, U 0x00, U 0x02, U 0x00, U 0x22, U 0x62, U 0x82, U 0x23, U 0x41, U 0x02, U 0x73, U 0x2F, U 0x06, U 0x03, U 0xE4, U 0x31, U 0xC0, U 0x20, U 0xD1, - U 0x0F, U 0x19, U 0xDD, U 0x87, - U 0x1A, U 0xDD, U 0x86, U 0x28, + U 0x0F, U 0x19, U 0xDD, U 0x04, + U 0x1A, U 0xDD, U 0x03, U 0x28, U 0x41, U 0x02, U 0x0A, U 0x2A, U 0x01, U 0x09, U 0x88, U 0x01, U 0x2A, U 0x66, U 0x82, U 0x28, U 0x45, U 0x02, U 0x08, U 0xE4, - U 0x31, U 0x15, U 0xDD, U 0x7D, - U 0x12, U 0xDD, U 0x82, U 0x25, + U 0x31, U 0x15, U 0xDC, U 0xFA, + U 0x12, U 0xDC, U 0xFF, U 0x25, U 0x46, U 0x1D, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0x29, U 0x20, U 0x06, U 0x28, U 0x9C, @@ -5487,20 +5619,20 @@ static unsigned char t3fw[30136] = { U 0x22, U 0x09, U 0x0E, U 0xAE, U 0x0C, U 0x66, U 0xE0, U 0x78, U 0x2B, U 0x20, U 0x0C, U 0x1E, - U 0xDD, U 0x1F, U 0x0C, U 0xBC, + U 0xDC, U 0x9C, U 0x0C, U 0xBC, U 0x11, U 0xAE, U 0xCC, U 0x28, - U 0xC2, U 0x86, U 0x19, U 0xDD, - U 0x1D, U 0x78, U 0xF3, U 0x02, + U 0xC2, U 0x86, U 0x19, U 0xDC, + U 0x9A, U 0x78, U 0xF3, U 0x02, U 0x60, U 0x00, U 0xAD, U 0x09, U 0xB9, U 0x0A, U 0x29, U 0x92, U 0xA3, U 0x68, U 0x90, U 0x08, U 0x2E, U 0x22, U 0x00, U 0x09, U 0xEE, U 0x0C, U 0x65, U 0xE0, U 0x9B, U 0x29, U 0xC2, U 0x85, - U 0x1F, U 0xDD, U 0x27, U 0x64, + U 0x1F, U 0xDC, U 0xA4, U 0x64, U 0x90, U 0x92, U 0x9F, U 0x90, - U 0xC0, U 0xE4, U 0x1F, U 0xDD, - U 0x34, U 0x9E, U 0x91, U 0x28, + U 0xC0, U 0xE4, U 0x1F, U 0xDC, + U 0xB0, U 0x9E, U 0x91, U 0x28, U 0x20, U 0x0A, U 0xC0, U 0xE0, U 0x9E, U 0x93, U 0x0F, U 0x88, U 0x02, U 0x98, U 0x92, U 0x88, @@ -5512,7 +5644,7 @@ static unsigned char t3fw[30136] = { U 0x20, U 0x06, U 0x29, U 0x20, U 0x64, U 0x68, U 0x83, U 0x33, U 0x28, U 0xC2, U 0x85, U 0x12, - U 0xDD, U 0x0E, U 0x28, U 0x8C, + U 0xDC, U 0x8B, U 0x28, U 0x8C, U 0x20, U 0xA2, U 0xB2, U 0x2E, U 0x24, U 0xCF, U 0x28, U 0xC6, U 0x85, U 0xC0, U 0x20, U 0xD1, @@ -5521,16 +5653,16 @@ static unsigned char t3fw[30136] = { U 0x01, U 0x11, U 0x02, U 0x0A, U 0x2A, U 0x41, U 0x65, U 0xAF, U 0x52, U 0xDA, U 0x20, U 0xC0, - U 0xB0, U 0x58, U 0x05, U 0xD1, + U 0xB0, U 0x58, U 0x05, U 0xE3, U 0x64, U 0xAF, U 0xE5, U 0xC0, U 0x21, U 0xD1, U 0x0F, U 0x00, U 0x64, U 0x9F, U 0xC8, U 0x1F, - U 0xDC, U 0xFB, U 0x2D, U 0x20, + U 0xDC, U 0x78, U 0x2D, U 0x20, U 0x16, U 0x8F, U 0xF2, U 0x09, U 0xDD, U 0x0C, U 0x00, U 0xF1, U 0x04, U 0x00, U 0xDD, U 0x1A, U 0xAD, U 0xAD, U 0x9D, U 0x29, - U 0x12, U 0xDC, U 0xFC, U 0x28, + U 0x12, U 0xDC, U 0x79, U 0x28, U 0xC2, U 0x85, U 0xA2, U 0xB2, U 0x2E, U 0x24, U 0xCF, U 0x28, U 0x8C, U 0x20, U 0x28, U 0xC6, @@ -5538,10 +5670,10 @@ static unsigned char t3fw[30136] = { U 0x0F, U 0xC0, U 0x21, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x26, - U 0x0A, U 0x00, U 0x1B, U 0xDD, - U 0x40, U 0x15, U 0xDC, U 0xEC, + U 0x0A, U 0x00, U 0x1B, U 0xDC, + U 0xBD, U 0x15, U 0xDC, U 0x69, U 0x28, U 0x20, U 0x65, U 0x17, - U 0xDC, U 0xE9, U 0x28, U 0x8C, + U 0xDC, U 0x66, U 0x28, U 0x8C, U 0xFE, U 0x64, U 0x80, U 0x94, U 0x0C, U 0x4D, U 0x11, U 0x0D, U 0xBD, U 0x08, U 0x2C, U 0xD2, @@ -5582,27 +5714,27 @@ static unsigned char t3fw[30136] = { U 0xE4, U 0x31, U 0xD1, U 0x0F, U 0x00, U 0xDB, U 0x30, U 0xDA, U 0x20, U 0x5B, U 0xFF, U 0x94, - U 0x1B, U 0xDD, U 0x15, U 0x64, + U 0x1B, U 0xDC, U 0x92, U 0x64, U 0xAF, U 0x5D, U 0x0C, U 0x4D, U 0x11, U 0xAD, U 0xBD, U 0x63, U 0xFF, U 0xA8, U 0x00, U 0x00, U 0x06, U 0xE4, U 0x31, U 0x00, U 0x02, U 0x00, U 0x2F, U 0x72, - U 0x82, U 0x18, U 0xDC, U 0xD4, + U 0x82, U 0x18, U 0xDC, U 0x50, U 0x2E, U 0x51, U 0x02, U 0x08, U 0xFF, U 0x02, U 0x2F, U 0x76, U 0x82, U 0x0E, U 0xE4, U 0x31, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x30, U 0x03, U 0xE4, U 0x31, - U 0x16, U 0xDC, U 0xB3, U 0x15, - U 0xDC, U 0xB4, U 0x00, U 0x02, + U 0x16, U 0xDC, U 0x30, U 0x15, + U 0xDC, U 0x31, U 0x00, U 0x02, U 0x00, U 0x24, U 0x62, U 0x82, U 0x74, U 0x47, U 0x21, U 0x18, - U 0xDD, U 0x05, U 0x87, U 0x5A, + U 0xDC, U 0x82, U 0x87, U 0x5A, U 0x08, U 0x48, U 0x01, U 0x28, U 0x66, U 0x82, U 0xCD, U 0x73, - U 0x19, U 0xDD, U 0x03, U 0x0C, + U 0x19, U 0xDC, U 0x80, U 0x0C, U 0x2A, U 0x11, U 0xAA, U 0x99, U 0x22, U 0x92, U 0x83, U 0x29, U 0x92, U 0x84, U 0x72, U 0x91, @@ -5610,22 +5742,22 @@ static unsigned char t3fw[30136] = { U 0x29, U 0x2B, U 0x51, U 0x02, U 0x0B, U 0xE4, U 0x31, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, - U 0x1F, U 0xDC, U 0xFC, U 0x2E, + U 0x1F, U 0xDC, U 0x79, U 0x2E, U 0x51, U 0x02, U 0x0F, U 0xEE, U 0x01, U 0x2E, U 0x55, U 0x02, U 0x0E, U 0xE4, U 0x31, U 0xB0, U 0x2D, U 0xB1, U 0x7C, U 0x9C, - U 0x5A, U 0x12, U 0xDC, U 0xF7, + U 0x5A, U 0x12, U 0xDC, U 0x74, U 0x08, U 0xDD, U 0x11, U 0x2D, U 0x56, U 0x19, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x1B, - U 0xDC, U 0x9A, U 0x1E, U 0xDC, - U 0x9C, U 0x22, U 0xB0, U 0x00, - U 0x1A, U 0xDC, U 0xF3, U 0x6F, + U 0xDC, U 0x17, U 0x1E, U 0xDC, + U 0x19, U 0x22, U 0xB0, U 0x00, + U 0x1A, U 0xDC, U 0x70, U 0x6F, U 0x23, U 0x72, U 0x1D, U 0xDC, - U 0xDA, U 0xC0, U 0x48, U 0x18, - U 0xDC, U 0xF2, U 0x1F, U 0xDC, - U 0xF0, U 0xDC, U 0x10, U 0xD5, + U 0x57, U 0xC0, U 0x48, U 0x18, + U 0xDC, U 0x6F, U 0x1F, U 0xDC, + U 0x6D, U 0xDC, U 0x10, U 0xD5, U 0xC0, U 0x83, U 0xF0, U 0x00, U 0x80, U 0x86, U 0x00, U 0x50, U 0x8A, U 0x6D, U 0x4A, U 0x4F, @@ -5651,13 +5783,13 @@ static unsigned char t3fw[30136] = { U 0x41, U 0x03, U 0x03, U 0x42, U 0xB1, U 0x38, U 0x08, U 0x08, U 0x42, U 0x98, U 0xF0, U 0xD1, - U 0x0F, U 0x1C, U 0xDC, U 0xD7, - U 0x13, U 0xDC, U 0xD8, U 0x27, + U 0x0F, U 0x1C, U 0xDC, U 0x54, + U 0x13, U 0xDC, U 0x55, U 0x27, U 0xB0, U 0x00, U 0x23, U 0x32, U 0xB5, U 0x64, U 0x70, U 0x57, U 0xC0, U 0x91, U 0xC0, U 0xD0, - U 0x16, U 0xDC, U 0xD6, U 0x15, - U 0xDC, U 0xD4, U 0xC0, U 0x40, + U 0x16, U 0xDC, U 0x53, U 0x15, + U 0xDC, U 0x51, U 0xC0, U 0x40, U 0x2A, U 0xC0, U 0x00, U 0x03, U 0x88, U 0x43, U 0x28, U 0xC4, U 0x00, U 0x6D, U 0x79, U 0x3C, @@ -5681,11 +5813,11 @@ static unsigned char t3fw[30136] = { U 0xC4, U 0x00, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x40, U 0x04, U 0xE4, U 0x31, - U 0x15, U 0xDC, U 0xBE, U 0x00, + U 0x15, U 0xDC, U 0x3B, U 0x00, U 0x02, U 0x00, U 0x88, U 0x50, - U 0x13, U 0xDC, U 0xBD, U 0xCB, + U 0x13, U 0xDC, U 0x3A, U 0xCB, U 0x81, U 0x5B, U 0xFF, U 0xBD, - U 0x1C, U 0xDC, U 0xBC, U 0x0C, + U 0x1C, U 0xDC, U 0x39, U 0x0C, U 0x2D, U 0x11, U 0xAD, U 0xCC, U 0x2B, U 0xC2, U 0x82, U 0x2A, U 0xC2, U 0x83, U 0x94, U 0x50, @@ -5697,7 +5829,7 @@ static unsigned char t3fw[30136] = { U 0x14, U 0x60, U 0x00, U 0x05, U 0x0B, U 0xA9, U 0x0C, U 0x09, U 0x29, U 0x14, U 0x99, U 0x30, - U 0x15, U 0xDC, U 0x4F, U 0x2A, + U 0x15, U 0xDB, U 0xCC, U 0x2A, U 0x51, U 0x02, U 0x0A, U 0xE4, U 0x31, U 0x2A, U 0x2C, U 0xFC, U 0x58, U 0x00, U 0x4B, U 0x2B, @@ -5707,7 +5839,7 @@ static unsigned char t3fw[30136] = { U 0xC8, U 0xA4, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x04, U 0xE4, U 0x31, U 0x1E, - U 0xDC, U 0x43, U 0x00, U 0x02, + U 0xDB, U 0xC0, U 0x00, U 0x02, U 0x00, U 0x2D, U 0xE2, U 0x82, U 0x2F, U 0xBA, U 0xFF, U 0x2C, U 0x51, U 0x02, U 0x0F, U 0xDD, @@ -5719,13 +5851,13 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x13, - U 0xDC, U 0x9B, U 0xC0, U 0xD1, + U 0xDC, U 0x18, U 0xC0, U 0xD1, U 0x03, U 0x23, U 0x09, U 0x23, U 0x31, U 0x8D, U 0xC0, U 0xA0, U 0x6F, U 0x34, U 0x02, U 0x60, - U 0x00, U 0x8D, U 0x19, U 0xDC, - U 0x32, U 0x1B, U 0xDC, U 0x33, - U 0x17, U 0xDC, U 0x94, U 0x0C, + U 0x00, U 0x8D, U 0x19, U 0xDB, + U 0xAF, U 0x1B, U 0xDB, U 0xB0, + U 0x17, U 0xDC, U 0x11, U 0x0C, U 0x28, U 0x11, U 0xA8, U 0x77, U 0x26, U 0x72, U 0x83, U 0x25, U 0x72, U 0x82, U 0x2C, U 0xFA, @@ -5762,7 +5894,7 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xDB, U 0x30, U 0x86, U 0x20, U 0x15, - U 0xDC, U 0x0B, U 0x28, U 0x0A, + U 0xDB, U 0x88, U 0x28, U 0x0A, U 0x00, U 0x28, U 0x25, U 0x02, U 0xDA, U 0x20, U 0x28, U 0xB0, U 0x00, U 0x2C, U 0xB0, U 0x07, @@ -5770,7 +5902,7 @@ static unsigned char t3fw[30136] = { U 0x82, U 0x4C, U 0x2D, U 0x0A, U 0x01, U 0x0B, U 0x80, U 0x00, U 0xDB, U 0xA0, U 0x65, U 0xAF, - U 0xE6, U 0x1A, U 0xDC, U 0x04, + U 0xE6, U 0x1A, U 0xDB, U 0x81, U 0x0A, U 0x4A, U 0x0A, U 0x29, U 0xA2, U 0xA3, U 0xC7, U 0xBF, U 0x76, U 0x91, U 0x01, U 0xD1, @@ -5778,8 +5910,8 @@ static unsigned char t3fw[30136] = { U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0xD1, U 0xC7, U 0xCF, U 0x1B, - U 0xDB, U 0xFE, U 0x19, U 0xDB, - U 0xFB, U 0x17, U 0xDB, U 0xF9, + U 0xDB, U 0x7B, U 0x19, U 0xDB, + U 0x78, U 0x17, U 0xDB, U 0x76, U 0x0C, U 0x28, U 0x11, U 0xA8, U 0x77, U 0x86, U 0x75, U 0x85, U 0x74, U 0xC0, U 0xA0, U 0x76, @@ -5812,17 +5944,17 @@ static unsigned char t3fw[30136] = { U 0x51, U 0xD6, U 0xD2, U 0x80, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x29, - U 0x0A, U 0x80, U 0x1E, U 0xDC, - U 0x00, U 0x1F, U 0xDC, U 0x00, - U 0x1C, U 0xDB, U 0xD8, U 0x0C, + U 0x0A, U 0x80, U 0x1E, U 0xDB, + U 0x7C, U 0x1F, U 0xDB, U 0x7C, + U 0x1C, U 0xDB, U 0x55, U 0x0C, U 0x2B, U 0x11, U 0xAC, U 0xBB, U 0x2C, U 0x2C, U 0xFC, U 0x2D, U 0xB2, U 0x85, U 0x0F, U 0xCC, U 0x02, U 0x9E, U 0xD1, U 0x9C, U 0xD0, U 0xC0, U 0x51, U 0xC0, - U 0x70, U 0x13, U 0xDB, U 0xFC, - U 0x14, U 0xDB, U 0xFB, U 0x18, - U 0xDB, U 0xF9, U 0x2A, U 0xB2, + U 0x70, U 0x13, U 0xDB, U 0x78, + U 0x14, U 0xDB, U 0x77, U 0x18, + U 0xDB, U 0x75, U 0x2A, U 0xB2, U 0x85, U 0xA8, U 0x28, U 0x04, U 0x24, U 0x0A, U 0x23, U 0x46, U 0x91, U 0xA9, U 0x86, U 0xB8, @@ -5831,20 +5963,20 @@ static unsigned char t3fw[30136] = { U 0x9F, U 0x25, U 0x64, U 0x9F, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x19, - U 0xDC, U 0x2C, U 0x0C, U 0x2A, + U 0xDB, U 0xA9, U 0x0C, U 0x2A, U 0x11, U 0xA9, U 0xA9, U 0x89, U 0x90, U 0xC4, U 0x84, U 0x79, - U 0x8B, U 0x76, U 0x1B, U 0xDC, - U 0x1A, U 0xAB, U 0xAC, U 0x2A, + U 0x8B, U 0x76, U 0x1B, U 0xDB, + U 0x97, U 0xAB, U 0xAC, U 0x2A, U 0xC2, U 0x83, U 0x2C, U 0xC2, U 0x84, U 0x7A, U 0xC1, U 0x68, U 0x8A, U 0xA0, U 0x2B, U 0xBC, U 0x30, U 0xD3, U 0xA0, U 0x64, U 0xA0, U 0x5E, U 0x0B, U 0x2B, U 0x0A, U 0x2C, U 0xB2, U 0xA3, - U 0x19, U 0xDB, U 0xE5, U 0x68, - U 0xC0, U 0x07, U 0x1D, U 0xDC, - U 0x20, U 0xD3, U 0x0F, U 0x7D, + U 0x19, U 0xDB, U 0x61, U 0x68, + U 0xC0, U 0x07, U 0x1D, U 0xDB, + U 0x9D, U 0xD3, U 0x0F, U 0x7D, U 0xC9, U 0x4A, U 0xA9, U 0x29, U 0x29, U 0x9D, U 0x01, U 0x29, U 0x90, U 0x1F, U 0x68, U 0x91, @@ -5855,9 +5987,9 @@ static unsigned char t3fw[30136] = { U 0x2A, U 0x2C, U 0xFC, U 0x5B, U 0xFF, U 0xB3, U 0xD2, U 0x30, U 0xD1, U 0x0F, U 0x00, U 0x00, - U 0x13, U 0xDB, U 0xC5, U 0x03, + U 0x13, U 0xDB, U 0x93, U 0x03, U 0xA3, U 0x01, U 0x8C, U 0x31, - U 0x1D, U 0xDB, U 0xB6, U 0x0C, + U 0x1D, U 0xDB, U 0x33, U 0x0C, U 0x8C, U 0x14, U 0x0D, U 0xCC, U 0x01, U 0x2C, U 0xB6, U 0xA3, U 0x63, U 0xFF, U 0xDC, U 0x00, @@ -5868,20 +6000,20 @@ static unsigned char t3fw[30136] = { U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xDB, U 0x30, U 0xC0, U 0xD0, U 0x19, - U 0xDB, U 0xA1, U 0xDA, U 0x20, + U 0xDB, U 0x1E, U 0xDA, U 0x20, U 0x28, U 0x30, U 0x00, U 0x22, U 0x30, U 0x07, U 0x08, U 0x48, U 0x12, U 0x09, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xDC, U 0x20, U 0x0B, U 0x80, U 0x00, - U 0x1B, U 0xDB, U 0x9C, U 0x0C, + U 0x1B, U 0xDB, U 0x19, U 0x0C, U 0x4A, U 0x11, U 0xAB, U 0xAA, U 0x29, U 0xA2, U 0x84, U 0x09, U 0x29, U 0x0B, U 0x29, U 0xA6, U 0x84, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, - U 0x41, U 0x18, U 0xDB, U 0x95, - U 0x17, U 0xDB, U 0x97, U 0x0C, + U 0x41, U 0x18, U 0xDB, U 0x12, + U 0x17, U 0xDB, U 0x14, U 0x0C, U 0x26, U 0x11, U 0xA7, U 0x27, U 0x27, U 0x70, U 0x30, U 0xA8, U 0x66, U 0x25, U 0x62, U 0x86, @@ -5889,17 +6021,17 @@ static unsigned char t3fw[30136] = { U 0x55, U 0x00, U 0x44, U 0x1A, U 0x75, U 0x41, U 0x48, U 0x22, U 0x62, U 0x84, U 0x15, U 0xDB, - U 0xB8, U 0x02, U 0x32, U 0x0B, + U 0x34, U 0x02, U 0x32, U 0x0B, U 0xC9, U 0x22, U 0x88, U 0x21, - U 0x17, U 0xDB, U 0x94, U 0x08, + U 0x17, U 0xDB, U 0x11, U 0x08, U 0x84, U 0x14, U 0x07, U 0x44, U 0x01, U 0x75, U 0x49, U 0x05, U 0xC8, U 0x34, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xD1, U 0x0F, U 0x08, U 0x09, U 0x47, U 0x1D, - U 0xDB, U 0xEB, U 0xC0, U 0xB2, - U 0x8E, U 0x20, U 0x1F, U 0xDB, - U 0x82, U 0x0E, U 0x0E, U 0x43, + U 0xDB, U 0x68, U 0xC0, U 0xB2, + U 0x8E, U 0x20, U 0x1F, U 0xDA, + U 0xFF, U 0x0E, U 0x0E, U 0x43, U 0xAF, U 0xEC, U 0x2B, U 0xC4, U 0xA0, U 0x0F, U 0xEE, U 0x0A, U 0x2D, U 0xE6, U 0x24, U 0x2A, @@ -5909,55 +6041,55 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xDB, U 0x30, U 0xC0, U 0xD0, U 0x18, - U 0xDB, U 0x78, U 0xDA, U 0x20, + U 0xDA, U 0xF5, U 0xDA, U 0x20, U 0x25, U 0x30, U 0x00, U 0x22, U 0x30, U 0x07, U 0x08, U 0x58, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xDC, U 0x20, U 0x0B, U 0x80, U 0x00, U 0x89, U 0x31, U 0x70, - U 0x9E, U 0x12, U 0x1B, U 0xDB, - U 0x72, U 0x0C, U 0x4A, U 0x11, + U 0x9E, U 0x12, U 0x1B, U 0xDA, + U 0xEF, U 0x0C, U 0x4A, U 0x11, U 0xAB, U 0xAA, U 0x29, U 0xA2, U 0x84, U 0x09, U 0x29, U 0x0B, U 0x29, U 0xA6, U 0x84, U 0xD1, U 0x0F, U 0x09, U 0xC9, U 0x52, U 0x68, U 0x53, U 0x26, U 0x00, - U 0x91, U 0x04, U 0x18, U 0xDB, - U 0x6D, U 0xC0, U 0xA1, U 0x2F, + U 0x91, U 0x04, U 0x18, U 0xDA, + U 0xEA, U 0xC0, U 0xA1, U 0x2F, U 0x81, U 0x12, U 0x00, U 0xAA, U 0x1A, U 0x0A, U 0xFF, U 0x02, U 0x2F, U 0x85, U 0x12, U 0x1E, - U 0xDB, U 0x67, U 0x0C, U 0x4D, + U 0xDA, U 0xE4, U 0x0C, U 0x4D, U 0x11, U 0xAE, U 0xDD, U 0x2C, U 0xD2, U 0x84, U 0x0C, U 0x2C, U 0x0B, U 0x2C, U 0xD6, U 0x84, U 0xD1, U 0x0F, U 0xC0, U 0x81, - U 0x1F, U 0xDB, U 0x64, U 0xB8, + U 0x1F, U 0xDA, U 0xE1, U 0xB8, U 0x9A, U 0x0A, U 0x0A, U 0x47, U 0x2E, U 0xF1, U 0x12, U 0x00, U 0xA1, U 0x04, U 0x00, U 0x88, U 0x1A, U 0x08, U 0xEE, U 0x02, U 0x2E, U 0xF5, U 0x12, U 0x1D, - U 0xDB, U 0x5C, U 0x0C, U 0x4C, + U 0xDA, U 0xD9, U 0x0C, U 0x4C, U 0x11, U 0xAD, U 0xCC, U 0x2B, U 0xC2, U 0x84, U 0x0B, U 0x2B, U 0x0B, U 0x2B, U 0xC6, U 0x84, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xDB, U 0x30, U 0xC0, U 0xD0, U 0x19, - U 0xDB, U 0x54, U 0xDA, U 0x20, + U 0xDA, U 0xD1, U 0xDA, U 0x20, U 0x28, U 0x30, U 0x00, U 0x22, U 0x30, U 0x07, U 0x09, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x4C, U 0xDC, U 0x20, U 0x0B, U 0x80, - U 0x00, U 0x1C, U 0xDB, U 0x4F, + U 0x00, U 0x1C, U 0xDA, U 0xCC, U 0x0C, U 0x4B, U 0x11, U 0xAC, U 0xBB, U 0x2A, U 0xB2, U 0x84, U 0x0A, U 0x2A, U 0x0B, U 0x2A, U 0xB6, U 0x84, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xC0, - U 0x41, U 0x18, U 0xDB, U 0x49, - U 0x16, U 0xDB, U 0x4B, U 0x0C, + U 0x41, U 0x18, U 0xDA, U 0xC6, + U 0x16, U 0xDA, U 0xC8, U 0x0C, U 0x27, U 0x11, U 0xA6, U 0x26, U 0x26, U 0x60, U 0x30, U 0xA8, U 0x72, U 0x25, U 0x22, U 0x86, @@ -5968,7 +6100,7 @@ static unsigned char t3fw[30136] = { U 0x0B, U 0xD1, U 0x0F, U 0x00, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0x15, - U 0xDB, U 0xA5, U 0x02, U 0x49, + U 0xDB, U 0x23, U 0x02, U 0x49, U 0x14, U 0x29, U 0x56, U 0x11, U 0x24, U 0x52, U 0x12, U 0x02, U 0x08, U 0x43, U 0x0F, U 0x88, @@ -5984,8 +6116,8 @@ static unsigned char t3fw[30136] = { U 0x23, U 0x02, U 0x60, U 0x00, U 0xAC, U 0x64, U 0x20, U 0xA7, U 0xC0, U 0xA0, U 0x85, U 0x10, - U 0x13, U 0xDB, U 0x7E, U 0x16, - U 0xDB, U 0x94, U 0xC0, U 0x40, + U 0x13, U 0xDA, U 0xFB, U 0x16, + U 0xDB, U 0x12, U 0xC0, U 0x40, U 0xA6, U 0xAA, U 0x2B, U 0xA2, U 0xAE, U 0x0B, U 0x19, U 0x41, U 0x64, U 0x90, U 0x66, U 0x68, @@ -6007,7 +6139,7 @@ static unsigned char t3fw[30136] = { U 0x00, U 0xB1, U 0x44, U 0x72, U 0x49, U 0xB1, U 0x60, U 0x00, U 0x4A, U 0x7F, U 0xBF, U 0x07, - U 0x15, U 0xDB, U 0x7F, U 0x63, + U 0x15, U 0xDA, U 0xFD, U 0x63, U 0xFF, U 0xB9, U 0x00, U 0x00, U 0x25, U 0x3A, U 0xE8, U 0x63, U 0xFF, U 0xB1, U 0x00, U 0x00, @@ -6027,9 +6159,9 @@ static unsigned char t3fw[30136] = { U 0x50, U 0x63, U 0xFF, U 0xA7, U 0xD1, U 0x0F, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0x1A, - U 0xDB, U 0x05, U 0x19, U 0xDB, - U 0x02, U 0x1C, U 0xDB, U 0x6A, - U 0x1B, U 0xDB, U 0x6B, U 0xC0, + U 0xDA, U 0x82, U 0x19, U 0xDA, + U 0x7F, U 0x1C, U 0xDA, U 0xE8, + U 0x1B, U 0xDA, U 0xE9, U 0xC0, U 0x80, U 0xC0, U 0x71, U 0x60, U 0x00, U 0x0D, U 0x00, U 0x00, U 0x00, U 0x22, U 0xA4, U 0x30, @@ -6059,18 +6191,18 @@ static unsigned char t3fw[30136] = { U 0x98, U 0x2D, U 0x98, U 0x2E, U 0x98, U 0x2F, U 0x22, U 0x2C, U 0x40, U 0x63, U 0xFF, U 0x97, - U 0x1E, U 0xDA, U 0xE3, U 0x27, + U 0x1E, U 0xDA, U 0x60, U 0x27, U 0xE6, U 0x80, U 0x27, U 0xE6, U 0x81, U 0xD1, U 0x0F, U 0x00, U 0xC0, U 0x20, U 0x63, U 0xFF, U 0x83, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, U 0x62, U 0xC0, U 0x41, U 0x12, - U 0xDA, U 0xDE, U 0x1A, U 0xDA, - U 0xDA, U 0x13, U 0xDB, U 0x45, + U 0xDA, U 0x5B, U 0x1A, U 0xDA, + U 0x57, U 0x13, U 0xDA, U 0xC3, U 0x2A, U 0xA0, U 0x00, U 0x23, - U 0x32, U 0x2D, U 0x19, U 0xDB, - U 0x3F, U 0x2B, U 0xAC, U 0xFE, + U 0x32, U 0x2D, U 0x19, U 0xDA, + U 0xBD, U 0x2B, U 0xAC, U 0xFE, U 0x29, U 0x92, U 0xAE, U 0x6E, U 0xA3, U 0x02, U 0x60, U 0x00, U 0x8E, U 0x09, U 0x0E, U 0x40, @@ -6078,46 +6210,46 @@ static unsigned char t3fw[30136] = { U 0xCD, U 0x0E, U 0xDC, U 0x39, U 0x2C, U 0x25, U 0x16, U 0x64, U 0xB0, U 0x89, U 0x5B, U 0xFF, - U 0x9E, U 0x15, U 0xDB, U 0x3B, - U 0x1A, U 0xDA, U 0xE5, U 0x2B, + U 0x9E, U 0x15, U 0xDA, U 0xB9, + U 0x1A, U 0xDA, U 0xB3, U 0x2B, U 0x3A, U 0xE8, U 0x0A, U 0x3A, - U 0x01, U 0x58, U 0x05, U 0x76, + U 0x01, U 0x58, U 0x05, U 0x8B, U 0x2B, U 0x21, U 0x16, U 0x0A, U 0xBB, U 0x28, U 0xD3, U 0xA0, - U 0x2B, U 0x56, U 0x00, U 0x58, - U 0x05, U 0x8D, U 0x8B, U 0x50, + U 0x9B, U 0x50, U 0x58, U 0x05, + U 0xA2, U 0x2B, U 0x52, U 0x00, U 0x0A, U 0xBB, U 0x08, U 0x2A, U 0x0A, U 0x00, U 0x58, U 0x05, - U 0x8C, U 0x15, U 0xDB, U 0x32, + U 0xA1, U 0x15, U 0xDA, U 0xB0, U 0x2D, U 0x21, U 0x02, U 0x2C, U 0x3A, U 0xE8, U 0x0C, U 0x3C, U 0x28, U 0x04, U 0xDD, U 0x02, U 0x2D, U 0x25, U 0x02, U 0x9C, - U 0x50, U 0x58, U 0x05, U 0x84, + U 0x50, U 0x58, U 0x05, U 0x99, U 0x8B, U 0x50, U 0xAA, U 0xBB, U 0xC0, U 0xA1, U 0x58, U 0x05, - U 0x84, U 0x1C, U 0xDB, U 0x2B, + U 0x99, U 0x1C, U 0xDA, U 0xA9, U 0x2D, U 0x21, U 0x02, U 0x0C, U 0x3C, U 0x28, U 0x06, U 0xDD, - U 0x02, U 0x13, U 0xDB, U 0x29, + U 0x02, U 0x13, U 0xDA, U 0xA7, U 0x2D, U 0x25, U 0x02, U 0x9C, - U 0x30, U 0x58, U 0x05, U 0x7C, + U 0x30, U 0x58, U 0x05, U 0x91, U 0x8B, U 0x30, U 0xAA, U 0xBB, U 0xC0, U 0xA2, U 0x58, U 0x05, - U 0x7C, U 0x2A, U 0x21, U 0x02, + U 0x91, U 0x2A, U 0x21, U 0x02, U 0xC0, U 0xB4, U 0x0B, U 0xAA, U 0x02, U 0x0A, U 0x0A, U 0x4F, U 0x2A, U 0x25, U 0x02, U 0x58, - U 0x05, U 0x90, U 0xD1, U 0x0F, + U 0x05, U 0xA5, U 0xD1, U 0x0F, U 0x24, U 0x24, U 0x23, U 0xC3, U 0xCC, U 0x2C, U 0x25, U 0x16, U 0x63, U 0xFF, U 0x76, U 0x00, - U 0x18, U 0xDB, U 0x21, U 0x1C, - U 0xDB, U 0x1D, U 0x19, U 0xDB, - U 0x1E, U 0x1B, U 0xDB, U 0x1C, - U 0x17, U 0xDA, U 0xF0, U 0x85, + U 0x18, U 0xDA, U 0x9F, U 0x1C, + U 0xDA, U 0x9B, U 0x19, U 0xDA, + U 0x9C, U 0x1B, U 0xDA, U 0x9A, + U 0x17, U 0xDA, U 0x6D, U 0x85, U 0x20, U 0x2E, U 0x0A, U 0xFD, - U 0x1F, U 0xDB, U 0x1D, U 0x2D, + U 0x1F, U 0xDA, U 0x9B, U 0x2D, U 0x20, U 0x2E, U 0x24, U 0xF4, U 0x7A, U 0x24, U 0xF4, U 0x7E, U 0x24, U 0xF4, U 0x82, U 0x0E, @@ -6146,14 +6278,14 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x04, U 0x2A, U 0x0A, U 0x30, U 0x2B, U 0x0A, U 0x03, U 0x5B, U 0xFF, U 0x4D, - U 0x12, U 0xDA, U 0xF3, U 0xC3, + U 0x12, U 0xDA, U 0x71, U 0xC3, U 0x90, U 0x29, U 0x26, U 0x16, U 0xC3, U 0xA1, U 0xC0, U 0xB3, U 0xC0, U 0x8A, U 0x28, U 0x26, U 0x17, U 0x5B, U 0xFF, U 0x48, U 0xC0, U 0x3C, U 0xC3, U 0xB1, U 0x2B, U 0x26, U 0x16, U 0x1A, - U 0xDA, U 0x87, U 0x2A, U 0xA0, + U 0xDA, U 0x04, U 0x2A, U 0xA0, U 0x20, U 0x23, U 0x26, U 0x17, U 0x64, U 0xA0, U 0x79, U 0xC3, U 0xA2, U 0xC0, U 0xB1, U 0x5B, @@ -6184,24 +6316,24 @@ static unsigned char t3fw[30136] = { U 0x28, U 0x26, U 0x17, U 0xC2, U 0xFB, U 0x2F, U 0x26, U 0x16, U 0xC0, U 0xE7, U 0x2E, U 0x26, - U 0x17, U 0x1D, U 0xDA, U 0xDA, + U 0x17, U 0x1D, U 0xDA, U 0x58, U 0x2D, U 0x26, U 0x10, U 0xD1, U 0x0F, U 0xC3, U 0xA2, U 0xC0, U 0xB3, U 0x5B, U 0xFF, U 0x23, U 0x63, U 0xFF, U 0x82, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x1C, - U 0xDA, U 0xA4, U 0x1B, U 0xDA, - U 0x91, U 0x18, U 0xDA, U 0xD4, - U 0x17, U 0xDA, U 0xD5, U 0x16, - U 0xDA, U 0xD5, U 0x15, U 0xDA, - U 0xD5, U 0xC0, U 0xE0, U 0xC0, - U 0xD4, U 0x14, U 0xDA, U 0xA0, - U 0x1F, U 0xDA, U 0x5C, U 0xC0, + U 0xDA, U 0x21, U 0x1B, U 0xDA, + U 0x0C, U 0x18, U 0xDA, U 0x52, + U 0x17, U 0xDA, U 0x53, U 0x16, + U 0xDA, U 0x53, U 0x15, U 0xDA, + U 0x53, U 0xC0, U 0xE0, U 0xC0, + U 0xD4, U 0x14, U 0xDA, U 0x1D, + U 0x1F, U 0xD9, U 0xD9, U 0xC0, U 0x28, U 0x8F, U 0xF0, U 0x6D, U 0x2A, U 0x36, U 0xDA, U 0xC0, U 0xD9, U 0xC0, U 0x7C, U 0x5B, U 0x02, U 0x0F, U 0xC9, U 0x0C, - U 0x1C, U 0xDA, U 0x9A, U 0x0C, + U 0x1C, U 0xDA, U 0x17, U 0x0C, U 0x9C, U 0x28, U 0xA8, U 0xC3, U 0xA6, U 0xC2, U 0x2A, U 0x36, U 0x80, U 0x2A, U 0x25, U 0x84, @@ -6212,13 +6344,13 @@ static unsigned char t3fw[30136] = { U 0xB1, U 0xBB, U 0x2E, U 0x36, U 0x9F, U 0x2C, U 0x36, U 0x9E, U 0x2C, U 0x36, U 0x9D, U 0xB1, - U 0xAC, U 0x1C, U 0xDA, U 0x7B, - U 0x1B, U 0xDA, U 0xC3, U 0xC0, + U 0xAC, U 0x1C, U 0xD9, U 0xF6, + U 0x1B, U 0xDA, U 0x41, U 0xC0, U 0x28, U 0x6D, U 0x2A, U 0x33, U 0xDA, U 0xC0, U 0xD9, U 0xC0, U 0x7C, U 0x5B, U 0x02, U 0x0F, U 0xC9, U 0x0C, U 0x1C, U 0xDA, - U 0x89, U 0x0C, U 0x9C, U 0x28, + U 0x06, U 0x0C, U 0x9C, U 0x28, U 0xA8, U 0xC3, U 0xA6, U 0xC2, U 0x2A, U 0x36, U 0x80, U 0x2B, U 0x25, U 0x84, U 0xA4, U 0xC2, @@ -6228,14 +6360,14 @@ static unsigned char t3fw[30136] = { U 0x8A, U 0x2E, U 0x36, U 0x9F, U 0x2C, U 0x36, U 0x9E, U 0x2C, U 0x36, U 0x9D, U 0xB1, U 0xAC, - U 0xC0, U 0x79, U 0x19, U 0xDA, - U 0x79, U 0x1B, U 0xDA, U 0xB5, - U 0x13, U 0xDA, U 0xB3, U 0x1A, - U 0xDA, U 0xB3, U 0x18, U 0xDA, - U 0xB4, U 0x14, U 0xDA, U 0x7A, - U 0x16, U 0xDA, U 0xB4, U 0x04, + U 0xC0, U 0x79, U 0x19, U 0xD9, + U 0xF6, U 0x1B, U 0xDA, U 0x33, + U 0x13, U 0xDA, U 0x31, U 0x1A, + U 0xDA, U 0x31, U 0x18, U 0xDA, + U 0x32, U 0x14, U 0xD9, U 0xF7, + U 0x16, U 0xDA, U 0x32, U 0x04, U 0xF4, U 0x28, U 0x12, U 0xDA, - U 0xB3, U 0x04, U 0x66, U 0x0C, + U 0x31, U 0x04, U 0x66, U 0x0C, U 0x04, U 0x05, U 0x06, U 0xA2, U 0x52, U 0xA8, U 0x58, U 0xAA, U 0x5A, U 0xA3, U 0x53, U 0x9B, @@ -6243,12 +6375,12 @@ static unsigned char t3fw[30136] = { U 0x27, U 0x84, U 0x8A, U 0xC0, U 0x91, U 0xC0, U 0xA5, U 0x2A, U 0x84, U 0x8C, U 0x29, U 0x84, - U 0x8B, U 0x17, U 0xDA, U 0xAC, - U 0x18, U 0xDA, U 0xAB, U 0xA7, + U 0x8B, U 0x17, U 0xDA, U 0x2A, + U 0x18, U 0xDA, U 0x29, U 0xA7, U 0x57, U 0x26, U 0x36, U 0x1D, U 0x26, U 0x36, U 0x1E, U 0x2E, U 0x36, U 0x1F, U 0x16, U 0xDA, - U 0xA9, U 0x13, U 0xDA, U 0xA9, + U 0x27, U 0x13, U 0xDA, U 0x27, U 0xA6, U 0x55, U 0x04, U 0x33, U 0x0C, U 0x28, U 0x26, U 0xC8, U 0x2E, U 0x75, U 0x00, U 0x2D, @@ -6258,40 +6390,40 @@ static unsigned char t3fw[30136] = { U 0x26, U 0xE5, U 0x2E, U 0x26, U 0xE7, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x13, - U 0xDA, U 0x87, U 0x17, U 0xDA, - U 0x82, U 0x24, U 0x72, U 0x3D, + U 0xDA, U 0x05, U 0x17, U 0xDA, + U 0x00, U 0x24, U 0x72, U 0x3D, U 0x22, U 0x32, U 0x93, U 0x7F, U 0x2F, U 0x0B, U 0x6D, U 0x08, U 0x05, U 0x28, U 0x32, U 0x93, U 0x7F, U 0x8F, U 0x02, U 0x63, U 0xFF, U 0xF3, U 0xC0, U 0xC4, - U 0xC0, U 0xB0, U 0x1A, U 0xDA, - U 0x16, U 0xC0, U 0x51, U 0xD9, + U 0xC0, U 0xB0, U 0x1A, U 0xD9, + U 0x93, U 0xC0, U 0x51, U 0xD9, U 0x40, U 0x04, U 0x59, U 0x39, U 0x29, U 0xA4, U 0x20, U 0x6E, U 0x44, U 0x02, U 0x0B, U 0xB5, U 0x02, U 0xC3, U 0x28, U 0x1E, - U 0xDA, U 0x11, U 0xDD, U 0xB0, + U 0xD9, U 0x8E, U 0xDD, U 0xB0, U 0x25, U 0xE4, U 0x22, U 0x05, U 0x2D, U 0x39, U 0x2D, U 0xE4, U 0x21, U 0xC0, U 0x50, U 0x1E, - U 0xDA, U 0x90, U 0x19, U 0xDA, - U 0x80, U 0x18, U 0xDA, U 0x80, - U 0x16, U 0xDA, U 0x82, U 0x1D, - U 0xDA, U 0x8E, U 0x94, U 0x10, + U 0xDA, U 0x0E, U 0x19, U 0xD9, + U 0xFE, U 0x18, U 0xD9, U 0xFE, + U 0x16, U 0xDA, U 0x00, U 0x1D, + U 0xDA, U 0x0C, U 0x94, U 0x10, U 0x2A, U 0x72, U 0x45, U 0x17, - U 0xDA, U 0x4C, U 0x6D, U 0xA9, + U 0xD9, U 0xC9, U 0x6D, U 0xA9, U 0x4B, U 0xD4, U 0x50, U 0xB3, U 0x55, U 0x7A, U 0x5B, U 0x17, U 0xDF, U 0x50, U 0x75, U 0x6B, - U 0x07, U 0x1F, U 0xDA, U 0x03, + U 0x07, U 0x1F, U 0xD9, U 0x80, U 0x8F, U 0xF0, U 0x0F, U 0x5F, - U 0x0C, U 0x12, U 0xDA, U 0x44, + U 0x0C, U 0x12, U 0xD9, U 0xC1, U 0x02, U 0xF2, U 0x28, U 0xAE, U 0x22, U 0x22, U 0xD6, U 0x81, - U 0xD5, U 0x40, U 0x13, U 0xDA, - U 0x41, U 0x74, U 0x6B, U 0x07, - U 0x15, U 0xD9, U 0xFD, U 0x85, + U 0xD5, U 0x40, U 0x13, U 0xD9, + U 0xBE, U 0x74, U 0x6B, U 0x07, + U 0x15, U 0xD9, U 0x7A, U 0x85, U 0x50, U 0x05, U 0x45, U 0x0C, U 0x03, U 0x53, U 0x28, U 0xB1, U 0x45, U 0xA7, U 0x3F, U 0xA8, @@ -6300,73 +6432,73 @@ static unsigned char t3fw[30136] = { U 0x9E, U 0x24, U 0x36, U 0x80, U 0x2B, U 0x36, U 0x9F, U 0x2B, U 0xF4, U 0x8B, U 0x2C, U 0xF4, - U 0x8C, U 0x14, U 0xDA, U 0x5C, + U 0x8C, U 0x14, U 0xD9, U 0xDA, U 0x24, U 0x42, U 0x4D, U 0xC0, U 0x30, U 0x04, U 0x14, U 0x14, U 0xC8, U 0x4C, U 0x6D, U 0x08, U 0x06, U 0xB1, U 0x33, U 0x04, U 0x14, U 0x14, U 0xC8, U 0x42, U 0x63, U 0xFF, U 0xF2, U 0x00, - U 0x15, U 0xD9, U 0xEA, U 0xC4, + U 0x15, U 0xD9, U 0x67, U 0xC4, U 0x40, U 0x00, U 0x31, U 0x04, - U 0x1A, U 0xD9, U 0xEB, U 0xC0, + U 0x1A, U 0xD9, U 0x68, U 0xC0, U 0xD1, U 0x93, U 0xA2, U 0x00, U 0xDD, U 0x1A, U 0xC1, U 0x38, U 0xB0, U 0xDD, U 0x9D, U 0xA3, - U 0x18, U 0xDA, U 0x50, U 0x2B, + U 0x18, U 0xD9, U 0xCE, U 0x2B, U 0x82, U 0x4D, U 0x29, U 0x82, U 0x4E, U 0x29, U 0xA5, U 0x1C, U 0x28, U 0x82, U 0x53, U 0x7A, U 0x87, U 0x1E, U 0x2C, U 0x54, U 0x00, U 0x8E, U 0x10, U 0x6F, U 0xE4, U 0x5D, U 0x12, U 0xD9, - U 0xE0, U 0x2F, U 0x21, U 0x1D, + U 0x5D, U 0x2F, U 0x21, U 0x1D, U 0x23, U 0x21, U 0x1C, U 0x2F, U 0x25, U 0x1B, U 0x04, U 0x33, U 0x0C, U 0x23, U 0x25, U 0x1C, U 0x23, U 0x25, U 0x1A, U 0xD1, U 0x0F, U 0xC0, U 0x62, U 0x18, - U 0xDA, U 0x3F, U 0x88, U 0x80, + U 0xD9, U 0xBD, U 0x88, U 0x80, U 0x7E, U 0x87, U 0xD9, U 0x89, U 0x10, U 0x26, U 0x54, U 0x00, U 0x6F, U 0x94, U 0x19, U 0x1B, - U 0xD9, U 0xD6, U 0x2A, U 0xB1, + U 0xD9, U 0x53, U 0x2A, U 0xB1, U 0x1C, U 0x0A, U 0x1A, U 0x14, U 0x04, U 0xAA, U 0x0C, U 0x2A, U 0xB5, U 0x1C, U 0x2A, U 0xB5, U 0x1D, U 0x2A, U 0xB5, U 0x1A, U 0x2A, U 0xB5, U 0x1B, U 0xD1, - U 0x0F, U 0x1B, U 0xD9, U 0xCF, + U 0x0F, U 0x1B, U 0xD9, U 0x4C, U 0x2A, U 0xB1, U 0x1C, U 0x0A, U 0x1A, U 0x14, U 0x03, U 0xAA, U 0x0C, U 0x2A, U 0xB5, U 0x1C, U 0x2A, U 0xB5, U 0x1D, U 0x2A, U 0xB5, U 0x1A, U 0x2A, U 0xB5, U 0x1B, U 0xD1, U 0x0F, U 0x00, - U 0x1C, U 0xD9, U 0xC9, U 0x2B, + U 0x1C, U 0xD9, U 0x46, U 0x2B, U 0xC1, U 0x1D, U 0x2D, U 0xC1, U 0x1C, U 0x2B, U 0xC5, U 0x1B, U 0x03, U 0xDD, U 0x0C, U 0x2D, U 0xC5, U 0x1C, U 0x2D, U 0xC5, U 0x1A, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x06, U 0x19, - U 0xD9, U 0xC2, U 0x14, U 0xDA, - U 0x26, U 0x12, U 0xDA, U 0x29, - U 0x15, U 0xDA, U 0x44, U 0xC7, + U 0xD9, U 0x3F, U 0x14, U 0xD9, + U 0xA4, U 0x12, U 0xD9, U 0xA7, + U 0x15, U 0xD9, U 0xC2, U 0xC7, U 0x3F, U 0xC0, U 0xE0, U 0x2E, U 0x56, U 0xA8, U 0x2E, U 0x56, U 0xA9, U 0x2E, U 0x56, U 0xAA, U 0x2E, U 0x56, U 0xAB, U 0x23, U 0x26, U 0x29, U 0x18, U 0xD9, - U 0xEA, U 0xDB, U 0x10, U 0x1C, - U 0xDA, U 0x3E, U 0xC0, U 0xD4, + U 0x65, U 0xDB, U 0x10, U 0x1C, + U 0xD9, U 0xBC, U 0xC0, U 0xD4, U 0x2A, U 0x42, U 0x45, U 0x2D, U 0x16, U 0x01, U 0x9C, U 0x10, U 0x00, U 0xB0, U 0x89, U 0x0A, U 0x88, U 0x0C, U 0x28, U 0x96, U 0x00, U 0x5B, U 0xFF, U 0x94, U 0x2B, U 0x22, U 0xE3, U 0x18, - U 0xD9, U 0xB2, U 0x0B, U 0x5B, + U 0xD9, U 0x2F, U 0x0B, U 0x5B, U 0x14, U 0x9B, U 0x84, U 0x2A, U 0x22, U 0xE4, U 0x8B, U 0x84, U 0xB1, U 0xAA, U 0x0A, U 0x5A, @@ -6378,27 +6510,27 @@ static unsigned char t3fw[30136] = { U 0x9F, U 0x87, U 0x5B, U 0xFF, U 0x45, U 0x5B, U 0xFF, U 0x16, U 0x23, U 0x46, U 0x3B, U 0xC1, - U 0xB0, U 0x1D, U 0xD9, U 0xA5, - U 0x1C, U 0xDA, U 0x03, U 0x2A, + U 0xB0, U 0x1D, U 0xD9, U 0x22, + U 0x1C, U 0xD9, U 0x80, U 0x2A, U 0xD1, U 0x02, U 0x2C, U 0x46, U 0x3A, U 0x0B, U 0xAA, U 0x02, U 0x0A, U 0x0A, U 0x4F, U 0x2A, U 0xD5, U 0x02, U 0x58, U 0x04, - U 0x7C, U 0x5B, U 0xFE, U 0xBF, + U 0x91, U 0x5B, U 0xFE, U 0xBF, U 0x5B, U 0xFE, U 0x98, U 0xC0, U 0x50, U 0xC0, U 0xB0, U 0x16, - U 0xD9, U 0x9B, U 0x14, U 0xD9, - U 0xA3, U 0x17, U 0xDA, U 0x12, + U 0xD9, U 0x18, U 0x14, U 0xD9, + U 0x20, U 0x17, U 0xD9, U 0x90, U 0xC0, U 0xC0, U 0xC7, U 0x3E, U 0x93, U 0x12, U 0x2C, U 0x26, U 0x2D, U 0xC0, U 0x30, U 0x60, - U 0x00, U 0x43, U 0x00, U 0x00, + U 0x00, U 0x44, U 0x00, U 0x00, U 0x00, U 0x7F, U 0x9F, U 0x0F, U 0xB1, U 0x55, U 0x09, U 0x19, U 0x14, U 0x65, U 0x9F, U 0xF4, U 0xC0, U 0x50, U 0x0A, U 0xA9, U 0x02, U 0x7F, U 0xA7, U 0xEF, - U 0x18, U 0xD9, U 0x8F, U 0xDA, + U 0x18, U 0xD9, U 0x0C, U 0xDA, U 0x50, U 0x08, U 0x58, U 0x0A, U 0x28, U 0x82, U 0x2C, U 0x2B, U 0x0A, U 0x00, U 0x0B, U 0x80, @@ -6406,63 +6538,67 @@ static unsigned char t3fw[30136] = { U 0xD2, U 0xA0, U 0xC0, U 0x91, U 0xC7, U 0xAF, U 0x00, U 0x99, U 0x1A, U 0x0A, U 0x99, U 0x03, - U 0x99, U 0x12, U 0xCE, U 0x33, - U 0x64, U 0x20, U 0x67, U 0xD3, + U 0x99, U 0x12, U 0xCE, U 0x38, + U 0x64, U 0x20, U 0x6B, U 0xD3, U 0x20, U 0x2B, U 0x20, U 0x07, - U 0x95, U 0x13, U 0x8C, U 0x12, - U 0x2A, U 0x62, U 0x82, U 0x7C, - U 0xA8, U 0x5F, U 0x18, U 0xD9, - U 0x81, U 0x08, U 0x58, U 0x0A, - U 0x28, U 0x82, U 0x2C, U 0xDA, - U 0x50, U 0x0B, U 0x80, U 0x00, - U 0xD2, U 0xA0, U 0x64, U 0x3F, - U 0xDA, U 0x8A, U 0x31, U 0x0A, - U 0x8A, U 0x14, U 0x04, U 0xAA, - U 0x01, U 0xC8, U 0x29, U 0x8B, - U 0x21, U 0x0B, U 0x8B, U 0x14, - U 0x04, U 0xBB, U 0x01, U 0x7B, - U 0xA9, U 0x45, U 0xDD, U 0xA0, - U 0x7A, U 0x7B, U 0x08, U 0x1D, - U 0xD9, U 0x79, U 0x2D, U 0xD2, - U 0x00, U 0x0D, U 0xAD, U 0x0C, - U 0xDB, U 0x30, U 0x19, U 0xD9, - U 0x73, U 0x1A, U 0xD9, U 0xB8, - U 0x28, U 0x12, U 0x03, U 0x0A, - U 0xDA, U 0x28, U 0x08, U 0x8C, - U 0x02, U 0x1D, U 0xD9, U 0xF5, + U 0x25, U 0x16, U 0x03, U 0x2C, + U 0x12, U 0x02, U 0x2A, U 0x62, + U 0x82, U 0x7C, U 0xA8, U 0x63, + U 0x18, U 0xD8, U 0xFE, U 0x01, + U 0x11, U 0x02, U 0x08, U 0x58, + U 0x0A, U 0x28, U 0x82, U 0x2C, + U 0xDA, U 0x50, U 0x0B, U 0x80, + U 0x00, U 0xD2, U 0xA0, U 0x64, + U 0x3F, U 0xD5, U 0x8A, U 0x31, + U 0x0A, U 0x8A, U 0x14, U 0x04, + U 0xAA, U 0x01, U 0xC8, U 0x2A, + U 0x2B, U 0x22, U 0x01, U 0x0B, + U 0x8B, U 0x14, U 0x04, U 0xBB, + U 0x01, U 0x7B, U 0xA9, U 0x45, + U 0xDD, U 0xA0, U 0x7A, U 0x7B, + U 0x08, U 0x1D, U 0xD8, U 0xF4, + U 0x2D, U 0xD2, U 0x00, U 0x0D, + U 0xAD, U 0x0C, U 0xDB, U 0x30, + U 0x19, U 0xD8, U 0xEF, U 0x1A, + U 0xD9, U 0x34, U 0x88, U 0x13, + U 0x0A, U 0xDA, U 0x28, U 0xDC, + U 0x80, U 0x1D, U 0xD9, U 0x72, U 0x09, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x3C, U 0x0D, U 0xAA, U 0x08, U 0x0B, U 0x80, U 0x00, - U 0x65, U 0x2F, U 0x97, U 0xD3, + U 0x65, U 0x2F, U 0x93, U 0xD3, U 0x20, U 0xC0, U 0xB0, U 0x63, - U 0xFF, U 0x97, U 0xCB, U 0x53, - U 0xB1, U 0x55, U 0x00, U 0x50, - U 0x04, U 0x0A, U 0x09, U 0x19, - U 0x63, U 0xFF, U 0x49, U 0x00, - U 0xDA, U 0xB0, U 0x7B, U 0x7B, - U 0x07, U 0x1A, U 0xD9, U 0x67, - U 0x8A, U 0xA0, U 0x0A, U 0xBA, - U 0x0C, U 0x1B, U 0xD9, U 0xA8, - U 0x8C, U 0x31, U 0x0B, U 0xAB, - U 0x28, U 0x0C, U 0x8A, U 0x14, - U 0x1C, U 0xD9, U 0xE6, U 0xAC, - U 0xBB, U 0x1C, U 0xD9, U 0xE5, - U 0x04, U 0xAA, U 0x01, U 0x2B, - U 0xC6, U 0x81, U 0x63, U 0xFF, - U 0x90, U 0x7F, U 0xA7, U 0xC7, - U 0x63, U 0xFF, U 0x62, U 0x00, + U 0xFF, U 0x94, U 0x00, U 0x00, + U 0x7F, U 0xAF, U 0x34, U 0xB1, + U 0x55, U 0x00, U 0x50, U 0x04, + U 0x0A, U 0x09, U 0x19, U 0x63, + U 0xFF, U 0x42, U 0xDA, U 0xB0, + U 0x7B, U 0x7B, U 0x08, U 0x1A, + U 0xD8, U 0xE3, U 0x2A, U 0xA2, + U 0x00, U 0x0A, U 0xBA, U 0x0C, + U 0x1B, U 0xD9, U 0x24, U 0x8C, + U 0x31, U 0x0B, U 0xAB, U 0x28, + U 0x0C, U 0x8A, U 0x14, U 0x1C, + U 0xD9, U 0x62, U 0xAC, U 0xBB, + U 0x1C, U 0xD9, U 0x62, U 0x04, + U 0xAA, U 0x01, U 0x2B, U 0xC6, + U 0x81, U 0x63, U 0xFF, U 0x8F, + U 0x64, U 0x5F, U 0x60, U 0xC0, + U 0x50, U 0xC0, U 0xB0, U 0xC7, + U 0xCE, U 0x9C, U 0x12, U 0x63, + U 0xFF, U 0x55, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x27, U 0x22, U 0x1E, U 0xC0, U 0x80, U 0x08, U 0xE4, U 0x31, U 0x1B, - U 0xD9, U 0x58, U 0x00, U 0x02, + U 0xD8, U 0xD1, U 0x00, U 0x02, U 0x00, U 0x2A, U 0xB2, U 0x82, - U 0x19, U 0xD9, U 0x58, U 0x00, + U 0x19, U 0xD8, U 0xD1, U 0x00, U 0x31, U 0x04, U 0xC0, U 0x61, U 0x00, U 0x66, U 0x1A, U 0x29, U 0x91, U 0x02, U 0x0A, U 0x6A, U 0x02, U 0x2A, U 0xB6, U 0x82, U 0x09, U 0xE4, U 0x31, U 0x15, - U 0xD9, U 0xB3, U 0x0C, U 0x38, + U 0xD9, U 0x2C, U 0x0C, U 0x38, U 0x11, U 0xA8, U 0x53, U 0x28, U 0x32, U 0x82, U 0x24, U 0x32, U 0x84, U 0x2A, U 0x8C, U 0xFC, @@ -6478,8 +6614,8 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x2B, U 0x25, U 0x02, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC0, - U 0xE7, U 0x1D, U 0xD9, U 0x3B, - U 0x1C, U 0xD9, U 0x3D, U 0x0D, + U 0xE7, U 0x1D, U 0xD8, U 0xB4, + U 0x1C, U 0xD8, U 0xB6, U 0x0D, U 0x49, U 0x11, U 0xD7, U 0x20, U 0x8B, U 0x22, U 0x8A, U 0x20, U 0x0B, U 0x4B, U 0x0B, U 0xD2, @@ -6487,7 +6623,7 @@ static unsigned char t3fw[30136] = { U 0x9B, U 0x72, U 0x28, U 0x8C, U 0xF4, U 0xC8, U 0x34, U 0x6F, U 0x8E, U 0x02, U 0x60, U 0x00, - U 0xA2, U 0x1F, U 0xD9, U 0x33, + U 0xA3, U 0x1F, U 0xD8, U 0xAC, U 0xA2, U 0x98, U 0xAF, U 0x7B, U 0x78, U 0xB3, U 0x34, U 0xC9, U 0x3D, U 0xC0, U 0x81, U 0xC0, @@ -6498,14 +6634,14 @@ static unsigned char t3fw[30136] = { U 0x05, U 0x00, U 0x30, U 0x88, U 0x00, U 0x50, U 0x8C, U 0x88, U 0x70, U 0x08, U 0x98, U 0x08, - U 0x78, U 0xB1, U 0x6C, U 0xD2, + U 0x78, U 0xB1, U 0x6D, U 0xD2, U 0xA0, U 0x98, U 0x70, U 0xD1, U 0x0F, U 0xC0, U 0xF0, U 0x03, U 0x8F, U 0x38, U 0x7F, U 0xE0, U 0xDE, U 0x63, U 0xFF, U 0xD8, U 0x02, U 0x7B, U 0x0C, U 0xAF, U 0xBB, U 0x0B, U 0x99, U 0x0C, - U 0x64, U 0x30, U 0x46, U 0xD8, + U 0x64, U 0x30, U 0x47, U 0xD8, U 0x30, U 0xC0, U 0xF1, U 0xC0, U 0x50, U 0x02, U 0xF5, U 0x38, U 0x05, U 0x05, U 0x42, U 0x64, @@ -6516,27 +6652,27 @@ static unsigned char t3fw[30136] = { U 0x05, U 0x00, U 0x80, U 0x88, U 0x00, U 0x20, U 0x8C, U 0x06, U 0x44, U 0x0C, U 0xC0, U 0x81, - U 0x25, U 0x0A, U 0x00, U 0x03, - U 0xB2, U 0x08, U 0x23, U 0x7C, - U 0x0C, U 0x03, U 0x85, U 0x38, - U 0x05, U 0x05, U 0x42, U 0x64, - U 0x50, U 0x59, U 0x2C, U 0xD6, - U 0x7E, U 0x6D, U 0x4A, U 0x05, - U 0x00, U 0x20, U 0x88, U 0x00, - U 0x30, U 0x8C, U 0xD2, U 0xA0, - U 0xA7, U 0x98, U 0xBC, U 0x88, - U 0x98, U 0x70, U 0xD1, U 0x0F, - U 0xD2, U 0xA0, U 0xBC, U 0x79, - U 0x99, U 0x70, U 0xD1, U 0x0F, - U 0xD2, U 0x30, U 0x2B, U 0xAD, - U 0x08, U 0xC0, U 0xF1, U 0xC0, - U 0x50, U 0x0B, U 0xF5, U 0x38, - U 0x05, U 0x05, U 0x42, U 0xCB, - U 0x55, U 0x2C, U 0xD6, U 0x7E, - U 0x08, U 0x3F, U 0x14, U 0xC1, - U 0x60, U 0x0F, U 0x66, U 0x0C, - U 0x06, U 0x46, U 0x36, U 0xD3, - U 0x0F, U 0x6D, U 0x6A, U 0x05, + U 0xC0, U 0x50, U 0x03, U 0xB2, + U 0x08, U 0x23, U 0x7C, U 0x0C, + U 0x03, U 0x85, U 0x38, U 0x05, + U 0x05, U 0x42, U 0x64, U 0x50, + U 0x5A, U 0x2C, U 0xD6, U 0x7E, + U 0xD3, U 0x0F, U 0x6D, U 0x4A, + U 0x05, U 0x00, U 0x20, U 0x88, + U 0x00, U 0x30, U 0x8C, U 0xD2, + U 0xA0, U 0xA7, U 0x98, U 0xBC, + U 0x88, U 0x98, U 0x70, U 0xD1, + U 0x0F, U 0xD2, U 0xA0, U 0xBC, + U 0x79, U 0x99, U 0x70, U 0xD1, + U 0x0F, U 0xD2, U 0x30, U 0x2B, + U 0xAD, U 0x08, U 0xC0, U 0xF1, + U 0xC0, U 0x50, U 0x0B, U 0xF5, + U 0x38, U 0x05, U 0x05, U 0x42, + U 0xCB, U 0x54, U 0x2C, U 0xD6, + U 0x7E, U 0x08, U 0x3F, U 0x14, + U 0x26, U 0x0A, U 0x10, U 0x0F, + U 0x66, U 0x0C, U 0x06, U 0x46, + U 0x36, U 0x6D, U 0x6A, U 0x05, U 0x00, U 0x20, U 0x88, U 0x00, U 0xB0, U 0x8C, U 0x82, U 0x70, U 0x63, U 0xFF, U 0x2D, U 0x00, @@ -6544,20 +6680,20 @@ static unsigned char t3fw[30136] = { U 0x38, U 0x75, U 0xE0, U 0x80, U 0x63, U 0xFF, U 0x7A, U 0x00, U 0xC0, U 0x60, U 0x02, U 0x86, - U 0x38, U 0x76, U 0xE0, U 0xA0, - U 0x63, U 0xFF, U 0x9A, U 0x00, + U 0x38, U 0x76, U 0xE0, U 0x9F, + U 0x63, U 0xFF, U 0x99, U 0x00, U 0xC0, U 0x50, U 0x03, U 0xF5, - U 0x38, U 0x75, U 0xE0, U 0xC3, - U 0x63, U 0xFF, U 0xBD, U 0x00, + U 0x38, U 0x75, U 0xE0, U 0xC4, + U 0x63, U 0xFF, U 0xBE, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xD6, U 0x20, U 0x68, U 0x52, U 0x0F, U 0x69, U 0x53, U 0x24, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x00, U 0xF0, + U 0x40, U 0x58, U 0x00, U 0xF2, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x58, U 0x00, - U 0xED, U 0x9A, U 0x24, U 0x24, + U 0xEF, U 0x9A, U 0x24, U 0x24, U 0x24, U 0x0E, U 0xC0, U 0x21, U 0x22, U 0x64, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, @@ -6575,8 +6711,8 @@ static unsigned char t3fw[30136] = { U 0x07, U 0x5B, U 0xFF, U 0xA0, U 0x69, U 0x51, U 0x1D, U 0xC0, U 0xE0, U 0x82, U 0x24, U 0x2A, - U 0x60, U 0x0F, U 0x18, U 0xD9, - U 0x66, U 0x2A, U 0x24, U 0x03, + U 0x60, U 0x0F, U 0x18, U 0xD8, + U 0xE0, U 0x2A, U 0x24, U 0x03, U 0x29, U 0x60, U 0x0E, U 0x8F, U 0x20, U 0x29, U 0x24, U 0x07, U 0x08, U 0xFF, U 0x02, U 0x9F, @@ -6584,12 +6720,12 @@ static unsigned char t3fw[30136] = { U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x94, - U 0x23, U 0x19, U 0xD9, U 0x5E, + U 0x23, U 0x19, U 0xD8, U 0xD8, U 0xC0, U 0xB3, U 0x08, U 0x3A, U 0x11, U 0x0B, U 0xAA, U 0x02, U 0x99, U 0x20, U 0x19, U 0xD8, - U 0xD2, U 0x9A, U 0x21, U 0x16, - U 0xD8, U 0xD0, U 0xC0, U 0x50, + U 0x4B, U 0x9A, U 0x21, U 0x16, + U 0xD8, U 0x49, U 0xC0, U 0x50, U 0x28, U 0x92, U 0x9D, U 0x25, U 0x64, U 0xA2, U 0x28, U 0x8C, U 0x18, U 0x28, U 0x96, U 0x9D, @@ -6599,84 +6735,86 @@ static unsigned char t3fw[30136] = { U 0x23, U 0x24, U 0x06, U 0xB7, U 0x88, U 0x28, U 0x24, U 0x66, U 0xD1, U 0x0F, U 0x00, U 0x00, - U 0x6C, U 0x10, U 0x06, U 0x03, - U 0x5A, U 0x0C, U 0x0D, U 0x36, - U 0x11, U 0x0D, U 0x5C, U 0x11, - U 0xD8, U 0x20, U 0x8B, U 0x22, - U 0x82, U 0x21, U 0x0C, U 0xBB, - U 0x0C, U 0x06, U 0x55, U 0x0F, - U 0x9B, U 0x82, U 0x02, U 0x32, - U 0x0B, U 0x92, U 0x81, U 0x13, - U 0xD8, U 0xBC, U 0xD9, U 0x20, - U 0xA3, U 0x8F, U 0x64, U 0x50, - U 0x53, U 0x1C, U 0xD8, U 0xB8, - U 0xC0, U 0xD7, U 0x1B, U 0xD8, - U 0xB9, U 0xA2, U 0x56, U 0xC0, - U 0xE1, U 0x29, U 0x0A, U 0x00, - U 0x04, U 0xE9, U 0x38, U 0x09, - U 0x09, U 0x42, U 0x76, U 0xF3, - U 0x4A, U 0x04, U 0x43, U 0x02, - U 0xC9, U 0x9E, U 0x2B, U 0xC6, - U 0x7E, U 0x6D, U 0xAA, U 0x05, - U 0x00, U 0x20, U 0x88, U 0x00, - U 0x30, U 0x8C, U 0x89, U 0x81, - U 0xA9, U 0x59, U 0x09, U 0xFA, - U 0x0C, U 0x64, U 0xA0, U 0x79, - U 0x99, U 0x81, U 0x8A, U 0x82, - U 0xC8, U 0xAD, U 0xD2, U 0x90, - U 0xD1, U 0x0F, U 0xC0, U 0x60, - U 0x02, U 0xE6, U 0x38, U 0x76, - U 0xD0, U 0xDA, U 0x63, U 0xFF, - U 0xD4, U 0xC0, U 0x20, U 0xBC, - U 0x89, U 0x99, U 0x81, U 0x99, - U 0x80, U 0x92, U 0x82, U 0xD1, - U 0x0F, U 0x7F, U 0x23, U 0x04, - U 0x29, U 0x2D, U 0xF8, U 0x99, - U 0x81, U 0x65, U 0xBF, U 0xD9, - U 0x63, U 0xFF, U 0xE5, U 0x00, - U 0x02, U 0x8F, U 0x0C, U 0xA3, - U 0xFF, U 0x0F, U 0x33, U 0x12, - U 0x93, U 0x10, U 0x03, U 0xAA, - U 0x0C, U 0xD3, U 0x40, U 0xCB, - U 0x9E, U 0x2B, U 0xC6, U 0x7E, - U 0x86, U 0x10, U 0x6D, U 0x6A, + U 0x6C, U 0x10, U 0x06, U 0x0D, + U 0x3C, U 0x11, U 0x1A, U 0xD8, + U 0x3B, U 0xD8, U 0x20, U 0x03, + U 0x5B, U 0x0C, U 0x86, U 0x22, + U 0x0D, U 0x55, U 0x11, U 0x82, + U 0x21, U 0xAA, U 0x89, U 0x02, + U 0x32, U 0x0B, U 0x92, U 0x81, + U 0x05, U 0x63, U 0x0C, U 0x93, + U 0x82, U 0x0C, U 0x55, U 0x0C, + U 0x79, U 0x2B, U 0x54, U 0xCB, + U 0x53, U 0x1C, U 0xD8, U 0x33, + U 0x1D, U 0xD8, U 0x31, U 0xC0, + U 0xF7, U 0xA2, U 0x56, U 0xC0, + U 0x31, U 0xC0, U 0xA0, U 0x04, + U 0x3A, U 0x38, U 0x0A, U 0x0A, + U 0x42, U 0x76, U 0x93, U 0x43, + U 0x04, U 0x43, U 0x02, U 0xC9, + U 0xAB, U 0x2C, U 0xD6, U 0x7E, + U 0xD3, U 0x0F, U 0x6D, U 0xBA, U 0x05, U 0x00, U 0x20, U 0x88, - U 0x00, U 0x30, U 0x8C, U 0xBC, - U 0x82, U 0x29, U 0x0A, U 0x00, - U 0x04, U 0xF3, U 0x08, U 0x24, - U 0x0A, U 0x01, U 0x03, U 0x49, - U 0x38, U 0x09, U 0x09, U 0x42, - U 0xCA, U 0x98, U 0x2B, U 0xC6, - U 0x7E, U 0x6D, U 0xAA, U 0x05, + U 0x00, U 0x30, U 0x8C, U 0x82, + U 0x81, U 0xA2, U 0x52, U 0x72, + U 0x91, U 0x7D, U 0x92, U 0x81, + U 0x83, U 0x82, U 0xC8, U 0x3E, + U 0xD1, U 0x0F, U 0xC0, U 0x71, + U 0xC0, U 0x60, U 0x02, U 0x76, + U 0x38, U 0x76, U 0xF0, U 0xDB, + U 0x63, U 0xFF, U 0xD5, U 0x00, + U 0xC0, U 0x20, U 0xBC, U 0x89, + U 0x99, U 0x81, U 0x99, U 0x80, + U 0x92, U 0x82, U 0xD1, U 0x0F, + U 0x22, U 0x2D, U 0xF8, U 0x92, + U 0x81, U 0x63, U 0xFF, U 0xA2, + U 0x19, U 0xD8, U 0x1C, U 0x02, + U 0x86, U 0x0C, U 0xA9, U 0x66, + U 0x96, U 0x11, U 0xD9, U 0x40, + U 0x06, U 0x36, U 0x12, U 0x96, + U 0x10, U 0x06, U 0xBB, U 0x0C, + U 0x64, U 0xA0, U 0x44, U 0x2C, + U 0xD6, U 0x7E, U 0x8A, U 0x10, + U 0xD3, U 0x0F, U 0x6D, U 0xAA, + U 0x05, U 0x00, U 0x20, U 0x88, + U 0x00, U 0x90, U 0x8C, U 0xBC, + U 0x82, U 0x83, U 0x11, U 0xC0, + U 0xE0, U 0xA4, U 0x33, U 0x24, + U 0x0A, U 0x01, U 0x03, U 0x4E, + U 0x38, U 0x0E, U 0x0E, U 0x42, + U 0xCA, U 0xEC, U 0x2C, U 0xD6, + U 0x7E, U 0x6D, U 0xBA, U 0x05, U 0x00, U 0x20, U 0x88, U 0x00, - U 0x30, U 0x8C, U 0x0F, U 0x59, - U 0x0C, U 0xA9, U 0x89, U 0xBC, - U 0x99, U 0x99, U 0x81, U 0x63, - U 0xFF, U 0x87, U 0xBC, U 0x89, - U 0x99, U 0x81, U 0x63, U 0xFF, - U 0x80, U 0xC0, U 0x60, U 0x02, - U 0xE6, U 0x38, U 0x76, U 0xD0, - U 0xBA, U 0x63, U 0xFF, U 0xB4, + U 0x30, U 0x8C, U 0x82, U 0x11, + U 0x02, U 0x52, U 0x0C, U 0xA2, + U 0x82, U 0xBC, U 0x22, U 0x92, + U 0x81, U 0x63, U 0xFF, U 0x83, + U 0xBC, U 0x82, U 0x92, U 0x81, + U 0x63, U 0xFF, U 0x7C, U 0x00, + U 0xC0, U 0x60, U 0x02, U 0x36, + U 0x38, U 0x76, U 0xF0, U 0xB5, + U 0x63, U 0xFF, U 0xAF, U 0x00, U 0xC0, U 0x70, U 0x02, U 0x47, - U 0x38, U 0x77, U 0xD0, U 0xD0, - U 0x63, U 0xFF, U 0xCA, U 0x00, - U 0x6C, U 0x10, U 0x04, U 0x14, - U 0xD8, U 0x95, U 0xC1, U 0x52, - U 0xA4, U 0x24, U 0xCA, U 0x30, - U 0x28, U 0x22, U 0x1D, U 0x73, - U 0x81, U 0x1B, U 0x29, U 0x21, - U 0x02, U 0xCD, U 0x95, U 0x2A, - U 0x30, U 0x00, U 0x75, U 0xA9, - U 0x12, U 0xDA, U 0x20, U 0x03, - U 0x3B, U 0x02, U 0x2C, U 0x30, - U 0x07, U 0x2D, U 0x0A, U 0x02, - U 0x58, U 0x01, U 0xC2, U 0x65, - U 0x3F, U 0xDD, U 0xD1, U 0x0F, - U 0x2B, U 0x30, U 0x07, U 0x03, - U 0xBB, U 0x0B, U 0xDA, U 0xB0, - U 0x74, U 0xB3, U 0x02, U 0x2A, - U 0xBD, U 0xF8, U 0xD3, U 0xA0, + U 0x38, U 0x77, U 0xF0, U 0xCC, U 0x63, U 0xFF, U 0xC6, U 0x00, + U 0x6C, U 0x10, U 0x04, U 0x14, + U 0xD8, U 0x0D, U 0xC1, U 0x52, + U 0xA4, U 0x24, U 0xCA, U 0x31, + U 0x28, U 0x22, U 0x1D, U 0x73, + U 0x81, U 0x1C, U 0x29, U 0x21, + U 0x02, U 0x65, U 0x90, U 0x16, + U 0x2A, U 0x30, U 0x00, U 0x75, + U 0xA9, U 0x12, U 0x02, U 0x2A, + U 0x02, U 0x03, U 0x3B, U 0x02, + U 0x2C, U 0x30, U 0x07, U 0xC0, + U 0xD2, U 0x58, U 0x01, U 0xD0, + U 0x65, U 0x3F, U 0xDC, U 0xD1, + U 0x0F, U 0x2B, U 0x30, U 0x07, + U 0x03, U 0xBB, U 0x0B, U 0x0B, + U 0xBA, U 0x02, U 0x74, U 0xB3, + U 0x02, U 0x2A, U 0xBD, U 0xF8, + U 0xD3, U 0xA0, U 0x63, U 0xFF, + U 0xC4, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x29, U 0x20, U 0x06, U 0xC0, U 0x70, U 0x6E, U 0x97, U 0x41, U 0x29, @@ -6691,8 +6829,8 @@ static unsigned char t3fw[30136] = { U 0x0E, U 0xC8, U 0xAB, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x2C, U 0x0A, U 0x00, U 0x03, U 0x3D, - U 0x02, U 0x5B, U 0xF8, U 0x14, - U 0x64, U 0x50, U 0x75, U 0x2D, + U 0x02, U 0x5B, U 0xF8, U 0x0E, + U 0x64, U 0x50, U 0x74, U 0x2D, U 0x21, U 0x02, U 0x0D, U 0x0D, U 0x4C, U 0xC9, U 0xD3, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, @@ -6700,8 +6838,8 @@ static unsigned char t3fw[30136] = { U 0x64, U 0xE0, U 0x82, U 0x2F, U 0x21, U 0x02, U 0x0F, U 0x0F, U 0x4C, U 0x65, U 0xF0, U 0x91, - U 0x1A, U 0xD8, U 0x62, U 0x1C, - U 0xD8, U 0x60, U 0x29, U 0xA2, + U 0x1A, U 0xD7, U 0xD9, U 0x1C, + U 0xD7, U 0xD7, U 0x29, U 0xA2, U 0x9E, U 0xC0, U 0x8A, U 0x79, U 0x8B, U 0x5D, U 0x2B, U 0xC2, U 0x26, U 0x68, U 0xB0, U 0x04, @@ -6709,11 +6847,11 @@ static unsigned char t3fw[30136] = { U 0x52, U 0x29, U 0xA2, U 0x9D, U 0xC0, U 0xF3, U 0x64, U 0x90, U 0x4A, U 0x97, U 0x90, U 0x1D, - U 0xD8, U 0x73, U 0x2E, U 0x21, + U 0xD7, U 0xE9, U 0x2E, U 0x21, U 0x04, U 0x9D, U 0x96, U 0x08, U 0xEE, U 0x11, U 0x0F, U 0xEE, U 0x02, U 0x9E, U 0x97, U 0x9E, - U 0x91, U 0x18, U 0xD8, U 0x6F, + U 0x91, U 0x18, U 0xD7, U 0xE5, U 0xC0, U 0xE5, U 0x27, U 0xC4, U 0xA2, U 0x2E, U 0x24, U 0x06, U 0x2B, U 0xA2, U 0x9D, U 0x2F, @@ -6722,10 +6860,10 @@ static unsigned char t3fw[30136] = { U 0x2F, U 0x25, U 0x02, U 0x2B, U 0xA6, U 0x9D, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, - U 0x00, U 0x2F, U 0x30, U 0x00, - U 0x68, U 0xF9, U 0x38, U 0xDA, - U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x00, U 0x44, + U 0x2F, U 0x30, U 0x00, U 0x68, + U 0xF9, U 0x39, U 0xDA, U 0x20, + U 0xDB, U 0x30, U 0x04, U 0x4C, + U 0x02, U 0x58, U 0x00, U 0x44, U 0x63, U 0xFF, U 0x77, U 0x00, U 0x02, U 0x2A, U 0x02, U 0x2B, U 0x0A, U 0x06, U 0x58, U 0x00, @@ -6740,11 +6878,11 @@ static unsigned char t3fw[30136] = { U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x2A, U 0x2C, U 0x74, U 0x03, U 0x3B, U 0x02, U 0x04, U 0x4C, - U 0x02, U 0x5B, U 0xFE, U 0xF8, + U 0x02, U 0x5B, U 0xFE, U 0xF6, U 0x63, U 0xFF, U 0x3B, U 0x00, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0x2A, U 0x2C, U 0x74, U 0x5B, - U 0xFE, U 0xF5, U 0xC0, U 0x20, + U 0xFE, U 0xF3, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0xC8, U 0x3F, U 0x89, U 0x26, U 0x88, @@ -6754,7 +6892,7 @@ static unsigned char t3fw[30136] = { U 0x25, U 0x25, U 0xCC, U 0x52, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDB, U 0x40, U 0x2A, U 0x2C, - U 0x74, U 0x5B, U 0xF9, U 0x3D, + U 0x74, U 0x5B, U 0xF9, U 0x37, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xD8, U 0x20, U 0xD7, U 0x30, U 0x82, @@ -6762,7 +6900,7 @@ static unsigned char t3fw[30136] = { U 0x05, U 0x22, U 0x0C, U 0x92, U 0x82, U 0x64, U 0x20, U 0x74, U 0x07, U 0x42, U 0x0B, U 0x13, - U 0xD8, U 0x21, U 0xD4, U 0x20, + U 0xD7, U 0x98, U 0xD4, U 0x20, U 0xA3, U 0x83, U 0x73, U 0x23, U 0x02, U 0x24, U 0x2D, U 0xF8, U 0x85, U 0x80, U 0x74, U 0x51, @@ -6776,12 +6914,12 @@ static unsigned char t3fw[30136] = { U 0x74, U 0x61, U 0x02, U 0x63, U 0xFF, U 0xE2, U 0xCA, U 0x98, U 0xC0, U 0x97, U 0xC0, U 0x41, - U 0x1B, U 0xD8, U 0xA0, U 0xC0, + U 0x1B, U 0xD8, U 0x18, U 0xC0, U 0xA0, U 0x0B, U 0x8B, U 0x0C, U 0x0B, U 0x4A, U 0x38, U 0x0A, U 0x0A, U 0x42, U 0xC9, U 0xAA, - U 0x1D, U 0xD8, U 0x0E, U 0x1C, - U 0xD8, U 0x0F, U 0x2C, U 0xD6, + U 0x1D, U 0xD7, U 0x85, U 0x1C, + U 0xD7, U 0x86, U 0x2C, U 0xD6, U 0x7E, U 0xC1, U 0x40, U 0xD3, U 0x0F, U 0x6D, U 0x4A, U 0x05, U 0x00, U 0x20, U 0x88, U 0x00, @@ -6795,8 +6933,8 @@ static unsigned char t3fw[30136] = { U 0x20, U 0x92, U 0x82, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x06, U 0xC0, - U 0xD7, U 0x1C, U 0xD7, U 0xFE, - U 0x1B, U 0xD8, U 0x00, U 0x0D, + U 0xD7, U 0x1C, U 0xD7, U 0x75, + U 0x1B, U 0xD7, U 0x77, U 0x0D, U 0x49, U 0x11, U 0xD7, U 0x20, U 0x2E, U 0x22, U 0x1F, U 0x28, U 0x22, U 0x1D, U 0x0E, U 0x4E, @@ -6806,7 +6944,7 @@ static unsigned char t3fw[30136] = { U 0xC8, U 0x34, U 0x6F, U 0xAE, U 0x02, U 0x60, U 0x00, U 0xCB, U 0x2F, U 0x0A, U 0x80, U 0x1A, - U 0xD8, U 0x04, U 0xA2, U 0x9E, + U 0xD7, U 0x7B, U 0xA2, U 0x9E, U 0xAA, U 0x7A, U 0x7E, U 0xA3, U 0x3F, U 0xC9, U 0x3F, U 0xC0, U 0xE1, U 0xC0, U 0x50, U 0x02, @@ -6824,7 +6962,7 @@ static unsigned char t3fw[30136] = { U 0xD1, U 0x0F, U 0xC0, U 0x50, U 0x03, U 0xE5, U 0x38, U 0x75, U 0xD0, U 0xD3, U 0x63, U 0xFF, - U 0xCD, U 0x15, U 0xD7, U 0xF1, + U 0xCD, U 0x15, U 0xD7, U 0x68, U 0x02, U 0x7E, U 0x0C, U 0xA5, U 0xEE, U 0x64, U 0x30, U 0x51, U 0xC0, U 0xA1, U 0x25, U 0x0A, @@ -6880,7 +7018,7 @@ static unsigned char t3fw[30136] = { U 0x63, U 0xFF, U 0xB9, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x2A, U 0x20, U 0x15, U 0x29, U 0x20, - U 0x16, U 0x14, U 0xD7, U 0xAF, + U 0x16, U 0x14, U 0xD7, U 0x26, U 0x0A, U 0x99, U 0x0C, U 0xCB, U 0x9D, U 0x2E, U 0x20, U 0x0B, U 0x04, U 0xED, U 0x09, U 0x2B, @@ -6943,15 +7081,15 @@ static unsigned char t3fw[30136] = { U 0x6C, U 0x10, U 0x04, U 0x27, U 0x22, U 0x1E, U 0xC0, U 0x80, U 0x08, U 0xE4, U 0x31, U 0x1D, - U 0xD7, U 0x6F, U 0x00, U 0x02, + U 0xD6, U 0xE6, U 0x00, U 0x02, U 0x00, U 0x2C, U 0xD2, U 0x82, - U 0x1B, U 0xD7, U 0x6F, U 0x00, + U 0x1B, U 0xD6, U 0xE6, U 0x00, U 0x31, U 0x04, U 0xC0, U 0x61, U 0x00, U 0x66, U 0x1A, U 0x2B, U 0xB1, U 0x02, U 0x0C, U 0x6C, U 0x02, U 0x2C, U 0xD6, U 0x82, U 0x0B, U 0xE4, U 0x31, U 0x19, - U 0xD7, U 0xF2, U 0x0C, U 0x3A, + U 0xD7, U 0x6A, U 0x0C, U 0x3A, U 0x11, U 0xAA, U 0x93, U 0x28, U 0x32, U 0x82, U 0x97, U 0x80, U 0x25, U 0x32, U 0x82, U 0x24, @@ -6965,19 +7103,31 @@ static unsigned char t3fw[30136] = { U 0x6A, U 0x02, U 0x2B, U 0x36, U 0x82, U 0x2A, U 0x25, U 0x02, U 0xD1, U 0x0F, U 0x00, U 0x00, + U 0x6C, U 0x10, U 0x04, U 0x18, + U 0xD6, U 0xCF, U 0x0C, U 0x27, + U 0x11, U 0x08, U 0x77, U 0x08, + U 0x26, U 0x72, U 0x86, U 0x25, + U 0x3C, U 0x04, U 0x76, U 0x5B, + U 0x13, U 0x15, U 0xD6, U 0xCB, + U 0x05, U 0x22, U 0x0A, U 0x22, + U 0x22, U 0xA3, U 0x68, U 0x20, + U 0x02, U 0x74, U 0x29, U 0x04, + U 0x22, U 0x72, U 0x85, U 0xD1, + U 0x0F, U 0xC0, U 0x20, U 0xD1, + U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x19, - U 0xD7, U 0x63, U 0x27, U 0x22, + U 0xD6, U 0xCE, U 0x27, U 0x22, U 0x1E, U 0xC0, U 0x80, U 0x09, U 0x77, U 0x02, U 0x08, U 0xE4, - U 0x31, U 0x1D, U 0xD7, U 0x54, + U 0x31, U 0x1D, U 0xD6, U 0xBF, U 0x00, U 0x02, U 0x00, U 0x2C, - U 0xD2, U 0x82, U 0x1B, U 0xD7, - U 0x54, U 0x00, U 0x31, U 0x04, + U 0xD2, U 0x82, U 0x1B, U 0xD6, + U 0xBF, U 0x00, U 0x31, U 0x04, U 0xC0, U 0x61, U 0x00, U 0x66, U 0x1A, U 0x2B, U 0xB1, U 0x02, U 0x0C, U 0x6C, U 0x02, U 0x2C, U 0xD6, U 0x82, U 0x0B, U 0xE4, - U 0x31, U 0x19, U 0xD7, U 0xD7, + U 0x31, U 0x19, U 0xD7, U 0x43, U 0x0C, U 0x3A, U 0x11, U 0xAA, U 0x93, U 0x28, U 0x32, U 0x82, U 0x97, U 0x80, U 0x25, U 0x32, @@ -6993,12 +7143,12 @@ static unsigned char t3fw[30136] = { U 0x2B, U 0x25, U 0x02, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x1B, - U 0xD7, U 0x3D, U 0x0C, U 0x2A, + U 0xD6, U 0xA8, U 0x0C, U 0x2A, U 0x11, U 0xAB, U 0xAA, U 0x29, U 0xA2, U 0x86, U 0xB4, U 0x38, U 0x79, U 0x8B, U 0x22, U 0x1B, - U 0xD7, U 0x3A, U 0x19, U 0xD7, - U 0x61, U 0x0B, U 0x2B, U 0x0A, + U 0xD6, U 0xA5, U 0x19, U 0xD6, + U 0xCB, U 0x0B, U 0x2B, U 0x0A, U 0x2B, U 0xB2, U 0xA3, U 0x09, U 0x29, U 0x08, U 0x68, U 0xB0, U 0x02, U 0x74, U 0xB9, U 0x0D, @@ -7008,12 +7158,12 @@ static unsigned char t3fw[30136] = { U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xC8, U 0x92, U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0xDA, U 0x20, U 0x5B, U 0xEF, - U 0x35, U 0xC0, U 0x20, U 0xD1, + U 0xDA, U 0x20, U 0x5B, U 0xEE, + U 0xA7, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x14, - U 0xD7, U 0x2A, U 0x28, U 0x42, - U 0x9E, U 0x19, U 0xD7, U 0x27, + U 0xD6, U 0x95, U 0x28, U 0x42, + U 0x9E, U 0x19, U 0xD6, U 0x92, U 0x6F, U 0x88, U 0x02, U 0x60, U 0x00, U 0xBA, U 0x29, U 0x92, U 0x26, U 0x68, U 0x90, U 0x07, @@ -7022,7 +7172,7 @@ static unsigned char t3fw[30136] = { U 0x2A, U 0x42, U 0x9D, U 0xC0, U 0xDC, U 0x64, U 0xA0, U 0xA4, U 0x2B, U 0x20, U 0x0C, U 0x19, - U 0xD7, U 0x21, U 0x0C, U 0xBC, + U 0xD6, U 0x8C, U 0x0C, U 0xBC, U 0x11, U 0xA4, U 0xCC, U 0x2E, U 0xC2, U 0x86, U 0x09, U 0xB9, U 0x0A, U 0x7E, U 0xD3, U 0x02, @@ -7037,16 +7187,16 @@ static unsigned char t3fw[30136] = { U 0x20, U 0x66, U 0xB8, U 0xCC, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0x65, U 0xC0, - U 0x7B, U 0x1C, U 0xD7, U 0x9C, - U 0x18, U 0xD7, U 0x28, U 0x1A, - U 0xD7, U 0x1E, U 0x19, U 0xD7, - U 0x2F, U 0x1D, U 0xD7, U 0x24, + U 0x7B, U 0x1C, U 0xD7, U 0x08, + U 0x18, U 0xD6, U 0x92, U 0x1A, + U 0xD6, U 0x89, U 0x19, U 0xD6, + U 0x99, U 0x1D, U 0xD6, U 0x8E, U 0xC0, U 0xE4, U 0x9E, U 0x51, U 0x9D, U 0x50, U 0x8F, U 0x20, U 0x93, U 0x57, U 0x93, U 0x55, U 0x99, U 0x53, U 0x9A, U 0x56, U 0x9A, U 0x54, U 0x08, U 0xFF, - U 0x02, U 0x1A, U 0xD7, U 0x3A, + U 0x02, U 0x1A, U 0xD6, U 0xA9, U 0x9F, U 0x52, U 0x88, U 0x26, U 0x9F, U 0x5A, U 0x9E, U 0x59, U 0x9D, U 0x58, U 0x93, U 0x5E, @@ -7054,7 +7204,7 @@ static unsigned char t3fw[30136] = { U 0x9A, U 0x5B, U 0x08, U 0x08, U 0x48, U 0x05, U 0x88, U 0x11, U 0x98, U 0x5F, U 0xC0, U 0xD8, - U 0x1F, U 0xD7, U 0x08, U 0x0C, + U 0x1F, U 0xD6, U 0x73, U 0x0C, U 0xB9, U 0x11, U 0xA4, U 0x99, U 0x28, U 0x92, U 0x85, U 0xAF, U 0xBF, U 0x23, U 0xF4, U 0xCF, @@ -7064,12 +7214,12 @@ static unsigned char t3fw[30136] = { U 0x29, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xCA, U 0x33, U 0xDA, U 0x20, U 0xC0, U 0xB6, U 0x5B, - U 0xFF, U 0x84, U 0xC7, U 0x2F, + U 0xFF, U 0x78, U 0xC7, U 0x2F, U 0xD1, U 0x0F, U 0xC9, U 0x3A, U 0xDA, U 0x20, U 0x5B, U 0xFF, - U 0x81, U 0xC7, U 0x2F, U 0xD1, + U 0x75, U 0xC7, U 0x2F, U 0xD1, U 0x0F, U 0xDB, U 0xD0, U 0x5B, - U 0xFE, U 0x1A, U 0x23, U 0x24, + U 0xFE, U 0x0C, U 0x23, U 0x24, U 0x66, U 0x2B, U 0x20, U 0x0C, U 0x63, U 0xFF, U 0x75, U 0x00, U 0xC7, U 0x2F, U 0xD1, U 0x0F, @@ -7082,52 +7232,53 @@ static unsigned char t3fw[30136] = { U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0x2E, U 0x0A, - U 0x00, U 0x5B, U 0xFE, U 0x6A, + U 0x00, U 0x5B, U 0xFE, U 0x5E, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x2E, U 0x20, U 0x0C, U 0x18, - U 0xD6, U 0xE1, U 0x0C, U 0xEF, + U 0xD6, U 0x4C, U 0x0C, U 0xEF, U 0x11, U 0xA8, U 0xFF, U 0x29, U 0xF2, U 0x86, U 0xC0, U 0x88, - U 0x79, U 0x8B, U 0x75, U 0x1A, - U 0xD6, U 0xDE, U 0x0A, U 0xEA, + U 0x79, U 0x8B, U 0x79, U 0x1A, + U 0xD6, U 0x49, U 0x0A, U 0xEA, U 0x0A, U 0x2A, U 0xA2, U 0xA3, U 0x68, U 0xA0, U 0x04, U 0x8B, - U 0x20, U 0x7A, U 0xB9, U 0x64, + U 0x20, U 0x7A, U 0xB9, U 0x68, U 0x23, U 0xF2, U 0x85, U 0x64, - U 0x30, U 0x5E, U 0x1C, U 0xD6, - U 0xE8, U 0x2A, U 0x0A, U 0x80, - U 0x2D, U 0x20, U 0x68, U 0x29, - U 0x20, U 0x67, U 0x28, U 0x21, - U 0x04, U 0x0B, U 0x99, U 0x11, - U 0x04, U 0x88, U 0x11, U 0x09, - U 0x88, U 0x02, U 0x08, U 0xDD, - U 0x02, U 0xC0, U 0x94, U 0x28, - U 0x4A, U 0x10, U 0x08, U 0xDD, - U 0x02, U 0x18, U 0xD6, U 0xE0, - U 0x99, U 0x31, U 0x98, U 0x30, - U 0x8B, U 0x2B, U 0x9A, U 0x37, - U 0x9D, U 0x34, U 0x0C, U 0xBB, - U 0x02, U 0x9B, U 0x32, U 0xC0, - U 0xC0, U 0x9C, U 0x35, U 0x9C, - U 0x36, U 0x2A, U 0x2C, U 0x74, - U 0xDB, U 0x40, U 0xC0, U 0xD3, - U 0x18, U 0xD6, U 0xCF, U 0x29, - U 0xF2, U 0x85, U 0xA8, U 0xEE, - U 0x29, U 0x9C, U 0x20, U 0x2C, - U 0xE4, U 0xCF, U 0x29, U 0xF6, - U 0x85, U 0x2D, U 0x24, U 0x06, - U 0xDD, U 0x40, U 0x5B, U 0xFD, - U 0xFA, U 0xD2, U 0xA0, U 0xD1, - U 0x0F, U 0xDA, U 0x20, U 0xDB, - U 0xE0, U 0x5B, U 0xFF, U 0x4C, + U 0x30, U 0x62, U 0x1B, U 0xD6, + U 0x53, U 0x29, U 0x0A, U 0x80, + U 0x2C, U 0x20, U 0x68, U 0x28, + U 0x20, U 0x67, U 0x2D, U 0x21, + U 0x04, U 0x0B, U 0x88, U 0x11, + U 0x04, U 0xDD, U 0x11, U 0x08, + U 0xDD, U 0x02, U 0x0D, U 0xCC, + U 0x02, U 0xC0, U 0x84, U 0x2D, + U 0x4A, U 0x10, U 0x0D, U 0xCC, + U 0x02, U 0x1D, U 0xD6, U 0x4B, + U 0x98, U 0x31, U 0x9D, U 0x30, + U 0x8A, U 0x2B, U 0x99, U 0x37, + U 0x9C, U 0x34, U 0x0B, U 0xAA, + U 0x02, U 0xC0, U 0xC0, U 0x9C, + U 0x35, U 0x9C, U 0x36, U 0x9A, + U 0x32, U 0x2A, U 0x2C, U 0x74, + U 0xDB, U 0x40, U 0x28, U 0xF2, + U 0x85, U 0xC0, U 0xD3, U 0x28, + U 0x8C, U 0x20, U 0x28, U 0xF6, + U 0x85, U 0x2C, U 0x25, U 0x04, + U 0x2D, U 0x24, U 0x06, U 0x1F, + U 0xD6, U 0x36, U 0xDD, U 0x40, + U 0xAF, U 0xEE, U 0x2C, U 0xE4, + U 0xCF, U 0x5B, U 0xFD, U 0xEB, + U 0xD2, U 0xA0, U 0xD1, U 0x0F, + U 0x00, U 0xDA, U 0x20, U 0xDB, + U 0xE0, U 0x5B, U 0xFF, U 0x3F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x0A, U 0xD6, U 0x30, U 0x2A, U 0x20, U 0x06, - U 0x94, U 0x11, U 0x28, U 0xAC, - U 0xF8, U 0x65, U 0x83, U 0x87, - U 0x2B, U 0x21, U 0x22, U 0xC0, - U 0xF2, U 0x2A, U 0x21, U 0x24, - U 0x65, U 0x50, U 0x08, U 0x2A, + U 0x24, U 0x16, U 0x01, U 0x28, + U 0xAC, U 0xF8, U 0x65, U 0x83, + U 0x86, U 0x2B, U 0x21, U 0x22, + U 0xC0, U 0xF2, U 0x2A, U 0x21, + U 0x24, U 0xCC, U 0x57, U 0x2A, U 0xAC, U 0x01, U 0x0A, U 0x0A, U 0x4F, U 0x2A, U 0x25, U 0x24, U 0x7A, U 0xBB, U 0x02, U 0x60, @@ -7138,25 +7289,25 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x91, U 0x0E, U 0xDD, U 0x0C, U 0x65, U 0xD3, U 0x90, U 0x88, U 0x38, U 0x1E, U 0xD6, - U 0xAC, U 0x64, U 0x83, U 0x6B, + U 0x16, U 0x64, U 0x83, U 0x6B, U 0x8C, U 0x37, U 0xC0, U 0xB8, U 0xC0, U 0x96, U 0x0C, U 0xB9, U 0x39, U 0x99, U 0x14, U 0xB4, U 0x9A, U 0x9A, U 0x12, U 0x0D, U 0x99, U 0x11, U 0x99, U 0x13, U 0x8F, U 0x67, U 0x18, U 0xD6, - U 0xA7, U 0xC9, U 0xFB, U 0x28, + U 0x11, U 0xC9, U 0xFB, U 0x28, U 0x80, U 0x21, U 0x7F, U 0x83, U 0x16, U 0x8B, U 0x14, U 0x2C, U 0x22, U 0x00, U 0x2A, U 0x20, - U 0x0C, U 0x5B, U 0xFF, U 0x62, + U 0x0C, U 0x5B, U 0xFF, U 0x61, U 0xD4, U 0xA0, U 0x64, U 0xA3, - U 0xA8, U 0x8F, U 0x67, U 0x60, + U 0xB3, U 0x8F, U 0x67, U 0x60, U 0x00, U 0x28, U 0x00, U 0x00, U 0x2B, U 0x20, U 0x0C, U 0x89, U 0x12, U 0x0C, U 0xBA, U 0x11, U 0xAE, U 0xAA, U 0x2C, U 0xA2, - U 0x86, U 0x1D, U 0xD6, U 0x9A, + U 0x86, U 0x1D, U 0xD6, U 0x04, U 0x7C, U 0x9B, U 0x3E, U 0x0D, U 0xBD, U 0x0A, U 0x2D, U 0xD2, U 0xA3, U 0x68, U 0xD0, U 0x04, @@ -7168,15 +7319,15 @@ static unsigned char t3fw[30136] = { U 0x6F, U 0x9D, U 0x01, U 0xD7, U 0xF0, U 0xDA, U 0x20, U 0xDB, U 0x70, U 0xC1, U 0xC4, U 0x2D, - U 0x21, U 0x1F, U 0x5B, U 0xFF, - U 0x05, U 0x89, U 0x26, U 0x88, + U 0x21, U 0x1F, U 0x5B, U 0xFE, + U 0xF8, U 0x89, U 0x26, U 0x88, U 0x27, U 0xDD, U 0xA0, U 0x09, U 0x88, U 0x0C, U 0x7A, U 0x8B, U 0x17, U 0x9A, U 0x10, U 0x60, U 0x00, U 0x06, U 0xC0, U 0x40, U 0x63, U 0xFF, U 0xCC, U 0x00, U 0x00, U 0xDA, U 0x20, U 0x8B, - U 0x10, U 0x5B, U 0xFE, U 0xD5, + U 0x10, U 0x5B, U 0xFE, U 0xC8, U 0x8D, U 0x10, U 0x65, U 0xA2, U 0x67, U 0xC0, U 0xE0, U 0x9E, U 0x48, U 0x8C, U 0x64, U 0x9C, @@ -7188,7 +7339,7 @@ static unsigned char t3fw[30136] = { U 0x52, U 0x9D, U 0x10, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x2C, U 0x12, U 0x01, U 0x5B, U 0xFE, - U 0x76, U 0x8D, U 0x10, U 0xC0, + U 0x69, U 0x8D, U 0x10, U 0xC0, U 0x51, U 0xD6, U 0xA0, U 0x8F, U 0xA7, U 0xC0, U 0xC0, U 0x8A, U 0x68, U 0x97, U 0x4D, U 0x9A, @@ -7224,15 +7375,15 @@ static unsigned char t3fw[30136] = { U 0x99, U 0x02, U 0x09, U 0x33, U 0x02, U 0x8A, U 0x2B, U 0x29, U 0x21, U 0x04, U 0x0B, U 0xAA, - U 0x02, U 0x1B, U 0xD6, U 0xE2, + U 0x02, U 0x1B, U 0xD6, U 0x4D, U 0x08, U 0x99, U 0x11, U 0x09, U 0x55, U 0x02, U 0x08, U 0x55, U 0x02, U 0x0B, U 0xAA, U 0x02, U 0x9A, U 0x40, U 0x89, U 0x20, U 0x88, U 0x14, U 0x08, U 0x99, U 0x11, U 0x09, U 0x88, U 0x02, - U 0x19, U 0xD6, U 0x63, U 0x1D, - U 0xD6, U 0xDC, U 0x09, U 0x88, + U 0x19, U 0xD5, U 0xCD, U 0x1D, + U 0xD6, U 0x47, U 0x09, U 0x88, U 0x02, U 0x98, U 0x41, U 0x8B, U 0x2A, U 0x93, U 0x46, U 0x95, U 0x47, U 0x83, U 0x15, U 0x0D, @@ -7249,11 +7400,11 @@ static unsigned char t3fw[30136] = { U 0x0E, U 0x48, U 0x2E, U 0x25, U 0x25, U 0x9B, U 0x67, U 0x2B, U 0x20, U 0x0C, U 0x87, U 0x13, - U 0x1E, U 0xD6, U 0x3D, U 0x0C, + U 0x1E, U 0xD5, U 0xA7, U 0x0C, U 0xB9, U 0x11, U 0xAE, U 0x99, U 0x28, U 0x92, U 0x85, U 0xA7, U 0x88, U 0x28, U 0x96, U 0x85, - U 0x17, U 0xD6, U 0x41, U 0xC0, + U 0x17, U 0xD5, U 0xAB, U 0xC0, U 0x90, U 0xA7, U 0xBB, U 0x29, U 0xB4, U 0xCF, U 0x87, U 0x18, U 0x63, U 0xFE, U 0x3C, U 0x00, @@ -7276,7 +7427,7 @@ static unsigned char t3fw[30136] = { U 0x1F, U 0x0A, U 0xBB, U 0x11, U 0x07, U 0x88, U 0x10, U 0x08, U 0xFF, U 0x02, U 0x0B, U 0xAA, - U 0x02, U 0x18, U 0xD6, U 0x35, + U 0x02, U 0x18, U 0xD5, U 0x9F, U 0x09, U 0x29, U 0x14, U 0x03, U 0xAA, U 0x02, U 0x2B, U 0x21, U 0x25, U 0x83, U 0x20, U 0x0B, @@ -7294,16 +7445,16 @@ static unsigned char t3fw[30136] = { U 0x4E, U 0x98, U 0x4F, U 0xC0, U 0x70, U 0x77, U 0xC7, U 0x01, U 0xC0, U 0x71, U 0x9A, U 0x47, - U 0x18, U 0xD6, U 0x9E, U 0x0B, + U 0x18, U 0xD6, U 0x09, U 0x0B, U 0x7C, U 0x10, U 0x0C, U 0xEC, U 0x02, U 0x08, U 0xF8, U 0x02, U 0x98, U 0x44, U 0x18, U 0xD6, - U 0x9B, U 0x0C, U 0xBC, U 0x02, + U 0x06, U 0x0C, U 0xBC, U 0x02, U 0x08, U 0xCC, U 0x02, U 0x9C, U 0x40, U 0x2A, U 0x20, U 0x0C, U 0x29, U 0x5C, U 0xFE, U 0xC0, - U 0x80, U 0x1F, U 0xD6, U 0x07, - U 0x1C, U 0xD6, U 0x0F, U 0x0C, + U 0x80, U 0x1F, U 0xD5, U 0x71, + U 0x1C, U 0xD5, U 0x79, U 0x0C, U 0xAE, U 0x11, U 0x2B, U 0x21, U 0x24, U 0xAC, U 0xAA, U 0xAF, U 0xEE, U 0xB0, U 0xBB, U 0x8F, @@ -7324,17 +7475,17 @@ static unsigned char t3fw[30136] = { U 0xC0, U 0x70, U 0x93, U 0x41, U 0x9F, U 0x44, U 0x99, U 0x46, U 0x9A, U 0x47, U 0x77, U 0xC7, - U 0x0A, U 0x1C, U 0xD5, U 0xF3, + U 0x0A, U 0x1C, U 0xD5, U 0x5D, U 0x2C, U 0xC0, U 0x22, U 0xC0, U 0x81, U 0x0C, U 0x87, U 0x38, - U 0x1C, U 0xD6, U 0x7F, U 0x0B, + U 0x1C, U 0xD5, U 0xEA, U 0x0B, U 0x78, U 0x10, U 0x08, U 0xE8, U 0x02, U 0x08, U 0xB8, U 0x02, U 0x0C, U 0x88, U 0x02, U 0x98, U 0x40, U 0x63, U 0xFF, U 0x80, U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x60, U 0x8C, - U 0x11, U 0x5B, U 0xFD, U 0xE3, + U 0x11, U 0x5B, U 0xFD, U 0xD6, U 0x29, U 0x21, U 0x02, U 0x68, U 0x98, U 0x06, U 0x68, U 0x94, U 0x03, U 0xC0, U 0x20, U 0xD1, @@ -7343,7 +7494,7 @@ static unsigned char t3fw[30136] = { U 0x1D, U 0x2A, U 0x25, U 0x02, U 0x7B, U 0x99, U 0x01, U 0xC0, U 0xB0, U 0x64, U 0xBF, U 0xE8, - U 0x13, U 0xD5, U 0xDE, U 0x2C, + U 0x13, U 0xD5, U 0x48, U 0x2C, U 0xB0, U 0x07, U 0x28, U 0xB0, U 0x00, U 0xDA, U 0x20, U 0x03, U 0x88, U 0x0A, U 0x28, U 0x82, @@ -7354,7 +7505,7 @@ static unsigned char t3fw[30136] = { U 0x68, U 0xA7, U 0x79, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, U 0x40, U 0xDD, U 0x50, U 0x5B, - U 0xFE, U 0xE8, U 0xD2, U 0xA0, + U 0xFE, U 0xE7, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC1, U 0x6D, U 0xC1, U 0x9D, U 0x29, U 0x25, U 0x2C, U 0x60, U 0x00, U 0x04, @@ -7364,7 +7515,7 @@ static unsigned char t3fw[30136] = { U 0x20, U 0xDB, U 0x30, U 0x8C, U 0x11, U 0xDD, U 0x50, U 0x2E, U 0x0A, U 0x80, U 0x5B, U 0xFD, - U 0x51, U 0xD2, U 0xA0, U 0xD1, + U 0x44, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC1, U 0x68, U 0xC1, U 0xA8, U 0x2A, U 0x25, U 0x2C, U 0x63, U 0xFF, U 0xDD, U 0x00, @@ -7375,77 +7526,79 @@ static unsigned char t3fw[30136] = { U 0x0B, U 0x48, U 0x2B, U 0x25, U 0x25, U 0x2A, U 0x2C, U 0x74, U 0xDB, U 0x60, U 0x2C, U 0x12, - U 0x01, U 0x5B, U 0xFD, U 0x94, + U 0x01, U 0x5B, U 0xFD, U 0x87, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x11, U 0x5B, U 0xF6, U 0xCD, + U 0x11, U 0x5B, U 0xF6, U 0xBA, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x5B, U 0xFE, - U 0x47, U 0x63, U 0xFF, U 0x38, + U 0x3A, U 0x63, U 0xFF, U 0x38, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB1, U 0x5B, U 0xFE, U 0x8B, - U 0x65, U 0xAF, U 0x2D, U 0x63, - U 0xFB, U 0xED, U 0xDA, U 0x20, - U 0x2B, U 0x20, U 0x0C, U 0x5B, - U 0xFE, U 0x5A, U 0x63, U 0xFF, - U 0x1F, U 0x00, U 0x00, U 0x00, - U 0x12, U 0xD6, U 0x42, U 0x82, + U 0xB1, U 0x5B, U 0xFE, U 0x8A, + U 0x64, U 0xAB, U 0xF1, U 0x65, + U 0x5F, U 0x35, U 0x2D, U 0x21, + U 0x24, U 0xB1, U 0xDD, U 0x2D, + U 0x25, U 0x24, U 0x63, U 0xFF, + U 0x1F, U 0xDA, U 0x20, U 0x2B, + U 0x20, U 0x0C, U 0x5B, U 0xFE, + U 0x56, U 0x63, U 0xFF, U 0x14, + U 0x12, U 0xD5, U 0xAB, U 0x82, U 0x20, U 0x02, U 0x82, U 0x57, U 0xC8, U 0x21, U 0x63, U 0xFF, - U 0xFC, U 0x12, U 0xD6, U 0x3E, + U 0xFC, U 0x12, U 0xD5, U 0xA7, U 0x03, U 0xE8, U 0x30, U 0x04, U 0xEE, U 0x30, U 0x05, U 0xB1, U 0x30, U 0x93, U 0x20, U 0x94, U 0x21, U 0x95, U 0x22, U 0x63, U 0xFF, U 0xFC, U 0x00, U 0x00, - U 0x10, U 0xD6, U 0x3A, U 0x91, + U 0x10, U 0xD5, U 0xA3, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD6, U 0x11, U 0x82, U 0x10, + U 0xD5, U 0x7A, U 0x82, U 0x10, U 0x01, U 0xEA, U 0x30, U 0xA2, U 0x11, U 0x01, U 0xF0, U 0x31, U 0xC0, U 0x40, U 0x04, U 0xE4, U 0x16, U 0x00, U 0x02, U 0x00, - U 0x11, U 0xD6, U 0x33, U 0x82, + U 0x11, U 0xD5, U 0x9C, U 0x82, U 0x10, U 0x23, U 0x4A, U 0x00, U 0x03, U 0x22, U 0x02, U 0x92, - U 0x10, U 0x11, U 0xD5, U 0xFD, + U 0x10, U 0x11, U 0xD5, U 0x65, U 0xC0, U 0x21, U 0x92, U 0x10, U 0x04, U 0xE4, U 0x31, U 0x84, U 0x03, U 0x83, U 0x02, U 0x82, U 0x01, U 0x81, U 0x00, U 0x00, U 0xD2, U 0x30, U 0x01, U 0x23, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x10, U 0xD6, U 0x2A, U 0x91, + U 0x10, U 0xD5, U 0x93, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD6, U 0x00, U 0x82, U 0x10, + U 0xD5, U 0x69, U 0x82, U 0x10, U 0x01, U 0xEA, U 0x30, U 0xA2, U 0x11, U 0x01, U 0xF1, U 0x31, U 0xC0, U 0x40, U 0x04, U 0xE4, U 0x16, U 0x00, U 0x02, U 0x00, - U 0x11, U 0xD6, U 0x21, U 0x82, - U 0x10, U 0x13, U 0xD5, U 0xA7, + U 0x11, U 0xD5, U 0x8A, U 0x82, + U 0x10, U 0x13, U 0xD5, U 0x0E, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, U 0x04, U 0xE4, U 0x31, U 0x84, U 0x03, U 0x83, U 0x02, U 0x82, U 0x01, U 0x81, U 0x00, U 0x00, U 0xD3, U 0x30, U 0x01, U 0x33, U 0x00, U 0x00, U 0x00, - U 0x10, U 0xD6, U 0x1B, U 0x91, + U 0x10, U 0xD5, U 0x84, U 0x91, U 0x00, U 0x81, U 0x01, U 0x65, U 0x10, U 0x49, U 0x81, U 0x02, U 0x65, U 0x10, U 0x44, U 0x81, U 0x03, U 0xCF, U 0x1F, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, - U 0x03, U 0x11, U 0xD5, U 0xEE, + U 0x03, U 0x11, U 0xD5, U 0x57, U 0x82, U 0x10, U 0x01, U 0xEA, U 0x30, U 0xA2, U 0x11, U 0x01, U 0xF2, U 0x31, U 0xC0, U 0x40, U 0x04, U 0xE4, U 0x16, U 0x00, - U 0x02, U 0x00, U 0x11, U 0xD6, - U 0x0D, U 0x82, U 0x10, U 0x13, - U 0xD5, U 0x8E, U 0x03, U 0x22, + U 0x02, U 0x00, U 0x11, U 0xD5, + U 0x76, U 0x82, U 0x10, U 0x13, + U 0xD4, U 0xF6, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, U 0x04, U 0xE4, U 0x31, U 0x84, U 0x03, U 0x83, U 0x02, U 0x82, U 0x01, @@ -7453,7 +7606,7 @@ static unsigned char t3fw[30136] = { U 0x91, U 0x02, U 0x91, U 0x01, U 0x81, U 0x00, U 0x00, U 0xD4, U 0x30, U 0x01, U 0x43, U 0x00, - U 0x12, U 0xD5, U 0xBD, U 0xC0, + U 0x12, U 0xD5, U 0x25, U 0xC0, U 0x30, U 0x28, U 0x37, U 0x40, U 0x28, U 0x37, U 0x44, U 0x28, U 0x37, U 0x48, U 0x28, U 0x37, @@ -7461,19 +7614,19 @@ static unsigned char t3fw[30136] = { U 0x72, U 0x33, U 0xED, U 0x03, U 0x02, U 0x00, U 0x63, U 0xFF, U 0xFC, U 0x00, U 0x00, U 0x00, - U 0x10, U 0xD5, U 0xFF, U 0x91, + U 0x10, U 0xD5, U 0x68, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD5, U 0xFD, U 0x82, U 0x10, + U 0xD5, U 0x66, U 0x82, U 0x10, U 0x92, U 0x10, U 0x11, U 0xD5, - U 0xAF, U 0x83, U 0x10, U 0x03, + U 0x17, U 0x83, U 0x10, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, - U 0x11, U 0xD5, U 0xFA, U 0x12, - U 0xD5, U 0xC1, U 0x92, U 0x10, + U 0x11, U 0xD5, U 0x63, U 0x12, + U 0xD5, U 0x29, U 0x92, U 0x10, U 0xC0, U 0x40, U 0x04, U 0xE4, U 0x16, U 0x00, U 0x02, U 0x00, - U 0x11, U 0xD5, U 0xF1, U 0x82, - U 0x10, U 0x13, U 0xD5, U 0xA8, + U 0x11, U 0xD5, U 0x5A, U 0x82, + U 0x10, U 0x13, U 0xD5, U 0x10, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, U 0x04, U 0xE4, U 0x31, U 0x84, U 0x03, U 0x83, U 0x02, @@ -7541,31 +7694,37 @@ static unsigned char t3fw[30136] = { U 0x45, U 0x42, U 0x55, U 0x47, U 0x3D, U 0x30, U 0x20, U 0x28, U 0x42, U 0x75, U 0x69, U 0x6C, - U 0x74, U 0x20, U 0x57, U 0x65, - U 0x64, U 0x20, U 0x4F, U 0x63, - U 0x74, U 0x20, U 0x20, U 0x38, - U 0x20, U 0x31, U 0x35, U 0x3A, - U 0x35, U 0x30, U 0x3A, U 0x35, - U 0x30, U 0x20, U 0x50, U 0x44, + U 0x74, U 0x20, U 0x54, U 0x68, + U 0x75, U 0x20, U 0x4A, U 0x75, + U 0x6C, U 0x20, U 0x33, U 0x30, + U 0x20, U 0x31, U 0x38, U 0x3A, + U 0x31, U 0x33, U 0x3A, U 0x34, + U 0x34, U 0x20, U 0x50, U 0x44, U 0x54, U 0x20, U 0x32, U 0x30, - U 0x30, U 0x38, U 0x20, U 0x6F, + U 0x30, U 0x39, U 0x20, U 0x6F, U 0x6E, U 0x20, U 0x63, U 0x6C, U 0x65, U 0x6F, U 0x70, U 0x61, - U 0x74, U 0x72, U 0x61, U 0x3A, - U 0x2F, U 0x68, U 0x6F, U 0x6D, - U 0x65, U 0x2F, U 0x66, U 0x65, - U 0x6C, U 0x69, U 0x78, U 0x2F, - U 0x77, U 0x2F, U 0x66, U 0x77, - U 0x5F, U 0x37, U 0x2E, U 0x30, + U 0x74, U 0x72, U 0x61, U 0x2E, + U 0x61, U 0x73, U 0x69, U 0x63, + U 0x64, U 0x65, U 0x73, U 0x69, + U 0x67, U 0x6E, U 0x65, U 0x72, + U 0x73, U 0x2E, U 0x63, U 0x6F, + U 0x6D, U 0x3A, U 0x2F, U 0x68, + U 0x6F, U 0x6D, U 0x65, U 0x2F, + U 0x66, U 0x65, U 0x6C, U 0x69, + U 0x78, U 0x2F, U 0x77, U 0x2F, + U 0x66, U 0x77, U 0x5F, U 0x37, + U 0x2E, U 0x34, U 0x2D, U 0x73, + U 0x74, U 0x65, U 0x76, U 0x65, U 0x29, U 0x2C, U 0x20, U 0x56, U 0x65, U 0x72, U 0x73, U 0x69, U 0x6F, U 0x6E, U 0x20, U 0x54, U 0x33, U 0x78, U 0x78, U 0x20, U 0x30, U 0x30, U 0x37, U 0x2E, - U 0x30, U 0x31, U 0x2E, U 0x30, + U 0x30, U 0x37, U 0x2E, U 0x30, U 0x30, U 0x20, U 0x2D, U 0x20, U 0x31, U 0x30, U 0x30, U 0x37, - U 0x30, U 0x31, U 0x30, U 0x30, - U 0x10, U 0x07, U 0x01, U 0x00, - U 0x6F, U 0x4E, U 0xF8, U 0xBB, + U 0x30, U 0x37, U 0x30, U 0x30, + U 0x10, U 0x07, U 0x07, U 0x00, + U 0xE5, U 0xF4, U 0xC5, U 0x92, }; diff --git a/sys/modules/cxgb/cxgb/Makefile b/sys/modules/cxgb/cxgb/Makefile index 8a5791c358f..65b2f6f4934 100644 --- a/sys/modules/cxgb/cxgb/Makefile +++ b/sys/modules/cxgb/cxgb/Makefile @@ -5,7 +5,7 @@ CXGB = ${.CURDIR}/../../../dev/cxgb KMOD= if_cxgb SRCS= cxgb_mc5.c cxgb_vsc8211.c cxgb_ael1002.c cxgb_mv88e1xxx.c -SRCS+= cxgb_xgmac.c cxgb_vsc7323.c cxgb_t3_hw.c cxgb_main.c +SRCS+= cxgb_xgmac.c cxgb_vsc7323.c cxgb_t3_hw.c cxgb_main.c cxgb_aq100x.c SRCS+= cxgb_sge.c cxgb_offload.c cxgb_tn1010.c SRCS+= device_if.h bus_if.h pci_if.h SRCS+= opt_inet.h opt_zero.h opt_sched.h From 8b8a820dedc81e60a85c0169b71aad82564e9352 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 5 Oct 2009 21:11:04 +0000 Subject: [PATCH 061/646] fts_open() requires that the list passed as argument to contain at least one path. When the list is empty (contain only a NULL pointer), return EINVAL instead of pretending to succeed, which will cause a NULL pointer deference in a later fts_read() call. Noticed by: Christoph Mallon (via rdivacky@) MFC after: 2 weeks --- lib/libc/gen/fts.3 | 4 ++-- lib/libc/gen/fts.c | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index 8e1a1e42269..dfe2de02dce 100644 --- a/lib/libc/gen/fts.3 +++ b/lib/libc/gen/fts.3 @@ -28,7 +28,7 @@ .\" @(#)fts.3 8.5 (Berkeley) 4/16/94 .\" $FreeBSD$ .\" -.Dd January 26, 2008 +.Dd October 5, 2009 .Dt FTS 3 .Os .Sh NAME @@ -776,7 +776,7 @@ may fail and set as follows: .Bl -tag -width Er .It Bq Er EINVAL -The options were invalid. +The options were invalid, or the list were empty. .El .Sh SEE ALSO .Xr find 1 , diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index 41443c5795c..392bda94138 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -124,6 +124,12 @@ fts_open(argv, options, compar) return (NULL); } + /* fts_open() requires at least one path */ + if (*argv == NULL) { + errno = EINVAL; + return (NULL); + } + /* Allocate/initialize the stream. */ if ((priv = malloc(sizeof(*priv))) == NULL) return (NULL); From 604f19c91ec0a9b1b5727a71023b926a4b462420 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 22:23:12 +0000 Subject: [PATCH 062/646] Fix build on amd64, where sysctl arg1 is a pointer. Reported by: Mr Tinderbox MFC after: 3 months --- sys/kern/uipc_usrreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 598080171ab..fdf3d902509 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1468,7 +1468,7 @@ unp_pcblist(SYSCTL_HANDLER_ARGS) break; default: - panic("unp_pcblist: arg1 %d", (intptr_t)arg1); + panic("unp_pcblist: arg1 %d", (int)(intptr_t)arg1); } /* From 883e9bc41d25f6a4a95e674455f88751814c8408 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 5 Oct 2009 22:24:13 +0000 Subject: [PATCH 063/646] In tcp_input(), we acquire a global write lock at first only if a segment is likely to trigger a TCP state change (i.e., FIN/RST/SYN). If we later have to upgrade the lock, we acquire an inpcb reference and drop both global/inpcb locks before reacquiring in-order. In that gap, the connection may transition into TIMEWAIT, so we need to loop back and reevaluate the inpcb after relocking. MFC after: 3 days Reported by: Kamigishi Rei Reviewed by: bz --- sys/netinet/tcp_input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 470d782ee5e..586a60ccbfc 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -648,6 +648,7 @@ findpcb: * tried to free the inpcb, in which case we need to loop back and * try to find a new inpcb to deliver to. */ +relocked: if (inp->inp_flags & INP_TIMEWAIT) { KASSERT(ti_locked == TI_RLOCKED || ti_locked == TI_WLOCKED, ("%s: INP_TIMEWAIT ti_locked %d", __func__, ti_locked)); @@ -698,7 +699,8 @@ findpcb: * We've identified a valid inpcb, but it could be that we need an * inpcbinfo write lock and have only a read lock. In this case, * attempt to upgrade/relock using the same strategy as the TIMEWAIT - * case above. + * case above. If we relock, we have to jump back to 'relocked' as + * the connection might now be in TIMEWAIT. */ if (tp->t_state != TCPS_ESTABLISHED || (thflags & (TH_SYN | TH_FIN | TH_RST)) != 0 || @@ -720,6 +722,7 @@ findpcb: goto findpcb; } tcp_wlock_relocked++; + goto relocked; } else { ti_locked = TI_WLOCKED; tcp_wlock_upgraded++; From 0f3d628ce320b4522e92998c1b018bb79b8bd2cc Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Tue, 6 Oct 2009 02:13:32 +0000 Subject: [PATCH 064/646] "Potluck Pogo" was a collection of Walt Kelly's "Pogo" cartoons first published in 1955. "Putluck Pogo" seems to be a typo. --- games/fortune/datfiles/fortunes | 2 +- games/fortune/datfiles/fortunes.sp.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes index de09c960db7..057bdeb1be1 100644 --- a/games/fortune/datfiles/fortunes +++ b/games/fortune/datfiles/fortunes @@ -18126,7 +18126,7 @@ tail on me, go ahead. They'd be very bored. commenting on rumors of womanizing. % Food for thought is no substitute for the real thing. - -- Walt Kelly, "Putluck Pogo" + -- Walt Kelly, "Potluck Pogo" % Foolproof Operation: No provision for adjustment. diff --git a/games/fortune/datfiles/fortunes.sp.ok b/games/fortune/datfiles/fortunes.sp.ok index ffe8b3c9c33..f26b5e3798f 100644 --- a/games/fortune/datfiles/fortunes.sp.ok +++ b/games/fortune/datfiles/fortunes.sp.ok @@ -3300,6 +3300,7 @@ postjudice Postnews Postpetroleum potholes +Potluck potty Poul Pournelle @@ -3376,7 +3377,6 @@ Purshottam PUSHes pushy pussycats -Putluck Putt's PVLC PxP From a903af238c91077b258b8ddd130163bb9488ddf3 Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Tue, 6 Oct 2009 04:57:18 +0000 Subject: [PATCH 065/646] o Fix typo: "an in particular" -> "and in particular". PR: docs/139370 Submitted by: Kenyon Ralph MFC after: 1 week --- share/man/man4/de.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/de.4 b/share/man/man4/de.4 index eeca37665f4..28287ef3c11 100644 --- a/share/man/man4/de.4 +++ b/share/man/man4/de.4 @@ -88,7 +88,7 @@ setup utility and are not changeable. .Pp Use the .Xr ifconfig 8 -command an in particular the +command and in particular the .Fl m flag to list the supported media types for your particular card. .Pp From 86d2e48c22258b9e93b6e5add32a20d60ecfc412 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 6 Oct 2009 13:45:49 +0000 Subject: [PATCH 067/646] Per their definition, atomic instructions used in conjuction with memory barriers should also ensure that the compiler doesn't reorder paths where they are used. GCC, however, does that aggressively, even in presence of volatile operands. The most reliable way GCC offers for avoid instructions reordering is clobbering "memory" even if that is theoretically an heavy-weight operation, flushing the content of all the registers and forcing reload of them (We could rely, however, on gcc DTRT by just understanding the purpose as this is a well-known pattern for many modern operating-systems). Not all our memory barriers, right now, clobber memory for GCC-like compilers. The most notable cases are IA32 and amd64 where the memory barrier are treacted the same as normal atomic instructions. Fix this by offering the possibility to implement atomic instructions with memory barriers separately from the normal version and implement the GCC-like specific one using memory clobbering. Thanks to Chris Lattner (@apple) for his discussion on llvm specifics. Reported by: jhb Reviewed by: jhb Tested by: rdivacky, Giovanni Trematerra --- sys/amd64/include/atomic.h | 107 +++++++++++++++++++++-------------- sys/i386/include/atomic.h | 113 +++++++++++++++++++++++-------------- 2 files changed, 134 insertions(+), 86 deletions(-) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index d2a3846172d..4c415deee3d 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -73,10 +73,13 @@ */ #if defined(KLD_MODULE) || !defined(__GNUCLIKE_ASM) #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ -void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) +void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \ +void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); +int atomic_cmpset_barr_int(volatile u_int *dst, u_int exp, u_int src); +int atomic_cmpset_barr_long(volatile u_long *dst, u_long exp, u_long src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); u_long atomic_fetchadd_long(volatile u_long *p, u_long v); @@ -97,8 +100,9 @@ void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) #endif /* - * The assembly is volatilized to demark potential before-and-after side - * effects if an interrupt or SMP collision were to occur. + * The assembly is volatilized to avoid code chunk removal by the compiler. + * GCC aggressively reorders operations and memory clobbering is necessary + * in order to avoid that for memory barriers. */ #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ static __inline void \ @@ -107,6 +111,15 @@ atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ __asm __volatile(MPLOCKED OP \ : "=m" (*p) \ : CONS (V), "m" (*p)); \ +} \ + \ +static __inline void \ +atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ +{ \ + __asm __volatile(MPLOCKED OP \ + : "=m" (*p) \ + : CONS (V), "m" (*p) \ + : "memory"); \ } \ struct __hack @@ -160,6 +173,9 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) return (res); } +#define atomic_cmpset_barr_int atomic_cmpset_int +#define atomic_cmpset_barr_long atomic_cmpset_long + /* * Atomically add the value of v to the integer pointed to by p and return * the previous value of *p. @@ -205,18 +221,23 @@ atomic_fetchadd_long(volatile u_long *p, u_long v) * PentiumPro or higher, reads may pass writes, so for that case we have * to use a serializing instruction (i.e. with LOCK) to do the load in * SMP kernels. For UP kernels, however, the cache of the single processor - * is always consistent, so we don't need any memory barriers. + * is always consistent, so we only need to take care of compiler. */ #define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ static __inline u_##TYPE \ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ { \ - return (*p); \ + u_##TYPE tmp; \ + \ + tmp = *p; \ + __asm __volatile ("" : : : "memory"); \ + return (tmp); \ } \ \ static __inline void \ atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ { \ + __asm __volatile ("" : : : "memory"); \ *p = v; \ } \ struct __hack @@ -247,7 +268,8 @@ atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ __asm __volatile(SOP \ : "=m" (*p), /* 0 */ \ "+r" (v) /* 1 */ \ - : "m" (*p)); /* 2 */ \ + : "m" (*p) /* 2 */ \ + : "memory"); \ } \ struct __hack @@ -327,46 +349,45 @@ u_long atomic_readandclear_long(volatile u_long *addr); #endif /* __GNUCLIKE_ASM */ -/* Acquire and release variants are identical to the normal ones. */ -#define atomic_set_acq_char atomic_set_char -#define atomic_set_rel_char atomic_set_char -#define atomic_clear_acq_char atomic_clear_char -#define atomic_clear_rel_char atomic_clear_char -#define atomic_add_acq_char atomic_add_char -#define atomic_add_rel_char atomic_add_char -#define atomic_subtract_acq_char atomic_subtract_char -#define atomic_subtract_rel_char atomic_subtract_char +#define atomic_set_acq_char atomic_set_barr_char +#define atomic_set_rel_char atomic_set_barr_char +#define atomic_clear_acq_char atomic_clear_barr_char +#define atomic_clear_rel_char atomic_clear_barr_char +#define atomic_add_acq_char atomic_add_barr_char +#define atomic_add_rel_char atomic_add_barr_char +#define atomic_subtract_acq_char atomic_subtract_barr_char +#define atomic_subtract_rel_char atomic_subtract_barr_char -#define atomic_set_acq_short atomic_set_short -#define atomic_set_rel_short atomic_set_short -#define atomic_clear_acq_short atomic_clear_short -#define atomic_clear_rel_short atomic_clear_short -#define atomic_add_acq_short atomic_add_short -#define atomic_add_rel_short atomic_add_short -#define atomic_subtract_acq_short atomic_subtract_short -#define atomic_subtract_rel_short atomic_subtract_short +#define atomic_set_acq_short atomic_set_barr_short +#define atomic_set_rel_short atomic_set_barr_short +#define atomic_clear_acq_short atomic_clear_barr_short +#define atomic_clear_rel_short atomic_clear_barr_short +#define atomic_add_acq_short atomic_add_barr_short +#define atomic_add_rel_short atomic_add_barr_short +#define atomic_subtract_acq_short atomic_subtract_barr_short +#define atomic_subtract_rel_short atomic_subtract_barr_short -#define atomic_set_acq_int atomic_set_int -#define atomic_set_rel_int atomic_set_int -#define atomic_clear_acq_int atomic_clear_int -#define atomic_clear_rel_int atomic_clear_int -#define atomic_add_acq_int atomic_add_int -#define atomic_add_rel_int atomic_add_int -#define atomic_subtract_acq_int atomic_subtract_int -#define atomic_subtract_rel_int atomic_subtract_int -#define atomic_cmpset_acq_int atomic_cmpset_int -#define atomic_cmpset_rel_int atomic_cmpset_int +#define atomic_set_acq_int atomic_set_barr_int +#define atomic_set_rel_int atomic_set_barr_int +#define atomic_clear_acq_int atomic_clear_barr_int +#define atomic_clear_rel_int atomic_clear_barr_int +#define atomic_add_acq_int atomic_add_barr_int +#define atomic_add_rel_int atomic_add_barr_int +#define atomic_subtract_acq_int atomic_subtract_barr_int +#define atomic_subtract_rel_int atomic_subtract_barr_int +#define atomic_cmpset_acq_int atomic_cmpset_barr_int +#define atomic_cmpset_rel_int atomic_cmpset_barr_int -#define atomic_set_acq_long atomic_set_long -#define atomic_set_rel_long atomic_set_long -#define atomic_clear_acq_long atomic_clear_long -#define atomic_clear_rel_long atomic_clear_long -#define atomic_add_acq_long atomic_add_long -#define atomic_add_rel_long atomic_add_long -#define atomic_subtract_acq_long atomic_subtract_long -#define atomic_subtract_rel_long atomic_subtract_long -#define atomic_cmpset_acq_long atomic_cmpset_long -#define atomic_cmpset_rel_long atomic_cmpset_long +#define atomic_set_acq_long atomic_set_barr_long +#define atomic_set_rel_long atomic_set_barr_long +#define atomic_clear_acq_long atomic_clear_barr_long +#define atomic_clear_rel_long atomic_clear_barr_long +#define atomic_add_acq_long atomic_add_barr_long +#define atomic_add_rel_long atomic_add_barr_long +#define atomic_subtract_acq_long atomic_subtract_barr_long +#define atomic_subtract_rel_long atomic_subtract_barr_long +#define atomic_cmpset_acq_long atomic_cmpset_barr_long +#define atomic_cmpset_rel_long atomic_cmpset_barr_long /* Operations on 8-bit bytes. */ #define atomic_set_8 atomic_set_char diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index 8c0b95ce069..e19ed7890b0 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -73,9 +73,11 @@ */ #if defined(KLD_MODULE) || !defined(__GNUCLIKE_ASM) #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ -void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) +void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \ +void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); +int atomic_cmpset_barr_int(volatile u_int *dst, u_int exp, u_int src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); #define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ @@ -95,8 +97,9 @@ void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) #endif /* - * The assembly is volatilized to demark potential before-and-after side - * effects if an interrupt or SMP collision were to occur. + * The assembly is volatilized to avoid code chunk removal by the compiler. + * GCC aggressively reorders operations and memory clobbering is necessary + * in order to avoid that for memory barriers. */ #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ static __inline void \ @@ -105,6 +108,15 @@ atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ __asm __volatile(MPLOCKED OP \ : "=m" (*p) \ : CONS (V), "m" (*p)); \ +} \ + \ +static __inline void \ +atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ +{ \ + __asm __volatile(MPLOCKED OP \ + : "=m" (*p) \ + : CONS (V), "m" (*p) \ + : "memory"); \ } \ struct __hack @@ -168,6 +180,8 @@ atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) #endif /* CPU_DISABLE_CMPXCHG */ +#define atomic_cmpset_barr_int atomic_cmpset_int + /* * Atomically add the value of v to the integer pointed to by p and return * the previous value of *p. @@ -194,18 +208,23 @@ atomic_fetchadd_int(volatile u_int *p, u_int v) * PentiumPro or higher, reads may pass writes, so for that case we have * to use a serializing instruction (i.e. with LOCK) to do the load in * SMP kernels. For UP kernels, however, the cache of the single processor - * is always consistent, so we don't need any memory barriers. + * is always consistent, so we only need to take care of compiler. */ #define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ static __inline u_##TYPE \ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ { \ - return (*p); \ + u_##TYPE tmp; \ + \ + tmp = *p; \ + __asm __volatile("" : : : "memory"); \ + return (tmp); \ } \ \ static __inline void \ atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ { \ + __asm __volatile("" : : : "memory"); \ *p = v; \ } \ struct __hack @@ -236,7 +255,8 @@ atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ __asm __volatile(SOP \ : "=m" (*p), /* 0 */ \ "+r" (v) /* 1 */ \ - : "m" (*p)); /* 2 */ \ + : "m" (*p) /* 2 */ \ + : "memory"); \ } \ struct __hack @@ -282,6 +302,14 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) (u_int)src)); } +static __inline int +atomic_cmpset_barr_long(volatile u_long *dst, u_long exp, u_long src) +{ + + return (atomic_cmpset_barr_int((volatile u_int *)dst, (u_int)exp, + (u_int)src)); +} + static __inline u_long atomic_fetchadd_long(volatile u_long *p, u_long v) { @@ -331,46 +359,45 @@ u_long atomic_readandclear_long(volatile u_long *addr); #endif /* __GNUCLIKE_ASM */ -/* Acquire and release variants are identical to the normal ones. */ -#define atomic_set_acq_char atomic_set_char -#define atomic_set_rel_char atomic_set_char -#define atomic_clear_acq_char atomic_clear_char -#define atomic_clear_rel_char atomic_clear_char -#define atomic_add_acq_char atomic_add_char -#define atomic_add_rel_char atomic_add_char -#define atomic_subtract_acq_char atomic_subtract_char -#define atomic_subtract_rel_char atomic_subtract_char +#define atomic_set_acq_char atomic_set_barr_char +#define atomic_set_rel_char atomic_set_barr_char +#define atomic_clear_acq_char atomic_clear_barr_char +#define atomic_clear_rel_char atomic_clear_barr_char +#define atomic_add_acq_char atomic_add_barr_char +#define atomic_add_rel_char atomic_add_barr_char +#define atomic_subtract_acq_char atomic_subtract_barr_char +#define atomic_subtract_rel_char atomic_subtract_barr_char -#define atomic_set_acq_short atomic_set_short -#define atomic_set_rel_short atomic_set_short -#define atomic_clear_acq_short atomic_clear_short -#define atomic_clear_rel_short atomic_clear_short -#define atomic_add_acq_short atomic_add_short -#define atomic_add_rel_short atomic_add_short -#define atomic_subtract_acq_short atomic_subtract_short -#define atomic_subtract_rel_short atomic_subtract_short +#define atomic_set_acq_short atomic_set_barr_short +#define atomic_set_rel_short atomic_set_barr_short +#define atomic_clear_acq_short atomic_clear_barr_short +#define atomic_clear_rel_short atomic_clear_barr_short +#define atomic_add_acq_short atomic_add_barr_short +#define atomic_add_rel_short atomic_add_barr_short +#define atomic_subtract_acq_short atomic_subtract_barr_short +#define atomic_subtract_rel_short atomic_subtract_barr_short -#define atomic_set_acq_int atomic_set_int -#define atomic_set_rel_int atomic_set_int -#define atomic_clear_acq_int atomic_clear_int -#define atomic_clear_rel_int atomic_clear_int -#define atomic_add_acq_int atomic_add_int -#define atomic_add_rel_int atomic_add_int -#define atomic_subtract_acq_int atomic_subtract_int -#define atomic_subtract_rel_int atomic_subtract_int -#define atomic_cmpset_acq_int atomic_cmpset_int -#define atomic_cmpset_rel_int atomic_cmpset_int +#define atomic_set_acq_int atomic_set_barr_int +#define atomic_set_rel_int atomic_set_barr_int +#define atomic_clear_acq_int atomic_clear_barr_int +#define atomic_clear_rel_int atomic_clear_barr_int +#define atomic_add_acq_int atomic_add_barr_int +#define atomic_add_rel_int atomic_add_barr_int +#define atomic_subtract_acq_int atomic_subtract_barr_int +#define atomic_subtract_rel_int atomic_subtract_barr_int +#define atomic_cmpset_acq_int atomic_cmpset_barr_int +#define atomic_cmpset_rel_int atomic_cmpset_barr_int -#define atomic_set_acq_long atomic_set_long -#define atomic_set_rel_long atomic_set_long -#define atomic_clear_acq_long atomic_clear_long -#define atomic_clear_rel_long atomic_clear_long -#define atomic_add_acq_long atomic_add_long -#define atomic_add_rel_long atomic_add_long -#define atomic_subtract_acq_long atomic_subtract_long -#define atomic_subtract_rel_long atomic_subtract_long -#define atomic_cmpset_acq_long atomic_cmpset_long -#define atomic_cmpset_rel_long atomic_cmpset_long +#define atomic_set_acq_long atomic_set_barr_long +#define atomic_set_rel_long atomic_set_barr_long +#define atomic_clear_acq_long atomic_clear_barr_long +#define atomic_clear_rel_long atomic_clear_barr_long +#define atomic_add_acq_long atomic_add_barr_long +#define atomic_add_rel_long atomic_add_barr_long +#define atomic_subtract_acq_long atomic_subtract_barr_long +#define atomic_subtract_rel_long atomic_subtract_barr_long +#define atomic_cmpset_acq_long atomic_cmpset_barr_long +#define atomic_cmpset_rel_long atomic_cmpset_barr_long /* Operations on 8-bit bytes. */ #define atomic_set_8 atomic_set_char From a502a84d5a0d6c3cf180278d39bf25bbf5313fd9 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 6 Oct 2009 14:05:57 +0000 Subject: [PATCH 068/646] Add basename_r(3) to complement basename(3). basename_r(3) which accepts a caller-allocated buffer of at least MAXPATHLEN, rather than using a global buffer. MFC after: 1 month Sponsored by: Google --- include/libgen.h | 1 + lib/libc/gen/Makefile.inc | 1 + lib/libc/gen/Symbol.map | 1 + lib/libc/gen/basename.3 | 20 +++++++++++++++----- lib/libc/gen/basename.c | 24 ++++++++++++++++-------- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/include/libgen.h b/include/libgen.h index 3639c712b9f..0d4472f0168 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -36,6 +36,7 @@ __BEGIN_DECLS char *basename(const char *); +char *basename_r(const char *, char *); char *dirname(const char *); #if 0 char *regcmp(const char *, ...); diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index b06f846dd47..dd9af85c637 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -76,6 +76,7 @@ MAN+= alarm.3 arc4random.3 \ MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 \ arc4random.3 arc4random_buf.3 arc4random.3 arc4random_uniform.3 +MLINKS+=basename.3 basename_r.3 MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=devname.3 devname_r.3 MLINKS+=devname.3 fdevname.3 diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 197430acdda..6fb61b18baf 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -367,6 +367,7 @@ FBSD_1.1 { }; FBSD_1.2 { + basename_r; getpagesizes; }; diff --git a/lib/libc/gen/basename.3 b/lib/libc/gen/basename.3 index 33a0a717d91..4a3743a8634 100644 --- a/lib/libc/gen/basename.3 +++ b/lib/libc/gen/basename.3 @@ -27,7 +27,7 @@ .\" $OpenBSD: basename.3,v 1.12 2000/04/18 03:01:25 aaron Exp $ .\" $FreeBSD$ .\" -.Dd October 12, 2006 +.Dd October 6, 2009 .Dt BASENAME 3 .Os .Sh NAME @@ -37,6 +37,8 @@ .In libgen.h .Ft char * .Fn basename "const char *path" +.Ft char * +.Fn basename_r "const char *path" "char *bname" .Sh DESCRIPTION The .Fn basename @@ -58,6 +60,12 @@ If is a null pointer or the empty string, a pointer to the string .Qq \&. is returned. +.Pp +The +.Fn basename_r +variation accepts a buffer of at least +.Dv MAXPATHLEN +bytes in which to store the resulting component. .Sh IMPLEMENTATION NOTES The .Fn basename @@ -65,15 +73,17 @@ function returns a pointer to internal storage space allocated on the first call that will be overwritten by subsequent calls. +.Fn basename_r +is therefore preferred for threaded applications. .Sh RETURN VALUES On successful completion, .Fn basename -returns a pointer to the last component of +and +.Fn basename_r +return pointers to the last component of .Fa path . .Pp -If -.Fn basename -fails, a null pointer is returned and the global variable +If they fail, a null pointer is returned and the global variable .Va errno is set to indicate the error. .Sh ERRORS diff --git a/lib/libc/gen/basename.c b/lib/libc/gen/basename.c index 9552ab34866..9588c282bcf 100644 --- a/lib/libc/gen/basename.c +++ b/lib/libc/gen/basename.c @@ -40,18 +40,12 @@ __FBSDID("$FreeBSD$"); #include char * -basename(path) +basename_r(path, bname) const char *path; + char *bname; { - static char *bname = NULL; const char *endp, *startp; - if (bname == NULL) { - bname = (char *)malloc(MAXPATHLEN); - if (bname == NULL) - return(NULL); - } - /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { (void)strcpy(bname, "."); @@ -82,3 +76,17 @@ basename(path) bname[endp - startp + 1] = '\0'; return(bname); } + +char * +basename(path) + const char *path; +{ + static char *bname = NULL; + + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return (NULL); + } + return (basename_r(path, bname)); +} From 1c232cd509c1fd9cb772bd829c3a220a5a6379bb Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 6 Oct 2009 17:14:39 +0000 Subject: [PATCH 069/646] In rtld's map_object(), use pread(..., 0) rather than read() to read the ELF header from the front of the file. As all other I/O on the binary is done using mmap(), this avoids the need for seek privileges on the file descriptor during run-time linking. MFC after: 1 month Sponsored by: Google --- libexec/rtld-elf/map_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 6de0c9e1a3d..d231830b351 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -273,7 +273,7 @@ get_elf_header (int fd, const char *path) } u; ssize_t nbytes; - if ((nbytes = read(fd, u.buf, PAGE_SIZE)) == -1) { + if ((nbytes = pread(fd, u.buf, PAGE_SIZE, 0)) == -1) { _rtld_error("%s: read error: %s", path, strerror(errno)); return NULL; } From e05b498065eaf49cc392b0315a26fe8f416b8ac1 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Tue, 6 Oct 2009 20:19:16 +0000 Subject: [PATCH 070/646] Fix tcsh losing history when tcsh terminates because the pty beneath it is closed. Diagnosed by Ted Anderson: New signal queuing logic was introduced in 6.15 and allows the signal handlers to be run explicitly by calling handle_pending_signals, instead of immediately when the signal is delivered. This function is called at various places, typically when receiving a EINTR from a slow system call such as read or write. In the pty exit case, it was called from xwrite, called from flush, while printing the "exit" message after receiving EOF when reading from the pty (note that the read did not return EINTR but zero bytes, indicating EOF). The SIGHUP handler, phup(), called rechist, which opened the history file and began writing the merged history to it. This process invoked flush recursively to actually write the data. In this case, however, the flush noticed it was being called recursively and decided fail by calling stderror. My conclusion was that the signal was being handled at a bad time. But whether to fix flush not to care about the recursive call, or to handle the signal some other time and when to handle it, was unclear to me. However, by adding an extra call to handle_pending_signals, just after process() returns to main(), I was able to avoid the truncated history after network outages and similar failures. I verified this fix in version 6.17. Approved by: ed (mentor) MFC after: 1 week --- contrib/tcsh/sh.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/tcsh/sh.c b/contrib/tcsh/sh.c index 73b6d7f5483..f90eeab1942 100644 --- a/contrib/tcsh/sh.c +++ b/contrib/tcsh/sh.c @@ -1291,6 +1291,8 @@ main(int argc, char **argv) /* * Mop-up. */ + /* Take care of these (especially HUP) here instead of inside flush. */ + handle_pending_signals(); if (intty) { if (loginsh) { xprintf("logout\n"); From f681a5fdd44a8b95b087ecbe25ec71bfde9b85b3 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 6 Oct 2009 20:35:41 +0000 Subject: [PATCH 071/646] Remove tcp_input lock statistics; these are intended for debugging only and are not intended to ship in 8.0 as they dirty additional cache lines in a performance-critical per-packet path. MFC after: 3 days --- sys/netinet/tcp_input.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 586a60ccbfc..09f834bcabd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -180,26 +180,6 @@ int tcp_read_locking = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, read_locking, CTLFLAG_RW, &tcp_read_locking, 0, "Enable read locking strategy"); -int tcp_rlock_atfirst; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, rlock_atfirst, CTLFLAG_RD, - &tcp_rlock_atfirst, 0, ""); - -int tcp_wlock_atfirst; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_wlock_atfirst, CTLFLAG_RD, - &tcp_wlock_atfirst, 0, ""); - -int tcp_wlock_upgraded; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, wlock_upgraded, CTLFLAG_RD, - &tcp_wlock_upgraded, 0, ""); - -int tcp_wlock_relocked; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, wlock_relocked, CTLFLAG_RD, - &tcp_wlock_relocked, 0, ""); - -int tcp_wlock_looped; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, wlock_looped, CTLFLAG_RD, - &tcp_wlock_looped, 0, ""); - VNET_DEFINE(struct inpcbhead, tcb); VNET_DEFINE(struct inpcbinfo, tcbinfo); #define tcb6 tcb /* for KAME src sync over BSD*'s */ @@ -505,11 +485,9 @@ tcp_input(struct mbuf *m, int off0) tcp_read_locking == 0) { INP_INFO_WLOCK(&V_tcbinfo); ti_locked = TI_WLOCKED; - tcp_wlock_atfirst++; } else { INP_INFO_RLOCK(&V_tcbinfo); ti_locked = TI_RLOCKED; - tcp_rlock_atfirst++; } findpcb: @@ -662,15 +640,11 @@ relocked: ti_locked = TI_WLOCKED; INP_WLOCK(inp); if (in_pcbrele(inp)) { - tcp_wlock_looped++; inp = NULL; goto findpcb; } - tcp_wlock_relocked++; - } else { + } else ti_locked = TI_WLOCKED; - tcp_wlock_upgraded++; - } } INP_INFO_WLOCK_ASSERT(&V_tcbinfo); @@ -717,16 +691,12 @@ relocked: ti_locked = TI_WLOCKED; INP_WLOCK(inp); if (in_pcbrele(inp)) { - tcp_wlock_looped++; inp = NULL; goto findpcb; } - tcp_wlock_relocked++; goto relocked; - } else { + } else ti_locked = TI_WLOCKED; - tcp_wlock_upgraded++; - } } INP_INFO_WLOCK_ASSERT(&V_tcbinfo); } From e6b112e27422734806e073dc5c1fd6c516c7f687 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Tue, 6 Oct 2009 21:40:50 +0000 Subject: [PATCH 072/646] Prevent paging pressure from draining arc too much - always drain arc if above arc_c_max - never drain arc if arc is below arc_c_max MFC after: 3 days --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 64fded4712e..83a4c97f8af 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1821,6 +1821,12 @@ arc_reclaim_needed(void) #endif #ifdef _KERNEL + if (needfree) + return (1); + if (arc_size > arc_c_max) + return (1); + if (arc_size <= arc_c_min) + return (0); /* * If pages are needed or we're within 2048 pages @@ -1829,9 +1835,6 @@ arc_reclaim_needed(void) if (vm_pages_needed || (vm_paging_target() > -2048)) return (1); - if (needfree) - return (1); - #if 0 /* * take 'desfree' extra pages, so we reclaim sooner, rather than later From 640b70e414ec45099bd3a63268b56013fb640004 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 6 Oct 2009 22:00:14 +0000 Subject: [PATCH 073/646] sh: Send the "xyz: not found" message to redirected fd 2. This also fixes that trying to execute a non-regular file with a command name without '/' returns 127 instead of 126. The fix is rather simplistic: treat CMDUNKNOWN as if the command were found as an external program. The resulting fork is a bit wasteful but executing unknown commands should not be very frequent. PR: bin/137659 --- bin/sh/eval.c | 9 ++---- bin/sh/exec.c | 1 + tools/regression/bin/sh/execution/unknown1.0 | 29 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 tools/regression/bin/sh/execution/unknown1.0 diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 7978b84f051..5ba244d76e4 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -713,12 +713,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) do_clearcmdentry = 1; } - find_command(argv[0], &cmdentry, 1, path); - if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ - exitstatus = 127; - flushout(&errout); - return; - } + find_command(argv[0], &cmdentry, 0, path); /* implement the bltin builtin here */ if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) { for (;;) { @@ -740,7 +735,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) /* Fork off a child process if necessary. */ if (cmd->ncmd.backgnd - || (cmdentry.cmdtype == CMDNORMAL + || ((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN) && ((flags & EV_EXIT) == 0 || have_traps())) || ((flags & EV_BACKCMD) != 0 && (cmdentry.cmdtype != CMDBUILTIN diff --git a/bin/sh/exec.c b/bin/sh/exec.c index 810782166a9..f9d3c221a3a 100644 --- a/bin/sh/exec.c +++ b/bin/sh/exec.c @@ -429,6 +429,7 @@ loop: outfmt(out2, "%s: %s\n", name, strerror(e)); } entry->cmdtype = CMDUNKNOWN; + entry->u.index = 0; return; success: diff --git a/tools/regression/bin/sh/execution/unknown1.0 b/tools/regression/bin/sh/execution/unknown1.0 new file mode 100644 index 00000000000..45f541e6eee --- /dev/null +++ b/tools/regression/bin/sh/execution/unknown1.0 @@ -0,0 +1,29 @@ +# $FreeBSD$ + +nosuchtool 2>/dev/null +[ $? -ne 127 ] && exit 1 +/var/empty/nosuchtool 2>/dev/null +[ $? -ne 127 ] && exit 1 +(nosuchtool) 2>/dev/null +[ $? -ne 127 ] && exit 1 +(/var/empty/nosuchtool) 2>/dev/null +[ $? -ne 127 ] && exit 1 +/ 2>/dev/null +[ $? -ne 126 ] && exit 1 +PATH=/usr bin 2>/dev/null +[ $? -ne 126 ] && exit 1 + +dummy=$(nosuchtool 2>/dev/null) +[ $? -ne 127 ] && exit 1 +dummy=$(/var/empty/nosuchtool 2>/dev/null) +[ $? -ne 127 ] && exit 1 +dummy=$( (nosuchtool) 2>/dev/null) +[ $? -ne 127 ] && exit 1 +dummy=$( (/var/empty/nosuchtool) 2>/dev/null) +[ $? -ne 127 ] && exit 1 +dummy=$(/ 2>/dev/null) +[ $? -ne 126 ] && exit 1 +dummy=$(PATH=/usr bin 2>/dev/null) +[ $? -ne 126 ] && exit 1 + +exit 0 From d9492a4483f9190a1fd80ef4f3bdedff261ad9fb Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 6 Oct 2009 23:48:28 +0000 Subject: [PATCH 074/646] - All the functions in atomic.h needs to be in "physical" form (like not defined through macros or similar) in order to be later compiled in the kernel and offer this way the support for modules (and compatibility among the UP case and SMP case). Fix this for the newly introduced atomic_cmpset_barr_* cases by defining and specifying a template. Note that the new DEFINE_CMPSET_GEN() template save more typing on amd64 than the current code. [1] - Fix the style for memory barriers on amd64. [1] Reported by: Paul B. Mahol --- sys/amd64/include/atomic.h | 75 ++++++++++++------------------ sys/i386/include/atomic.h | 95 ++++++++++++++++++++------------------ 2 files changed, 79 insertions(+), 91 deletions(-) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 4c415deee3d..7d7199c9d7e 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -32,9 +32,9 @@ #error this file needs sys/cdefs.h as a prerequisite #endif -#define mb() __asm__ __volatile__ ("mfence;": : :"memory") -#define wmb() __asm__ __volatile__ ("sfence;": : :"memory") -#define rmb() __asm__ __volatile__ ("lfence;": : :"memory") +#define mb() __asm __volatile("mfence;" : : : "memory") +#define wmb() __asm __volatile("sfence;" : : : "memory") +#define rmb() __asm __volatile("lfence;" : : : "memory") /* * Various simple operations on memory, each of which is atomic in the @@ -131,50 +131,33 @@ struct __hack * Returns 0 on failure, non-zero on success */ -static __inline int -atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) -{ - u_char res; +#define DEFINE_CMPSET_GEN(NAME, TYPE, OP) \ +static __inline int \ +atomic_cmpset_##NAME(volatile u_##TYPE *dst, u_##TYPE exp, u_##TYPE src)\ +{ \ + u_char res; \ + \ + __asm __volatile( \ + " " MPLOCKED " " \ + " " OP " %2,%1 ; " \ + " sete %0 ; " \ + "1: " \ + "# atomic_cmpset_##NAME" \ + : "=a" (res), /* 0 */ \ + "=m" (*dst) /* 1 */ \ + : "r" (src), /* 2 */ \ + "a" (exp), /* 3 */ \ + "m" (*dst) /* 4 */ \ + : "memory"); \ + \ + return (res); \ +} \ +struct __hack - __asm __volatile( - " " MPLOCKED " " - " cmpxchgl %2,%1 ; " - " sete %0 ; " - "1: " - "# atomic_cmpset_int" - : "=a" (res), /* 0 */ - "=m" (*dst) /* 1 */ - : "r" (src), /* 2 */ - "a" (exp), /* 3 */ - "m" (*dst) /* 4 */ - : "memory"); - - return (res); -} - -static __inline int -atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) -{ - u_char res; - - __asm __volatile( - " " MPLOCKED " " - " cmpxchgq %2,%1 ; " - " sete %0 ; " - "1: " - "# atomic_cmpset_long" - : "=a" (res), /* 0 */ - "=m" (*dst) /* 1 */ - : "r" (src), /* 2 */ - "a" (exp), /* 3 */ - "m" (*dst) /* 4 */ - : "memory"); - - return (res); -} - -#define atomic_cmpset_barr_int atomic_cmpset_int -#define atomic_cmpset_barr_long atomic_cmpset_long +DEFINE_CMPSET_GEN(int, int, "cmpxchgl"); +DEFINE_CMPSET_GEN(long, long, "cmpxchgq"); +DEFINE_CMPSET_GEN(barr_int, int, "cmpxchgl"); +DEFINE_CMPSET_GEN(barr_long, long, "cmpxchgq"); /* * Atomically add the value of v to the integer pointed to by p and return diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index e19ed7890b0..b60f2a14ea9 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -130,57 +130,62 @@ struct __hack #ifdef CPU_DISABLE_CMPXCHG -static __inline int -atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) -{ - u_char res; - - __asm __volatile( - " pushfl ; " - " cli ; " - " cmpl %3,%4 ; " - " jne 1f ; " - " movl %2,%1 ; " - "1: " - " sete %0 ; " - " popfl ; " - "# atomic_cmpset_int" - : "=q" (res), /* 0 */ - "=m" (*dst) /* 1 */ - : "r" (src), /* 2 */ - "r" (exp), /* 3 */ - "m" (*dst) /* 4 */ - : "memory"); - - return (res); -} +#define DEFINE_CMPSET_GEN(NAME) \ +static __inline int \ +atomic_cmpset_##NAME(volatile u_int *dst, u_int exp, u_int src)\ +{ \ + u_char res; \ + \ + __asm __volatile( \ + " pushfl ; " \ + " cli ; " \ + " cmpl %3,%4 ; " \ + " jne 1f ; " \ + " movl %2,%1 ; " \ + "1: " \ + " sete %0 ; " \ + " popfl ; " \ + "# atomic_cmpset_##NAME" \ + : "=q" (res), /* 0 */ \ + "=m" (*dst) /* 1 */ \ + : "r" (src), /* 2 */ \ + "r" (exp), /* 3 */ \ + "m" (*dst) /* 4 */ \ + : "memory"); \ + \ + return (res); \ +} \ +struct __hack #else /* !CPU_DISABLE_CMPXCHG */ -static __inline int -atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) -{ - u_char res; - - __asm __volatile( - " " MPLOCKED " " - " cmpxchgl %2,%1 ; " - " sete %0 ; " - "1: " - "# atomic_cmpset_int" - : "=a" (res), /* 0 */ - "=m" (*dst) /* 1 */ - : "r" (src), /* 2 */ - "a" (exp), /* 3 */ - "m" (*dst) /* 4 */ - : "memory"); - - return (res); -} +#define DEFINE_CMPSET_GEN(NAME) \ +static __inline int \ +atomic_cmpset_##NAME(volatile u_int *dst, u_int exp, u_int src)\ +{ \ + u_char res; \ + \ + __asm __volatile( \ + " " MPLOCKED " " \ + " cmpxchgl %2,%1 ; " \ + " sete %0 ; " \ + "1: " \ + "# atomic_cmpset_##NAME" \ + : "=a" (res), /* 0 */ \ + "=m" (*dst) /* 1 */ \ + : "r" (src), /* 2 */ \ + "a" (exp), /* 3 */ \ + "m" (*dst) /* 4 */ \ + : "memory"); \ + \ + return (res); \ +} \ +struct __hack #endif /* CPU_DISABLE_CMPXCHG */ -#define atomic_cmpset_barr_int atomic_cmpset_int +DEFINE_CMPSET_GEN(int); +DEFINE_CMPSET_GEN(barr_int); /* * Atomically add the value of v to the integer pointed to by p and return From ce3ed1caa182a916189bac5a1eba0208b217bb2b Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Wed, 7 Oct 2009 09:07:06 +0000 Subject: [PATCH 075/646] Add parsing code for TCP UTO (User Timeout Option). Submitted by: fangwang@ Obtained from: //depot/projects/soc2009/tcputo/ --- contrib/tcpdump/print-tcp.c | 12 ++++++++++++ contrib/tcpdump/tcp.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/contrib/tcpdump/print-tcp.c b/contrib/tcpdump/print-tcp.c index 5b0a7969a58..4200c319372 100644 --- a/contrib/tcpdump/print-tcp.c +++ b/contrib/tcpdump/print-tcp.c @@ -124,6 +124,7 @@ struct tok tcp_option_values[] = { { TCPOPT_CCECHO, "" }, { TCPOPT_SIGNATURE, "md5" }, { TCPOPT_AUTH, "enhanced auth" }, + { TCPOPT_UTO, "uto" }, { 0, NULL } }; @@ -613,6 +614,17 @@ tcp_print(register const u_char *bp, register u_int length, */ break; + case TCPOPT_UTO: + datalen = 2; + LENCHECK(datalen); + uint utoval = EXTRACT_16BITS(cp); + if (utoval & 0x0001) + utoval = (utoval >> 1) * 60; + else + utoval >>= 1; + (void)printf(" %u", utoval); + break; + default: datalen = len - 2; for (i = 0; i < datalen; ++i) { diff --git a/contrib/tcpdump/tcp.h b/contrib/tcpdump/tcp.h index db7dd44775e..1393a277cd9 100644 --- a/contrib/tcpdump/tcp.h +++ b/contrib/tcpdump/tcp.h @@ -83,6 +83,8 @@ struct tcphdr { #define TCPOLEN_SIGNATURE 18 #define TCP_SIGLEN 16 /* length of an option 19 digest */ #define TCPOPT_AUTH 20 /* Enhanced AUTH option */ +#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */ +#define TCPOLEN_UTO 4 #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) From c0103003c0fe9ccf730ebda322e09342e9fde333 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Wed, 7 Oct 2009 12:38:19 +0000 Subject: [PATCH 076/646] Fix situation where Mac OS X NFS client creates a file and when it tries to set ownership and mode in the same setattr operation, the mode was overwritten by secpolicy_vnode_setattr(). PR: kern/118320 Submitted by: Mark Thompson MFC after: 3 days --- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 37a5f30042c..4136e7d66c8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -2538,6 +2538,7 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, vattr_t oldva; uint_t mask = vap->va_mask; uint_t saved_mask; + uint64_t saved_mode; int trim_mask = 0; uint64_t new_mode; znode_t *attrzp; @@ -2766,6 +2767,13 @@ top: if (trim_mask) { saved_mask = vap->va_mask; vap->va_mask &= ~trim_mask; + if (trim_mask & AT_MODE) { + /* + * Save the mode, as secpolicy_vnode_setattr() + * will overwrite it with ova.va_mode. + */ + saved_mode = vap->va_mode; + } } err = secpolicy_vnode_setattr(cr, vp, vap, &oldva, flags, (int (*)(void *, int, cred_t *))zfs_zaccess_unix, zp); @@ -2774,8 +2782,16 @@ top: return (err); } - if (trim_mask) + if (trim_mask) { vap->va_mask |= saved_mask; + if (trim_mask & AT_MODE) { + /* + * Recover the mode after + * secpolicy_vnode_setattr(). + */ + vap->va_mode = saved_mode; + } + } } /* From a57795536a9be831fa5f3ea877f72cc81bc105c6 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Wed, 7 Oct 2009 13:12:43 +0000 Subject: [PATCH 077/646] - Add support for new BGE chips (5761, 5784 and 57780). These chips uses new BGE_PCI_PRODID_ASICREV register to store the chip identifier and its revision. - Add new grouping macro for 7575+ chips (BGE_IS_5755_PLUS). - Add IDs for Fujitsu-branded Broadcom adapters. PR: kern/127587 Tested by: Thomas Quinot (BCM7561 A0) MFC after: 2 weeks Obtained from: OpenBSD --- sys/dev/bge/if_bge.c | 80 +++++++++++++++---- sys/dev/bge/if_bgereg.h | 167 +++++++++++++++++++++++++--------------- 2 files changed, 173 insertions(+), 74 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index db65ec2caad..d9a7b7fb9a1 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -170,6 +170,7 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5720 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5721 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5722 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5723 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5751 }, @@ -184,12 +185,21 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5754M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5755 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5755M }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5761 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5761E }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5761S }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5761SE }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5764 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5780 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5780S }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5781 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5782 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5784 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5785F }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5785G }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5786 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5787 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5787F }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5787M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5788 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5789 }, @@ -198,11 +208,19 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5903M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5906 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5906M }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57760 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57780 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57788 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57790 }, { SK_VENDORID, SK_DEVICEID_ALTIMA }, { TC_VENDORID, TC_DEVICEID_3C996 }, + { FJTSU_VENDORID, FJTSU_DEVICEID_PW008GE4 }, + { FJTSU_VENDORID, FJTSU_DEVICEID_PW008GE5 }, + { FJTSU_VENDORID, FJTSU_DEVICEID_PP250450 }, + { 0, 0 } }; @@ -216,6 +234,7 @@ static const struct bge_vendor { { BCOM_VENDORID, "Broadcom" }, { SK_VENDORID, "SysKonnect" }, { TC_VENDORID, "3Com" }, + { FJTSU_VENDORID, "Fujitsu" }, { 0, NULL } }; @@ -271,12 +290,18 @@ static const struct bge_revision { { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" }, { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" }, { BGE_CHIPID_BCM5722_A0, "BCM5722 A0" }, + { BGE_CHIPID_BCM5761_A0, "BCM5761 A0" }, + { BGE_CHIPID_BCM5761_A1, "BCM5761 A1" }, + { BGE_CHIPID_BCM5784_A0, "BCM5784 A0" }, + { BGE_CHIPID_BCM5784_A1, "BCM5784 A1" }, /* 5754 and 5787 share the same ASIC ID */ { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" }, { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" }, { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" }, { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" }, { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" }, + { BGE_CHIPID_BCM57780_A0, "BCM57780 A0" }, + { BGE_CHIPID_BCM57780_A1, "BCM57780 A1" }, { 0, NULL } }; @@ -297,9 +322,13 @@ static const struct bge_revision bge_majorrevs[] = { { BGE_ASICREV_BCM5780, "unknown BCM5780" }, { BGE_ASICREV_BCM5714, "unknown BCM5714" }, { BGE_ASICREV_BCM5755, "unknown BCM5755" }, + { BGE_ASICREV_BCM5761, "unknown BCM5761" }, + { BGE_ASICREV_BCM5784, "unknown BCM5784" }, + { BGE_ASICREV_BCM5785, "unknown BCM5785" }, /* 5754 and 5787 share the same ASIC ID */ { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" }, { BGE_ASICREV_BCM5906, "unknown BCM5906" }, + { BGE_ASICREV_BCM57780, "unknown BCM57780" }, { 0, NULL } }; @@ -309,6 +338,7 @@ static const struct bge_revision bge_majorrevs[] = { #define BGE_IS_5705_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_5705_PLUS) #define BGE_IS_5714_FAMILY(sc) ((sc)->bge_flags & BGE_FLAG_5714_FAMILY) #define BGE_IS_575X_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_575X_PLUS) +#define BGE_IS_5755_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_5755_PLUS) const struct bge_revision * bge_lookup_rev(uint32_t); const struct bge_vendor * bge_lookup_vendor(uint16_t); @@ -1758,8 +1788,7 @@ bge_blockinit(struct bge_softc *sc) val = BGE_WDMAMODE_ENABLE | BGE_WDMAMODE_ALL_ATTNS; /* Enable host coalescing bug fix. */ - if (sc->bge_asicrev == BGE_ASICREV_BCM5755 || - sc->bge_asicrev == BGE_ASICREV_BCM5787) + if (BGE_IS_5755_PLUS(sc)) val |= 1 << 29; /* Turn on write DMA state machine */ @@ -1768,6 +1797,12 @@ bge_blockinit(struct bge_softc *sc) /* Turn on read DMA state machine */ val = BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS; + if (sc->bge_asicrev == BGE_ASICREV_BCM5784 || + sc->bge_asicrev == BGE_ASICREV_BCM5785 || + sc->bge_asicrev == BGE_ASICREV_BCM57780) + val |= BGE_RDMAMODE_BD_SBD_CRPT_ATTN | + BGE_RDMAMODE_MBUF_RBD_CRPT_ATTN | + BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN; if (sc->bge_flags & BGE_FLAG_PCIE) val |= BGE_RDMAMODE_FIFO_LONG_BURST; CSR_WRITE_4(sc, BGE_RDMA_MODE, val); @@ -1790,7 +1825,10 @@ bge_blockinit(struct bge_softc *sc) CSR_WRITE_4(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE); /* Turn on send data completion state machine */ - CSR_WRITE_4(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE); + val = BGE_SDCMODE_ENABLE; + if (sc->bge_asicrev == BGE_ASICREV_BCM5761) + val |= BGE_SDCMODE_CDELAY; + CSR_WRITE_4(sc, BGE_SDC_MODE, val); /* Turn on send data initiator state machine */ CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE); @@ -1897,8 +1935,11 @@ bge_probe(device_t dev) const struct bge_vendor *v; uint32_t id; - id = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) & - BGE_PCIMISCCTL_ASICREV; + id = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) >> + BGE_PCIMISCCTL_ASICREV_SHIFT; + if (BGE_ASICREV(id) == BGE_ASICREV_USE_PRODID_REG) + id = pci_read_config(dev, + BGE_PCI_PRODID_ASICREV, 4); br = bge_lookup_rev(id); v = bge_lookup_vendor(vid); { @@ -1915,8 +1956,8 @@ bge_probe(device_t dev) br != NULL ? br->br_name : "NetXtreme Ethernet Controller"); } - snprintf(buf, 96, "%s, %sASIC rev. %#04x", model, - br != NULL ? "" : "unknown ", id >> 16); + snprintf(buf, 96, "%s, %sASIC rev. %#08x", model, + br != NULL ? "" : "unknown ", id); device_set_desc_copy(dev, buf); if (pci_get_subvendor(dev) == DELL_VENDORID) sc->bge_flags |= BGE_FLAG_NO_3LED; @@ -2411,8 +2452,11 @@ bge_attach(device_t dev) /* Save various chip information. */ sc->bge_chipid = - pci_read_config(dev, BGE_PCI_MISC_CTL, 4) & - BGE_PCIMISCCTL_ASICREV; + pci_read_config(dev, BGE_PCI_MISC_CTL, 4) >> + BGE_PCIMISCCTL_ASICREV_SHIFT; + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG) + sc->bge_chipid = pci_read_config(dev, BGE_PCI_PRODID_ASICREV, + 4); sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid); sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid); @@ -2431,6 +2475,15 @@ bge_attach(device_t dev) /* Save chipset family. */ switch (sc->bge_asicrev) { + case BGE_ASICREV_BCM5755: + case BGE_ASICREV_BCM5761: + case BGE_ASICREV_BCM5784: + case BGE_ASICREV_BCM5785: + case BGE_ASICREV_BCM5787: + case BGE_ASICREV_BCM57780: + sc->bge_flags |= BGE_FLAG_5755_PLUS | BGE_FLAG_575X_PLUS | + BGE_FLAG_5705_PLUS; + break; case BGE_ASICREV_BCM5700: case BGE_ASICREV_BCM5701: case BGE_ASICREV_BCM5703: @@ -2444,8 +2497,6 @@ bge_attach(device_t dev) /* FALLTHROUGH */ case BGE_ASICREV_BCM5750: case BGE_ASICREV_BCM5752: - case BGE_ASICREV_BCM5755: - case BGE_ASICREV_BCM5787: case BGE_ASICREV_BCM5906: sc->bge_flags |= BGE_FLAG_575X_PLUS; /* FALLTHROUGH */ @@ -2466,6 +2517,8 @@ bge_attach(device_t dev) if (BGE_IS_5705_PLUS(sc) && !(sc->bge_flags & BGE_FLAG_ADJUST_TRIM)) { if (sc->bge_asicrev == BGE_ASICREV_BCM5755 || + sc->bge_asicrev == BGE_ASICREV_BCM5761 || + sc->bge_asicrev == BGE_ASICREV_BCM5784 || sc->bge_asicrev == BGE_ASICREV_BCM5787) { if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0) sc->bge_flags |= BGE_FLAG_JITTER_BUG; @@ -2873,8 +2926,7 @@ bge_reset(struct bge_softc *sc) /* Disable fastboot on controllers that support it. */ if (sc->bge_asicrev == BGE_ASICREV_BCM5752 || - sc->bge_asicrev == BGE_ASICREV_BCM5755 || - sc->bge_asicrev == BGE_ASICREV_BCM5787) { + BGE_IS_5755_PLUS(sc)) { if (bootverbose) device_printf(sc->bge_dev, "Disabling fastboot\n"); CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0x0); @@ -4689,6 +4741,8 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS) } printf("Hardware Flags:\n"); + if (BGE_IS_5755_PLUS(sc)) + printf(" - 5755 Plus\n"); if (BGE_IS_575X_PLUS(sc)) printf(" - 575X Plus\n"); if (BGE_IS_5705_PLUS(sc)) diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 66e36b57c15..7e8b38d2773 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -218,6 +218,7 @@ #define BGE_PCI_UNDI_TX_BD_PRODIDX_LO 0xAC #define BGE_PCI_ISR_MBX_HI 0xB0 #define BGE_PCI_ISR_MBX_LO 0xB4 +#define BGE_PCI_PRODID_ASICREV 0xBC /* PCI Misc. Host control register */ #define BGE_PCIMISCCTL_CLEAR_INTA 0x00000001 @@ -229,6 +230,7 @@ #define BGE_PCIMISCCTL_REG_WORDSWAP 0x00000040 #define BGE_PCIMISCCTL_INDIRECT_ACCESS 0x00000080 #define BGE_PCIMISCCTL_ASICREV 0xFFFF0000 +#define BGE_PCIMISCCTL_ASICREV_SHIFT 16 #define BGE_HIF_SWAP_OPTIONS (BGE_PCIMISCCTL_ENDIAN_WORDSWAP) #if BYTE_ORDER == LITTLE_ENDIAN @@ -245,66 +247,72 @@ (BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_CLEAR_INTA| \ BGE_PCIMISCCTL_MASK_PCI_INTR|BGE_PCIMISCCTL_INDIRECT_ACCESS) -#define BGE_CHIPID_TIGON_I 0x40000000 -#define BGE_CHIPID_TIGON_II 0x60000000 -#define BGE_CHIPID_BCM5700_A0 0x70000000 -#define BGE_CHIPID_BCM5700_A1 0x70010000 -#define BGE_CHIPID_BCM5700_B0 0x71000000 -#define BGE_CHIPID_BCM5700_B1 0x71010000 -#define BGE_CHIPID_BCM5700_B2 0x71020000 -#define BGE_CHIPID_BCM5700_B3 0x71030000 -#define BGE_CHIPID_BCM5700_ALTIMA 0x71040000 -#define BGE_CHIPID_BCM5700_C0 0x72000000 -#define BGE_CHIPID_BCM5701_A0 0x00000000 /* grrrr */ -#define BGE_CHIPID_BCM5701_B0 0x01000000 -#define BGE_CHIPID_BCM5701_B2 0x01020000 -#define BGE_CHIPID_BCM5701_B5 0x01050000 -#define BGE_CHIPID_BCM5703_A0 0x10000000 -#define BGE_CHIPID_BCM5703_A1 0x10010000 -#define BGE_CHIPID_BCM5703_A2 0x10020000 -#define BGE_CHIPID_BCM5703_A3 0x10030000 -#define BGE_CHIPID_BCM5703_B0 0x11000000 -#define BGE_CHIPID_BCM5704_A0 0x20000000 -#define BGE_CHIPID_BCM5704_A1 0x20010000 -#define BGE_CHIPID_BCM5704_A2 0x20020000 -#define BGE_CHIPID_BCM5704_A3 0x20030000 -#define BGE_CHIPID_BCM5704_B0 0x21000000 -#define BGE_CHIPID_BCM5705_A0 0x30000000 -#define BGE_CHIPID_BCM5705_A1 0x30010000 -#define BGE_CHIPID_BCM5705_A2 0x30020000 -#define BGE_CHIPID_BCM5705_A3 0x30030000 -#define BGE_CHIPID_BCM5750_A0 0x40000000 -#define BGE_CHIPID_BCM5750_A1 0x40010000 -#define BGE_CHIPID_BCM5750_A3 0x40030000 -#define BGE_CHIPID_BCM5750_B0 0x41000000 -#define BGE_CHIPID_BCM5750_B1 0x41010000 -#define BGE_CHIPID_BCM5750_C0 0x42000000 -#define BGE_CHIPID_BCM5750_C1 0x42010000 -#define BGE_CHIPID_BCM5750_C2 0x42020000 -#define BGE_CHIPID_BCM5714_A0 0x50000000 -#define BGE_CHIPID_BCM5752_A0 0x60000000 -#define BGE_CHIPID_BCM5752_A1 0x60010000 -#define BGE_CHIPID_BCM5752_A2 0x60020000 -#define BGE_CHIPID_BCM5714_B0 0x80000000 -#define BGE_CHIPID_BCM5714_B3 0x80030000 -#define BGE_CHIPID_BCM5715_A0 0x90000000 -#define BGE_CHIPID_BCM5715_A1 0x90010000 -#define BGE_CHIPID_BCM5715_A3 0x90030000 -#define BGE_CHIPID_BCM5755_A0 0xa0000000 -#define BGE_CHIPID_BCM5755_A1 0xa0010000 -#define BGE_CHIPID_BCM5755_A2 0xa0020000 -#define BGE_CHIPID_BCM5722_A0 0xa2000000 -#define BGE_CHIPID_BCM5754_A0 0xb0000000 -#define BGE_CHIPID_BCM5754_A1 0xb0010000 -#define BGE_CHIPID_BCM5754_A2 0xb0020000 -#define BGE_CHIPID_BCM5787_A0 0xb0000000 -#define BGE_CHIPID_BCM5787_A1 0xb0010000 -#define BGE_CHIPID_BCM5787_A2 0xb0020000 -#define BGE_CHIPID_BCM5906_A1 0xc0010000 -#define BGE_CHIPID_BCM5906_A2 0xc0020000 +#define BGE_CHIPID_TIGON_I 0x4000 +#define BGE_CHIPID_TIGON_II 0x6000 +#define BGE_CHIPID_BCM5700_A0 0x7000 +#define BGE_CHIPID_BCM5700_A1 0x7001 +#define BGE_CHIPID_BCM5700_B0 0x7100 +#define BGE_CHIPID_BCM5700_B1 0x7101 +#define BGE_CHIPID_BCM5700_B2 0x7102 +#define BGE_CHIPID_BCM5700_B3 0x7103 +#define BGE_CHIPID_BCM5700_ALTIMA 0x7104 +#define BGE_CHIPID_BCM5700_C0 0x7200 +#define BGE_CHIPID_BCM5701_A0 0x0000 /* grrrr */ +#define BGE_CHIPID_BCM5701_B0 0x0100 +#define BGE_CHIPID_BCM5701_B2 0x0102 +#define BGE_CHIPID_BCM5701_B5 0x0105 +#define BGE_CHIPID_BCM5703_A0 0x1000 +#define BGE_CHIPID_BCM5703_A1 0x1001 +#define BGE_CHIPID_BCM5703_A2 0x1002 +#define BGE_CHIPID_BCM5703_A3 0x1003 +#define BGE_CHIPID_BCM5703_B0 0x1100 +#define BGE_CHIPID_BCM5704_A0 0x2000 +#define BGE_CHIPID_BCM5704_A1 0x2001 +#define BGE_CHIPID_BCM5704_A2 0x2002 +#define BGE_CHIPID_BCM5704_A3 0x2003 +#define BGE_CHIPID_BCM5704_B0 0x2100 +#define BGE_CHIPID_BCM5705_A0 0x3000 +#define BGE_CHIPID_BCM5705_A1 0x3001 +#define BGE_CHIPID_BCM5705_A2 0x3002 +#define BGE_CHIPID_BCM5705_A3 0x3003 +#define BGE_CHIPID_BCM5750_A0 0x4000 +#define BGE_CHIPID_BCM5750_A1 0x4001 +#define BGE_CHIPID_BCM5750_A3 0x4000 +#define BGE_CHIPID_BCM5750_B0 0x4100 +#define BGE_CHIPID_BCM5750_B1 0x4101 +#define BGE_CHIPID_BCM5750_C0 0x4200 +#define BGE_CHIPID_BCM5750_C1 0x4201 +#define BGE_CHIPID_BCM5750_C2 0x4202 +#define BGE_CHIPID_BCM5714_A0 0x5000 +#define BGE_CHIPID_BCM5752_A0 0x6000 +#define BGE_CHIPID_BCM5752_A1 0x6001 +#define BGE_CHIPID_BCM5752_A2 0x6002 +#define BGE_CHIPID_BCM5714_B0 0x8000 +#define BGE_CHIPID_BCM5714_B3 0x8003 +#define BGE_CHIPID_BCM5715_A0 0x9000 +#define BGE_CHIPID_BCM5715_A1 0x9001 +#define BGE_CHIPID_BCM5715_A3 0x9003 +#define BGE_CHIPID_BCM5755_A0 0xa000 +#define BGE_CHIPID_BCM5755_A1 0xa001 +#define BGE_CHIPID_BCM5755_A2 0xa002 +#define BGE_CHIPID_BCM5722_A0 0xa200 +#define BGE_CHIPID_BCM5754_A0 0xb000 +#define BGE_CHIPID_BCM5754_A1 0xb001 +#define BGE_CHIPID_BCM5754_A2 0xb002 +#define BGE_CHIPID_BCM5761_A0 0x5761000 +#define BGE_CHIPID_BCM5761_A1 0x5761100 +#define BGE_CHIPID_BCM5784_A0 0x5784000 +#define BGE_CHIPID_BCM5784_A1 0x5784100 +#define BGE_CHIPID_BCM5787_A0 0xb000 +#define BGE_CHIPID_BCM5787_A1 0xb001 +#define BGE_CHIPID_BCM5787_A2 0xb002 +#define BGE_CHIPID_BCM5906_A1 0xc001 +#define BGE_CHIPID_BCM5906_A2 0xc002 +#define BGE_CHIPID_BCM57780_A0 0x57780000 +#define BGE_CHIPID_BCM57780_A1 0x57780001 /* shorthand one */ -#define BGE_ASICREV(x) ((x) >> 28) +#define BGE_ASICREV(x) ((x) >> 12) #define BGE_ASICREV_BCM5701 0x00 #define BGE_ASICREV_BCM5703 0x01 #define BGE_ASICREV_BCM5704 0x02 @@ -319,9 +327,16 @@ #define BGE_ASICREV_BCM5754 0x0b #define BGE_ASICREV_BCM5787 0x0b #define BGE_ASICREV_BCM5906 0x0c +/* Should consult BGE_PCI_PRODID_ASICREV for ChipID */ +#define BGE_ASICREV_USE_PRODID_REG 0x0f +/* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */ +#define BGE_ASICREV_BCM5761 0x5761 +#define BGE_ASICREV_BCM5784 0x5784 +#define BGE_ASICREV_BCM5785 0x5785 +#define BGE_ASICREV_BCM57780 0x57780 /* chip revisions */ -#define BGE_CHIPREV(x) ((x) >> 24) +#define BGE_CHIPREV(x) ((x) >> 8) #define BGE_CHIPREV_5700_AX 0x70 #define BGE_CHIPREV_5700_BX 0x71 #define BGE_CHIPREV_5700_CX 0x72 @@ -331,6 +346,9 @@ #define BGE_CHIPREV_5704_BX 0x21 #define BGE_CHIPREV_5750_AX 0x40 #define BGE_CHIPREV_5750_BX 0x41 +/* BGE_PCI_PRODID_ASICREV chip rev. identifiers. */ +#define BGE_CHIPREV_5761_AX 0x57611 +#define BGE_CHIPREV_5784_AX 0x57841 /* PCI DMA Read/Write Control register */ #define BGE_PCIDMARWCTL_MINDMA 0x000000FF @@ -861,6 +879,7 @@ #define BGE_SDCMODE_RESET 0x00000001 #define BGE_SDCMODE_ENABLE 0x00000002 #define BGE_SDCMODE_ATTN 0x00000004 +#define BGE_SDCMODE_CDELAY 0x00000010 /* Send Data completion status register */ #define BGE_SDCSTAT_ATTN 0x00000004 @@ -1378,6 +1397,9 @@ #define BGE_RDMAMODE_PCI_FIFOOREAD_ATTN 0x00000100 #define BGE_RDMAMODE_LOCWRITE_TOOBIG 0x00000200 #define BGE_RDMAMODE_ALL_ATTNS 0x000003FC +#define BGE_RDMAMODE_BD_SBD_CRPT_ATTN 0x00000800 +#define BGE_RDMAMODE_MBUF_RBD_CRPT_ATTN 0x00001000 +#define BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN 0x00002000 #define BGE_RDMAMODE_FIFO_SIZE_128 0x00020000 #define BGE_RDMAMODE_FIFO_LONG_BURST 0x00030000 @@ -2101,6 +2123,7 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5720 0x1658 #define BCOM_DEVICEID_BCM5721 0x1659 #define BCOM_DEVICEID_BCM5722 0x165A +#define BCOM_DEVICEID_BCM5723 0x165B #define BCOM_DEVICEID_BCM5750 0x1676 #define BCOM_DEVICEID_BCM5750M 0x167C #define BCOM_DEVICEID_BCM5751 0x1677 @@ -2115,13 +2138,22 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5754M 0x1672 #define BCOM_DEVICEID_BCM5755 0x167B #define BCOM_DEVICEID_BCM5755M 0x1673 +#define BCOM_DEVICEID_BCM5761 0x1681 +#define BCOM_DEVICEID_BCM5761E 0x1680 +#define BCOM_DEVICEID_BCM5761S 0x1688 +#define BCOM_DEVICEID_BCM5761SE 0x1689 +#define BCOM_DEVICEID_BCM5764 0x1684 #define BCOM_DEVICEID_BCM5780 0x166A #define BCOM_DEVICEID_BCM5780S 0x166B #define BCOM_DEVICEID_BCM5781 0x16DD #define BCOM_DEVICEID_BCM5782 0x1696 +#define BCOM_DEVICEID_BCM5784 0x1698 +#define BCOM_DEVICEID_BCM5785F 0x16a0 +#define BCOM_DEVICEID_BCM5785G 0x1699 #define BCOM_DEVICEID_BCM5786 0x169A #define BCOM_DEVICEID_BCM5787 0x169B #define BCOM_DEVICEID_BCM5787M 0x1693 +#define BCOM_DEVICEID_BCM5787F 0x167f #define BCOM_DEVICEID_BCM5788 0x169C #define BCOM_DEVICEID_BCM5789 0x169D #define BCOM_DEVICEID_BCM5901 0x170D @@ -2129,6 +2161,10 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5903M 0x16FF #define BCOM_DEVICEID_BCM5906 0x1712 #define BCOM_DEVICEID_BCM5906M 0x1713 +#define BCOM_DEVICEID_BCM57760 0x1690 +#define BCOM_DEVICEID_BCM57780 0x1692 +#define BCOM_DEVICEID_BCM57788 0x1691 +#define BCOM_DEVICEID_BCM57790 0x1694 /* * Alteon AceNIC PCI vendor/device ID. @@ -2178,6 +2214,14 @@ struct bge_status_block { */ #define SUN_VENDORID 0x108e +/* + * Fujitsu vendor/device IDs + */ +#define FJTSU_VENDORID 0x10cf +#define FJTSU_DEVICEID_PW008GE5 0x11a1 +#define FJTSU_DEVICEID_PW008GE4 0x11a2 +#define FJTSU_DEVICEID_PP250450 0x11cc /* PRIMEPOWER250/450 LAN */ + /* * Offset of MAC address inside EEPROM. */ @@ -2558,6 +2602,7 @@ struct bge_softc { #define BGE_FLAG_5705_PLUS 0x00002000 #define BGE_FLAG_5714_FAMILY 0x00004000 #define BGE_FLAG_575X_PLUS 0x00008000 +#define BGE_FLAG_5755_PLUS 0x00010000 #define BGE_FLAG_RX_ALIGNBUG 0x00100000 #define BGE_FLAG_NO_3LED 0x00200000 #define BGE_FLAG_ADC_BUG 0x00400000 @@ -2568,8 +2613,8 @@ struct bge_softc { #define BGE_FLAG_CRC_BUG 0x08000000 #define BGE_FLAG_5788 0x20000000 uint32_t bge_chipid; - uint8_t bge_asicrev; - uint8_t bge_chiprev; + uint32_t bge_asicrev; + uint32_t bge_chiprev; uint8_t bge_asf_mode; uint8_t bge_asf_count; struct bge_ring_data bge_ldata; /* rings */ From 6e7b6303bae846ed7b138238f1733dfb368a985d Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Wed, 7 Oct 2009 13:25:22 +0000 Subject: [PATCH 078/646] When run() returns an error, print the error message also in non-interactive mode. Previously error messages were printed only in interactive mode. PR: bin/124517 Approved by: trasz (mentor) MFC after: 1 month --- usr.sbin/cdcontrol/cdcontrol.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/usr.sbin/cdcontrol/cdcontrol.c b/usr.sbin/cdcontrol/cdcontrol.c index ede59043201..a4b13d8f633 100644 --- a/usr.sbin/cdcontrol/cdcontrol.c +++ b/usr.sbin/cdcontrol/cdcontrol.c @@ -241,7 +241,7 @@ int main (int argc, char **argv) if (argc > 0) { char buf[80], *p; - int len; + int len, rc; for (p=buf; argc-->0; ++argv) { len = strlen (*argv); @@ -257,7 +257,11 @@ int main (int argc, char **argv) } *p = 0; arg = parse (buf, &cmd); - return (run (cmd, arg)); + rc = run (cmd, arg); + if (rc < 0 && verbose) + warn(NULL); + + return (rc); } if (verbose == 1) From 6410fec30ad39cfd425f0e664f01a1b94232095f Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Wed, 7 Oct 2009 13:25:24 +0000 Subject: [PATCH 079/646] - Document new revisions of chips supported. --- share/man/man4/bge.4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4 index d4cc265237b..10dd0dbdb82 100644 --- a/share/man/man4/bge.4 +++ b/share/man/man4/bge.4 @@ -31,12 +31,12 @@ .\" .\" $FreeBSD$ .\" -.Dd May 19, 2009 +.Dd Oct 7, 2009 .Dt BGE 4 .Os .Sh NAME .Nm bge -.Nd "Broadcom BCM570x/5714/5721/5722/5750/5751/5752/5789 PCI Gigabit Ethernet adapter driver" +.Nd "Broadcom BCM570x/5714/5721/5722/5750/5751/5752/5761/5784/5789/57780 PCI Gigabit Ethernet adapter driver" .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your @@ -56,8 +56,8 @@ if_bge_load="YES" The .Nm driver provides support for various NICs based on the Broadcom BCM570x, -5714, 5721, 5722, 5750, 5751, 5752 and 5789 families of Gigabit Ethernet -controller chips. +5714, 5721, 5722, 5750, 5751, 5752, 5761, 5784, 5789 and 57780 families +of Gigabit Ethernet controller chips. .Pp All of these NICs are capable of 10, 100 and 1000Mbps speeds over CAT5 copper cable, except for the SysKonnect SK-9D41 which supports only From e9e6bb8ea3586ea3e83f5be79e0a1eeb200e6e22 Mon Sep 17 00:00:00 2001 From: "Simon L. B. Nielsen" Date: Wed, 7 Oct 2009 13:45:12 +0000 Subject: [PATCH 080/646] - Document that 'Dell PowerEdge R710' has bce(4) supported NIC. - Bump document date. MFC after: 3 days --- share/man/man4/bce.4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/share/man/man4/bce.4 b/share/man/man4/bce.4 index 41c9fe9202a..0bca57b3d2f 100644 --- a/share/man/man4/bce.4 +++ b/share/man/man4/bce.4 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 7, 2009 +.Dd October 7, 2009 .Dt BCE 4 .Os .Sh NAME @@ -165,6 +165,8 @@ Dell PowerEdge 1950 integrated BCM5708 NIC .It Dell PowerEdge 2950 integrated BCM5708 NIC .It +Dell PowerEdge R710 integrated BCM5709 NIC +.It HP NC370F Multifunction Gigabit Server Adapter .It HP NC370T Multifunction Gigabit Server Adapter From 3889907fb26845efda5611a756e69c2adbd91df6 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Wed, 7 Oct 2009 14:29:48 +0000 Subject: [PATCH 081/646] - Give a name to the host coalescing bug fix WDMA mode register bit instead of using hardcoded value in the code. Obtained from: OpenBSD --- sys/dev/bge/if_bge.c | 2 +- sys/dev/bge/if_bgereg.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index d9a7b7fb9a1..1fabee01b73 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1789,7 +1789,7 @@ bge_blockinit(struct bge_softc *sc) /* Enable host coalescing bug fix. */ if (BGE_IS_5755_PLUS(sc)) - val |= 1 << 29; + val |= BGE_WDMAMODE_STATUS_TAG_FIX; /* Turn on write DMA state machine */ CSR_WRITE_4(sc, BGE_WDMA_MODE, val); diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 7e8b38d2773..ab336f44627 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -1431,6 +1431,7 @@ #define BGE_WDMAMODE_PCI_FIFOOREAD_ATTN 0x00000100 #define BGE_WDMAMODE_LOCREAD_TOOBIG 0x00000200 #define BGE_WDMAMODE_ALL_ATTNS 0x000003FC +#define BGE_WDMAMODE_STATUS_TAG_FIX 0x20000000 /* Write DMA status register */ #define BGE_WDMASTAT_PCI_TGT_ABRT_ATTN 0x00000004 From 660d482a4ea05850d561de920a2c844282dd6dbc Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 7 Oct 2009 15:40:04 +0000 Subject: [PATCH 082/646] On command timeout handle frozen command first, to not run it inside XXX_end_transaction(). Submitted by: avg --- sys/dev/ahci/ahci.c | 7 ++++--- sys/dev/siis/siis.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 273c276bd2a..f420629eaab 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1259,15 +1259,16 @@ ahci_timeout(struct ahci_slot *slot) if (!ch->readlog) xpt_freeze_simq(ch->sim, ch->numrslots); - /* Handle command with timeout. */ - ahci_end_transaction(&ch->slot[slot->slot], AHCI_ERR_TIMEOUT); - /* Handle the rest of commands. */ + /* Handle frozen command. */ if (ch->frozen) { union ccb *fccb = ch->frozen; ch->frozen = NULL; fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; xpt_done(fccb); } + /* Handle command with timeout. */ + ahci_end_transaction(&ch->slot[slot->slot], AHCI_ERR_TIMEOUT); + /* Handle the rest of commands. */ for (i = 0; i < ch->numslots; i++) { /* Do we have a running request on slot? */ if (ch->slot[i].state < AHCI_SLOT_RUNNING) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 31002ebcfce..c5577d945af 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -982,15 +982,16 @@ device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n", if (!ch->readlog) xpt_freeze_simq(ch->sim, ch->numrslots); - /* Handle command with timeout. */ - siis_end_transaction(&ch->slot[slot->slot], SIIS_ERR_TIMEOUT); - /* Handle the rest of commands. */ + /* Handle frozen command. */ if (ch->frozen) { union ccb *fccb = ch->frozen; ch->frozen = NULL; fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; xpt_done(fccb); } + /* Handle command with timeout. */ + siis_end_transaction(&ch->slot[slot->slot], SIIS_ERR_TIMEOUT); + /* Handle the rest of commands. */ for (i = 0; i < SIIS_MAX_SLOTS; i++) { /* Do we have a running request on slot? */ if (ch->slot[i].state < SIIS_SLOT_RUNNING) From fbaa591f50948f714fc5bc20dc755103bc00de71 Mon Sep 17 00:00:00 2001 From: Zachary Loafman Date: Wed, 7 Oct 2009 19:50:14 +0000 Subject: [PATCH 083/646] Handle GRANTED_RES messages more gracefully: Send along a grant cookie to reference the lock, look up the grant cookie when the GRANTED_RES comes back. Properly handle the case of an error on the grant. Add a short expiration window so that granted locks are not freed immediately. Approved by: dfr (mentor) MFC after: 2 weeks --- sys/nlm/nlm.h | 12 +++ sys/nlm/nlm_prot_impl.c | 157 +++++++++++++++++++++++++++++++++----- sys/nlm/nlm_prot_server.c | 1 + 3 files changed, 152 insertions(+), 18 deletions(-) diff --git a/sys/nlm/nlm.h b/sys/nlm/nlm.h index d2c5ee1610a..379d4ece934 100644 --- a/sys/nlm/nlm.h +++ b/sys/nlm/nlm.h @@ -48,6 +48,12 @@ struct vnode; extern struct timeval nlm_zero_tv; extern int nlm_nsm_state; +/* + * Make a struct netobj. + */ +extern void nlm_make_netobj(struct netobj *dst, caddr_t srt, + size_t srcsize, struct malloc_type *type); + /* * Copy a struct netobj. */ @@ -192,6 +198,12 @@ extern int nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, extern int nlm_do_granted(nlm4_testargs *argp, nlm4_res *result, struct svc_req *rqstp, CLIENT **rpcp); +/* + * Implementation for the granted result RPC. The client may reject the granted + * message, in which case we need to handle it appropriately. + */ +extern void nlm_do_granted_res(nlm4_res *argp, struct svc_req *rqstp); + /* * Free all locks associated with the hostname argp->name. */ diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index f7db7591876..f6b296d6f3c 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -76,6 +77,11 @@ MALLOC_DEFINE(M_NLM, "NLM", "Network Lock Manager"); */ #define NLM_IDLE_PERIOD 5 +/* + * We only look for GRANTED_RES messages for a little while. + */ +#define NLM_EXPIRE_TIMEOUT 10 + /* * Support for sysctl vfs.nlm.sysid */ @@ -204,6 +210,7 @@ struct nlm_async_lock { struct nlm_host *af_host; /* (c) host which is locking */ CLIENT *af_rpc; /* (c) rpc client to send message */ nlm4_testargs af_granted; /* (c) notification details */ + time_t af_expiretime; /* (c) notification time */ }; TAILQ_HEAD(nlm_async_lock_list, nlm_async_lock); @@ -237,7 +244,9 @@ struct nlm_host { enum nlm_host_state nh_monstate; /* (l) local NSM monitoring state */ time_t nh_idle_timeout; /* (s) Time at which host is idle */ struct sysctl_ctx_list nh_sysctl; /* (c) vfs.nlm.sysid nodes */ + uint32_t nh_grantcookie; /* (l) grant cookie counter */ struct nlm_async_lock_list nh_pending; /* (l) pending async locks */ + struct nlm_async_lock_list nh_granted; /* (l) granted locks */ struct nlm_async_lock_list nh_finished; /* (l) finished async locks */ }; TAILQ_HEAD(nlm_host_list, nlm_host); @@ -247,6 +256,25 @@ static uint32_t nlm_next_sysid = 1; /* (g) */ static void nlm_host_unmonitor(struct nlm_host *); +struct nlm_grantcookie { + uint32_t ng_sysid; + uint32_t ng_cookie; +}; + +static inline uint32_t +ng_sysid(struct netobj *src) +{ + + return ((struct nlm_grantcookie *)src->n_bytes)->ng_sysid; +} + +static inline uint32_t +ng_cookie(struct netobj *src) +{ + + return ((struct nlm_grantcookie *)src->n_bytes)->ng_cookie; +} + /**********************************************************************/ /* @@ -280,6 +308,19 @@ nlm_uninit(void *dummy) } SYSUNINIT(nlm_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, nlm_uninit, NULL); +/* + * Create a netobj from an arbitrary source. + */ +void +nlm_make_netobj(struct netobj *dst, caddr_t src, size_t srcsize, + struct malloc_type *type) +{ + + dst->n_len = srcsize; + dst->n_bytes = malloc(srcsize, type, M_WAITOK); + memcpy(dst->n_bytes, src, srcsize); +} + /* * Copy a struct netobj. */ @@ -288,11 +329,10 @@ nlm_copy_netobj(struct netobj *dst, struct netobj *src, struct malloc_type *type) { - dst->n_len = src->n_len; - dst->n_bytes = malloc(src->n_len, type, M_WAITOK); - memcpy(dst->n_bytes, src->n_bytes, src->n_len); + nlm_make_netobj(dst, src->n_bytes, src->n_len, type); } + /* * Create an RPC client handle for the given (address,prog,vers) * triple using UDP. @@ -518,8 +558,10 @@ nlm_lock_callback(void *arg, int pending) struct nlm_async_lock *af = (struct nlm_async_lock *) arg; struct rpc_callextra ext; - NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted\n", - af, af->af_host->nh_caller_name, af->af_host->nh_sysid); + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted," + " cookie %d:%d\n", af, af->af_host->nh_caller_name, + af->af_host->nh_sysid, ng_sysid(&af->af_granted.cookie), + ng_cookie(&af->af_granted.cookie)); /* * Send the results back to the host. @@ -556,16 +598,12 @@ nlm_lock_callback(void *arg, int pending) } /* - * Move this entry to the nh_finished list. Someone else will - * free it later - its too hard to do it here safely without - * racing with cancel. - * - * XXX possibly we should have a third "granted sent but not - * ack'ed" list so that we can re-send the granted message. + * Move this entry to the nh_granted list. */ + af->af_expiretime = time_uptime + NLM_EXPIRE_TIMEOUT; mtx_lock(&af->af_host->nh_lock); TAILQ_REMOVE(&af->af_host->nh_pending, af, af_link); - TAILQ_INSERT_TAIL(&af->af_host->nh_finished, af, af_link); + TAILQ_INSERT_TAIL(&af->af_host->nh_granted, af, af_link); mtx_unlock(&af->af_host->nh_lock); } @@ -635,11 +673,23 @@ nlm_cancel_async_lock(struct nlm_async_lock *af) } static void -nlm_free_finished_locks(struct nlm_host *host) +nlm_check_expired_locks(struct nlm_host *host) { struct nlm_async_lock *af; + time_t uptime = time_uptime; mtx_lock(&host->nh_lock); + while ((af = TAILQ_FIRST(&host->nh_granted)) != NULL + && uptime >= af->af_expiretime) { + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) expired," + " cookie %d:%d\n", af, af->af_host->nh_caller_name, + af->af_host->nh_sysid, ng_sysid(&af->af_granted.cookie), + ng_cookie(&af->af_granted.cookie)); + TAILQ_REMOVE(&host->nh_granted, af, af_link); + mtx_unlock(&host->nh_lock); + nlm_free_async_lock(af); + mtx_lock(&host->nh_lock); + } while ((af = TAILQ_FIRST(&host->nh_finished)) != NULL) { TAILQ_REMOVE(&host->nh_finished, af, af_link); mtx_unlock(&host->nh_lock); @@ -722,7 +772,7 @@ nlm_host_notify(struct nlm_host *host, int newstate) nlm_cancel_async_lock(af); } mtx_unlock(&host->nh_lock); - nlm_free_finished_locks(host); + nlm_check_expired_locks(host); /* * The host just rebooted - trash its locks. @@ -799,7 +849,9 @@ nlm_create_host(const char* caller_name) host->nh_vers = 0; host->nh_state = 0; host->nh_monstate = NLM_UNMONITORED; + host->nh_grantcookie = 1; TAILQ_INIT(&host->nh_pending); + TAILQ_INIT(&host->nh_granted); TAILQ_INIT(&host->nh_finished); TAILQ_INSERT_TAIL(&nlm_hosts, host, nh_link); @@ -1834,7 +1886,7 @@ nlm_do_test(nlm4_testargs *argp, nlm4_testres *result, struct svc_req *rqstp, NLM_DEBUG(3, "nlm_do_test(): caller_name = %s (sysid = %d)\n", host->nh_caller_name, host->nh_sysid); - nlm_free_finished_locks(host); + nlm_check_expired_locks(host); sysid = host->nh_sysid; nlm_convert_to_fhandle_t(&fh, &argp->alock.fh); @@ -1939,7 +1991,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, nlm_host_notify(host, argp->state); } - nlm_free_finished_locks(host); + nlm_check_expired_locks(host); sysid = host->nh_sysid; nlm_convert_to_fhandle_t(&fh, &argp->alock.fh); @@ -1968,6 +2020,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, if (argp->block) { struct nlm_async_lock *af; CLIENT *client; + struct nlm_grantcookie cookie; /* * First, make sure we can contact the host's NLM. @@ -1993,6 +2046,10 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, break; } } + if (!af) { + cookie.ng_sysid = host->nh_sysid; + cookie.ng_cookie = host->nh_grantcookie++; + } mtx_unlock(&host->nh_lock); if (af) { CLNT_RELEASE(client); @@ -2011,6 +2068,8 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, * We use M_RPC here so that we can xdr_free the thing * later. */ + nlm_make_netobj(&af->af_granted.cookie, + (caddr_t)&cookie, sizeof(cookie), M_RPC); af->af_granted.exclusive = argp->exclusive; af->af_granted.alock.caller_name = strdup(argp->alock.caller_name, M_RPC); @@ -2111,7 +2170,7 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_res *result, struct svc_req *rqstp, NLM_DEBUG(3, "nlm_do_cancel(): caller_name = %s (sysid = %d)\n", host->nh_caller_name, host->nh_sysid); - nlm_free_finished_locks(host); + nlm_check_expired_locks(host); sysid = host->nh_sysid; nlm_convert_to_fhandle_t(&fh, &argp->alock.fh); @@ -2200,7 +2259,7 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, struct svc_req *rqstp, NLM_DEBUG(3, "nlm_do_unlock(): caller_name = %s (sysid = %d)\n", host->nh_caller_name, host->nh_sysid); - nlm_free_finished_locks(host); + nlm_check_expired_locks(host); sysid = host->nh_sysid; nlm_convert_to_fhandle_t(&fh, &argp->alock.fh); @@ -2257,6 +2316,7 @@ nlm_do_granted(nlm4_testargs *argp, nlm4_res *result, struct svc_req *rqstp, nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC); result->stat.stat = nlm4_denied; + KFAIL_POINT_CODE(DEBUG_FP, nlm_deny_grant, goto out); mtx_lock(&nlm_global_lock); TAILQ_FOREACH(nw, &nlm_waiting_locks, nw_link) { @@ -2275,12 +2335,73 @@ nlm_do_granted(nlm4_testargs *argp, nlm4_res *result, struct svc_req *rqstp, } } mtx_unlock(&nlm_global_lock); + +out: if (rpcp) *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } +void +nlm_do_granted_res(nlm4_res *argp, struct svc_req *rqstp) +{ + struct nlm_host *host = NULL; + struct nlm_async_lock *af = NULL; + int error; + + if (argp->cookie.n_len != sizeof(struct nlm_grantcookie)) { + NLM_DEBUG(1, "NLM: bogus grant cookie"); + goto out; + } + + host = nlm_find_host_by_sysid(ng_sysid(&argp->cookie)); + if (!host) { + NLM_DEBUG(1, "NLM: Unknown host rejected our grant"); + goto out; + } + + mtx_lock(&host->nh_lock); + TAILQ_FOREACH(af, &host->nh_granted, af_link) + if (ng_cookie(&argp->cookie) == + ng_cookie(&af->af_granted.cookie)) + break; + if (af) + TAILQ_REMOVE(&host->nh_granted, af, af_link); + mtx_unlock(&host->nh_lock); + + if (!af) { + NLM_DEBUG(1, "NLM: host %s (sysid %d) replied to our grant " + "with unrecognized cookie %d:%d", host->nh_caller_name, + host->nh_sysid, ng_sysid(&argp->cookie), + ng_cookie(&argp->cookie)); + goto out; + } + + if (argp->stat.stat != nlm4_granted) { + af->af_fl.l_type = F_UNLCK; + error = VOP_ADVLOCK(af->af_vp, NULL, F_UNLCK, &af->af_fl, F_REMOTE); + if (error) { + NLM_DEBUG(1, "NLM: host %s (sysid %d) rejected our grant " + "and we failed to unlock (%d)", host->nh_caller_name, + host->nh_sysid, error); + goto out; + } + + NLM_DEBUG(5, "NLM: async lock %p rejected by host %s (sysid %d)", + af, host->nh_caller_name, host->nh_sysid); + } else { + NLM_DEBUG(5, "NLM: async lock %p accepted by host %s (sysid %d)", + af, host->nh_caller_name, host->nh_sysid); + } + + out: + if (af) + nlm_free_async_lock(af); + if (host) + nlm_host_release(host); +} + void nlm_do_free_all(nlm4_notify *argp) { diff --git a/sys/nlm/nlm_prot_server.c b/sys/nlm/nlm_prot_server.c index 6ff86ce3815..21b54cbb27e 100644 --- a/sys/nlm/nlm_prot_server.c +++ b/sys/nlm/nlm_prot_server.c @@ -671,6 +671,7 @@ bool_t nlm4_granted_res_4_svc(nlm4_res *argp, void *result, struct svc_req *rqstp) { + nlm_do_granted_res(argp, rqstp); return (FALSE); } From 44a43f00ed0654acd7921257ba27cb5b47b11da0 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Wed, 7 Oct 2009 20:20:51 +0000 Subject: [PATCH 084/646] Add a new errno, ENOTCAPABLE, to be returned when a process requests an operation on a file descriptor that is not authorized by the descriptor's capability flags. MFC after: 1 month Sponsored by: Google --- lib/libc/gen/errlst.c | 1 + lib/libc/sys/intro.2 | 3 +++ sys/sys/errno.h | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/libc/gen/errlst.c b/lib/libc/gen/errlst.c index bc3e0c98f3f..db6bfa29685 100644 --- a/lib/libc/gen/errlst.c +++ b/lib/libc/gen/errlst.c @@ -150,5 +150,6 @@ const char *const sys_errlist[] = { "Multihop attempted", /* 90 - EMULTIHOP */ "Link has been severed", /* 91 - ENOLINK */ "Protocol error", /* 92 - EPROTO */ + "Capabilities insufficient", /* 93 - ENOTCAPABLE */ }; const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2 index 1c01c3937e7..b75e52c8a3d 100644 --- a/lib/libc/sys/intro.2 +++ b/lib/libc/sys/intro.2 @@ -456,6 +456,9 @@ The specified extended attribute does not exist. .It Er 88 EDOOFUS Em "Programming error" . A function or API is being abused in a way which could only be detected at run-time. +.It Er 93 ENOTCAPABLE Em "Capabilities insufficient" . +An operation on a capability file descriptor requires greater privilege than +the capability allows. .El .Sh DEFINITIONS .Bl -tag -width Ds diff --git a/sys/sys/errno.h b/sys/sys/errno.h index 77b5f67a173..1fceb007c18 100644 --- a/sys/sys/errno.h +++ b/sys/sys/errno.h @@ -174,7 +174,11 @@ __END_DECLS #define EPROTO 92 /* Protocol error */ #ifndef _POSIX_SOURCE -#define ELAST 92 /* Must be equal largest errno */ +#define ENOTCAPABLE 93 /* Capabilities insufficient */ +#endif /* _POSIX_SOURCE */ + +#ifndef _POSIX_SOURCE +#define ELAST 93 /* Must be equal largest errno */ #endif /* _POSIX_SOURCE */ #ifdef _KERNEL From 2ada529a14433d1dba5348906a4f3b5f5573ac5e Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Wed, 7 Oct 2009 20:54:07 +0000 Subject: [PATCH 085/646] Fix white-spaces. MFC after: 3 days --- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index b4bec95f5fb..869b4ee87b6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -433,7 +433,7 @@ vdev_geom_open_by_guid(vdev_t *vd) if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); - + snprintf(buf, len, "/dev/%s", cp->provider->name); spa_strfree(vd->vdev_path); vd->vdev_path = buf; @@ -663,11 +663,11 @@ static void vdev_geom_io_done(zio_t *zio) { - /* - * If the device returned ENXIO, then attempt we should verify if GEOM - * provider has been removed. If this is the case, then we trigger an - * asynchronous removal of the device. - */ + /* + * If the device returned ENXIO, then attempt we should verify if GEOM + * provider has been removed. If this is the case, then we trigger an + * asynchronous removal of the device. + */ if (zio->io_error == ENXIO) { vdev_t *vd = zio->io_vd; vdev_geom_ctx_t *ctx; From 3a6c0cbf26f01dce8309de5ff19927b5690a86a3 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Wed, 7 Oct 2009 20:56:15 +0000 Subject: [PATCH 086/646] On FreeBSD it is enough to report provider removal when orphan event is received, we don't have to do it on every ENXIO error in I/O path. Solaris has no GEOM so they have to handle it in a less clean way. MFC after: 3 days --- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index 869b4ee87b6..f0f9c6fa693 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -662,26 +662,6 @@ sendreq: static void vdev_geom_io_done(zio_t *zio) { - - /* - * If the device returned ENXIO, then attempt we should verify if GEOM - * provider has been removed. If this is the case, then we trigger an - * asynchronous removal of the device. - */ - if (zio->io_error == ENXIO) { - vdev_t *vd = zio->io_vd; - vdev_geom_ctx_t *ctx; - struct g_provider *pp = NULL; - - ctx = vd->vdev_tsd; - if (ctx != NULL && ctx->gc_consumer != NULL) - pp = ctx->gc_consumer->provider; - - if (pp == NULL || (pp->flags & G_PF_ORPHAN)) { - vd->vdev_remove_wanted = B_TRUE; - spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE); - } - } } vdev_ops_t vdev_geom_ops = { From dec5a150d1b2918efe7369ca6b2b1ad518b2185b Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Wed, 7 Oct 2009 21:14:45 +0000 Subject: [PATCH 087/646] Add the comment "(FreeBSD only)" to the altmonth_x keywords MFC after: 1 week --- usr.bin/locale/locale.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/usr.bin/locale/locale.c b/usr.bin/locale/locale.c index da4a560b2d2..cad3afe71bd 100644 --- a/usr.bin/locale/locale.c +++ b/usr.bin/locale/locale.c @@ -190,18 +190,18 @@ struct _kwinfo { { "abmon_10", 1, LC_TIME, ABMON_10, "" }, { "abmon_11", 1, LC_TIME, ABMON_11, "" }, { "abmon_12", 1, LC_TIME, ABMON_12, "" }, - { "altmon_1", 1, LC_TIME, ALTMON_1, "" }, - { "altmon_2", 1, LC_TIME, ALTMON_2, "" }, - { "altmon_3", 1, LC_TIME, ALTMON_3, "" }, - { "altmon_4", 1, LC_TIME, ALTMON_4, "" }, - { "altmon_5", 1, LC_TIME, ALTMON_5, "" }, - { "altmon_6", 1, LC_TIME, ALTMON_6, "" }, - { "altmon_7", 1, LC_TIME, ALTMON_7, "" }, - { "altmon_8", 1, LC_TIME, ALTMON_8, "" }, - { "altmon_9", 1, LC_TIME, ALTMON_9, "" }, - { "altmon_10", 1, LC_TIME, ALTMON_10, "" }, - { "altmon_11", 1, LC_TIME, ALTMON_11, "" }, - { "altmon_12", 1, LC_TIME, ALTMON_12, "" }, + { "altmon_1", 1, LC_TIME, ALTMON_1, "(FreeBSD only)" }, + { "altmon_2", 1, LC_TIME, ALTMON_2, "(FreeBSD only)" }, + { "altmon_3", 1, LC_TIME, ALTMON_3, "(FreeBSD only)" }, + { "altmon_4", 1, LC_TIME, ALTMON_4, "(FreeBSD only)" }, + { "altmon_5", 1, LC_TIME, ALTMON_5, "(FreeBSD only)" }, + { "altmon_6", 1, LC_TIME, ALTMON_6, "(FreeBSD only)" }, + { "altmon_7", 1, LC_TIME, ALTMON_7, "(FreeBSD only)" }, + { "altmon_8", 1, LC_TIME, ALTMON_8, "(FreeBSD only)" }, + { "altmon_9", 1, LC_TIME, ALTMON_9, "(FreeBSD only)" }, + { "altmon_10", 1, LC_TIME, ALTMON_10, "(FreeBSD only)" }, + { "altmon_11", 1, LC_TIME, ALTMON_11, "(FreeBSD only)" }, + { "altmon_12", 1, LC_TIME, ALTMON_12, "(FreeBSD only)" }, { "era", 1, LC_TIME, ERA, "(unavailable)" }, { "era_d_fmt", 1, LC_TIME, ERA_D_FMT, "(unavailable)" }, { "era_d_t_fmt", 1, LC_TIME, ERA_D_T_FMT, "(unavailable)" }, From b139165ca65858f96b4f50b3eff846fcce8bdddd Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Wed, 7 Oct 2009 22:21:53 +0000 Subject: [PATCH 088/646] Clarify quoting of word in ${v=word} in sh(1). --- bin/sh/sh.1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 2739dccdd8e..937fda75434 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -1227,6 +1227,9 @@ In all cases, the final value of .Ar parameter is substituted. +Quoting inside +.Ar word +does not prevent field splitting or pathname expansion. Only variables, not positional parameters or special parameters, can be assigned in this way. From c27838c722a2042bcf1f8b2bd1dbe82e0cabcca4 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 7 Oct 2009 23:01:31 +0000 Subject: [PATCH 089/646] Fix build on amd64. PR: misc/139409 Submitted by: gk --- tools/regression/tmpfs/h_tools.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/regression/tmpfs/h_tools.c b/tools/regression/tmpfs/h_tools.c index 1339060bc9a..6e8a236c649 100644 --- a/tools/regression/tmpfs/h_tools.c +++ b/tools/regression/tmpfs/h_tools.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -250,10 +251,10 @@ statvfs_main(int argc, char **argv) return EXIT_FAILURE; } - (void)printf("f_bsize=%llu\n", buf.f_bsize); - (void)printf("f_blocks=%llu\n", buf.f_blocks); - (void)printf("f_bfree=%llu\n", buf.f_bfree); - (void)printf("f_files=%llu\n", buf.f_files); + (void)printf("f_bsize=%ju\n", (uintmax_t)buf.f_bsize); + (void)printf("f_blocks=%ju\n", (uintmax_t)buf.f_blocks); + (void)printf("f_bfree=%ju\n", (uintmax_t)buf.f_bfree); + (void)printf("f_files=%ju\n", (uintmax_t)buf.f_files); return EXIT_SUCCESS; } From 3fa0694aaa00d1c724196f052007a83bf257fca8 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 7 Oct 2009 23:17:15 +0000 Subject: [PATCH 090/646] Add a special workaround to handle UIO_NOCOPY case. This fixes data corruption observed when sendfile() is being used. PR: kern/127213 Submitted by: gk MFC after: 2 weeks --- sys/fs/tmpfs/tmpfs_vnops.c | 118 +++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 59d94d75db9..49a71973877 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -428,42 +430,13 @@ tmpfs_setattr(struct vop_setattr_args *v) } /* --------------------------------------------------------------------- */ - static int -tmpfs_mappedread(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *uio) +tmpfs_nocacheread(vm_object_t tobj, vm_pindex_t idx, + vm_offset_t offset, size_t tlen, struct uio *uio) { - vm_pindex_t idx; vm_page_t m; - vm_offset_t offset; - off_t addr; - size_t tlen; int error; - addr = uio->uio_offset; - idx = OFF_TO_IDX(addr); - offset = addr & PAGE_MASK; - tlen = MIN(PAGE_SIZE - offset, len); - - if ((vobj == NULL) || - (vobj->resident_page_count == 0 && vobj->cache == NULL)) - goto nocache; - - VM_OBJECT_LOCK(vobj); -lookupvpg: - if (((m = vm_page_lookup(vobj, idx)) != NULL) && - vm_page_is_valid(m, offset, tlen)) { - if (vm_page_sleep_if_busy(m, FALSE, "tmfsmr")) - goto lookupvpg; - vm_page_busy(m); - VM_OBJECT_UNLOCK(vobj); - error = uiomove_fromphys(&m, offset, tlen, uio); - VM_OBJECT_LOCK(vobj); - vm_page_wakeup(m); - VM_OBJECT_UNLOCK(vobj); - return (error); - } - VM_OBJECT_UNLOCK(vobj); -nocache: VM_OBJECT_LOCK(tobj); vm_object_pip_add(tobj, 1); m = vm_page_grab(tobj, idx, VM_ALLOC_WIRED | @@ -489,6 +462,89 @@ out: vm_object_pip_subtract(tobj, 1); VM_OBJECT_UNLOCK(tobj); + return (error); +} + +static __inline int +tmpfs_nocacheread_buf(vm_object_t tobj, vm_pindex_t idx, + vm_offset_t offset, size_t tlen, void *buf) +{ + struct uio uio; + struct iovec iov; + + uio.uio_iovcnt = 1; + uio.uio_iov = &iov; + iov.iov_base = buf; + iov.iov_len = tlen; + + uio.uio_offset = 0; + uio.uio_resid = tlen; + uio.uio_rw = UIO_READ; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_td = curthread; + + return (tmpfs_nocacheread(tobj, idx, offset, tlen, &uio)); +} + +static int +tmpfs_mappedread(vm_object_t vobj, vm_object_t tobj, size_t len, struct uio *uio) +{ + struct sf_buf *sf; + vm_pindex_t idx; + vm_page_t m; + vm_offset_t offset; + off_t addr; + size_t tlen; + char *ma; + int error; + + addr = uio->uio_offset; + idx = OFF_TO_IDX(addr); + offset = addr & PAGE_MASK; + tlen = MIN(PAGE_SIZE - offset, len); + + if ((vobj == NULL) || + (vobj->resident_page_count == 0 && vobj->cache == NULL)) + goto nocache; + + VM_OBJECT_LOCK(vobj); +lookupvpg: + if (((m = vm_page_lookup(vobj, idx)) != NULL) && + vm_page_is_valid(m, offset, tlen)) { + if (vm_page_sleep_if_busy(m, FALSE, "tmfsmr")) + goto lookupvpg; + vm_page_busy(m); + VM_OBJECT_UNLOCK(vobj); + error = uiomove_fromphys(&m, offset, tlen, uio); + VM_OBJECT_LOCK(vobj); + vm_page_wakeup(m); + VM_OBJECT_UNLOCK(vobj); + return (error); + } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) { + if (vm_page_sleep_if_busy(m, FALSE, "tmfsmr")) + goto lookupvpg; + vm_page_busy(m); + VM_OBJECT_UNLOCK(vobj); + sched_pin(); + sf = sf_buf_alloc(m, SFB_CPUPRIVATE); + ma = (char *)sf_buf_kva(sf); + error = tmpfs_nocacheread_buf(tobj, idx, offset, tlen, + ma + offset); + if (error == 0) { + uio->uio_offset += tlen; + uio->uio_resid -= tlen; + } + sf_buf_free(sf); + sched_unpin(); + VM_OBJECT_LOCK(vobj); + vm_page_wakeup(m); + VM_OBJECT_UNLOCK(vobj); + return (error); + } + VM_OBJECT_UNLOCK(vobj); +nocache: + error = tmpfs_nocacheread(tobj, idx, offset, tlen, uio); + return (error); } From 4a11e7f142b1ff9a7c10cf090ff2ff29c9b86258 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 8 Oct 2009 10:26:49 +0000 Subject: [PATCH 091/646] Discard Device Control Strings and Operating System Commands. These strings often contain things like: - Window titles. - Extended key map functionality. - Color palette switching. We could look at these features in the future (if people consider them to be important enough), but we'd better discard them now. This fixes some artifacts people reported when using TERM=xterm. Reported by: des@, Paul B. Mahol --- sys/teken/sequences | 1 + sys/teken/teken.c | 19 +++++++++++++++++++ sys/teken/teken_subr.h | 18 +++++++++++++++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/sys/teken/sequences b/sys/teken/sequences index 957665a02f5..cf720b0ca0f 100644 --- a/sys/teken/sequences +++ b/sys/teken/sequences @@ -88,6 +88,7 @@ ICH Insert character ^[ [ @ n IL Insert line ^[ [ L n IND Index ^[ D NEL Next line ^[ E +OSC Operating System Command ^[ ] RI Reverse index ^[ M RIS Reset to Initial State ^[ c RM Reset Mode ^[ [ l r diff --git a/sys/teken/teken.c b/sys/teken/teken.c index c8d6b09cc33..81b8ac08f81 100644 --- a/sys/teken/teken.c +++ b/sys/teken/teken.c @@ -56,6 +56,7 @@ static FILE *df; #define TS_WRAPPED 0x10 /* Next character should be printed on col 0. */ #define TS_8BIT 0x20 /* UTF-8 disabled. */ #define TS_CONS25 0x40 /* cons25 emulation. */ +#define TS_INSTRING 0x80 /* Inside string. */ /* Character that blanks a cell. */ #define BLANK ' ' @@ -176,6 +177,24 @@ static void teken_input_char(teken_t *t, teken_char_t c) { + /* + * There is no support for DCS and OSC. Just discard strings + * until we receive characters that may indicate string + * termination. + */ + if (t->t_stateflags & TS_INSTRING) { + switch (c) { + case '\x1B': + t->t_stateflags &= ~TS_INSTRING; + break; + case '\a': + t->t_stateflags &= ~TS_INSTRING; + return; + default: + return; + } + } + switch (c) { case '\0': break; diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h index b8ebcdc1302..ad10abbb6fd 100644 --- a/sys/teken/teken_subr.h +++ b/sys/teken/teken_subr.h @@ -425,10 +425,11 @@ teken_subr_delete_line(teken_t *t, unsigned int nrows) } static void -teken_subr_device_control_string(teken_t *t __unused) +teken_subr_device_control_string(teken_t *t) { - teken_printf("device control string???\n"); + teken_printf("Unsupported device control string\n"); + t->t_stateflags |= TS_INSTRING; } static void @@ -743,6 +744,14 @@ teken_subr_next_line(teken_t *t) teken_subr_newline(t); } +static void +teken_subr_operating_system_command(teken_t *t) +{ + + teken_printf("Unsupported operating system command\n"); + t->t_stateflags |= TS_INSTRING; +} + static void teken_subr_pan_down(teken_t *t, unsigned int nrows) { @@ -1258,7 +1267,10 @@ static void teken_subr_string_terminator(teken_t *t __unused) { - teken_printf("string terminator???\n"); + /* + * Strings are already terminated in teken_input_char() when ^[ + * is inserted. + */ } static void From 806a5b8414f616eecbd7b1cf37c902df2ede3dd9 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 8 Oct 2009 11:36:06 +0000 Subject: [PATCH 092/646] Fix so that round robing stream scheduling works as advertised MFC after: 0 days --- sys/netinet/sctp_output.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index b9750b9d50e..f581f0df77a 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -5602,8 +5602,6 @@ sctp_insert_on_wheel(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, int holds_lock) { - struct sctp_stream_out *stre, *strn; - if (holds_lock == 0) { SCTP_TCB_SEND_LOCK(stcb); } @@ -5612,26 +5610,7 @@ sctp_insert_on_wheel(struct sctp_tcb *stcb, /* already on wheel */ goto outof_here; } - stre = TAILQ_FIRST(&asoc->out_wheel); - if (stre == NULL) { - /* only one on wheel */ - TAILQ_INSERT_HEAD(&asoc->out_wheel, strq, next_spoke); - goto outof_here; - } - for (; stre; stre = strn) { - strn = TAILQ_NEXT(stre, next_spoke); - if (stre->stream_no > strq->stream_no) { - TAILQ_INSERT_BEFORE(stre, strq, next_spoke); - goto outof_here; - } else if (stre->stream_no == strq->stream_no) { - /* huh, should not happen */ - goto outof_here; - } else if (strn == NULL) { - /* next one is null */ - TAILQ_INSERT_AFTER(&asoc->out_wheel, stre, strq, - next_spoke); - } - } + TAILQ_INSERT_TAIL(&asoc->out_wheel, strq, next_spoke); outof_here: if (holds_lock == 0) { SCTP_TCB_SEND_UNLOCK(stcb); @@ -7202,8 +7181,6 @@ done_it: if (strq == NULL) { strq = asoc->last_out_stream = TAILQ_FIRST(&asoc->out_wheel); } - /* Save off the last stream */ - asoc->last_out_stream = strq; return (strq); } @@ -7280,7 +7257,9 @@ sctp_fill_outqueue(struct sctp_tcb *stcb, bail = 0; moved_how_much = sctp_move_to_outqueue(stcb, net, strq, goal_mtu, frag_point, &locked, &giveup, eeor_mode, &bail); - asoc->last_out_stream = strq; + if (moved_how_much) + asoc->last_out_stream = strq; + if (locked) { asoc->locked_on_sending = strq; if ((moved_how_much == 0) || (giveup) || bail) From 987a09e8f816bb3eb4f1e720a8b939cb939b2528 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 8 Oct 2009 15:34:01 +0000 Subject: [PATCH 093/646] 'aclmode' and 'aclinherit' properties should work as advertised; don't refuse to set them. --- cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index 58ce6c8fa20..f1cc27b7168 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -1792,8 +1792,6 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) switch (prop) { case ZFS_PROP_SHAREISCSI: case ZFS_PROP_DEVICES: - case ZFS_PROP_ACLMODE: - case ZFS_PROP_ACLINHERIT: case ZFS_PROP_ISCSIOPTIONS: (void) snprintf(errbuf, sizeof (errbuf), "property '%s' not supported on FreeBSD", propname); From 68c53ef84980bd7e858da36be8b550893085978d Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 8 Oct 2009 16:03:19 +0000 Subject: [PATCH 094/646] File system owner is when uid matches and jail matches. MFC after: 3 days --- sys/cddl/compat/opensolaris/kern/opensolaris_policy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c index cedf335257d..040f27d6e5f 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c @@ -78,12 +78,11 @@ secpolicy_fs_owner(struct mount *mp, struct ucred *cred) if (zfs_super_owner) { if (cred->cr_uid == mp->mnt_cred->cr_uid && - (!jailed(cred) || - cred->cr_prison == mp->mnt_cred->cr_prison)) { + cred->cr_prison == mp->mnt_cred->cr_prison) { return (0); } } - return (priv_check_cred(cred, PRIV_VFS_MOUNT_OWNER, 0)); + return (EPERM); } /* From c217b20ef6dbb61de76e4c194d03cdb0cffcbb01 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 8 Oct 2009 16:05:17 +0000 Subject: [PATCH 095/646] Allow file system owner to modify system flags if securelevel permits. MFC after: 3 days --- .../opensolaris/kern/opensolaris_policy.c | 5 ++++- sys/cddl/compat/opensolaris/sys/policy.h | 3 ++- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 21 ++++++++++--------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c index 040f27d6e5f..865fba337f5 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c @@ -358,8 +358,11 @@ secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp) * Check privileges for setting xvattr attributes */ int -secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype) +secpolicy_xvattr(struct vnode *vp, xvattr_t *xvap, uid_t owner, cred_t *cr, + vtype_t vtype) { + if (secpolicy_fs_owner(vp->v_mount, cr) == 0) + return (0); return (priv_check_cred(cr, PRIV_VFS_SYSFLAGS, 0)); } diff --git a/sys/cddl/compat/opensolaris/sys/policy.h b/sys/cddl/compat/opensolaris/sys/policy.h index 08db5ca763d..6731d7cbcd4 100644 --- a/sys/cddl/compat/opensolaris/sys/policy.h +++ b/sys/cddl/compat/opensolaris/sys/policy.h @@ -70,7 +70,8 @@ int secpolicy_setid_setsticky_clear(struct vnode *vp, struct vattr *vap, int secpolicy_fs_owner(struct mount *vfsp, struct ucred *cred); int secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct mount *vfsp); void secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp); -int secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype); +int secpolicy_xvattr(struct vnode *vp, xvattr_t *xvap, uid_t owner, + cred_t *cr, vtype_t vtype); #endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 4136e7d66c8..6d9ec9cd4a7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -1306,7 +1306,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode, } if (vap->va_mask & AT_XVATTR) { - if ((error = secpolicy_xvattr((xvattr_t *)vap, + if ((error = secpolicy_xvattr(dvp, (xvattr_t *)vap, crgetuid(cr), cr, vap->va_type)) != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -1758,7 +1758,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, zf |= ZCILOOK; if (vap->va_mask & AT_XVATTR) - if ((error = secpolicy_xvattr((xvattr_t *)vap, + if ((error = secpolicy_xvattr(dvp, (xvattr_t *)vap, crgetuid(cr), cr, vap->va_type)) != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -4205,12 +4205,6 @@ zfs_freebsd_setattr(ap) fflags = vap->va_flags; if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0) return (EOPNOTSUPP); - /* - * Callers may only modify the file flags on objects they - * have VADMIN rights for. - */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, curthread)) != 0) - return (error); /* * Unprivileged processes are not permitted to unset system * flags, or modify flags if any system flags are set. @@ -4221,14 +4215,21 @@ zfs_freebsd_setattr(ap) * is non-zero; otherwise, they behave like unprivileged * processes. */ - if (priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0) == 0) { + if (secpolicy_fs_owner(vp->v_mount, cred) == 0 || + priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0) == 0) { if (zflags & (ZFS_IMMUTABLE | ZFS_APPENDONLY | ZFS_NOUNLINK)) { error = securelevel_gt(cred, 0); - if (error) + if (error != 0) return (error); } } else { + /* + * Callers may only modify the file flags on objects they + * have VADMIN rights for. + */ + if ((error = VOP_ACCESS(vp, VADMIN, cred, curthread)) != 0) + return (error); if (zflags & (ZFS_IMMUTABLE | ZFS_APPENDONLY | ZFS_NOUNLINK)) { return (EPERM); From a7e2341e20a38619ffecb850186736ca89e0243c Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Thu, 8 Oct 2009 17:41:53 +0000 Subject: [PATCH 096/646] Clean up amd64 suspend/resume code. - Allocate memory for wakeup code after ACPI bus is attached. The early memory allocation hack was inherited from i386 but amd64 does not need it. - Exclude real mode IVT and BDA explicitly. Improve comments about memory allocation and reason for the exclusions. It is a no-op in reality, though. - Remove an unnecessary CLD from wakeup code and re-align. --- sys/amd64/acpica/acpi_machdep.c | 13 +++++++-- sys/amd64/acpica/acpi_wakecode.S | 6 ++-- sys/amd64/acpica/acpi_wakeup.c | 49 ++++++++++++++------------------ 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c index 9d62ab5c81e..7e7a01aef50 100644 --- a/sys/amd64/acpica/acpi_machdep.c +++ b/sys/amd64/acpica/acpi_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include + #include #include @@ -511,7 +512,6 @@ acpi_machdep_init(device_t dev) sc->acpi_clone = apm_create_clone(sc->acpi_dev_t, sc); clone_setup(&apm_clones); EVENTHANDLER_REGISTER(dev_clone, apm_clone, 0, 1000); - acpi_install_wakeup_handler(sc); if (intr_model != ACPI_INTR_PIC) acpi_SetIntrModel(intr_model); @@ -801,13 +801,20 @@ nexus_acpi_probe(device_t dev) static int nexus_acpi_attach(device_t dev) { + device_t acpi_dev; + int error; nexus_init_resources(); bus_generic_probe(dev); - if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL) + acpi_dev = BUS_ADD_CHILD(dev, 10, "acpi", 0); + if (acpi_dev == NULL) panic("failed to add acpi0 device"); - return (bus_generic_attach(dev)); + error = bus_generic_attach(dev); + if (error == 0) + acpi_install_wakeup_handler(device_get_softc(acpi_dev)); + + return (error); } static device_method_t nexus_acpi_methods[] = { diff --git a/sys/amd64/acpica/acpi_wakecode.S b/sys/amd64/acpica/acpi_wakecode.S index 4e82f53196a..1372cc1a2d0 100644 --- a/sys/amd64/acpica/acpi_wakecode.S +++ b/sys/amd64/acpica/acpi_wakecode.S @@ -54,18 +54,17 @@ .data /* So we can modify it */ ALIGN_TEXT -wakeup_start: .code16 +wakeup_start: /* * Set up segment registers for real mode, a small stack for * any calls we make, and clear any flags. */ cli /* make sure no interrupts */ - cld mov %cs, %ax /* copy %cs to %ds. Remember these */ mov %ax, %ds /* are offsets rather than selectors */ mov %ax, %ss - movw $PAGE_SIZE - 8, %sp + movw $PAGE_SIZE, %sp xorw %ax, %ax pushw %ax popfw @@ -129,6 +128,7 @@ wakeup_sw32: /* * At this point, we are running in 32 bit legacy protected mode. */ + ALIGN_TEXT .code32 wakeup_32: diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c index bcc405fca0a..cfc960b3951 100644 --- a/sys/amd64/acpica/acpi_wakeup.c +++ b/sys/amd64/acpica/acpi_wakeup.c @@ -31,13 +31,11 @@ __FBSDID("$FreeBSD$"); #include -#include #include #include #include #include #include -#include #include #include @@ -46,11 +44,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #ifdef SMP #include #include +#include #endif #include @@ -63,10 +61,6 @@ __FBSDID("$FreeBSD$"); /* Make sure the code is less than a page and leave room for the stack. */ CTASSERT(sizeof(wakecode) < PAGE_SIZE - 1024); -#ifndef _SYS_CDEFS_H_ -#error this file needs sys/cdefs.h as a prerequisite -#endif - extern int acpi_resume_beep; extern int acpi_reset_video; @@ -79,7 +73,7 @@ static struct xpcb *stopxpcbs; int acpi_restorecpu(struct xpcb *, vm_offset_t); int acpi_savecpu(struct xpcb *); -static void acpi_alloc_wakeup_handler(void); +static void *acpi_alloc_wakeup_handler(void); static void acpi_stop_beep(void *); #ifdef SMP @@ -322,49 +316,50 @@ out: return (ret); } -static vm_offset_t acpi_wakeaddr; - -static void +static void * acpi_alloc_wakeup_handler(void) { void *wakeaddr; - if (!cold) - return; - /* * Specify the region for our wakeup code. We want it in the low 1 MB - * region, excluding video memory and above (0xa0000). We ask for - * it to be page-aligned, just to be safe. + * region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA + * (less than 128KB, below 0xa0000, must be excluded by SMAP and DSDT), + * and ROM area (0xa0000 and above). The temporary page tables must be + * page-aligned. */ - wakeaddr = contigmalloc(4 * PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0, 0x9ffff, - PAGE_SIZE, 0ul); + wakeaddr = contigmalloc(4 * PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0x500, + 0xa0000, PAGE_SIZE, 0ul); if (wakeaddr == NULL) { printf("%s: can't alloc wake memory\n", __func__); - return; + return (NULL); } stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_NOWAIT); if (stopxpcbs == NULL) { contigfree(wakeaddr, 4 * PAGE_SIZE, M_DEVBUF); printf("%s: can't alloc CPU state memory\n", __func__); - return; + return (NULL); } - acpi_wakeaddr = (vm_offset_t)wakeaddr; -} -SYSINIT(acpiwakeup, SI_SUB_KMEM, SI_ORDER_ANY, acpi_alloc_wakeup_handler, 0); + return (wakeaddr); +} void acpi_install_wakeup_handler(struct acpi_softc *sc) { + static void *wakeaddr = NULL; uint64_t *pt4, *pt3, *pt2; int i; - if (acpi_wakeaddr == 0ul) + if (wakeaddr != NULL) return; - sc->acpi_wakeaddr = acpi_wakeaddr; - sc->acpi_wakephys = vtophys(acpi_wakeaddr); + wakeaddr = acpi_alloc_wakeup_handler(); + if (wakeaddr == NULL) + return; + + sc->acpi_wakeaddr = (vm_offset_t)wakeaddr; + sc->acpi_wakephys = vtophys(wakeaddr); bcopy(wakecode, (void *)WAKECODE_VADDR(sc), sizeof(wakecode)); @@ -390,7 +385,7 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) WAKECODE_FIXUP(wakeup_sfmask, uint64_t, rdmsr(MSR_SF_MASK)); /* Build temporary page tables below realmode code. */ - pt4 = (uint64_t *)acpi_wakeaddr; + pt4 = wakeaddr; pt3 = pt4 + (PAGE_SIZE) / sizeof(uint64_t); pt2 = pt3 + (PAGE_SIZE) / sizeof(uint64_t); From 9384d88a51510ddeb410ff4bf3fe8f3859820d4e Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 8 Oct 2009 19:45:37 +0000 Subject: [PATCH 097/646] Properly mark ZFS properties which are not changeable under FreeBSD. Reviewed by: pjd --- .../contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index f1cc27b7168..f3b132f1fc8 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -1790,9 +1790,14 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) /* We don't support those properties on FreeBSD. */ switch (prop) { - case ZFS_PROP_SHAREISCSI: case ZFS_PROP_DEVICES: + case ZFS_PROP_ZONED: + case ZFS_PROP_SHAREISCSI: case ZFS_PROP_ISCSIOPTIONS: + case ZFS_PROP_XATTR: + case ZFS_PROP_VSCAN: + case ZFS_PROP_NBMAND: + case ZFS_PROP_SHARESMB: (void) snprintf(errbuf, sizeof (errbuf), "property '%s' not supported on FreeBSD", propname); ret = zfs_error(hdl, EZFS_PERM, errbuf); From 9dd512290c313caac5d14a25807c43ac70466137 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 8 Oct 2009 20:33:12 +0000 Subject: [PATCH 098/646] Use correct arguments when calling SCTP_RTALLOC(). Approved by: rrs (mentor) MFC after: 0 days --- sys/netinet/sctp_output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index f581f0df77a..a99fc691230 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3570,7 +3570,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctp_free_ifa(_lsrc); } else { ip->ip_src = over_addr->sin.sin_addr; - SCTP_RTALLOC((&ro->ro_rt), vrf_id); + SCTP_RTALLOC(ro, vrf_id); } } if (port) { @@ -3924,7 +3924,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctp_free_ifa(_lsrc); } else { lsa6->sin6_addr = over_addr->sin6.sin6_addr; - SCTP_RTALLOC((&ro->ro_rt), vrf_id); + SCTP_RTALLOC(ro, vrf_id); } (void)sa6_recoverscope(sin6); } From 9cdcd1c5205b4a756c86982dedd04e72d79a3452 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Fri, 9 Oct 2009 09:29:59 +0000 Subject: [PATCH 099/646] Export disk serial numbers for adaX disks. Reviewed by: mav MFC after: 3 days --- sys/cam/ata/ata_da.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 7d7230b154f..622b91b250a 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -721,6 +721,8 @@ adaregister(struct cam_periph *periph, void *arg) softc->disk->d_flags = 0; if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; + strlcpy(softc->disk->d_ident, cgd->serial_num, + MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1)); adasetgeom(periph, cgd); softc->disk->d_sectorsize = softc->params.secsize; From 65b8d0b5ad22cc3a65acf03ff14d04ea520044ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 9 Oct 2009 09:38:57 +0000 Subject: [PATCH 100/646] Merge upstream r421: grammar nit in pam.conf(5). --- doc/man/pam.conf.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/man/pam.conf.5 b/doc/man/pam.conf.5 index 8ffb6a32b0d..d94163d13ba 100644 --- a/doc/man/pam.conf.5 +++ b/doc/man/pam.conf.5 @@ -109,7 +109,7 @@ will be failure regardless of the success of later modules. .It Cm requisite If this module succeeds, the result of the chain will be success unless a later module fails. -If it module fails, the chain is broken and the result is failure. +If the module fails, the chain is broken and the result is failure. .It Cm sufficient If this module succeeds, the chain is broken and the result is success. From f8727e71d75636984159403a82819796731872ae Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Fri, 9 Oct 2009 09:42:22 +0000 Subject: [PATCH 101/646] If provider is open for writing when we taste it, skip it for classes that depend on on-disk metadata. This was we won't attach to providers that are used by other classes. For example we don't want to configure partitions on da0 if it is part of gmirror, what we really want is partitions on mirror/foo. During regular work it works like this: if provider is open for writing a class receives the spoiled event from GEOM and detaches, once provider is closed the taste event is send again and class can rediscover its metadata if it is still there. This doesn't work that way when new class arrives, because GEOM gives all existing providers for it to taste, also those open for writing. Classes have to decided on their own if they want to deal with such providers (eg. geom_dev) or not (classes modified by this commit). Reported by: des, Oliver Lehmann Tested by: des, Oliver Lehmann Discussed with: phk, marcel Reviewed by: marcel MFC after: 3 days --- sys/geom/concat/g_concat.c | 4 ++++ sys/geom/label/g_label.c | 4 ++++ sys/geom/part/g_part.c | 4 ++++ sys/geom/shsec/g_shsec.c | 4 ++++ sys/geom/stripe/g_stripe.c | 4 ++++ sys/geom/uzip/g_uzip.c | 5 +++++ 6 files changed, 25 insertions(+) diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index 021c9f56fc0..a12f7b830e0 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -599,6 +599,10 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); g_topology_assert(); + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + G_CONCAT_DEBUG(3, "Tasting %s.", pp->name); gp = g_new_geomf(mp, "concat:taste"); diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c index 0a22dcfabb3..e39c2335e74 100644 --- a/sys/geom/label/g_label.c +++ b/sys/geom/label/g_label.c @@ -271,6 +271,10 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_LABEL_DEBUG(2, "Tasting %s.", pp->name); + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + if (strcmp(pp->geom->class->name, mp->name) == 0) return (NULL); diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index 6e81a9c70b6..92a1db0f3ee 100644 --- a/sys/geom/part/g_part.c +++ b/sys/geom/part/g_part.c @@ -1459,6 +1459,10 @@ g_part_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_PART_TRACE((G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name)); g_topology_assert(); + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + /* * Create a GEOM with consumer and hook it up to the provider. * With that we become part of the topology. Optain read access diff --git a/sys/geom/shsec/g_shsec.c b/sys/geom/shsec/g_shsec.c index 96650cf5a83..7be39bb648d 100644 --- a/sys/geom/shsec/g_shsec.c +++ b/sys/geom/shsec/g_shsec.c @@ -638,6 +638,10 @@ g_shsec_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); g_topology_assert(); + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + G_SHSEC_DEBUG(3, "Tasting %s.", pp->name); gp = g_new_geomf(mp, "shsec:taste"); diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c index 17e258ce67b..81f75610777 100644 --- a/sys/geom/stripe/g_stripe.c +++ b/sys/geom/stripe/g_stripe.c @@ -912,6 +912,10 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); g_topology_assert(); + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + G_STRIPE_DEBUG(3, "Tasting %s.", pp->name); gp = g_new_geomf(mp, "stripe:taste"); diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c index 99d7c222afe..90eee02f248 100644 --- a/sys/geom/uzip/g_uzip.c +++ b/sys/geom/uzip/g_uzip.c @@ -363,6 +363,11 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags) g_trace(G_T_TOPOLOGY, "g_uzip_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + buf = NULL; /* From 6be57b604fac4bf860582c5146d7e7a6054b6d73 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 9 Oct 2009 10:03:41 +0000 Subject: [PATCH 102/646] Improved one-line description of this module (taken from NOTES). --- share/man/man4/lindev.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/lindev.4 b/share/man/man4/lindev.4 index b2dc60efc80..199bd8d6fd1 100644 --- a/share/man/man4/lindev.4 +++ b/share/man/man4/lindev.4 @@ -30,7 +30,7 @@ .Os .Sh NAME .Nm lindev -.Nd the lindev module +.Nd Linux-specific pseudo devices support .Sh SYNOPSIS To compile this collection of linux-specific pseudo devices into the kernel, place the following line in your kernel configuration file: From 8448afced87232ebe05d920dcd9b351ea1cf33a6 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 9 Oct 2009 15:51:40 +0000 Subject: [PATCH 103/646] atomic_cmpset_barr_* was added in order to cope with compilers willing to specify their own version of atomic_cmpset_* which could have been different than the membar version. Right now, however, FreeBSD is bound mostly to GCC-like compilers and it is desired to add new support and compat shim mostly when there is a real necessity, in order to avoid too much compatibility bloats. In this optic, bring back atomic_cmpset_{acq, rel}_* to be the same as atomic_cmpset_* and unwind the atomic_cmpset_barr_* introduction. Requested by: jhb Reviewed by: jhb Tested by: Giovanni Trematerra --- sys/amd64/include/atomic.h | 76 ++++++++++++++----------- sys/i386/include/atomic.h | 112 ++++++++++++++++--------------------- 2 files changed, 92 insertions(+), 96 deletions(-) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 7d7199c9d7e..a2bd93002e8 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -78,8 +78,6 @@ void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); -int atomic_cmpset_barr_int(volatile u_int *dst, u_int exp, u_int src); -int atomic_cmpset_barr_long(volatile u_long *dst, u_long exp, u_long src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); u_long atomic_fetchadd_long(volatile u_long *p, u_long v); @@ -131,33 +129,47 @@ struct __hack * Returns 0 on failure, non-zero on success */ -#define DEFINE_CMPSET_GEN(NAME, TYPE, OP) \ -static __inline int \ -atomic_cmpset_##NAME(volatile u_##TYPE *dst, u_##TYPE exp, u_##TYPE src)\ -{ \ - u_char res; \ - \ - __asm __volatile( \ - " " MPLOCKED " " \ - " " OP " %2,%1 ; " \ - " sete %0 ; " \ - "1: " \ - "# atomic_cmpset_##NAME" \ - : "=a" (res), /* 0 */ \ - "=m" (*dst) /* 1 */ \ - : "r" (src), /* 2 */ \ - "a" (exp), /* 3 */ \ - "m" (*dst) /* 4 */ \ - : "memory"); \ - \ - return (res); \ -} \ -struct __hack +static __inline int +atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) +{ + u_char res; -DEFINE_CMPSET_GEN(int, int, "cmpxchgl"); -DEFINE_CMPSET_GEN(long, long, "cmpxchgq"); -DEFINE_CMPSET_GEN(barr_int, int, "cmpxchgl"); -DEFINE_CMPSET_GEN(barr_long, long, "cmpxchgq"); + __asm __volatile( + " " MPLOCKED " " + " cmpxchgl %2,%1 ; " + " sete %0 ; " + "1: " + "# atomic_cmpset_int" + : "=a" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "a" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} + +static __inline int +atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " cmpxchgq %2,%1 ; " + " sete %0 ; " + "1: " + "# atomic_cmpset_long" + : "=a" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "a" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} /* * Atomically add the value of v to the integer pointed to by p and return @@ -358,8 +370,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_int atomic_add_barr_int #define atomic_subtract_acq_int atomic_subtract_barr_int #define atomic_subtract_rel_int atomic_subtract_barr_int -#define atomic_cmpset_acq_int atomic_cmpset_barr_int -#define atomic_cmpset_rel_int atomic_cmpset_barr_int +#define atomic_cmpset_acq_int atomic_cmpset_int +#define atomic_cmpset_rel_int atomic_cmpset_int #define atomic_set_acq_long atomic_set_barr_long #define atomic_set_rel_long atomic_set_barr_long @@ -369,8 +381,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_long atomic_add_barr_long #define atomic_subtract_acq_long atomic_subtract_barr_long #define atomic_subtract_rel_long atomic_subtract_barr_long -#define atomic_cmpset_acq_long atomic_cmpset_barr_long -#define atomic_cmpset_rel_long atomic_cmpset_barr_long +#define atomic_cmpset_acq_long atomic_cmpset_long +#define atomic_cmpset_rel_long atomic_cmpset_long /* Operations on 8-bit bytes. */ #define atomic_set_8 atomic_set_char diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index b60f2a14ea9..b00eb45592f 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -77,7 +77,6 @@ void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \ void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); -int atomic_cmpset_barr_int(volatile u_int *dst, u_int exp, u_int src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); #define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ @@ -130,63 +129,56 @@ struct __hack #ifdef CPU_DISABLE_CMPXCHG -#define DEFINE_CMPSET_GEN(NAME) \ -static __inline int \ -atomic_cmpset_##NAME(volatile u_int *dst, u_int exp, u_int src)\ -{ \ - u_char res; \ - \ - __asm __volatile( \ - " pushfl ; " \ - " cli ; " \ - " cmpl %3,%4 ; " \ - " jne 1f ; " \ - " movl %2,%1 ; " \ - "1: " \ - " sete %0 ; " \ - " popfl ; " \ - "# atomic_cmpset_##NAME" \ - : "=q" (res), /* 0 */ \ - "=m" (*dst) /* 1 */ \ - : "r" (src), /* 2 */ \ - "r" (exp), /* 3 */ \ - "m" (*dst) /* 4 */ \ - : "memory"); \ - \ - return (res); \ -} \ -struct __hack +static __inline int +atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) +{ + u_char res; + + __asm __volatile( + " pushfl ; " + " cli ; " + " cmpl %3,%4 ; " + " jne 1f ; " + " movl %2,%1 ; " + "1: " + " sete %0 ; " + " popfl ; " + "# atomic_cmpset_int" + : "=q" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "r" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} #else /* !CPU_DISABLE_CMPXCHG */ -#define DEFINE_CMPSET_GEN(NAME) \ -static __inline int \ -atomic_cmpset_##NAME(volatile u_int *dst, u_int exp, u_int src)\ -{ \ - u_char res; \ - \ - __asm __volatile( \ - " " MPLOCKED " " \ - " cmpxchgl %2,%1 ; " \ - " sete %0 ; " \ - "1: " \ - "# atomic_cmpset_##NAME" \ - : "=a" (res), /* 0 */ \ - "=m" (*dst) /* 1 */ \ - : "r" (src), /* 2 */ \ - "a" (exp), /* 3 */ \ - "m" (*dst) /* 4 */ \ - : "memory"); \ - \ - return (res); \ -} \ -struct __hack +static __inline int +atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " cmpxchgl %2,%1 ; " + " sete %0 ; " + "1: " + "# atomic_cmpset_int" + : "=a" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "a" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} #endif /* CPU_DISABLE_CMPXCHG */ -DEFINE_CMPSET_GEN(int); -DEFINE_CMPSET_GEN(barr_int); - /* * Atomically add the value of v to the integer pointed to by p and return * the previous value of *p. @@ -307,14 +299,6 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) (u_int)src)); } -static __inline int -atomic_cmpset_barr_long(volatile u_long *dst, u_long exp, u_long src) -{ - - return (atomic_cmpset_barr_int((volatile u_int *)dst, (u_int)exp, - (u_int)src)); -} - static __inline u_long atomic_fetchadd_long(volatile u_long *p, u_long v) { @@ -390,8 +374,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_int atomic_add_barr_int #define atomic_subtract_acq_int atomic_subtract_barr_int #define atomic_subtract_rel_int atomic_subtract_barr_int -#define atomic_cmpset_acq_int atomic_cmpset_barr_int -#define atomic_cmpset_rel_int atomic_cmpset_barr_int +#define atomic_cmpset_acq_int atomic_cmpset_int +#define atomic_cmpset_rel_int atomic_cmpset_int #define atomic_set_acq_long atomic_set_barr_long #define atomic_set_rel_long atomic_set_barr_long @@ -401,8 +385,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_long atomic_add_barr_long #define atomic_subtract_acq_long atomic_subtract_barr_long #define atomic_subtract_rel_long atomic_subtract_barr_long -#define atomic_cmpset_acq_long atomic_cmpset_barr_long -#define atomic_cmpset_rel_long atomic_cmpset_barr_long +#define atomic_cmpset_acq_long atomic_cmpset_long +#define atomic_cmpset_rel_long atomic_cmpset_long /* Operations on 8-bit bytes. */ #define atomic_set_8 atomic_set_char From 3b1de911e0962cfd77abae70a6b92140bdeeb2fd Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Fri, 9 Oct 2009 19:30:23 +0000 Subject: [PATCH 104/646] Do not include vnet.h twice. Approved by: rrs (mentor) MFC after: 3 days --- sys/netinet/sctp_os_bsd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index f0cca72c76d..b123d3d034a 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include From 200b56607f48198d80f60019a07c486e70d318df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ermal=20Lu=C3=A7i?= Date: Sat, 10 Oct 2009 03:32:46 +0000 Subject: [PATCH 105/646] Fix typo which has survived amazingly long! Approved by: mlaier(mentor) MFC after: 3 days --- sys/modules/pf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/pf/Makefile b/sys/modules/pf/Makefile index c921f806a66..78aa564576b 100644 --- a/sys/modules/pf/Makefile +++ b/sys/modules/pf/Makefile @@ -28,7 +28,7 @@ opt_bpf.h: # pflog can be loaded as a module, have the additional checks turned on opt_pf.h: echo "#define DEV_PF 1" > ${.TARGET} - echo "#define DEF_PFLOG 1" >> ${.TARGET} + echo "#define DEV_PFLOG 1" >> ${.TARGET} .endif .include From 45623593fb3beb3725d278ecb9bf1cc4e6eacab6 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 10 Oct 2009 13:59:18 +0000 Subject: [PATCH 106/646] Correct include order as indicated by bz. Approved by: re (mentor) MFC after: 3 days --- sys/netinet/sctp_os_bsd.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index b123d3d034a..00878c4528b 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -77,8 +78,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #ifdef IPSEC #include #include From 47d81c1b70389d74d905484a28550a29d97529a7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 14:56:34 +0000 Subject: [PATCH 107/646] Postpone dropping fp till both kq_global and kqueue mutexes are unlocked. fdrop() closes file descriptor when reference count goes to zero. Close method for vnodes locks the vnode, resulting in "sleepable after non-sleepable". For pipes, pipe mutex is before kqueue lock, causing LOR. Reported and tested by: pho MFC after: 2 weeks --- sys/kern/kern_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 478432e2072..7c405945cdc 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1025,13 +1025,13 @@ findkn: /* knote is in the process of changing, wait for it to stablize. */ if (kn != NULL && (kn->kn_status & KN_INFLUX) == KN_INFLUX) { + KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); + kq->kq_state |= KQ_FLUXWAIT; + msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0); if (fp != NULL) { fdrop(fp, td); fp = NULL; } - KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); - kq->kq_state |= KQ_FLUXWAIT; - msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0); goto findkn; } From dec4912e62917bca9afd7b67fb2d9e04129c99ce Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 15:27:10 +0000 Subject: [PATCH 108/646] Calculate relocation base for the main object, and apply the relocation adjustment for all virtual addresses encoded into the ELF structures of it. PIE binary could and should be loaded at non-zero mapbase. For sym_zero pseudosymbol used as a return value from find_symdef() for undefined weak symbols, st_value also should be adjusted, since _rtld_bind corrects symbol values by relocbase. Discussed with: bz Reviewed by: kan Tested by: bz (i386, amd64), bsam (linux) MFC after: some time --- libexec/rtld-elf/rtld.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 721fe8967eb..2eebf220b5c 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -474,6 +474,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) /* Initialize a fake symbol for resolving undefined weak references. */ sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); sym_zero.st_shndx = SHN_UNDEF; + sym_zero.st_value = -(uintptr_t)obj_main->relocbase; if (!libmap_disable) libmap_disable = (bool)lm_init(libmap_override); @@ -990,27 +991,27 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) int nsegs = 0; obj = obj_new(); + for (ph = phdr; ph < phlimit; ph++) { + if (ph->p_type != PT_PHDR) + continue; + + obj->phdr = phdr; + obj->phsize = ph->p_memsz; + obj->relocbase = (caddr_t)phdr - ph->p_vaddr; + break; + } + for (ph = phdr; ph < phlimit; ph++) { switch (ph->p_type) { - case PT_PHDR: - if ((const Elf_Phdr *)ph->p_vaddr != phdr) { - _rtld_error("%s: invalid PT_PHDR", path); - return NULL; - } - obj->phdr = (const Elf_Phdr *) ph->p_vaddr; - obj->phsize = ph->p_memsz; - break; - case PT_INTERP: - obj->interp = (const char *) ph->p_vaddr; + obj->interp = (const char *)(ph->p_vaddr + obj->relocbase); break; case PT_LOAD: if (nsegs == 0) { /* First load segment */ obj->vaddrbase = trunc_page(ph->p_vaddr); - obj->mapbase = (caddr_t) obj->vaddrbase; - obj->relocbase = obj->mapbase - obj->vaddrbase; + obj->mapbase = obj->vaddrbase + obj->relocbase; obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) - obj->vaddrbase; } else { /* Last load segment */ @@ -1021,7 +1022,7 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) break; case PT_DYNAMIC: - obj->dynamic = (const Elf_Dyn *) ph->p_vaddr; + obj->dynamic = (const Elf_Dyn *)(ph->p_vaddr + obj->relocbase); break; case PT_TLS: @@ -1029,7 +1030,7 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) obj->tlssize = ph->p_memsz; obj->tlsalign = ph->p_align; obj->tlsinitsize = ph->p_filesz; - obj->tlsinit = (void*) ph->p_vaddr; + obj->tlsinit = (void*)(ph->p_vaddr + obj->relocbase); break; } } From 5b33842a9b996c9352f1251c070dc4b14da31449 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 15:28:52 +0000 Subject: [PATCH 109/646] Do not map segments of zero length. Discussed with: bz Reviewed by: kan Tested by: bz (i386, amd64), bsam (linux) MFC after: some time --- sys/kern/imgact_elf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 4ed7382a6f6..3841d1fa643 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -635,7 +635,8 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr, } for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) { - if (phdr[i].p_type == PT_LOAD) { /* Loadable segment */ + if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) { + /* Loadable segment */ prot = 0; if (phdr[i].p_flags & PF_X) prot |= VM_PROT_EXECUTE; @@ -764,6 +765,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) for (i = 0; i < hdr->e_phnum; i++) { switch (phdr[i].p_type) { case PT_LOAD: /* Loadable segment */ + if (phdr[i].p_memsz == 0) + break; prot = 0; if (phdr[i].p_flags & PF_X) prot |= VM_PROT_EXECUTE; From 023063938a37626ac34610fc9e03cc735233b62d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 15:31:24 +0000 Subject: [PATCH 110/646] Define architectural load bases for PIE binaries. Addresses were selected by looking at the bases used for non-relocatable executables by gnu ld(1), and adjusting it slightly. Discussed with: bz Reviewed by: kan Tested by: bz (i386, amd64), bsam (linux) MFC after: some time --- sys/amd64/include/elf.h | 6 ++++++ sys/arm/include/elf.h | 3 +++ sys/i386/include/elf.h | 2 ++ sys/ia64/include/elf.h | 2 ++ sys/mips/include/elf.h | 2 ++ sys/powerpc/include/elf.h | 2 ++ sys/sparc64/include/elf.h | 2 ++ sys/sun4v/include/elf.h | 2 ++ 8 files changed, 21 insertions(+) diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h index e5c95f78507..88f439805ba 100644 --- a/sys/amd64/include/elf.h +++ b/sys/amd64/include/elf.h @@ -106,4 +106,10 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH EM_X86_64 #define ELF_TARG_VER 1 +#if __ELF_WORD_SIZE == 32 +#define ET_DYN_LOAD_ADDR 0x01001000 +#else +#define ET_DYN_LOAD_ADDR 0x01021000 +#endif + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/arm/include/elf.h b/sys/arm/include/elf.h index ee2843fb135..0660ba6bea6 100644 --- a/sys/arm/include/elf.h +++ b/sys/arm/include/elf.h @@ -97,4 +97,7 @@ __ElfType(Auxinfo); * value. */ #define MAGIC_TRAMP_NUMBER 0x5c000003 + +#define ET_DYN_LOAD_ADDR 0x12000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/i386/include/elf.h b/sys/i386/include/elf.h index af71ab8fd0b..37ee279c167 100644 --- a/sys/i386/include/elf.h +++ b/sys/i386/include/elf.h @@ -105,4 +105,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH EM_386 #define ELF_TARG_VER 1 +#define ET_DYN_LOAD_ADDR 0x01001000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/ia64/include/elf.h b/sys/ia64/include/elf.h index 65802aa20f1..c6a43fcdc17 100644 --- a/sys/ia64/include/elf.h +++ b/sys/ia64/include/elf.h @@ -141,4 +141,6 @@ __ElfType(Auxinfo); #define DT_IA_64_PLT_RESERVE 0x70000000 +#define ET_DYN_LOAD_ADDR 0x2500000000000000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index 3a31daa0bd1..995862cb927 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -250,4 +250,6 @@ __ElfType(Auxinfo); #define AT_COUNT 16 /* Count of defined aux entry types. */ +#define ET_DYN_LOAD_ADDR 0x0120000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/powerpc/include/elf.h b/sys/powerpc/include/elf.h index 1224fbb284f..e01488dcc0c 100644 --- a/sys/powerpc/include/elf.h +++ b/sys/powerpc/include/elf.h @@ -96,4 +96,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH EM_PPC #define ELF_TARG_VER 1 +#define ET_DYN_LOAD_ADDR 0x01010000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/sparc64/include/elf.h b/sys/sparc64/include/elf.h index c0fcbee5ecd..d35d736b1f6 100644 --- a/sys/sparc64/include/elf.h +++ b/sys/sparc64/include/elf.h @@ -97,4 +97,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH ELF_ARCH #define ELF_TARG_VER 1 +#define ET_DYN_LOAD_ADDR 0x150000000 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/sun4v/include/elf.h b/sys/sun4v/include/elf.h index c0fcbee5ecd..d35d736b1f6 100644 --- a/sys/sun4v/include/elf.h +++ b/sys/sun4v/include/elf.h @@ -97,4 +97,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH ELF_ARCH #define ELF_TARG_VER 1 +#define ET_DYN_LOAD_ADDR 0x150000000 + #endif /* !_MACHINE_ELF_H_ */ From ab02d85f0da9e1903222c6ac7e6f24efdbf57cff Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 15:33:01 +0000 Subject: [PATCH 111/646] Map PIE binaries at non-zero base address. Discussed with: bz Reviewed by: kan Tested by: bz (i386, amd64), bsam (linux) MFC after: some time --- sys/kern/imgact_elf.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 3841d1fa643..e112fe1271d 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -688,7 +688,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) u_long text_size = 0, data_size = 0, total_size = 0; u_long text_addr = 0, data_addr = 0; u_long seg_size, seg_addr; - u_long addr, entry = 0, proghdr = 0; + u_long addr, et_dyn_addr, entry = 0, proghdr = 0; int32_t osrel = 0; int error = 0, i; const char *interp = NULL, *newinterp = NULL; @@ -736,9 +736,12 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) hdr->e_ident[EI_OSABI]); return (ENOEXEC); } - if (hdr->e_type == ET_DYN && - (brand_info->flags & BI_CAN_EXEC_DYN) == 0) - return (ENOEXEC); + if (hdr->e_type == ET_DYN) { + if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) + return (ENOEXEC); + et_dyn_addr = ET_DYN_LOAD_ADDR; + } else + et_dyn_addr = 0; sv = brand_info->sysvec; if (interp != NULL && brand_info->interp_newpath != NULL) newinterp = brand_info->interp_newpath; @@ -786,7 +789,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if ((error = __elfN(load_section)(vmspace, imgp->object, phdr[i].p_offset, - (caddr_t)(uintptr_t)phdr[i].p_vaddr, + (caddr_t)(uintptr_t)phdr[i].p_vaddr + et_dyn_addr, phdr[i].p_memsz, phdr[i].p_filesz, prot, sv->sv_pagesize)) != 0) return (error); @@ -800,11 +803,12 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (phdr[i].p_offset == 0 && hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize <= phdr[i].p_filesz) - proghdr = phdr[i].p_vaddr + hdr->e_phoff; + proghdr = phdr[i].p_vaddr + hdr->e_phoff + + et_dyn_addr; - seg_addr = trunc_page(phdr[i].p_vaddr); + seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr); seg_size = round_page(phdr[i].p_memsz + - phdr[i].p_vaddr - seg_addr); + phdr[i].p_vaddr + et_dyn_addr - seg_addr); /* * Is this .text or .data? We can't use @@ -826,7 +830,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) phdr[i].p_memsz)) { text_size = seg_size; text_addr = seg_addr; - entry = (u_long)hdr->e_entry; + entry = (u_long)hdr->e_entry + et_dyn_addr; } else { data_size = seg_size; data_addr = seg_addr; @@ -834,7 +838,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) total_size += seg_size; break; case PT_PHDR: /* Program header table info */ - proghdr = phdr[i].p_vaddr; + proghdr = phdr[i].p_vaddr + et_dyn_addr; break; default: break; From 6728dc169df8bd773235d3d4d82aa90d2011240f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Oct 2009 21:17:30 +0000 Subject: [PATCH 112/646] Refine r195509, instead of checking that vnode type is VBAD, that is set quite late in the revocation path, properly verify that vnode is not doomed before calling VOP. Reported and tested by: Harald Schmalzbauer MFC after: 3 days --- sys/kern/kern_exit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 39b48e01bde..b96cdbf0976 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -340,10 +340,10 @@ exit1(struct thread *td, int rv) if (ttyvp != NULL) { sx_xunlock(&proctree_lock); - vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); - if (ttyvp->v_type != VBAD) + if (vn_lock(ttyvp, LK_EXCLUSIVE) == 0) { VOP_REVOKE(ttyvp, REVOKEALL); - VOP_UNLOCK(ttyvp, 0); + VOP_UNLOCK(ttyvp, 0); + } sx_xlock(&proctree_lock); } } From 7c3a3fbe951ba9d6e13833751ec6b64b326445e6 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 10 Oct 2009 21:49:04 +0000 Subject: [PATCH 113/646] Orphaning provider with EXDEV seems weird; perhaps the author meant ENXIO here? --- sys/dev/fdc/fdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index a207bfcbc02..b2145cd0074 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -864,7 +864,7 @@ fdc_worker(struct fdc_data *fdc) fd->flags |= FD_NEWDISK; mtx_unlock(&fdc->fdc_mtx); g_topology_lock(); - g_orphan_provider(fd->fd_provider, EXDEV); + g_orphan_provider(fd->fd_provider, ENXIO); fd->fd_provider->flags |= G_PF_WITHER; fd->fd_provider = g_new_providerf(fd->fd_geom, fd->fd_geom->name); From 70d4ef1ea19075a48d3dfe3012c6a1aba185c718 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 10 Oct 2009 22:17:03 +0000 Subject: [PATCH 114/646] In regards to the "Starting foo:" type messages at boot time, create and employ a more generic solution, and use it in the individual rc.d scripts that also have an $rc_quiet test: 1. Add check_startmsgs() to rc.subr. 2. In the rc.d scripts that use rc_quiet (and rc.subr) substitute variations of [ -z "$rc_quiet" ] with check_startmsgs 3. In savecore add a trailing '.' to the end of the message to make it more consistent with other scripts. 4. In newsyslog remove a : before the terminal '.' since we do not expect there to be anything printed out in between to make it more consistent. 5. In the following scripts change "quotes" to 'quotes' where no variables exist in the message: savecore pf newsyslog 6. In the following scripts substitute if/then/fi for the simpler (and more consistent) check_startmsgs &&: faith stf 7. In the following scripts separate the "Starting foo:" from the terminal '.' to make them more consistent: moused hostname pf 8. In nfsclient move the message to its own line to avoid a style bug 9. In pf rc_quiet does not apply to the _stop method, so remove the test there. 10. In motd add 'quotes' around the terminal '.' for consistency --- etc/rc.d/bgfsck | 2 +- etc/rc.d/cleartmp | 4 ++-- etc/rc.d/faith | 4 +--- etc/rc.d/fsck | 2 +- etc/rc.d/hostid | 4 ++-- etc/rc.d/hostname | 3 ++- etc/rc.d/ldconfig | 7 +++---- etc/rc.d/motd | 4 ++-- etc/rc.d/mountcritlocal | 4 ++-- etc/rc.d/moused | 3 ++- etc/rc.d/netif | 2 +- etc/rc.d/newsyslog | 4 ++-- etc/rc.d/nfsclient | 3 ++- etc/rc.d/pf | 6 ++++-- etc/rc.d/savecore | 2 +- etc/rc.d/stf | 5 ++--- etc/rc.subr | 22 +++++++++++++++------- 17 files changed, 45 insertions(+), 36 deletions(-) diff --git a/etc/rc.d/bgfsck b/etc/rc.d/bgfsck index 04c4cb529ca..3715354fc3e 100755 --- a/etc/rc.d/bgfsck +++ b/etc/rc.d/bgfsck @@ -31,7 +31,7 @@ bgfsck_start () bgfsck_msg="${bgfsck_msg} in ${background_fsck_delay} seconds" fi if [ -z "${rc_force}" ]; then - [ -z "${rc_quiet}" ] && echo "${bgfsck_msg}." + check_startmsgs && echo "${bgfsck_msg}." fi (sleep ${background_fsck_delay}; nice -4 fsck -B -p) 2>&1 | \ diff --git a/etc/rc.d/cleartmp b/etc/rc.d/cleartmp index a41a15ebf45..94b7799ba6d 100755 --- a/etc/rc.d/cleartmp +++ b/etc/rc.d/cleartmp @@ -25,7 +25,7 @@ cleartmp_start() ${tmp}/.ICE-unix ${tmp}/.font-unix" if checkyesno ${rcvar1}; then - [ -z "${rc_quiet}" ] && echo "Clearing ${tmp}." + check_startmsgs && echo "Clearing ${tmp}." # This is not needed for mfs, but doesn't hurt anything. # Things to note: @@ -44,7 +44,7 @@ cleartmp_start() elif checkyesno clear_tmp_X; then # Remove X lock files, since they will prevent you from # restarting X. Remove other X related directories. - [ -z "${rc_quiet}" ] && echo "Clearing ${tmp} (X related)." + check_startmsgs && echo "Clearing ${tmp} (X related)." rm -rf ${tmp}/.X[0-9]-lock ${x11_socket_dirs} fi if checkyesno clear_tmp_X; then diff --git a/etc/rc.d/faith b/etc/rc.d/faith index 020b947ec86..a7f4cd8cdf8 100755 --- a/etc/rc.d/faith +++ b/etc/rc.d/faith @@ -39,9 +39,7 @@ faith_up() route change -inet6 ${prefix} -prefixlen ${prefixlen} \ -ifp faith0 done - if [ -z "${rc_quiet}" ]; then - ifconfig faith0 - fi + check_startmsgs && ifconfig faith0 ;; esac } diff --git a/etc/rc.d/fsck b/etc/rc.d/fsck index a2ca0b75384..c1fe155e48f 100755 --- a/etc/rc.d/fsck +++ b/etc/rc.d/fsck @@ -23,7 +23,7 @@ fsck_start() # During fsck ignore SIGQUIT trap : 3 - [ -z "${rc_quiet}" ] && echo "Starting file system checks:" + check_startmsgs && echo "Starting file system checks:" if checkyesno background_fsck; then fsck -F -p else diff --git a/etc/rc.d/hostid b/etc/rc.d/hostid index f8a3d94485f..45d679bbabf 100755 --- a/etc/rc.d/hostid +++ b/etc/rc.d/hostid @@ -49,9 +49,9 @@ hostid_set() # Set both kern.hostuuid and kern.hostid. # - [ -z "${rc_quiet}" ] && echo "Setting hostuuid: ${uuid}." + check_startmsgs && echo "Setting hostuuid: ${uuid}." ${SYSCTL_W} kern.hostuuid="${uuid}" >/dev/null - [ -z "${rc_quiet}" ] && echo "Setting hostid: ${id}." + check_startmsgs && echo "Setting hostid: ${id}." ${SYSCTL_W} kern.hostid=${id} >/dev/null } diff --git a/etc/rc.d/hostname b/etc/rc.d/hostname index 52f4408b635..142dc4713c3 100755 --- a/etc/rc.d/hostname +++ b/etc/rc.d/hostname @@ -72,8 +72,9 @@ hostname_start() # All right, it is safe to invoke hostname(1) now. # - [ -z "${rc_quiet}" ] && echo "Setting hostname: ${hostname}." + check_startmsgs && echo -n "Setting hostname: ${hostname}" /bin/hostname "${hostname}" + check_startmsgs && echo '.' } load_rc_config $name diff --git a/etc/rc.d/ldconfig b/etc/rc.d/ldconfig index 8e30576394f..5ed1ed1d5d7 100755 --- a/etc/rc.d/ldconfig +++ b/etc/rc.d/ldconfig @@ -36,7 +36,7 @@ ldconfig_start() _LDC="${_LDC} ${i}" fi done - [ -z "${rc_quiet}" ] && echo 'ELF ldconfig path:' ${_LDC} + check_startmsgs && echo 'ELF ldconfig path:' ${_LDC} ${ldconfig} -elf ${_ins} ${_LDC} case `sysctl -n hw.machine_arch` in @@ -55,7 +55,7 @@ ldconfig_start() _LDC="${_LDC} ${i}" fi done - [ -z "${rc_quiet}" ] && + check_startmsgs && echo '32-bit compatibility ldconfig path:' ${_LDC} ${ldconfig} -32 -m ${_ins} ${_LDC} ;; @@ -72,8 +72,7 @@ ldconfig_start() _LDC="${_LDC} ${i}" fi done - [ -z "${rc_quiet}" ] && - echo 'a.out ldconfig path:' ${_LDC} + check_startmsgs && echo 'a.out ldconfig path:' ${_LDC} ${ldconfig} -aout ${_ins} ${_LDC} ;; esac diff --git a/etc/rc.d/motd b/etc/rc.d/motd index 0b6707a58a2..8256d968283 100755 --- a/etc/rc.d/motd +++ b/etc/rc.d/motd @@ -22,7 +22,7 @@ motd_start() # Must be done *before* interactive logins are possible # to prevent possible race conditions. # - [ -z "${rc_quiet}" ] && echo -n 'Updating motd:' + check_startmsgs && echo -n 'Updating motd:' if [ ! -f /etc/motd ]; then install -c -o root -g wheel -m ${PERMS} /dev/null /etc/motd fi @@ -42,7 +42,7 @@ motd_start() } rm -f $T - [ -z "${rc_quiet}" ] && echo . + check_startmsgs && echo '.' } load_rc_config $name diff --git a/etc/rc.d/mountcritlocal b/etc/rc.d/mountcritlocal index 49f8f06bb8a..789251765eb 100755 --- a/etc/rc.d/mountcritlocal +++ b/etc/rc.d/mountcritlocal @@ -28,7 +28,7 @@ mountcritlocal_start() esac # Mount everything except nfs filesystems. - [ -z "${rc_quiet}" ] && echo -n 'Mounting local file systems:' + check_startmsgs && echo -n 'Mounting local file systems:' mount_excludes='no' for i in ${netfs_types}; do fstype=${i%:*} @@ -37,7 +37,7 @@ mountcritlocal_start() mount_excludes=${mount_excludes%,} mount -a -t ${mount_excludes} err=$? - [ -z "${rc_quiet}" ] && echo '.' + check_startmsgs && echo '.' case ${err} in 0) diff --git a/etc/rc.d/moused b/etc/rc.d/moused index 60372a020f2..fd2c447c60a 100755 --- a/etc/rc.d/moused +++ b/etc/rc.d/moused @@ -51,8 +51,9 @@ moused_start() mytype="$moused_type" fi - [ -z "${rc_quiet}" ] && echo -n "Starting ${ms} moused." + check_startmsgs && echo -n "Starting ${ms} moused" /usr/sbin/moused ${myflags} -p ${myport} -t ${mytype} ${pidarg} + check_startmsgs && echo '.' mousechar_arg= case ${mousechar_start} in diff --git a/etc/rc.d/netif b/etc/rc.d/netif index 3c8e5dc5d20..f982cfce647 100755 --- a/etc/rc.d/netif +++ b/etc/rc.d/netif @@ -143,7 +143,7 @@ network_common() ;; esac echo "${_str} Network:${_ok}." - if [ -z "${rc_quiet}" ]; then + if check_startmsgs; then for ifn in ${_ok}; do /sbin/ifconfig ${ifn} done diff --git a/etc/rc.d/newsyslog b/etc/rc.d/newsyslog index f03d97cfb0f..ab8f2d31497 100755 --- a/etc/rc.d/newsyslog +++ b/etc/rc.d/newsyslog @@ -17,9 +17,9 @@ stop_cmd=":" newsyslog_start() { - [ -z "${rc_quiet}" ] && echo -n "Creating and/or trimming log files:" + check_startmsgs && echo -n 'Creating and/or trimming log files' ${command} ${rc_flags} - [ -z "${rc_quiet}" ] && echo "." + check_startmsgs && echo '.' } load_rc_config $name diff --git a/etc/rc.d/nfsclient b/etc/rc.d/nfsclient index 2b26d09da6d..d28e45f6a2e 100755 --- a/etc/rc.d/nfsclient +++ b/etc/rc.d/nfsclient @@ -22,7 +22,8 @@ nfsclient_start() # if [ -n "${nfs_access_cache}" ]; then - [ -z "${rc_quiet}" ] && echo "NFS access cache time=${nfs_access_cache}" + check_startmsgs && + echo "NFS access cache time=${nfs_access_cache}" if ! sysctl vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null; then warn "failed to set access cache timeout" fi diff --git a/etc/rc.d/pf b/etc/rc.d/pf index f1044a36882..9f64c04a669 100755 --- a/etc/rc.d/pf +++ b/etc/rc.d/pf @@ -25,19 +25,21 @@ required_modules="pf" pf_start() { - [ -z "${rc_quiet}" ] && echo "Enabling pf." + check_startmsgs && echo -n 'Enabling pf' $pf_program -F all > /dev/null 2>&1 $pf_program -f "$pf_rules" $pf_flags if ! $pf_program -s info | grep -q "Enabled" ; then $pf_program -e fi + check_startmsgs && echo '.' } pf_stop() { if $pf_program -s info | grep -q "Enabled" ; then - [ -z "${rc_quiet}" ] && echo "Disabling pf." + echo -n 'Disabling pf' $pf_program -d + echo '.' fi } diff --git a/etc/rc.d/savecore b/etc/rc.d/savecore index ff8e128eda0..2bee021392c 100755 --- a/etc/rc.d/savecore +++ b/etc/rc.d/savecore @@ -69,7 +69,7 @@ savecore_start() ${crashinfo_program} -d ${dumpdir} fi else - [ -z "${rc_quiet}" ] && echo "No core dumps found" + check_startmsgs && echo 'No core dumps found.' fi } diff --git a/etc/rc.d/stf b/etc/rc.d/stf index 40b182a0de9..6f7347b98c5 100755 --- a/etc/rc.d/stf +++ b/etc/rc.d/stf @@ -53,9 +53,8 @@ stf_up() ifconfig stf0 create >/dev/null 2>&1 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ prefixlen ${stf_prefixlen} - if [ -z "${rc_quiet}" ]; then - /sbin/ifconfig stf0 - fi + check_startmsgs && /sbin/ifconfig stf0 + # disallow packets to malicious 6to4 prefix route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject diff --git a/etc/rc.subr b/etc/rc.subr index fd94cc9c372..fa372ddf369 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -397,6 +397,20 @@ wait_for_pids() fi } +# +# check_startmsgs +# If rc_quiet is set (usually as a result of using faststart at +# boot time) check if rc_startmsgs is enabled. +# +check_startmsgs() +{ + if [ -n "$rc_quiet" ]; then + checkyesno rc_startmsgs + else + return 0 + fi +} + # # run_rc_command argument # Search for argument in the list of supported commands, which is: @@ -708,13 +722,7 @@ run_rc_command() # setup the full command to run # - _show_startmsgs=1 - if [ -n "${rc_quiet}" ]; then - if ! checkyesno rc_startmsgs; then - unset _show_startmsgs - fi - fi - [ -n "$_show_startmsgs" ] && echo "Starting ${name}." + check_startmsgs && echo "Starting ${name}." if [ -n "$_chroot" ]; then _doit="\ ${_nice:+nice -n $_nice }\ From 4eaee90e39ae4c17073bc34c6a140bb221c4a3f5 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 10 Oct 2009 22:29:34 +0000 Subject: [PATCH 115/646] Atheros EEPROM version 4K. This version is mostly based on version 1.4. This is needed by the upcoming AR9285 support. Information on the layout gathered from Linux ath9k. Not yet connected to the build. Tested by: Eugeny Dzhurinsky --- sys/dev/ath/ath_hal/ah_eeprom_v4k.c | 404 ++++++++++++++++++++++++++++ sys/dev/ath/ath_hal/ah_eeprom_v4k.h | 157 +++++++++++ 2 files changed, 561 insertions(+) create mode 100644 sys/dev/ath/ath_hal/ah_eeprom_v4k.c create mode 100644 sys/dev/ath/ath_hal/ah_eeprom_v4k.h diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v4k.c b/sys/dev/ath/ath_hal/ah_eeprom_v4k.c new file mode 100644 index 00000000000..03bb04c08a5 --- /dev/null +++ b/sys/dev/ath/ath_hal/ah_eeprom_v4k.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2009 Rui Paulo + * Copyright (c) 2008 Sam Leffler, Errno Consulting + * Copyright (c) 2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#include "opt_ah.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ah_eeprom_v14.h" +#include "ah_eeprom_v4k.h" + +static HAL_STATUS +v4kEepromGet(struct ath_hal *ah, int param, void *val) +{ +#define CHAN_A_IDX 0 +#define CHAN_B_IDX 1 +#define IS_VERS(op, v) ((pBase->version & AR5416_EEP_VER_MINOR_MASK) op (v)) + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader; + const BASE_EEP4K_HEADER *pBase = &ee->ee_base.baseEepHeader; + uint32_t sum; + uint8_t *macaddr; + int i; + + switch (param) { + case AR_EEP_NFTHRESH_5: + *(int16_t *)val = pModal[0].noiseFloorThreshCh[0]; + return HAL_OK; + case AR_EEP_NFTHRESH_2: + *(int16_t *)val = pModal[1].noiseFloorThreshCh[0]; + return HAL_OK; + case AR_EEP_MACADDR: /* Get MAC Address */ + sum = 0; + macaddr = val; + for (i = 0; i < 6; i++) { + macaddr[i] = pBase->macAddr[i]; + sum += pBase->macAddr[i]; + } + if (sum == 0 || sum == 0xffff*3) { + HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad mac address %s\n", + __func__, ath_hal_ether_sprintf(macaddr)); + return HAL_EEBADMAC; + } + return HAL_OK; + case AR_EEP_REGDMN_0: + return pBase->regDmn[0]; + case AR_EEP_REGDMN_1: + return pBase->regDmn[1]; + case AR_EEP_OPCAP: + return pBase->deviceCap; + case AR_EEP_OPMODE: + return pBase->opCapFlags; + case AR_EEP_RFSILENT: + return pBase->rfSilent; + case AR_EEP_OB_5: + return pModal[CHAN_A_IDX].ob; + case AR_EEP_DB_5: + return pModal[CHAN_A_IDX].db; + case AR_EEP_OB_2: + return pModal[CHAN_B_IDX].ob; + case AR_EEP_DB_2: + return pModal[CHAN_B_IDX].db; + case AR_EEP_TXMASK: + return pBase->txMask; + case AR_EEP_RXMASK: + return pBase->rxMask; + case AR_EEP_RXGAIN_TYPE: + return AR5416_EEP_RXGAIN_ORIG; + case AR_EEP_TXGAIN_TYPE: + return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ? + pBase->txGainType : AR5416_EEP_TXGAIN_ORIG; +#if 0 + case AR_EEP_OL_PWRCTRL: + HALASSERT(val == AH_NULL); + return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO; +#endif + case AR_EEP_AMODE: + HALASSERT(val == AH_NULL); + return pBase->opCapFlags & AR5416_OPFLAGS_11A ? + HAL_OK : HAL_EIO; + case AR_EEP_BMODE: + case AR_EEP_GMODE: + HALASSERT(val == AH_NULL); + return pBase->opCapFlags & AR5416_OPFLAGS_11G ? + HAL_OK : HAL_EIO; + case AR_EEP_32KHZCRYSTAL: + case AR_EEP_COMPRESS: + case AR_EEP_FASTFRAME: /* XXX policy decision, h/w can do it */ + case AR_EEP_WRITEPROTECT: /* NB: no write protect bit */ + HALASSERT(val == AH_NULL); + /* fall thru... */ + case AR_EEP_MAXQCU: /* NB: not in opCapFlags */ + case AR_EEP_KCENTRIES: /* NB: not in opCapFlags */ + return HAL_EIO; + case AR_EEP_AES: + case AR_EEP_BURST: + case AR_EEP_RFKILL: + case AR_EEP_TURBO5DISABLE: + case AR_EEP_TURBO2DISABLE: + HALASSERT(val == AH_NULL); + return HAL_OK; + case AR_EEP_ANTGAINMAX_2: + *(int8_t *) val = ee->ee_antennaGainMax[1]; + return HAL_OK; + case AR_EEP_ANTGAINMAX_5: + *(int8_t *) val = ee->ee_antennaGainMax[0]; + return HAL_OK; + default: + HALASSERT(0); + return HAL_EINVAL; + } +#undef IS_VERS +#undef CHAN_A_IDX +#undef CHAN_B_IDX +} + +static HAL_BOOL +v4kEepromSet(struct ath_hal *ah, int param, int v) +{ + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + + switch (param) { + case AR_EEP_ANTGAINMAX_2: + ee->ee_antennaGainMax[1] = (int8_t) v; + return HAL_OK; + case AR_EEP_ANTGAINMAX_5: + ee->ee_antennaGainMax[0] = (int8_t) v; + return HAL_OK; + } + return HAL_EINVAL; +} + +static HAL_BOOL +v4kEepromDiag(struct ath_hal *ah, int request, + const void *args, uint32_t argsize, void **result, uint32_t *resultsize) +{ + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + + switch (request) { + case HAL_DIAG_EEPROM: + *result = &ee->ee_base; + *resultsize = sizeof(ee->ee_base); + return AH_TRUE; + } + return AH_FALSE; +} + +/* Do structure specific swaps if Eeprom format is non native to host */ +static void +eepromSwap(struct ar5416eeprom_4k *ee) +{ + uint32_t integer, i; + uint16_t word; + MODAL_EEP4K_HEADER *pModal; + + /* convert Base Eep header */ + word = __bswap16(ee->baseEepHeader.length); + ee->baseEepHeader.length = word; + + word = __bswap16(ee->baseEepHeader.checksum); + ee->baseEepHeader.checksum = word; + + word = __bswap16(ee->baseEepHeader.version); + ee->baseEepHeader.version = word; + + word = __bswap16(ee->baseEepHeader.regDmn[0]); + ee->baseEepHeader.regDmn[0] = word; + + word = __bswap16(ee->baseEepHeader.regDmn[1]); + ee->baseEepHeader.regDmn[1] = word; + + word = __bswap16(ee->baseEepHeader.rfSilent); + ee->baseEepHeader.rfSilent = word; + + word = __bswap16(ee->baseEepHeader.blueToothOptions); + ee->baseEepHeader.blueToothOptions = word; + + word = __bswap16(ee->baseEepHeader.deviceCap); + ee->baseEepHeader.deviceCap = word; + + /* convert Modal Eep header */ + pModal = &ee->modalHeader; + + /* XXX linux/ah_osdep.h only defines __bswap32 for BE */ + integer = __bswap32(pModal->antCtrlCommon); + pModal->antCtrlCommon = integer; + + for (i = 0; i < AR5416_4K_MAX_CHAINS; i++) { + integer = __bswap32(pModal->antCtrlChain[i]); + pModal->antCtrlChain[i] = integer; + } + + for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + word = __bswap16(pModal->spurChans[i].spurChan); + pModal->spurChans[i].spurChan = word; + } +} + +static uint16_t +v4kEepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz) +{ + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + + HALASSERT(0 <= ix && ix < AR5416_EEPROM_MODAL_SPURS); + HALASSERT(is2GHz); + return ee->ee_base.modalHeader.spurChans[ix].spurChan; +} + +/************************************************************************** + * fbin2freq + * + * Get channel value from binary representation held in eeprom + * RETURNS: the frequency in MHz + */ +static uint16_t +fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) +{ + /* + * Reserved value 0xFF provides an empty definition both as + * an fbin and as a frequency - do not convert + */ + if (fbin == AR5416_BCHAN_UNUSED) + return fbin; + return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); +} + +/* + * Copy EEPROM Conformance Testing Limits contents + * into the allocated space + */ +/* USE CTLS from chain zero */ +#define CTL_CHAIN 0 + +static void +v4kEepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_v4k *ee) +{ + RD_EDGES_POWER *rep = ee->ee_rdEdgesPower; + int i, j; + + HALASSERT(AR5416_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES); + + for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_4K_NUM_CTLS; i++) { + for (j = 0; j < NUM_EDGES; j ++) { + /* XXX Confirm this is the right thing to do when an invalid channel is stored */ + if (ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].bChannel == AR5416_BCHAN_UNUSED) { + rep[j].rdEdge = 0; + rep[j].twice_rdEdgePower = 0; + rep[j].flag = 0; + } else { + rep[j].rdEdge = fbin2freq( + ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].bChannel, + (ee->ee_base.ctlIndex[i] & CTL_MODE_M) != CTL_11A); + rep[j].twice_rdEdgePower = MS(ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].tPowerFlag, CAL_CTL_EDGES_POWER); + rep[j].flag = MS(ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].tPowerFlag, CAL_CTL_EDGES_FLAG) != 0; + } + } + rep += NUM_EDGES; + } + ee->ee_numCtls = i; + HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM, + "%s Numctls = %u\n",__func__,i); +} + +/* + * Reclaim any EEPROM-related storage. + */ +static void +v4kEepromDetach(struct ath_hal *ah) +{ + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + + ath_hal_free(ee); + AH_PRIVATE(ah)->ah_eeprom = AH_NULL; +} + +#define owl_get_eep_ver(_ee) \ + (((_ee)->ee_base.baseEepHeader.version >> 12) & 0xF) +#define owl_get_eep_rev(_ee) \ + (((_ee)->ee_base.baseEepHeader.version) & 0xFFF) + +HAL_STATUS +ath_hal_v4kEepromAttach(struct ath_hal *ah) +{ +#define NW(a) (sizeof(a) / sizeof(uint16_t)) + HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; + uint16_t *eep_data, magic; + HAL_BOOL need_swap; + u_int w, off, len; + uint32_t sum; + + HALASSERT(ee == AH_NULL); + + if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s Error reading Eeprom MAGIC\n", __func__); + return HAL_EEREAD; + } + HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n", + __func__, magic); + if (magic != AR5416_EEPROM_MAGIC) { + HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n"); + return HAL_EEMAGIC; + } + + ee = ath_hal_malloc(sizeof(HAL_EEPROM_v4k)); + if (ee == AH_NULL) { + /* XXX message */ + return HAL_ENOMEM; + } + + eep_data = (uint16_t *)&ee->ee_base; + for (w = 0; w < NW(struct ar5416eeprom_4k); w++) { + off = owl_eep_start_loc + w; /* NB: AP71 starts at 0 */ + if (!ath_hal_eepromRead(ah, off, &eep_data[w])) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s eeprom read error at offset 0x%x\n", + __func__, off); + return HAL_EEREAD; + } + } + /* Convert to eeprom native eeprom endian format */ + if (isBigEndian()) { + for (w = 0; w < NW(struct ar5416eeprom_4k); w++) + eep_data[w] = __bswap16(eep_data[w]); + } + + /* + * At this point, we're in the native eeprom endian format + * Now, determine the eeprom endian by looking at byte 26?? + */ + need_swap = ((ee->ee_base.baseEepHeader.eepMisc & AR5416_EEPMISC_BIG_ENDIAN) != 0) ^ isBigEndian(); + if (need_swap) { + HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM, + "Byte swap EEPROM contents.\n"); + len = __bswap16(ee->ee_base.baseEepHeader.length); + } else { + len = ee->ee_base.baseEepHeader.length; + } + len = AH_MIN(len, sizeof(struct ar5416eeprom_4k)) / sizeof(uint16_t); + + /* Apply the checksum, done in native eeprom format */ + /* XXX - Need to check to make sure checksum calculation is done + * in the correct endian format. Right now, it seems it would + * cast the raw data to host format and do the calculation, which may + * not be correct as the calculation may need to be done in the native + * eeprom format + */ + sum = 0; + for (w = 0; w < len; w++) { + sum ^= eep_data[w]; + } + /* Check CRC - Attach should fail on a bad checksum */ + if (sum != 0xffff) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "Bad EEPROM checksum 0x%x (Len=%u)\n", sum, len); + return HAL_EEBADSUM; + } + + if (need_swap) + eepromSwap(&ee->ee_base); /* byte swap multi-byte data */ + + /* swap words 0+2 so version is at the front */ + magic = eep_data[0]; + eep_data[0] = eep_data[2]; + eep_data[2] = magic; + + HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM, + "%s Eeprom Version %u.%u\n", __func__, + owl_get_eep_ver(ee), owl_get_eep_rev(ee)); + + /* NB: must be after all byte swapping */ + if (owl_get_eep_ver(ee) != AR5416_EEP_VER) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "Bad EEPROM version 0x%x\n", owl_get_eep_ver(ee)); + return HAL_EEBADSUM; + } + + v4kEepromReadCTLInfo(ah, ee); /* Get CTLs */ + + AH_PRIVATE(ah)->ah_eeprom = ee; + AH_PRIVATE(ah)->ah_eeversion = ee->ee_base.baseEepHeader.version; + AH_PRIVATE(ah)->ah_eepromDetach = v4kEepromDetach; + AH_PRIVATE(ah)->ah_eepromGet = v4kEepromGet; + AH_PRIVATE(ah)->ah_eepromSet = v4kEepromSet; + AH_PRIVATE(ah)->ah_getSpurChan = v4kEepromGetSpurChan; + AH_PRIVATE(ah)->ah_eepromDiag = v4kEepromDiag; + return HAL_OK; +#undef NW +} diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v4k.h b/sys/dev/ath/ath_hal/ah_eeprom_v4k.h new file mode 100644 index 00000000000..a1dbf513bd8 --- /dev/null +++ b/sys/dev/ath/ath_hal/ah_eeprom_v4k.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2009 Rui Paulo + * Copyright (c) 2008 Sam Leffler, Errno Consulting + * Copyright (c) 2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#ifndef _AH_EEPROM_V4K_H_ +#define _AH_EEPROM_V4K_H_ + +#include "ah_eeprom.h" +#include "ah_eeprom_v14.h" + +#undef owl_eep_start_loc +#ifdef __LINUX_ARM_ARCH__ /* AP71 */ +#define owl_eep_start_loc 0 +#else +#define owl_eep_start_loc 64 +#endif + +// 16-bit offset location start of calibration struct +#define AR5416_4K_EEP_START_LOC 64 +#define AR5416_4K_NUM_2G_CAL_PIERS 3 +#define AR5416_4K_NUM_2G_CCK_TARGET_POWERS 3 +#define AR5416_4K_NUM_2G_20_TARGET_POWERS 3 +#define AR5416_4K_NUM_2G_40_TARGET_POWERS 3 +#define AR5416_4K_NUM_CTLS 12 +#define AR5416_4K_NUM_BAND_EDGES 4 +#define AR5416_4K_NUM_PD_GAINS 2 +#define AR5416_4K_PD_GAINS_IN_MASK 4 +#define AR5416_4K_PD_GAIN_ICEPTS 5 +#define AR5416_4K_MAX_CHAINS 1 + +/* + * NB: The format in EEPROM has words 0 and 2 swapped (i.e. version + * and length are swapped). We reverse their position after reading + * the data into host memory so the version field is at the same + * offset as in previous EEPROM layouts. This makes utilities that + * inspect the EEPROM contents work without looking at the PCI device + * id which may or may not be reliable. + */ +typedef struct BaseEepHeader4k { + uint16_t version; /* NB: length in EEPROM */ + uint16_t checksum; + uint16_t length; /* NB: version in EEPROM */ + uint8_t opCapFlags; + uint8_t eepMisc; + uint16_t regDmn[2]; + uint8_t macAddr[6]; + uint8_t rxMask; + uint8_t txMask; + uint16_t rfSilent; + uint16_t blueToothOptions; + uint16_t deviceCap; + uint32_t binBuildNumber; + uint8_t deviceType; + uint8_t txGainType; /* high power tx gain table support */ +} __packed BASE_EEP4K_HEADER; // 32 B + +typedef struct ModalEepHeader4k { + uint32_t antCtrlChain[AR5416_4K_MAX_CHAINS]; // 12 + uint32_t antCtrlCommon; // 4 + int8_t antennaGainCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t switchSettling; // 1 + uint8_t txRxAttenCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t rxTxMarginCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t adcDesiredSize; // 1 + int8_t pgaDesiredSize; // 1 + uint8_t xlnaGainCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t txEndToXpaOff; // 1 + uint8_t txEndToRxOn; // 1 + uint8_t txFrameToXpaOn; // 1 + uint8_t thresh62; // 1 + uint8_t noiseFloorThreshCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t xpdGain; // 1 + uint8_t xpd; // 1 + int8_t iqCalICh[AR5416_4K_MAX_CHAINS]; // 1 + int8_t iqCalQCh[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t pdGainOverlap; // 1 + uint8_t ob; // 1 + uint8_t db; // 1 + uint8_t xpaBiasLvl; // 1 +#if 0 + uint8_t pwrDecreaseFor2Chain; // 1 + uint8_t pwrDecreaseFor3Chain; // 1 -> 48 B +#endif + uint8_t txFrameToDataStart; // 1 + uint8_t txFrameToPaOn; // 1 + uint8_t ht40PowerIncForPdadc; // 1 + uint8_t bswAtten[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t bswMargin[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t swSettleHt40; // 1 + uint8_t xatten2Db[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t xatten2Margin[AR5416_4K_MAX_CHAINS]; // 1 + uint8_t ob_ch1; // 1 -> ob and db become chain specific from AR9280 + uint8_t db_ch1; // 1 + uint8_t flagBits; // 1 +#define AR5416_EEP_FLAG_USEANT1 0x01 /* +1 configured antenna */ +#define AR5416_EEP_FLAG_FORCEXPAON 0x02 /* force XPA bit for 5G */ +#define AR5416_EEP_FLAG_LOCALBIAS 0x04 /* enable local bias */ +#define AR5416_EEP_FLAG_FEMBANDSELECT 0x08 /* FEM band select used */ +#define AR5416_EEP_FLAG_XLNABUFIN 0x10 +#define AR5416_EEP_FLAG_XLNAISEL 0x60 +#define AR5416_EEP_FLAG_XLNAISEL_S 5 +#define AR5416_EEP_FLAG_XLNABUFMODE 0x80 + uint8_t miscBits; // [0..1]: bb_tx_dac_scale_cck + uint16_t xpaBiasLvlFreq[3]; // 6 + uint8_t futureModal[2]; // 2 + + SPUR_CHAN spurChans[AR5416_EEPROM_MODAL_SPURS]; // 20 B +} __packed MODAL_EEP4K_HEADER; // == 68 B + +typedef struct CalCtlData4k { + CAL_CTL_EDGES ctlEdges[AR5416_4K_MAX_CHAINS][AR5416_4K_NUM_BAND_EDGES]; +} __packed CAL_CTL_DATA_4K; + +typedef struct calDataPerFreq4k { + uint8_t pwrPdg[AR5416_4K_NUM_PD_GAINS][AR5416_4K_PD_GAIN_ICEPTS]; + uint8_t vpdPdg[AR5416_4K_NUM_PD_GAINS][AR5416_4K_PD_GAIN_ICEPTS]; +} __packed CAL_DATA_PER_FREQ_4K; + +struct ar5416eeprom_4k { + BASE_EEP4K_HEADER baseEepHeader; // 32 B + uint8_t custData[20]; // 20 B + MODAL_EEP4K_HEADER modalHeader; // 68 B + uint8_t calFreqPier2G[AR5416_4K_NUM_2G_CAL_PIERS]; + CAL_DATA_PER_FREQ_4K calPierData2G[AR5416_4K_MAX_CHAINS][AR5416_4K_NUM_2G_CAL_PIERS]; + CAL_TARGET_POWER_LEG calTargetPowerCck[AR5416_4K_NUM_2G_CCK_TARGET_POWERS]; + CAL_TARGET_POWER_LEG calTargetPower2G[AR5416_4K_NUM_2G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower2GHT20[AR5416_4K_NUM_2G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower2GHT40[AR5416_4K_NUM_2G_40_TARGET_POWERS]; + uint8_t ctlIndex[AR5416_4K_NUM_CTLS]; + CAL_CTL_DATA_4K ctlData[AR5416_4K_NUM_CTLS]; + uint8_t padding; +} __packed; + +typedef struct { + struct ar5416eeprom_4k ee_base; +#define NUM_EDGES 8 + uint16_t ee_numCtls; + RD_EDGES_POWER ee_rdEdgesPower[NUM_EDGES*AR5416_4K_NUM_CTLS]; + /* XXX these are dynamically calculated for use by shared code */ + int8_t ee_antennaGainMax[2]; +} HAL_EEPROM_v4k; +#endif /* _AH_EEPROM_V4K_H_ */ From 6cc40ae58b1f2e8e1e7b6d71fe608b0acda796ed Mon Sep 17 00:00:00 2001 From: David Schultz Date: Sun, 11 Oct 2009 00:08:55 +0000 Subject: [PATCH 116/646] Document errno codes added in r144530. --- lib/libc/sys/intro.2 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2 index b75e52c8a3d..e5ff9df77d2 100644 --- a/lib/libc/sys/intro.2 +++ b/lib/libc/sys/intro.2 @@ -456,6 +456,14 @@ The specified extended attribute does not exist. .It Er 88 EDOOFUS Em "Programming error" . A function or API is being abused in a way which could only be detected at run-time. +.It Er 89 EBADMSG Em "Bad message" . +A corrupted message was detected. +.It Er 90 EMULTIHOP Em "Multihop attempted" . +This error code is unused, but present for compatibility with other systems. +.It Er 91 ENOLINK Em "Link has been severed" . +This error code is unused, but present for compatibility with other systems. +.It Er 92 EPROTO Em "Protocol error" . +A device or socket encountered an unrecoverable protocol error. .It Er 93 ENOTCAPABLE Em "Capabilities insufficient" . An operation on a capability file descriptor requires greater privilege than the capability allows. From 2d52bcc46bb46819bb659ab7f97e4be2603723b8 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 11 Oct 2009 01:51:35 +0000 Subject: [PATCH 117/646] Add pci id's for Intel G41 chipset Submitted by: Artyom Mirgorodsky MFC after: 3 days --- sys/dev/agp/agp_i810.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c index a1758244dee..be51bb231c2 100644 --- a/sys/dev/agp/agp_i810.c +++ b/sys/dev/agp/agp_i810.c @@ -175,6 +175,8 @@ static const struct agp_i810_match { "Intel Q45 SVGA controller"}, {0x2E228086, CHIP_G4X, 0x00020000, "Intel G45 SVGA controller"}, + {0x2E328086, CHIP_G4X, 0x00020000, + "Intel G41 SVGA controller"}, {0, 0, 0, NULL} }; From 33cba7feacf4dfbdd9b2316a3e3a97056e2b5c26 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 11 Oct 2009 01:54:00 +0000 Subject: [PATCH 118/646] Add support for Intel G41 chipset Submitted by: Artyom Mirgorodsky MFC after: 3 days --- sys/dev/drm/drm_pciids.h | 1 + sys/dev/drm/i915_drv.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h index 7cc084c4713..acebad4e002 100644 --- a/sys/dev/drm/drm_pciids.h +++ b/sys/dev/drm/drm_pciids.h @@ -552,6 +552,7 @@ {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Integrated Graphics Device"}, \ {0x8086, 0x2E12, CHIP_I9XX|CHIP_I965, "Intel Q45/Q43"}, \ {0x8086, 0x2E22, CHIP_I9XX|CHIP_I965, "Intel G45/G43"}, \ + {0x8086, 0x2E32, CHIP_I9XX|CHIP_I965, "Intel G41"}, \ {0, 0, 0, NULL} #define imagine_PCI_IDS \ diff --git a/sys/dev/drm/i915_drv.h b/sys/dev/drm/i915_drv.h index ac754139d35..38ae374b341 100644 --- a/sys/dev/drm/i915_drv.h +++ b/sys/dev/drm/i915_drv.h @@ -644,7 +644,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x2A42 || \ (dev)->pci_device == 0x2E02 || \ (dev)->pci_device == 0x2E12 || \ - (dev)->pci_device == 0x2E22) + (dev)->pci_device == 0x2E22 || \ + (dev)->pci_device == 0x2E32) #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) @@ -653,6 +654,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ (dev)->pci_device == 0x2E12 || \ (dev)->pci_device == 0x2E22 || \ + (dev)->pci_device == 0x2E32 || \ IS_GM45(dev)) #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ From 0b4b0b0feea2734cdf46d8542dee3cc4a56fa52b Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Sun, 11 Oct 2009 05:59:43 +0000 Subject: [PATCH 119/646] Virtualize the pfil hooks so that different jails may chose different packet filters. ALso allows ipfw to be enabled on on ejail and disabled on another. In 8.0 it's a global setting. Sitting aroung in tree waiting to commit for: 2 months MFC after: 2 months --- sys/net/if_bridge.c | 41 +++++++------- sys/net/if_ethersubr.c | 6 +- sys/net/pfil.c | 53 ++++++++++++++++-- sys/netgraph/ng_bridge.c | 2 +- sys/netinet/ip_fastfwd.c | 9 +-- sys/netinet/ip_input.c | 20 +++---- sys/netinet/ip_output.c | 4 +- sys/netinet/ip_var.h | 12 +++- sys/netinet/ipfw/ip_fw2.c | 102 ++++++++++++++++++---------------- sys/netinet/ipfw/ip_fw_pfil.c | 36 ++++++++---- sys/netinet/raw_ip.c | 12 ++-- sys/netinet6/ip6_forward.c | 4 +- sys/netinet6/ip6_input.c | 21 +++---- sys/netinet6/ip6_output.c | 4 +- sys/netinet6/ip6_var.h | 3 +- 15 files changed, 199 insertions(+), 130 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index d3a55fd15af..8e0e6e1e6a5 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -109,6 +109,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include /* for struct arpcom */ #include @@ -1800,9 +1801,9 @@ bridge_dummynet(struct mbuf *m, struct ifnet *ifp) return; } - if (PFIL_HOOKED(&inet_pfil_hook) + if (PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif ) { if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0) @@ -2062,9 +2063,9 @@ bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif, ETHER_BPF_MTAP(ifp, m); /* run the packet filter */ - if (PFIL_HOOKED(&inet_pfil_hook) + if (PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif ) { BRIDGE_UNLOCK(sc); @@ -2102,9 +2103,9 @@ bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif, BRIDGE_UNLOCK(sc); - if (PFIL_HOOKED(&inet_pfil_hook) + if (PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif ) { if (bridge_pfil(&m, ifp, dst_if, PFIL_OUT) != 0) @@ -2243,7 +2244,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) #ifdef INET6 # define OR_PFIL_HOOKED_INET6 \ - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #else # define OR_PFIL_HOOKED_INET6 #endif @@ -2260,7 +2261,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) iface->if_ipackets++; \ /* Filter on the physical interface. */ \ if (pfil_local_phys && \ - (PFIL_HOOKED(&inet_pfil_hook) \ + (PFIL_HOOKED(&V_inet_pfil_hook) \ OR_PFIL_HOOKED_INET6)) { \ if (bridge_pfil(&m, NULL, ifp, \ PFIL_IN) != 0 || m == NULL) { \ @@ -2349,9 +2350,9 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, } /* Filter on the bridge interface before broadcasting */ - if (runfilt && (PFIL_HOOKED(&inet_pfil_hook) + if (runfilt && (PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif )) { if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0) @@ -2396,9 +2397,9 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, * pointer so we do not redundantly filter on the bridge for * each interface we broadcast on. */ - if (runfilt && (PFIL_HOOKED(&inet_pfil_hook) + if (runfilt && (PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif )) { if (used == 0) { @@ -3037,7 +3038,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) goto bad; } - if (ip_fw_chk_ptr && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) { + if (V_ip_fw_chk_ptr && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) { struct dn_pkt_tag *dn_tag; error = -1; @@ -3057,7 +3058,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) args.next_hop = NULL; args.eh = &eh2; args.inp = NULL; /* used by ipfw uid/gid/jail rules */ - i = ip_fw_chk_ptr(&args); + i = V_ip_fw_chk_ptr(&args); *mp = args.m; if (*mp == NULL) @@ -3109,21 +3110,21 @@ ipfwpass: * in_if -> bridge_if -> out_if */ if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) - error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, + error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp, dir, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (pfil_member && ifp != NULL) - error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, + error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, dir, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (pfil_bridge && dir == PFIL_IN && bifp != NULL) - error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, + error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp, dir, NULL); if (*mp == NULL || error != 0) /* filter may consume */ @@ -3163,21 +3164,21 @@ ipfwpass: #ifdef INET6 case ETHERTYPE_IPV6: if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) - error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, + error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp, dir, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (pfil_member && ifp != NULL) - error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, + error = pfil_run_hooks(&V_inet6_pfil_hook, mp, ifp, dir, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (pfil_bridge && dir == PFIL_IN && bifp != NULL) - error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, + error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp, dir, NULL); break; #endif diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index bac20444923..5dff9bce55d 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -434,7 +434,7 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m) { #if defined(INET) || defined(INET6) - if (ip_fw_chk_ptr && V_ether_ipfw != 0) { + if (V_ip_fw_chk_ptr && V_ether_ipfw != 0) { if (ether_ipfw_chk(&m, ifp, 0) == 0) { if (m) { m_freem(m); @@ -502,7 +502,7 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared) args.next_hop = NULL; /* we do not support forward yet */ args.eh = &save_eh; /* MAC header for bridged/MAC packets */ args.inp = NULL; /* used by ipfw uid/gid/jail rules */ - i = ip_fw_chk_ptr(&args); + i = V_ip_fw_chk_ptr(&args); m = args.m; if (m != NULL) { /* @@ -775,7 +775,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) * Allow dummynet and/or ipfw to claim the frame. * Do not do this for PROMISC frames in case we are re-entered. */ - if (ip_fw_chk_ptr && V_ether_ipfw != 0 && !(m->m_flags & M_PROMISC)) { + if (V_ip_fw_chk_ptr && V_ether_ipfw != 0 && !(m->m_flags & M_PROMISC)) { if (ether_ipfw_chk(&m, NULL, 0) == 0) { if (m) m_freem(m); /* dropped; free mbuf chain */ diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 3018eb9a578..76ed664fb84 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -56,8 +56,9 @@ static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int); static int pfil_list_remove(pfil_list_t *, int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *); -LIST_HEAD(, pfil_head) pfil_head_list = - LIST_HEAD_INITIALIZER(&pfil_head_list); +LIST_HEAD(pfilheadhead, pfil_head); +VNET_DEFINE(struct pfilheadhead, pfil_head_list); +#define V_pfil_head_list VNET(pfil_head_list) /* * pfil_run_hooks() runs the specified packet filter hooks. @@ -97,7 +98,7 @@ pfil_head_register(struct pfil_head *ph) struct pfil_head *lph; PFIL_LIST_LOCK(); - LIST_FOREACH(lph, &pfil_head_list, ph_list) { + LIST_FOREACH(lph, &V_pfil_head_list, ph_list) { if (ph->ph_type == lph->ph_type && ph->ph_un.phu_val == lph->ph_un.phu_val) { PFIL_LIST_UNLOCK(); @@ -108,7 +109,7 @@ pfil_head_register(struct pfil_head *ph) ph->ph_nhooks = 0; TAILQ_INIT(&ph->ph_in); TAILQ_INIT(&ph->ph_out); - LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list); + LIST_INSERT_HEAD(&V_pfil_head_list, ph, ph_list); PFIL_LIST_UNLOCK(); return (0); } @@ -143,7 +144,7 @@ pfil_head_get(int type, u_long val) struct pfil_head *ph; PFIL_LIST_LOCK(); - LIST_FOREACH(ph, &pfil_head_list, ph_list) + LIST_FOREACH(ph, &V_pfil_head_list, ph_list) if (ph->ph_type == type && ph->ph_un.phu_val == val) break; PFIL_LIST_UNLOCK(); @@ -284,3 +285,45 @@ pfil_list_remove(pfil_list_t *list, } return ENOENT; } + +/**************** + * Stuff that must be initialized for every instance + * (including the first of course). + */ +static int +vnet_pfil_init(const void *unused) +{ + LIST_INIT(&V_pfil_head_list); + return (0); +} + +/*********************** + * Called for the removal of each instance. + */ +static int +vnet_pfil_uninit(const void *unused) +{ + /* XXX should panic if list is not empty */ + return 0; +} + +/* Define startup order. */ +#define PFIL_SYSINIT_ORDER SI_SUB_PROTO_BEGIN +#define PFIL_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */ +#define PFIL_VNET_ORDER (PFIL_MODEVENT_ORDER + 2) /* Later still. */ + +/* + * Starting up. + * VNET_SYSINIT is called for each existing vnet and each new vnet. + */ +VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, + vnet_pfil_init, NULL); + +/* + * Closing up shop. These are done in REVERSE ORDER, + * Not called on reboot. + * VNET_SYSUNINIT is called for each exiting vnet as it exits. + */ +VNET_SYSUNINIT(vnet_pfil_uninit, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, + vnet_pfil_uninit, NULL); + diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c index e42b5a547f0..c6f41836cca 100644 --- a/sys/netgraph/ng_bridge.c +++ b/sys/netgraph/ng_bridge.c @@ -634,7 +634,7 @@ ng_bridge_rcvdata(hook_p hook, item_p item) /* Run packet through ipfw processing, if enabled */ #if 0 - if (priv->conf.ipfw[linkNum] && V_fw_enable && ip_fw_chk_ptr != NULL) { + if (priv->conf.ipfw[linkNum] && V_fw_enable && V_ip_fw_chk_ptr != NULL) { /* XXX not implemented yet */ } #endif diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index 78b6d3046e2..03993930f03 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -351,10 +351,11 @@ ip_fastforward(struct mbuf *m) /* * Run through list of ipfilter hooks for input packets */ - if (!PFIL_HOOKED(&inet_pfil_hook)) + if (!PFIL_HOOKED(&V_inet_pfil_hook)) goto passin; - if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) || + if (pfil_run_hooks( + &V_inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) || m == NULL) goto drop; @@ -438,10 +439,10 @@ passin: /* * Run through list of hooks for output packets. */ - if (!PFIL_HOOKED(&inet_pfil_hook)) + if (!PFIL_HOOKED(&V_inet_pfil_hook)) goto passout; - if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) { + if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) { goto drop; } diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7886fa73716..50b66b564e7 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -170,7 +170,7 @@ SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_RW, &VNET_NAME(ip_checkinterface), 0, "Verify packet arrives on correct interface"); -struct pfil_head inet_pfil_hook; /* Packet filter hooks */ +VNET_DEFINE(struct pfil_head, inet_pfil_hook); /* Packet filter hooks */ static struct netisr_handler ip_nh = { .nh_name = "ip", @@ -318,6 +318,13 @@ ip_init(void) NULL, UMA_ALIGN_PTR, 0); maxnipq_update(); + /* Initialize packet filter hooks. */ + V_inet_pfil_hook.ph_type = PFIL_TYPE_AF; + V_inet_pfil_hook.ph_af = AF_INET; + if ((i = pfil_head_register(&V_inet_pfil_hook)) != 0) + printf("%s: WARNING: unable to register pfil hook, " + "error %d\n", __func__, i); + #ifdef FLOWTABLE TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size", &V_ip_output_flowtable_size); @@ -348,13 +355,6 @@ ip_init(void) ip_protox[pr->pr_protocol] = pr - inetsw; } - /* Initialize packet filter hooks. */ - inet_pfil_hook.ph_type = PFIL_TYPE_AF; - inet_pfil_hook.ph_af = AF_INET; - if ((i = pfil_head_register(&inet_pfil_hook)) != 0) - printf("%s: WARNING: unable to register pfil hook, " - "error %d\n", __func__, i); - /* Start ipport_tick. */ callout_init(&ipport_tick_callout, CALLOUT_MPSAFE); callout_reset(&ipport_tick_callout, 1, ipport_tick, NULL); @@ -510,11 +510,11 @@ tooshort: */ /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&inet_pfil_hook)) + if (!PFIL_HOOKED(&V_inet_pfil_hook)) goto passin; odst = ip->ip_dst; - if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_IN, NULL) != 0) + if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_IN, NULL) != 0) return; if (m == NULL) /* consumed by filter */ return; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index e222cdaaa1f..b5be6fd1e1f 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -489,12 +489,12 @@ sendit: #endif /* IPSEC */ /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&inet_pfil_hook)) + if (!PFIL_HOOKED(&V_inet_pfil_hook)) goto passout; /* Run through list of hooks for output packets. */ odst.s_addr = ip->ip_dst.s_addr; - error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, inp); + error = pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, inp); if (error != 0 || m == NULL) goto done; diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 448ba3d7978..a1d2166ac3a 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -244,14 +244,20 @@ extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *); extern void (*ip_rsvp_force_done)(struct socket *); extern void (*rsvp_input_p)(struct mbuf *m, int off); -extern struct pfil_head inet_pfil_hook; /* packet filter hooks */ +VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */ +#define V_inet_pfil_hook VNET(inet_pfil_hook) void in_delayed_cksum(struct mbuf *m); /* ipfw and dummynet hooks. Most are declared in raw_ip.c */ struct ip_fw_args; -extern int (*ip_fw_chk_ptr)(struct ip_fw_args *args); -extern int (*ip_fw_ctl_ptr)(struct sockopt *); +typedef int (*ip_fw_chk_ptr_t)(struct ip_fw_args *args); +typedef int (*ip_fw_ctl_ptr_t)(struct sockopt *); +VNET_DECLARE(ip_fw_chk_ptr_t, ip_fw_chk_ptr); +VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr); +#define V_ip_fw_chk_ptr VNET(ip_fw_chk_ptr) +#define V_ip_fw_ctl_ptr VNET(ip_fw_ctl_ptr) + extern int (*ip_dn_ctl_ptr)(struct sockopt *); extern int (*ip_dn_io_ptr)(struct mbuf **m, int dir, struct ip_fw_args *fwa); extern void (*ip_dn_ruledel_ptr)(void *); /* in ip_fw2.c */ diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c index e35669dc3a2..975d3033130 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -2495,6 +2495,10 @@ do { \ } IPFW_RLOCK(chain); + if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */ + IPFW_RUNLOCK(chain); + return (IP_FW_PASS); /* accept */ + } mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL); if (args->rule) { /* @@ -4637,29 +4641,21 @@ ipfw_init(void) printf("limited to %d packets/entry by default\n", V_verbose_limit); - /* - * Hook us up to pfil. - * Eventually pfil will be per vnet. - */ - if ((error = ipfw_hook()) != 0) { - printf("ipfw_hook() error\n"); - return (error); - } -#ifdef INET6 - if ((error = ipfw6_hook()) != 0) { - printf("ipfw6_hook() error\n"); - return (error); - } -#endif - /* - * Other things that are only done the first time. - * (now that we are guaranteed of success). - */ - ip_fw_ctl_ptr = ipfw_ctl; - ip_fw_chk_ptr = ipfw_chk; return (error); } +/********************** + * Called for the removal of the last instance only on module unload. + */ +static void +ipfw_destroy(void) +{ + + uma_zdestroy(ipfw_dyn_rule_zone); + IPFW_DYN_LOCK_DESTROY(); + printf("IP firewall unloaded\n"); +} + /**************** * Stuff that must be initialized for every instance * (including the first of course). @@ -4743,21 +4739,32 @@ vnet_ipfw_init(const void *unused) /* First set up some values that are compile time options */ V_ipfw_vnet_ready = 1; /* Open for business */ + + /* Hook up the raw inputs */ + V_ip_fw_ctl_ptr = ipfw_ctl; + V_ip_fw_chk_ptr = ipfw_chk; + + /* + * Hook us up to pfil. + */ + if (V_fw_enable) { + if ((error = ipfw_hook()) != 0) { + printf("ipfw_hook() error\n"); + return (error); + } + } +#ifdef INET6 + if (V_fw6_enable) { + if ((error = ipfw6_hook()) != 0) { + printf("ipfw6_hook() error\n"); + /* XXX should we unhook everything else? */ + return (error); + } + } +#endif return (0); } -/********************** - * Called for the removal of the last instance only on module unload. - */ -static void -ipfw_destroy(void) -{ - - uma_zdestroy(ipfw_dyn_rule_zone); - IPFW_DYN_LOCK_DESTROY(); - printf("IP firewall unloaded\n"); -} - /*********************** * Called for the removal of each instance. */ @@ -4767,9 +4774,18 @@ vnet_ipfw_uninit(const void *unused) struct ip_fw *reap; V_ipfw_vnet_ready = 0; /* tell new callers to go away */ - callout_drain(&V_ipfw_timeout); - /* We wait on the wlock here until the last user leaves */ + ipfw_unhook(); +#ifdef INET6 + ipfw6_unhook(); +#endif + /* layer2 and other entrypoints still come in this way. */ + V_ip_fw_chk_ptr = NULL; + V_ip_fw_ctl_ptr = NULL; IPFW_WLOCK(&V_layer3_chain); + /* We wait on the wlock here until the last user leaves */ + IPFW_WUNLOCK(&V_layer3_chain); + IPFW_WLOCK(&V_layer3_chain); + callout_drain(&V_ipfw_timeout); flush_tables(&V_layer3_chain); V_layer3_chain.reap = NULL; free_chain(&V_layer3_chain, 1 /* kill default rule */); @@ -4803,21 +4819,10 @@ ipfw_modevent(module_t mod, int type, void *unused) /* Called once at module load or * system boot if compiled in. */ break; - case MOD_UNLOAD: - break; case MOD_QUIESCE: - /* Yes, the unhooks can return errors, we can safely ignore - * them. Eventually these will be done per jail as they - * shut down. We will wait on each vnet's l3 lock as existing - * callers go away. - */ - ipfw_unhook(); -#ifdef INET6 - ipfw6_unhook(); -#endif - /* layer2 and other entrypoints still come in this way. */ - ip_fw_chk_ptr = NULL; - ip_fw_ctl_ptr = NULL; + /* Called before unload. May veto unloading. */ + break; + case MOD_UNLOAD: /* Called during unload. */ break; case MOD_SHUTDOWN: @@ -4866,4 +4871,3 @@ SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER, VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER, vnet_ipfw_uninit, NULL); - diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c index ffffb594546..db7308407a8 100644 --- a/sys/netinet/ipfw/ip_fw_pfil.c +++ b/sys/netinet/ipfw/ip_fw_pfil.c @@ -515,42 +515,54 @@ ipfw6_unhook(void) int ipfw_chg_hook(SYSCTL_HANDLER_ARGS) { - int enable = *(int *)arg1; + int enable; + int oldenable; int error; -#ifdef VIMAGE /* Since enabling is global, only let base do it. */ - if (! IS_DEFAULT_VNET(curvnet)) - return (EPERM); + if (arg1 == &VNET_NAME(fw_enable)) { + enable = V_fw_enable; + } +#ifdef INET6 + else if (arg1 == &VNET_NAME(fw6_enable)) { + enable = V_fw6_enable; + } #endif + else + return (EINVAL); + + oldenable = enable; + error = sysctl_handle_int(oidp, &enable, 0, req); + if (error) return (error); enable = (enable) ? 1 : 0; - if (enable == *(int *)arg1) + if (enable == oldenable) return (0); - if (arg1 == &V_fw_enable) { + if (arg1 == &VNET_NAME(fw_enable)) { if (enable) error = ipfw_hook(); else error = ipfw_unhook(); + if (error) + return (error); + V_fw_enable = enable; } #ifdef INET6 - if (arg1 == &V_fw6_enable) { + else if (arg1 == &VNET_NAME(fw6_enable)) { if (enable) error = ipfw6_hook(); else error = ipfw6_unhook(); + if (error) + return (error); + V_fw6_enable = enable; } #endif - if (error) - return (error); - - *(int *)arg1 = enable; - return (0); } diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index b40ceb28b79..d612c2c1d5a 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -84,9 +84,9 @@ VNET_DEFINE(struct inpcbinfo, ripcbinfo); * The data hooks are not used here but it is convenient * to keep them all in one place. */ -int (*ip_fw_ctl_ptr)(struct sockopt *) = NULL; +VNET_DEFINE(ip_fw_chk_ptr_t, ip_fw_chk_ptr) = NULL; +VNET_DEFINE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr) = NULL; int (*ip_dn_ctl_ptr)(struct sockopt *) = NULL; -int (*ip_fw_chk_ptr)(struct ip_fw_args *args) = NULL; int (*ip_dn_io_ptr)(struct mbuf **m, int dir, struct ip_fw_args *fwa) = NULL; /* @@ -523,8 +523,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_FW_TABLE_LIST: case IP_FW_NAT_GET_CONFIG: case IP_FW_NAT_GET_LOG: - if (ip_fw_ctl_ptr != NULL) - error = ip_fw_ctl_ptr(sopt); + if (V_ip_fw_ctl_ptr != NULL) + error = V_ip_fw_ctl_ptr(sopt); else error = ENOPROTOOPT; break; @@ -584,8 +584,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_FW_TABLE_FLUSH: case IP_FW_NAT_CFG: case IP_FW_NAT_DEL: - if (ip_fw_ctl_ptr != NULL) - error = ip_fw_ctl_ptr(sopt); + if (V_ip_fw_ctl_ptr != NULL) + error = V_ip_fw_ctl_ptr(sopt); else error = ENOPROTOOPT; break; diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 7ba4977d919..cff29e19be5 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -551,11 +551,11 @@ skip_routing: in6_clearscope(&ip6->ip6_dst); /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&inet6_pfil_hook)) + if (!PFIL_HOOKED(&V_inet6_pfil_hook)) goto pass; /* Run through list of hooks for output packets. */ - error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL); + error = pfil_run_hooks(&V_inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL); if (error != 0) goto senderr; if (m == NULL) diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 730b3bee7a2..fc26cffeb9d 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -152,7 +152,7 @@ VNET_DECLARE(int, udp6_recvspace); struct rwlock in6_ifaddr_lock; RW_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); -struct pfil_head inet6_pfil_hook; +VNET_DEFINE (struct pfil_head, inet6_pfil_hook); static void ip6_init2(void *); static struct ip6aux *ip6_setdstifaddr(struct mbuf *, struct in6_ifaddr *); @@ -247,6 +247,13 @@ ip6_init(void) V_ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR; + /* Initialize packet filter hooks. */ + V_inet6_pfil_hook.ph_type = PFIL_TYPE_AF; + V_inet6_pfil_hook.ph_af = AF_INET6; + if ((i = pfil_head_register(&V_inet6_pfil_hook)) != 0) + printf("%s: WARNING: unable to register pfil hook, " + "error %d\n", __func__, i); + /* Skip global initialization stuff for non-default instances. */ if (!IS_DEFAULT_VNET(curvnet)) return; @@ -275,13 +282,6 @@ ip6_init(void) ip6_protox[pr->pr_protocol] = pr - inet6sw; } - /* Initialize packet filter hooks. */ - inet6_pfil_hook.ph_type = PFIL_TYPE_AF; - inet6_pfil_hook.ph_af = AF_INET6; - if ((i = pfil_head_register(&inet6_pfil_hook)) != 0) - printf("%s: WARNING: unable to register pfil hook, " - "error %d\n", __func__, i); - netisr_register(&ip6_nh); } @@ -515,10 +515,11 @@ ip6_input(struct mbuf *m) odst = ip6->ip6_dst; /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&inet6_pfil_hook)) + if (!PFIL_HOOKED(&V_inet6_pfil_hook)) goto passin; - if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL)) + if (pfil_run_hooks(&V_inet6_pfil_hook, &m, + m->m_pkthdr.rcvif, PFIL_IN, NULL)) return; if (m == NULL) /* consumed by filter */ return; diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 98875640e7a..c2ec49aa350 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -805,12 +805,12 @@ again: } /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&inet6_pfil_hook)) + if (!PFIL_HOOKED(&V_inet6_pfil_hook)) goto passout; odst = ip6->ip6_dst; /* Run through list of hooks for output packets. */ - error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT, inp); + error = pfil_run_hooks(&V_inet6_pfil_hook, &m, ifp, PFIL_OUT, inp); if (error != 0 || m == NULL) goto done; ip6 = mtod(m, struct ip6_hdr *); diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index e8fe3ec04a4..a0a0f3a18d8 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -358,7 +358,8 @@ VNET_DECLARE(int, ip6_use_defzone); /* Whether to use the default scope #endif #define V_ip6_use_defzone VNET(ip6_use_defzone) -extern struct pfil_head inet6_pfil_hook; /* packet filter hooks */ +VNET_DECLARE (struct pfil_head, inet6_pfil_hook); /* packet filter hooks */ +#define V_inet6_pfil_hook VNET(inet6_pfil_hook) extern struct pr_usrreqs rip6_usrreqs; struct sockopt; From 82cf92d4836ca0dbdeec98d8a294119594608cd3 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sun, 11 Oct 2009 07:03:56 +0000 Subject: [PATCH 120/646] Add locking around access to parent node, and bail out when the parent node is already freed rather than panicking the system. PR: kern/122038 Submitted by: gk Tested by: pho MFC after: 1 week --- sys/fs/tmpfs/tmpfs.h | 22 +++++++++++- sys/fs/tmpfs/tmpfs_subr.c | 27 ++++++++++++-- sys/fs/tmpfs/tmpfs_vnops.c | 74 +++++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 8 deletions(-) diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index ffd705fe026..1edbc415106 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -303,10 +303,30 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node); #define TMPFS_NODE_LOCK(node) mtx_lock(&(node)->tn_interlock) #define TMPFS_NODE_UNLOCK(node) mtx_unlock(&(node)->tn_interlock) -#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock) +#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock) + +#ifdef INVARIANTS +#define TMPFS_ASSERT_LOCKED(node) do { \ + MPASS(node != NULL); \ + MPASS(node->tn_vnode != NULL); \ + if (!VOP_ISLOCKED(node->tn_vnode) && \ + !mtx_owned(TMPFS_NODE_MTX(node))) \ + panic("tmpfs: node is not locked: %p", node); \ + } while (0) +#define TMPFS_ASSERT_ELOCKED(node) do { \ + MPASS((node) != NULL); \ + MPASS((node)->tn_vnode != NULL); \ + mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED); \ + ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs"); \ + } while (0) +#else +#define TMPFS_ASSERT_LOCKED(node) (void)0 +#define TMPFS_ASSERT_ELOCKED(node) (void)0 +#endif #define TMPFS_VNODE_ALLOCATING 1 #define TMPFS_VNODE_WANT 2 +#define TMPFS_VNODE_DOOMED 4 /* --------------------------------------------------------------------- */ /* diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index dad634ea1f7..8dc833816f9 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -124,7 +124,9 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type, nnode->tn_dir.tn_readdir_lastn = 0; nnode->tn_dir.tn_readdir_lastp = NULL; nnode->tn_links++; + TMPFS_NODE_LOCK(nnode->tn_dir.tn_parent); nnode->tn_dir.tn_parent->tn_links++; + TMPFS_NODE_UNLOCK(nnode->tn_dir.tn_parent); break; case VFIFO: @@ -187,6 +189,7 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node) #ifdef INVARIANTS TMPFS_NODE_LOCK(node); MPASS(node->tn_vnode == NULL); + MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0); TMPFS_NODE_UNLOCK(node); #endif @@ -312,6 +315,7 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag, loop: TMPFS_NODE_LOCK(node); if ((vp = node->tn_vnode) != NULL) { + MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0); VI_LOCK(vp); TMPFS_NODE_UNLOCK(node); vholdl(vp); @@ -330,6 +334,14 @@ loop: goto out; } + if ((node->tn_vpstate & TMPFS_VNODE_DOOMED) || + (node->tn_type == VDIR && node->tn_dir.tn_parent == NULL)) { + TMPFS_NODE_UNLOCK(node); + error = ENOENT; + vp = NULL; + goto out; + } + /* * otherwise lock the vp list while we call getnewvnode * since that can block. @@ -375,6 +387,7 @@ loop: vp->v_op = &tmpfs_fifoop_entries; break; case VDIR: + MPASS(node->tn_dir.tn_parent != NULL); if (node->tn_dir.tn_parent == node) vp->v_vflag |= VV_ROOT; break; @@ -428,10 +441,9 @@ tmpfs_free_vp(struct vnode *vp) node = VP_TO_TMPFS_NODE(vp); - TMPFS_NODE_LOCK(node); + mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED); node->tn_vnode = NULL; vp->v_data = NULL; - TMPFS_NODE_UNLOCK(node); } /* --------------------------------------------------------------------- */ @@ -653,7 +665,18 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio) TMPFS_VALIDATE_DIR(node); MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT); + /* + * Return ENOENT if the current node is already removed. + */ + TMPFS_ASSERT_LOCKED(node); + if (node->tn_dir.tn_parent == NULL) { + return (ENOENT); + } + + TMPFS_NODE_LOCK(node->tn_dir.tn_parent); dent.d_fileno = node->tn_dir.tn_parent->tn_id; + TMPFS_NODE_UNLOCK(node->tn_dir.tn_parent); + dent.d_type = DT_DIR; dent.d_namlen = 2; dent.d_name[0] = '.'; diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 49a71973877..c17efff9d5f 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -87,6 +87,11 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) dnode->tn_dir.tn_parent == dnode, !(cnp->cn_flags & ISDOTDOT))); + TMPFS_ASSERT_LOCKED(dnode); + if (dnode->tn_dir.tn_parent == NULL) { + error = ENOENT; + goto out; + } if (cnp->cn_flags & ISDOTDOT) { int ltype = 0; @@ -914,6 +919,7 @@ tmpfs_rename(struct vop_rename_args *v) char *newname; int error; struct tmpfs_dirent *de; + struct tmpfs_mount *tmp; struct tmpfs_node *fdnode; struct tmpfs_node *fnode; struct tmpfs_node *tnode; @@ -934,6 +940,7 @@ tmpfs_rename(struct vop_rename_args *v) goto out; } + tmp = VFS_TO_TMPFS(tdvp->v_mount); tdnode = VP_TO_TMPFS_DIR(tdvp); /* If source and target are the same file, there is nothing to do. */ @@ -1018,25 +1025,63 @@ tmpfs_rename(struct vop_rename_args *v) * directory being moved. Otherwise, we'd end up * with stale nodes. */ n = tdnode; + /* TMPFS_LOCK garanties that no nodes are freed while + * traversing the list. Nodes can only be marked as + * removed: tn_parent == NULL. */ + TMPFS_LOCK(tmp); + TMPFS_NODE_LOCK(n); while (n != n->tn_dir.tn_parent) { + struct tmpfs_node *parent; + if (n == fnode) { + TMPFS_NODE_UNLOCK(n); + TMPFS_UNLOCK(tmp); error = EINVAL; if (newname != NULL) free(newname, M_TMPFSNAME); goto out_locked; } - n = n->tn_dir.tn_parent; + parent = n->tn_dir.tn_parent; + TMPFS_NODE_UNLOCK(n); + if (parent == NULL) { + n = NULL; + break; + } + TMPFS_NODE_LOCK(parent); + if (parent->tn_dir.tn_parent == NULL) { + TMPFS_NODE_UNLOCK(parent); + n = NULL; + break; + } + n = parent; } + TMPFS_UNLOCK(tmp); + if (n == NULL) { + error = EINVAL; + if (newname != NULL) + free(newname, M_TMPFSNAME); + goto out_locked; + } + TMPFS_NODE_UNLOCK(n); /* Adjust the parent pointer. */ TMPFS_VALIDATE_DIR(fnode); + TMPFS_NODE_LOCK(de->td_node); de->td_node->tn_dir.tn_parent = tdnode; + TMPFS_NODE_UNLOCK(de->td_node); /* As a result of changing the target of the '..' * entry, the link count of the source and target * directories has to be adjusted. */ - fdnode->tn_links--; + TMPFS_NODE_LOCK(tdnode); + TMPFS_ASSERT_LOCKED(tdnode); tdnode->tn_links++; + TMPFS_NODE_UNLOCK(tdnode); + + TMPFS_NODE_LOCK(fdnode); + TMPFS_ASSERT_LOCKED(fdnode); + fdnode->tn_links--; + TMPFS_NODE_UNLOCK(fdnode); } /* Do the move: just remove the entry from the source directory @@ -1163,15 +1208,26 @@ tmpfs_rmdir(struct vop_rmdir_args *v) goto out; } + /* Detach the directory entry from the directory (dnode). */ tmpfs_dir_detach(dvp, de); + /* No vnode should be allocated for this entry from this point */ + TMPFS_NODE_LOCK(node); + TMPFS_ASSERT_ELOCKED(node); node->tn_links--; + node->tn_dir.tn_parent = NULL; node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ TMPFS_NODE_MODIFIED; - node->tn_dir.tn_parent->tn_links--; - node->tn_dir.tn_parent->tn_status |= TMPFS_NODE_ACCESSED | \ + + TMPFS_NODE_UNLOCK(node); + + TMPFS_NODE_LOCK(dnode); + TMPFS_ASSERT_ELOCKED(dnode); + dnode->tn_links--; + dnode->tn_status |= TMPFS_NODE_ACCESSED | \ TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + TMPFS_NODE_UNLOCK(dnode); cache_purge(dvp); cache_purge(vp); @@ -1359,13 +1415,21 @@ tmpfs_reclaim(struct vop_reclaim_args *v) vnode_destroy_vobject(vp); cache_purge(vp); + + TMPFS_NODE_LOCK(node); + TMPFS_ASSERT_ELOCKED(node); tmpfs_free_vp(vp); /* If the node referenced by this vnode was deleted by the user, * we must free its associated data structures (now that the vnode * is being reclaimed). */ - if (node->tn_links == 0) + if (node->tn_links == 0 && + (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0) { + node->tn_vpstate = TMPFS_VNODE_DOOMED; + TMPFS_NODE_UNLOCK(node); tmpfs_free_node(tmp, node); + } else + TMPFS_NODE_UNLOCK(node); MPASS(vp->v_data == NULL); return 0; From f71e78a1d929115bddfa44b7ba5613fbbea6d905 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 11 Oct 2009 12:23:56 +0000 Subject: [PATCH 121/646] Fix a race condition where a mutex was destroyed while sleeping on it. Found while analyzing a report from julian. It might fix his bug. Approved by: rrs (mentor) MFC after: 3 days --- sys/netinet/sctp_bsd_addr.c | 1 + sys/netinet/sctp_pcb.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 6a8dfc91163..e508a4ab986 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -97,6 +97,7 @@ sctp_iterator_thread(void *v) &SCTP_BASE_INFO(ipi_iterator_wq_mtx), 0, "waiting_for_work", 0); if (SCTP_BASE_INFO(threads_must_exit)) { + SCTP_IPI_ITERATOR_WQ_DESTROY(); kthread_exit(); } sctp_iterator_worker(); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 21cd88998a8..7d12f375a8e 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -5616,7 +5616,6 @@ sctp_pcb_finish(void) SCTP_IP_PKTLOG_DESTROY(); #endif - SCTP_IPI_ITERATOR_WQ_DESTROY(); SCTP_IPI_ADDR_DESTROY(); SCTP_ITERATOR_LOCK_DESTROY(); SCTP_STATLOG_DESTROY(); From c2dbb0de277a3d3721f208be6756f9de746f93c8 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sun, 11 Oct 2009 12:32:25 +0000 Subject: [PATCH 122/646] - Catch SIGHUP to perform cleanup before exiting. - Exit if getch() returns with an error other than EINTR. Otherwise systat(1) may get stuck in an infinite loop if it doesn't receive SIGHUP when terminal closes. [1] - Remove attempt to clear stdio error indicators. getch() doesn't use stdio, making it useless. [2] - Remove unneeded masking of getch() return value. [2] PR: bin/107171 Reviewed by: bde Approved by: trasz (mentor) Obtained from: OpenBSD [1] Suggested by: bde [2] MFC after: 1 month --- usr.bin/systat/keyboard.c | 11 +++++++---- usr.bin/systat/main.c | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/usr.bin/systat/keyboard.c b/usr.bin/systat/keyboard.c index 7784f5be98a..0ab28eb2603 100644 --- a/usr.bin/systat/keyboard.c +++ b/usr.bin/systat/keyboard.c @@ -39,8 +39,10 @@ __FBSDID("$FreeBSD$"); static const char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93"; #endif +#include #include #include +#include #include #include "systat.h" @@ -57,10 +59,11 @@ keyboard(void) move(CMDLINE, 0); do { refresh(); - ch = getch() & 0177; - if (ch == 0177 && ferror(stdin)) { - clearerr(stdin); - continue; + ch = getch(); + if (ch == ERR) { + if (errno == EINTR) + continue; + exit(1); } if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A'; diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c index 28673e54e6b..6f6b9940686 100644 --- a/usr.bin/systat/main.c +++ b/usr.bin/systat/main.c @@ -133,6 +133,7 @@ main(int argc, char **argv) exit(1); } } + signal(SIGHUP, die); signal(SIGINT, die); signal(SIGQUIT, die); signal(SIGTERM, die); From 5972f81bbe5367ea55d76ee64952293c8792b7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sun, 11 Oct 2009 14:27:33 +0000 Subject: [PATCH 123/646] Remove dupe. --- crypto/openssh/sshd_config | 1 - 1 file changed, 1 deletion(-) diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 78e51aba35b..fc2b6836492 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -17,7 +17,6 @@ #VersionAddendum FreeBSD-20091001 #Port 22 -#Protocol 2 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: From 0a747fb23c6ceb3311c0462ec5d221b98da590ad Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 11 Oct 2009 16:23:11 +0000 Subject: [PATCH 124/646] In nanosleep(2), note that the calling thread is put to sleep, not the whole process. Also explicitely name the parameter that specifies sleep interval. --- lib/libc/sys/nanosleep.2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/nanosleep.2 b/lib/libc/sys/nanosleep.2 index 18e4c88af49..f50544b83d6 100644 --- a/lib/libc/sys/nanosleep.2 +++ b/lib/libc/sys/nanosleep.2 @@ -47,7 +47,9 @@ The .Fn nanosleep system call -causes the process to sleep for the specified time. +causes the calling thread to sleep until the time interval specified by +.Fa rqtp +has elapsed. An unmasked signal will cause it to terminate the sleep early, regardless of the .Dv SA_RESTART From b70b3ebfdd82f5091477d2ad3e9656466ffa8900 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 Oct 2009 16:41:39 +0000 Subject: [PATCH 125/646] Correct a typo here and actually save DSISR instead of overwriting it. --- sys/powerpc/aim/trap_subr.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/aim/trap_subr.S b/sys/powerpc/aim/trap_subr.S index f946575a3f9..bcffb2930ff 100644 --- a/sys/powerpc/aim/trap_subr.S +++ b/sys/powerpc/aim/trap_subr.S @@ -451,7 +451,7 @@ disitrap: lwz %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) /* get DAR */ stw %r30,(PC_DBSAVE +CPUSAVE_AIM_DAR)(%r1) /* save DAR */ lwz %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) /* get DSISR */ - lwz %r30,(PC_DBSAVE +CPUSAVE_AIM_DSISR)(%r1) /* save DSISR */ + stw %r30,(PC_DBSAVE +CPUSAVE_AIM_DSISR)(%r1) /* save DSISR */ lwz %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */ stw %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */ lwz %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */ From a8211b27b9e66fce2ecaa46b9c3e4c9e5f1b6af1 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 Oct 2009 16:44:58 +0000 Subject: [PATCH 126/646] Correct another typo. Actually save the condition register instead of overwriting r12 by mistake. --- sys/powerpc/aim/swtch.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S index 619bf890762..71d39d0b77f 100644 --- a/sys/powerpc/aim/swtch.S +++ b/sys/powerpc/aim/swtch.S @@ -171,7 +171,7 @@ ENTRY(savectx) mr %r12,%r2 stmw %r12,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */ mfcr %r4 /* Save the condition register */ - stw %r4,PCB_CONTEXT(%r3) + stw %r4,PCB_CR(%r3) blr /* From 6b286ee8b5fe6b8fec7fb78f030b151a7767886c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 11 Oct 2009 16:49:30 +0000 Subject: [PATCH 127/646] Currently, when signal is delivered to the process and there is a thread not blocking the signal, signal is placed on the thread sigqueue. If the selected thread is in kernel executing thr_exit() or sigprocmask() syscalls, then signal might be not delivered to usermode for arbitrary amount of time, and for exiting thread it is lost. Put process-directed signals to the process queue unconditionally, selecting the thread to deliver the signal only by the thread returning to usermode, since only then the thread can handle delivery of signal reliably. For exiting thread or thread that has blocked some signals, check whether the newly blocked signal is queued for the process, and try to find a thread to wakeup for delivery, in reschedule_signal(). For exiting thread, assume that all signals are blocked. Change cursig() and postsig() to look both into the thread and process signal queues. When there is a signal that thread returning to usermode could consume, TDF_NEEDSIGCHK flag is not neccessary set now. Do unlocked read of p_siglist and p_pendingcnt to check for queued signals. Note that thread that has a signal unblocked might get spurious wakeup and EINTR from the interruptible system call now, due to the possibility of being selected by reschedule_signals(), while other thread returned to usermode earlier and removed the signal from process queue. This should not cause compliance issues, since the thread has not blocked a signal and thus should be ready to receive it anyway. Reported by: Justin Teller Reviewed by: davidxu, jilles MFC after: 1 month --- sys/kern/kern_sig.c | 131 +++++++++++++++++++++++++++++++++---------- sys/kern/kern_thr.c | 2 +- sys/kern/subr_trap.c | 11 +++- sys/sys/signalvar.h | 8 ++- 4 files changed, 118 insertions(+), 34 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 0386fc4e79d..d7523ae9370 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -220,6 +220,8 @@ static int sigproptbl[NSIG] = { SA_KILL|SA_PROC, /* SIGUSR2 */ }; +static void reschedule_signals(struct proc *p, sigset_t block); + static void sigqueue_start(void) { @@ -581,20 +583,11 @@ void signotify(struct thread *td) { struct proc *p; - sigset_t set; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); - /* - * If our mask changed we may have to move signal that were - * previously masked by all threads to our sigqueue. - */ - set = p->p_sigqueue.sq_signals; - SIGSETNAND(set, td->td_sigmask); - if (! SIGISEMPTY(set)) - sigqueue_move_set(&p->p_sigqueue, &td->td_sigqueue, &set); if (SIGPENDING(td)) { thread_lock(td); td->td_flags |= TDF_NEEDSIGCHK | TDF_ASTPENDING; @@ -976,24 +969,28 @@ execsigs(struct proc *p) * Manipulate signal mask. */ int -kern_sigprocmask(td, how, set, oset, old) - struct thread *td; - int how; - sigset_t *set, *oset; - int old; +kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset, + int old) { + sigset_t new_block, oset1; + struct proc *p; int error; - PROC_LOCK(td->td_proc); + p = td->td_proc; + PROC_LOCK(p); if (oset != NULL) *oset = td->td_sigmask; error = 0; + SIGEMPTYSET(new_block); if (set != NULL) { switch (how) { case SIG_BLOCK: SIG_CANTMASK(*set); + oset1 = td->td_sigmask; SIGSETOR(td->td_sigmask, *set); + new_block = td->td_sigmask; + SIGSETNAND(new_block, oset1); break; case SIG_UNBLOCK: SIGSETNAND(td->td_sigmask, *set); @@ -1001,10 +998,13 @@ kern_sigprocmask(td, how, set, oset, old) break; case SIG_SETMASK: SIG_CANTMASK(*set); + oset1 = td->td_sigmask; if (old) SIGSETLO(td->td_sigmask, *set); else td->td_sigmask = *set; + new_block = td->td_sigmask; + SIGSETNAND(new_block, oset1); signotify(td); break; default: @@ -1012,7 +1012,20 @@ kern_sigprocmask(td, how, set, oset, old) break; } } - PROC_UNLOCK(td->td_proc); + + /* + * The new_block set contains signals that were not previosly + * blocked, but are blocked now. + * + * In case we block any signal that was not previously blocked + * for td, and process has the signal pending, try to schedule + * signal delivery to some thread that does not block the signal, + * possibly waking it up. + */ + if (p->p_numthreads != 1) + reschedule_signals(p, new_block); + + PROC_UNLOCK(p); return (error); } @@ -1985,17 +1998,9 @@ tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) KNOTE_LOCKED(&p->p_klist, NOTE_SIGNAL | sig); prop = sigprop(sig); - /* - * If the signal is blocked and not destined for this thread, then - * assign it to the process so that we can find it later in the first - * thread that unblocks it. Otherwise, assign it to this thread now. - */ if (td == NULL) { td = sigtd(p, sig, prop); - if (SIGISMEMBER(td->td_sigmask, sig)) - sigqueue = &p->p_sigqueue; - else - sigqueue = &td->td_sigqueue; + sigqueue = &p->p_sigqueue; } else { KASSERT(td->td_proc == p, ("invalid thread")); sigqueue = &td->td_sigqueue; @@ -2392,6 +2397,62 @@ stopme: return (td->td_xsig); } +static void +reschedule_signals(struct proc *p, sigset_t block) +{ + struct sigacts *ps; + struct thread *td; + int i; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + ps = p->p_sigacts; + for (i = 1; !SIGISEMPTY(block); i++) { + if (!SIGISMEMBER(block, i)) + continue; + SIGDELSET(block, i); + if (!SIGISMEMBER(p->p_siglist, i)) + continue; + + td = sigtd(p, i, 0); + signotify(td); + mtx_lock(&ps->ps_mtx); + if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, i)) + tdsigwakeup(td, i, SIG_CATCH, + (SIGISMEMBER(ps->ps_sigintr, i) ? EINTR : + ERESTART)); + mtx_unlock(&ps->ps_mtx); + } +} + +void +tdsigcleanup(struct thread *td) +{ + struct proc *p; + sigset_t unblocked; + + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + + sigqueue_flush(&td->td_sigqueue); + if (p->p_numthreads == 1) + return; + + /* + * Since we cannot handle signals, notify signal post code + * about this by filling the sigmask. + * + * Also, if needed, wake up thread(s) that do not block the + * same signals as the exiting thread, since the thread might + * have been selected for delivery and woken up. + */ + SIGFILLSET(unblocked); + SIGSETNAND(unblocked, td->td_sigmask); + SIGFILLSET(td->td_sigmask); + reschedule_signals(p, unblocked); + +} + /* * If the current process has received a signal (should be caught or cause * termination, should interrupt current syscall), return the signal number. @@ -2409,8 +2470,9 @@ issignal(struct thread *td, int stop_allowed) { struct proc *p; struct sigacts *ps; + struct sigqueue *queue; sigset_t sigpending; - int sig, prop, newsig; + int sig, prop, newsig, signo; p = td->td_proc; ps = p->p_sigacts; @@ -2420,6 +2482,7 @@ issignal(struct thread *td, int stop_allowed) int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); sigpending = td->td_sigqueue.sq_signals; + SIGSETOR(sigpending, p->p_sigqueue.sq_signals); SIGSETNAND(sigpending, td->td_sigmask); if (p->p_flag & P_PPWAIT) @@ -2440,6 +2503,7 @@ issignal(struct thread *td, int stop_allowed) */ if (SIGISMEMBER(ps->ps_sigignore, sig) && (traced == 0)) { sigqueue_delete(&td->td_sigqueue, sig); + sigqueue_delete(&p->p_sigqueue, sig); continue; } if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) { @@ -2452,12 +2516,18 @@ issignal(struct thread *td, int stop_allowed) if (sig != newsig) { ksiginfo_t ksi; + + queue = &td->td_sigqueue; /* * clear old signal. * XXX shrug off debugger, it causes siginfo to * be thrown away. */ - sigqueue_get(&td->td_sigqueue, sig, &ksi); + if (sigqueue_get(queue, sig, &ksi) == 0) { + queue = &p->p_sigqueue; + signo = sigqueue_get(queue, sig, &ksi); + KASSERT(signo == sig, ("signo != sig")); + } /* * If parent wants us to take the signal, @@ -2472,7 +2542,7 @@ issignal(struct thread *td, int stop_allowed) * Put the new signal into td_sigqueue. If the * signal is being masked, look for other signals. */ - SIGADDSET(td->td_sigqueue.sq_signals, sig); + SIGADDSET(queue->sq_signals, sig); if (SIGISMEMBER(td->td_sigmask, sig)) continue; signotify(td); @@ -2567,6 +2637,7 @@ issignal(struct thread *td, int stop_allowed) return (sig); } sigqueue_delete(&td->td_sigqueue, sig); /* take the signal! */ + sigqueue_delete(&p->p_sigqueue, sig); } /* NOTREACHED */ } @@ -2613,7 +2684,9 @@ postsig(sig) ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); ksiginfo_init(&ksi); - sigqueue_get(&td->td_sigqueue, sig, &ksi); + if (sigqueue_get(&td->td_sigqueue, sig, &ksi) == 0 && + sigqueue_get(&p->p_sigqueue, sig, &ksi) == 0) + return; ksi.ksi_signo = sig; if (ksi.ksi_code == SI_TIMER) itimer_accept(p, ksi.ksi_timerid, &ksi); diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 630069b5940..3159a910b0b 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -282,7 +282,7 @@ thr_exit(struct thread *td, struct thr_exit_args *uap) } PROC_LOCK(p); - sigqueue_flush(&td->td_sigqueue); + tdsigcleanup(td); PROC_SLOCK(p); /* diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 6d60ddbe460..ccf64791e15 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -90,6 +90,7 @@ userret(struct thread *td, struct trapframe *frame) CTR3(KTR_SYSC, "userret: thread %p (pid %d, %s)", td, p->p_pid, td->td_name); +#if 0 #ifdef DIAGNOSTIC /* Check that we called signotify() enough. */ PROC_LOCK(p); @@ -100,6 +101,7 @@ userret(struct thread *td, struct trapframe *frame) thread_unlock(td); PROC_UNLOCK(p); #endif +#endif #ifdef KTRACE KTRUSERRET(td); #endif @@ -218,7 +220,14 @@ ast(struct trapframe *framep) ktrcsw(0, 1); #endif } - if (flags & TDF_NEEDSIGCHK) { + + /* + * Check for signals. Unlocked reads of p_pendingcnt or + * p_siglist might cause process-directed signal to be handled + * later. + */ + if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || + !SIGISEMPTY(p->p_siglist)) { PROC_LOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0) diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 89b40f02976..b39f2bfd4c4 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -252,9 +252,10 @@ typedef struct sigqueue { /* Return nonzero if process p has an unmasked pending signal. */ #define SIGPENDING(td) \ - (!SIGISEMPTY((td)->td_siglist) && \ - !sigsetmasked(&(td)->td_siglist, &(td)->td_sigmask)) - + ((!SIGISEMPTY((td)->td_siglist) && \ + !sigsetmasked(&(td)->td_siglist, &(td)->td_sigmask)) || \ + (!SIGISEMPTY((td)->td_proc->p_siglist) && \ + !sigsetmasked(&(td)->td_proc->p_siglist, &(td)->td_sigmask))) /* * Return the value of the pseudo-expression ((*set & ~*mask) != 0). This * is an optimized version of SIGISEMPTY() on a temporary variable @@ -336,6 +337,7 @@ void sigexit(struct thread *td, int signum) __dead2; int sig_ffs(sigset_t *set); void siginit(struct proc *p); void signotify(struct thread *td); +void tdsigcleanup(struct thread *td); int tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi); void trapsignal(struct thread *td, ksiginfo_t *); From eb9de28f2018d17997a4d83d3a303bb7e4c10f4c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 11 Oct 2009 17:04:13 +0000 Subject: [PATCH 128/646] Tweaks for sigqueue tests: - slightly adjust code for style, sort headers. - in sigqtest2, print received signals, to make it easy to see why test failed. - in sigqtest2, job_control_test(), cover a race by adding sleep after child stopped itself to allow for SIGCHLD due to stop and exit to not be coalesced. MFC after: 2 weeks --- .../regression/sigqueue/sigqtest1/sigqtest1.c | 11 +++++--- .../regression/sigqueue/sigqtest2/sigqtest2.c | 28 +++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/tools/regression/sigqueue/sigqtest1/sigqtest1.c b/tools/regression/sigqueue/sigqtest1/sigqtest1.c index 0f40021b4ab..f0201c37af8 100644 --- a/tools/regression/sigqueue/sigqtest1/sigqtest1.c +++ b/tools/regression/sigqueue/sigqtest1/sigqtest1.c @@ -1,12 +1,14 @@ /* $FreeBSD$ */ -#include -#include #include #include +#include +#include +#include int received; -void handler(int sig, siginfo_t *si, void *ctx) +void +handler(int sig, siginfo_t *si, void *ctx) { if (si->si_code != SI_QUEUE) errx(1, "si_code != SI_QUEUE"); @@ -15,7 +17,8 @@ void handler(int sig, siginfo_t *si, void *ctx) received++; } -int main() +int +main() { struct sigaction sa; union sigval val; diff --git a/tools/regression/sigqueue/sigqtest2/sigqtest2.c b/tools/regression/sigqueue/sigqtest2/sigqtest2.c index 078ea81f627..50b579d0a42 100644 --- a/tools/regression/sigqueue/sigqtest2/sigqtest2.c +++ b/tools/regression/sigqueue/sigqtest2/sigqtest2.c @@ -1,24 +1,29 @@ /* $FreeBSD$ */ -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include int stop_received; int exit_received; int cont_received; -void job_handler(int sig, siginfo_t *si, void *ctx) +void +job_handler(int sig, siginfo_t *si, void *ctx) { int status; int ret; if (si->si_code == CLD_STOPPED) { + printf("%d: stop received\n", si->si_pid); stop_received = 1; kill(si->si_pid, SIGCONT); } else if (si->si_code == CLD_EXITED) { + printf("%d: exit received\n", si->si_pid); ret = waitpid(si->si_pid, &status, 0); if (ret == -1) errx(1, "waitpid"); @@ -26,11 +31,13 @@ void job_handler(int sig, siginfo_t *si, void *ctx) errx(1, "!WIFEXITED(status)"); exit_received = 1; } else if (si->si_code == CLD_CONTINUED) { + printf("%d: cont received\n", si->si_pid); cont_received = 1; } } -void job_control_test() +void +job_control_test(void) { struct sigaction sa; pid_t pid; @@ -43,9 +50,12 @@ void job_control_test() stop_received = 0; cont_received = 0; exit_received = 0; + fflush(stdout); pid = fork(); if (pid == 0) { + printf("child %d\n", getpid()); kill(getpid(), SIGSTOP); + sleep(2); exit(1); } @@ -60,11 +70,13 @@ void job_control_test() printf("job control test OK.\n"); } -void rtsig_handler(int sig, siginfo_t *si, void *ctx) +void +rtsig_handler(int sig, siginfo_t *si, void *ctx) { } -int main() +int +main() { struct sigaction sa; sigset_t set; From 29670497af1b178fee5a8c7a36f20050bbb55c28 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 11 Oct 2009 20:19:45 +0000 Subject: [PATCH 129/646] Make openat(2) a cancellation point. This is required by POSIX and matches open(2). Reviewed by: kib, jhb MFC after: 1 month --- lib/libc/include/namespace.h | 1 + lib/libc/include/un-namespace.h | 1 + lib/libc/sys/Symbol.map | 2 ++ lib/libthr/pthread.map | 5 +++++ lib/libthr/thread/thr_private.h | 1 + lib/libthr/thread/thr_syscalls.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 38 insertions(+) diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h index a65b929bbc0..6ba8bab6155 100644 --- a/lib/libc/include/namespace.h +++ b/lib/libc/include/namespace.h @@ -80,6 +80,7 @@ #define listen _listen #define nanosleep _nanosleep #define open _open +#define openat _openat #define poll _poll #define pthread_atfork _pthread_atfork #define pthread_attr_destroy _pthread_attr_destroy diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h index 6b7f49a2764..00f0df27480 100644 --- a/lib/libc/include/un-namespace.h +++ b/lib/libc/include/un-namespace.h @@ -61,6 +61,7 @@ #undef listen #undef nanosleep #undef open +#undef openat #undef poll #undef pthread_atfork #undef pthread_attr_destroy diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 56d8aaaa464..c834a25e948 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -769,6 +769,8 @@ FBSDprivate_1.0 { __sys_olio_listio; _open; __sys_open; + _openat; + __sys_openat; _pathconf; __sys_pathconf; _pipe; diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index 79bbd4c11a8..62f3ff581d1 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -195,6 +195,7 @@ FBSDprivate_1.0 { __msync; __nanosleep; __open; + __openat; __poll; __pthread_cond_timedwait; __pthread_cond_wait; @@ -406,3 +407,7 @@ FBSD_1.1 { pthread_mutex_setspinloops_np; pthread_mutex_setyieldloops_np; }; + +FBSD_1.2 { + openat; +}; diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index e336b2cd664..57be0ae0894 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -668,6 +668,7 @@ void _pthread_cleanup_pop(int); #ifdef _SYS_FCNTL_H_ int __sys_fcntl(int, int, ...); int __sys_open(const char *, int, ...); +int __sys_openat(int, const char *, int, ...); #endif /* #include */ diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index 698c0c3f115..d05d68b2e3b 100644 --- a/lib/libthr/thread/thr_syscalls.c +++ b/lib/libthr/thread/thr_syscalls.c @@ -139,6 +139,7 @@ int __fsync(int); int __msync(void *, size_t, int); int __nanosleep(const struct timespec *, struct timespec *); int __open(const char *, int,...); +int __openat(int, const char *, int,...); int __poll(struct pollfd *, unsigned int, int); ssize_t __read(int, void *buf, size_t); ssize_t __readv(int, const struct iovec *, int); @@ -341,6 +342,33 @@ __open(const char *path, int flags,...) return ret; } +__weak_reference(__openat, openat); + +int +__openat(int fd, const char *path, int flags, ...) +{ + struct pthread *curthread = _get_curthread(); + int ret; + int mode = 0; + va_list ap; + + _thr_cancel_enter(curthread); + + /* Check if the file is being created: */ + if (flags & O_CREAT) { + /* Get the creation mode: */ + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } + + ret = __sys_openat(fd, path, flags, mode); + + _thr_cancel_leave(curthread); + + return ret; +} + __weak_reference(__poll, poll); int From bbaa712c0fcef3217e934837b8ceb2a4ee13d087 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 11 Oct 2009 20:42:26 +0000 Subject: [PATCH 130/646] Scan for option ROMs on i386 and amd64 only. --- sys/conf/files | 1 - sys/conf/files.amd64 | 1 + sys/conf/files.i386 | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/conf/files b/sys/conf/files index e0dff65ca94..52dc34a0880 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1919,7 +1919,6 @@ gnu/fs/reiserfs/reiserfs_vnops.c optional reiserfs isa/isa_if.m standard isa/isa_common.c optional isa isa/isahint.c optional isa -isa/orm.c optional isa isa/pnp.c optional isa isapnp isa/pnpparse.c optional isa isapnp fs/cd9660/cd9660_bmap.c optional cd9660 diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 30d6e5ac133..6fda086b772 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -228,6 +228,7 @@ dev/syscons/scvtb.c optional sc dev/uart/uart_cpu_amd64.c optional uart dev/wpi/if_wpi.c optional wpi isa/atrtc.c standard +isa/orm.c optional isa isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/link_elf_obj.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 7f6cadd4293..34d190a29e6 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -362,6 +362,7 @@ i386/svr4/svr4_locore.s optional compat_svr4 \ i386/svr4/svr4_machdep.c optional compat_svr4 # isa/atrtc.c optional atpic +isa/orm.c optional isa isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/imgact_aout.c optional compat_aout From 6b8c18292c7196ffb38f05e0b3fcbf54e3e49a52 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 12 Oct 2009 10:08:58 +0000 Subject: [PATCH 131/646] Another 3.03 draft bit that I missed in the previous 802.11s stack update. The Mesh Configuration IE has changed quite a bit. Refactor the code to handle this change. MFC after: 3 days --- sys/net80211/ieee80211_hwmp.c | 2 +- sys/net80211/ieee80211_mesh.c | 79 +++++++++++++---------------------- sys/net80211/ieee80211_mesh.h | 52 ++++++++--------------- 3 files changed, 48 insertions(+), 85 deletions(-) diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c index 2468169122a..df988505b7f 100644 --- a/sys/net80211/ieee80211_hwmp.c +++ b/sys/net80211/ieee80211_hwmp.c @@ -192,7 +192,7 @@ static ieee80211_recv_action_func hwmp_recv_action_meshpath; static struct ieee80211_mesh_proto_path mesh_proto_hwmp = { .mpp_descr = "HWMP", - .mpp_ie = IEEE80211_MESHCONF_HWMP, + .mpp_ie = IEEE80211_MESHCONF_PATH_HWMP, .mpp_discover = hwmp_discover, .mpp_peerdown = hwmp_peerdown, .mpp_vattach = hwmp_vattach, diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index b0bfe8892d0..6cb82584060 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -132,7 +132,7 @@ static ieee80211_send_action_func mesh_send_action_meshlink_reply; static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = { .mpm_descr = "AIRTIME", - .mpm_ie = IEEE80211_MESHCONF_AIRTIME, + .mpm_ie = IEEE80211_MESHCONF_METRIC_AIRTIME, .mpm_metric = mesh_airtime_calc, }; @@ -344,18 +344,18 @@ int ieee80211_mesh_register_proto_path(const struct ieee80211_mesh_proto_path *mpp) { int i, firstempty = -1; - static const uint8_t emptyie[4] = { 0, 0, 0, 0 }; for (i = 0; i < N(mesh_proto_paths); i++) { - if (memcmp(mpp->mpp_ie, mesh_proto_paths[i].mpp_ie, 4) == 0) + if (strncmp(mpp->mpp_descr, mesh_proto_paths[i].mpp_descr, + IEEE80211_MESH_PROTO_DSZ) == 0) return EEXIST; - if (memcmp(mesh_proto_paths[i].mpp_ie, emptyie, 4) == 0 && - firstempty == -1) + if (!mesh_proto_paths[i].mpp_active && firstempty == -1) firstempty = i; } if (firstempty < 0) return ENOSPC; memcpy(&mesh_proto_paths[firstempty], mpp, sizeof(*mpp)); + mesh_proto_paths[firstempty].mpp_active = 1; return 0; } @@ -364,18 +364,18 @@ ieee80211_mesh_register_proto_metric(const struct ieee80211_mesh_proto_metric *mpm) { int i, firstempty = -1; - static const uint8_t emptyie[4] = { 0, 0, 0, 0 }; for (i = 0; i < N(mesh_proto_metrics); i++) { - if (memcmp(mpm->mpm_ie, mesh_proto_metrics[i].mpm_ie, 4) == 0) + if (strncmp(mpm->mpm_descr, mesh_proto_metrics[i].mpm_descr, + IEEE80211_MESH_PROTO_DSZ) == 0) return EEXIST; - if (memcmp(mesh_proto_metrics[i].mpm_ie, emptyie, 4) == 0 && - firstempty == -1) + if (!mesh_proto_metrics[i].mpm_active && firstempty == -1) firstempty = i; } if (firstempty < 0) return ENOSPC; memcpy(&mesh_proto_metrics[firstempty], mpm, sizeof(*mpm)); + mesh_proto_metrics[firstempty].mpm_active = 1; return 0; } @@ -2282,51 +2282,40 @@ mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie) static int mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie) { - static const uint8_t null[4] = IEEE80211_MESHCONF_NULL; const struct ieee80211_meshconf_ie *meshconf = (const struct ieee80211_meshconf_ie *) ie; const struct ieee80211_mesh_state *ms = vap->iv_mesh; if (meshconf == NULL) return 1; - if (meshconf->conf_ver != IEEE80211_MESHCONF_VERSION) { + if (meshconf->conf_pselid != ms->ms_ppath->mpp_ie) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "wrong mesh conf version: %d\n", meshconf->conf_ver); + "unknown path selection algorithm: 0x%x\n", + meshconf->conf_pselid); return 1; } - if (memcmp(meshconf->conf_pselid, ms->ms_ppath->mpp_ie, 4) != 0) { + if (meshconf->conf_pmetid != ms->ms_pmetric->mpm_ie) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown path selection algorithm: 0x%x%x%x%x\n", - meshconf->conf_pselid[0], meshconf->conf_pselid[1], - meshconf->conf_pselid[2], meshconf->conf_pselid[3]); + "unknown path metric algorithm: 0x%x\n", + meshconf->conf_pmetid); return 1; } - if (memcmp(meshconf->conf_pmetid, ms->ms_pmetric->mpm_ie, 4) != 0) { + if (meshconf->conf_ccid != 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown path metric algorithm: 0x%x%x%x%x\n", - meshconf->conf_pmetid[0], meshconf->conf_pmetid[1], - meshconf->conf_pmetid[2], meshconf->conf_pmetid[3]); + "unknown congestion control algorithm: 0x%x\n", + meshconf->conf_ccid); return 1; } - if (memcmp(meshconf->conf_ccid, null, 4) != 0) { + if (meshconf->conf_syncid != IEEE80211_MESHCONF_SYNC_NEIGHOFF) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown congestion sig algorithm: 0x%x%x%x%x\n", - meshconf->conf_ccid[0], meshconf->conf_ccid[1], - meshconf->conf_ccid[2], meshconf->conf_ccid[3]); + "unknown sync algorithm: 0x%x\n", + meshconf->conf_syncid); return 1; } - if (memcmp(meshconf->conf_syncid, null, 4) != 0) { + if (meshconf->conf_authid != 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown sync algorithm: 0x%x%x%x%x\n", - meshconf->conf_syncid[0], meshconf->conf_syncid[1], - meshconf->conf_syncid[2], meshconf->conf_syncid[3]); - return 1; - } - if (memcmp(meshconf->conf_authid, null, 4) != 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown auth auth algorithm: 0x%x%x%x%x\n", - meshconf->conf_pselid[0], meshconf->conf_pselid[1], - meshconf->conf_pselid[2], meshconf->conf_pselid[3]); + "unknown auth auth algorithm: 0x%x\n", + meshconf->conf_pselid); return 1; } /* Not accepting peers */ @@ -2394,24 +2383,16 @@ uint8_t * ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap) { const struct ieee80211_mesh_state *ms = vap->iv_mesh; - static const uint8_t null[4] = IEEE80211_MESHCONF_NULL; KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); *frm++ = IEEE80211_ELEMID_MESHCONF; *frm++ = sizeof(struct ieee80211_meshconf_ie) - 2; - *frm++ = IEEE80211_MESHCONF_VERSION; - memcpy(frm, ms->ms_ppath->mpp_ie, 4); /* path selection */ - frm += 4; - memcpy(frm, ms->ms_pmetric->mpm_ie, 4); /* link metric */ - frm += 4; - /* XXX null for now */ - memcpy(frm, null, 4); /* congestion control */ - frm += 4; - memcpy(frm, null, 4); /* sync */ - frm += 4; - memcpy(frm, null, 4); /* auth */ - frm += 4; + *frm++ = ms->ms_ppath->mpp_ie; /* path selection */ + *frm++ = ms->ms_pmetric->mpm_ie; /* link metric */ + *frm++ = IEEE80211_MESHCONF_CC_DISABLED; + *frm++ = IEEE80211_MESHCONF_SYNC_NEIGHOFF; + *frm++ = IEEE80211_MESHCONF_AUTH_DISABLED; /* NB: set the number of neighbors before the rest */ *frm = (ms->ms_neighbors > 15 ? 15 : ms->ms_neighbors) << 1; if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) @@ -2440,7 +2421,7 @@ ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, *frm++ = IEEE80211_ELEMID_MESHPEER; switch (subtype) { case IEEE80211_MESH_PEER_LINK_OPEN: - *frm++ = 6; /* length */ + frm++ = 6; /* length */ memcpy(frm, meshpeerproto, 4); frm += 4; ADDSHORT(frm, localid); /* local ID */ diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h index e3ce79a4945..72108ddcdab 100644 --- a/sys/net80211/ieee80211_mesh.h +++ b/sys/net80211/ieee80211_mesh.h @@ -43,47 +43,27 @@ struct ieee80211_meshconf_ie { uint8_t conf_ie; /* IEEE80211_ELEMID_MESHCONF */ uint8_t conf_len; - uint8_t conf_ver; - uint8_t conf_pselid[4]; /* Active Path Sel. Proto. ID */ - uint8_t conf_pmetid[4]; /* APS Metric Identifier */ - uint8_t conf_ccid[4]; /* Congestion Control Mode ID */ - uint8_t conf_syncid[4]; /* Sync. Protocol ID */ - uint8_t conf_authid[4]; /* Auth. Protocol ID */ + uint8_t conf_pselid; /* Active Path Sel. Proto. ID */ + uint8_t conf_pmetid; /* Active Metric Identifier */ + uint8_t conf_ccid; /* Congestion Control Mode ID */ + uint8_t conf_syncid; /* Sync. Protocol ID */ + uint8_t conf_authid; /* Auth. Protocol ID */ uint8_t conf_form; /* Formation Information */ uint8_t conf_cap; } __packed; -#define IEEE80211_MESHCONF_VERSION 1 -/* Null Protocol */ -#define IEEE80211_MESHCONF_NULL_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_NULL_VALUE 0xff -#define IEEE80211_MESHCONF_NULL { IEEE80211_MESHCONF_NULL_OUI, \ - IEEE80211_MESHCONF_NULL_VALUE } /* Hybrid Wireless Mesh Protocol */ -#define IEEE80211_MESHCONF_HWMP_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_HWMP_VALUE 0x00 -#define IEEE80211_MESHCONF_HWMP { IEEE80211_MESHCONF_HWMP_OUI, \ - IEEE80211_MESHCONF_HWMP_VALUE } +#define IEEE80211_MESHCONF_PATH_HWMP 0x00 /* Airtime Link Metric */ -#define IEEE80211_MESHCONF_AIRTIME_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_AIRTIME_VALUE 0x00 -#define IEEE80211_MESHCONF_AIRTIME { IEEE80211_MESHCONF_AIRTIME_OUI, \ - IEEE80211_MESHCONF_AIRTIME_VALUE } -/* Congestion Control Signaling */ -#define IEEE80211_MESHCONF_CCSIG_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_CCSIG_VALUE 0x00 -#define IEEE80211_MESHCONF_CCSIG { IEEE80211_MESHCONF_CCSIG_OUI,\ - IEEE80211_MESHCONF_CCSIG_VALUE } +#define IEEE80211_MESHCONF_METRIC_AIRTIME 0x00 +/* Congestion Control */ +#define IEEE80211_MESHCONF_CC_DISABLED 0x00 +#define IEEE80211_MESHCONF_CC_SIG 0x01 /* Neighbour Offset */ -#define IEEE80211_MESHCONF_NEIGHOFF_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_NEIGHOFF_VALUE 0x00 -#define IEEE80211_MESHCONF_NEIGHOFF { IEEE80211_MESHCONF_NEIGHOFF_OUI, \ - IEEE80211_MESHCONF_NEIGHOFF_VALUE } +#define IEEE80211_MESHCONF_SYNC_NEIGHOFF 0x00 +#define IEEE80211_MESHCONF_AUTH_DISABLED 0x00 /* Simultaneous Authenticaction of Equals */ -#define IEEE80211_MESHCONF_SAE_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESHCONF_SAE_VALUE 0x01 -#define IEEE80211_MESHCONF_SAE { IEEE80211_MESHCONF_SAE_OUI, \ - IEEE80211_MESHCONF_SAE_VALUE } +#define IEEE80211_MESHCONF_AUTH_SAE 0x01 #define IEEE80211_MESHCONF_FORM_MP 0x01 /* Connected to Portal */ #define IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x04 /* Number of Neighbours */ #define IEEE80211_MESHCONF_CAP_AP 0x01 /* Accepting Peers */ @@ -390,8 +370,9 @@ struct ieee80211_mesh_route { */ enum ieee80211_state; struct ieee80211_mesh_proto_path { + uint8_t mpp_active; char mpp_descr[IEEE80211_MESH_PROTO_DSZ]; - uint8_t mpp_ie[4]; + uint8_t mpp_ie; struct ieee80211_node * (*mpp_discover)(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], @@ -411,8 +392,9 @@ struct ieee80211_mesh_proto_path { * Mesh Link Metric Report Protocol. */ struct ieee80211_mesh_proto_metric { + uint8_t mpm_active; char mpm_descr[IEEE80211_MESH_PROTO_DSZ]; - uint8_t mpm_ie[4]; + uint8_t mpm_ie; uint32_t (*mpm_metric)(struct ieee80211_node *); }; From 7df8f6ab6fd6479b62859fa7b01ab49408d57900 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 12 Oct 2009 10:09:48 +0000 Subject: [PATCH 132/646] Fix typo. Submitted by: rdivacky MFC after: 1 month --- sys/kern/kern_sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index d7523ae9370..c826f5beae4 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1014,7 +1014,7 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset, } /* - * The new_block set contains signals that were not previosly + * The new_block set contains signals that were not previously * blocked, but are blocked now. * * In case we block any signal that was not previously blocked From f78595fa101aeb426268a7720e4e457c50b1a06e Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 12 Oct 2009 10:30:15 +0000 Subject: [PATCH 133/646] Fix a wrong initialization that snuck in the latest commit. MFC after: 3 days --- sys/net80211/ieee80211_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index 6cb82584060..a1b594b9286 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -2421,7 +2421,7 @@ ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, *frm++ = IEEE80211_ELEMID_MESHPEER; switch (subtype) { case IEEE80211_MESH_PEER_LINK_OPEN: - frm++ = 6; /* length */ + *frm++ = 6; /* length */ memcpy(frm, meshpeerproto, 4); frm += 4; ADDSHORT(frm, localid); /* local ID */ From 57c81ff830bcdba89b7acfa3c2cf584ba6257c0c Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 12 Oct 2009 14:51:19 +0000 Subject: [PATCH 134/646] Update for latest 802.11s changes in meshconf format. MFC after: 3 days --- sbin/ifconfig/ifieee80211.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index 10fb83d8399..ccb650c6e99 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -2624,25 +2624,31 @@ do { \ if (verbose) { const struct ieee80211_meshconf_ie *mconf = (const struct ieee80211_meshconf_ie *)ie; - const uint8_t null[4] = IEEE80211_MESHCONF_NULL; - const uint8_t hwmp[4] = IEEE80211_MESHCONF_HWMP; - const uint8_t airtime[4] = IEEE80211_MESHCONF_AIRTIME; - const uint8_t ccsig[4] = IEEE80211_MESHCONF_CCSIG; - const uint8_t sae[4] = IEEE80211_MESHCONF_SAE; - const uint8_t neighoff[4] = IEEE80211_MESHCONF_SAE; - printf("conf_ver); - MATCHOUI(mconf->conf_pselid, hwmp, "HWMP"); + printf("conf_pselid == IEEE80211_MESHCONF_PATH_HWMP) + printf("HWMP"); + else + printf("UNKNOWN"); printf(" LINK:"); - MATCHOUI(mconf->conf_pmetid, airtime, "AIRTIME"); + if (mconf->conf_pmetid == IEEE80211_MESHCONF_METRIC_AIRTIME) + printf("AIRTIME"); + else + printf("UNKNOWN"); printf(" CONGESTION:"); - MATCHOUI(mconf->conf_ccid, ccsig, "SIG"); - MATCHOUI(mconf->conf_ccid, null, "NULL"); + if (mconf->conf_ccid == IEEE80211_MESHCONF_CC_DISABLED) + printf("DISABLED"); + else + printf("UNKNOWN"); printf(" SYNC:"); - MATCHOUI(mconf->conf_syncid, neighoff, "NEIGHOFF"); - MATCHOUI(mconf->conf_syncid, null, "NULL"); + if (mconf->conf_syncid == IEEE80211_MESHCONF_SYNC_NEIGHOFF) + printf("NEIGHOFF"); + else + printf("UNKNOWN"); printf(" AUTH:"); - MATCHOUI(mconf->conf_authid, sae, "SAE"); - MATCHOUI(mconf->conf_authid, null, "NULL"); + if (mconf->conf_authid == IEEE80211_MESHCONF_AUTH_DISABLED) + printf("DISABLED"); + else + printf("UNKNOWN"); printf(" FORM:0x%x CAPS:0x%x>", mconf->conf_form, mconf->conf_cap); } From 8b5adf9dd998ddc5591cdd0ae94d9a39a09a5b3f Mon Sep 17 00:00:00 2001 From: Joseph Koshy Date: Mon, 12 Oct 2009 15:49:48 +0000 Subject: [PATCH 135/646] Improve the description of sysctl "kern.sugid_coredump". Submitted by: Mel Flynn on -hackers --- sys/kern/kern_sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index c826f5beae4..bc09686bcf1 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -162,7 +162,7 @@ SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL); int sugid_coredump; SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, - &sugid_coredump, 0, "Enable coredumping set user/group ID processes"); + &sugid_coredump, 0, "Allow setuid and setgid processes to dump core"); static int do_coredump = 1; SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW, From e62aa473c57d9d250ab643220ef471fb0f674e08 Mon Sep 17 00:00:00 2001 From: Alexander Nedotsukov Date: Mon, 12 Oct 2009 17:10:51 +0000 Subject: [PATCH 136/646] Link GSS mechanics modules against libgssapi so they will not fail due unresolved symbol errors when in turn libgssapi was loaded with RTLD_LOCAL flag set (which is the default). Reviewed by: dfr, jhb MFC after: 3 days --- kerberos5/lib/libgssapi_krb5/Makefile | 4 ++-- kerberos5/lib/libgssapi_spnego/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kerberos5/lib/libgssapi_krb5/Makefile b/kerberos5/lib/libgssapi_krb5/Makefile index b2cbe51f4e2..6c2f4217b3c 100644 --- a/kerberos5/lib/libgssapi_krb5/Makefile +++ b/kerberos5/lib/libgssapi_krb5/Makefile @@ -2,8 +2,8 @@ LIB= gssapi_krb5 LDFLAGS= -Wl,-Bsymbolic -LDADD= -lkrb5 -lhx509 -lcrypto -lroken -lasn1 -lcom_err -lcrypt -DPADD= ${LIBKRB5} ${LIBHX509} ${LIBCRYPTO} ${LIBROKEN} ${LIBASN1} \ +LDADD= -lgssapi -lkrb5 -lhx509 -lcrypto -lroken -lasn1 -lcom_err -lcrypt +DPADD= ${LIBGSSAPI} ${LIBKRB5} ${LIBHX509} ${LIBCRYPTO} ${LIBROKEN} ${LIBASN1} \ ${LIBCOM_ERR} ${LIBCRYPT} INCS= ${KRB5DIR}/lib/gssapi/gssapi/gssapi_krb5.h diff --git a/kerberos5/lib/libgssapi_spnego/Makefile b/kerberos5/lib/libgssapi_spnego/Makefile index af98880a638..32348ecf1ba 100644 --- a/kerberos5/lib/libgssapi_spnego/Makefile +++ b/kerberos5/lib/libgssapi_spnego/Makefile @@ -2,8 +2,8 @@ LIB= gssapi_spnego LDFLAGS= -Wl,-Bsymbolic -LDADD= -lasn1 -DPADD= ${LIBASN1} +LDADD= -lgssapi -lasn1 +DPADD= ${LIBGSSAPI} ${LIBASN1} SRCS= accept_sec_context.c \ compat.c \ From 27f13d5d0f266df07edbe9253bf087460e82e1bc Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 12 Oct 2009 18:54:02 +0000 Subject: [PATCH 137/646] - Do not assign a link-local address when ND6_IFF_IFDISABLED. Adding a tentative address is useless. - Comment out a confused warning message when in6_ifattach_linklocal() fails. This can occur when the interface does not support ioctl(SIOCAIFADDR) (interfaces associated with 802.11 wireless network device drivers, for example). --- sys/netinet6/in6_ifattach.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index c77b93f8e03..5041ee2f233 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -751,16 +751,19 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) * assign a link-local address, if there's none. */ if (ifp->if_type != IFT_BRIDGE && + !(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) { int error; ia = in6ifa_ifpforlinklocal(ifp, 0); if (ia == NULL) { error = in6_ifattach_linklocal(ifp, altifp); +#if 0 if (error) log(LOG_NOTICE, "in6_ifattach_linklocal: " "failed to add a link-local addr to %s\n", if_name(ifp)); +#endif } else ifa_free(&ia->ia_ifa); } From 4347e9fd666b30e124df66d4eb1adcc723c44261 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 12 Oct 2009 18:58:42 +0000 Subject: [PATCH 138/646] Add a MODULE_DEPEND() on the NFS client from dtnfsclient so that dtnfsclient can access NFS client symbols. MFC after: 3 days Discussed with: kib Reported by: markm --- sys/nfsclient/nfs_kdtrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/nfsclient/nfs_kdtrace.c b/sys/nfsclient/nfs_kdtrace.c index cc6ba456c02..fc7e4469b96 100644 --- a/sys/nfsclient/nfs_kdtrace.c +++ b/sys/nfsclient/nfs_kdtrace.c @@ -543,3 +543,4 @@ DEV_MODULE(dtnfsclient, dtnfsclient_modevent, NULL); MODULE_VERSION(dtnfsclient, 1); MODULE_DEPEND(dtnfsclient, dtrace, 1, 1, 1); MODULE_DEPEND(dtnfsclient, opensolaris, 1, 1, 1); +MODULE_DEPEND(dtnfsclient, nfs, 1, 1, 1); From 99b5e2f1d2bfd9e1504197f67664b802eac5b503 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 12 Oct 2009 18:59:31 +0000 Subject: [PATCH 139/646] Export DTrace symbols from nfsclient so that dtnfsclient can get to them. This fixes DTrace with nfsclient built as a module. MFC after: 3 days Reported by: markm --- sys/modules/nfsclient/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile index c53e3d5f98a..d41dadc3fea 100644 --- a/sys/modules/nfsclient/Makefile +++ b/sys/modules/nfsclient/Makefile @@ -41,4 +41,14 @@ NFS_ROOT= 1 SRCS+= nfs_diskless.c .endif +EXPORT_SYMS= \ + dtrace_nfsclient_accesscache_flush_done_probe \ + dtrace_nfsclient_accesscache_get_hit_probe \ + dtrace_nfsclient_accesscache_get_miss_probe \ + dtrace_nfsclient_accesscache_load_done_probe \ + nfsclient_accesscache_flush_done_id \ + nfsclient_accesscache_get_hit_id \ + nfsclient_accesscache_get_miss_id \ + nfsclient_accesscache_load_done_id + .include From aea0c7f3670081e205ac3784315c23f40b0b9bf4 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 12 Oct 2009 19:19:08 +0000 Subject: [PATCH 140/646] Fix the 106/109 USB Japanese keyboard "underscore" issue. Sun Type 6 USB keyboard support added in rev 1.46 conflicted with some scan codes used in Japanese keyboards because the scan code conversion routine was ambiguous for the overlapped codes. PR: ports/134005 Submitted by: YAMASHIRO Jun --- sys/dev/usb/input/ukbd.c | 63 ++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 5816079b3f6..1687755e33e 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -247,8 +247,8 @@ static const uint8_t ukbd_trtab[256] = { NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */ NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */ 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */ - 121, 120, NN, NN, NN, NN, NN, 115, /* 80 - 87 */ - 112, 125, 121, 123, NN, NN, NN, NN, /* 88 - 8F */ + 121, 120, NN, NN, NN, NN, NN, 123, /* 80 - 87 */ + 124, 125, 126, 127, 128, NN, NN, NN, /* 88 - 8F */ NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */ NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */ NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */ @@ -1636,20 +1636,59 @@ static int ukbd_key2scan(struct ukbd_softc *sc, int code, int shift, int up) { static const int scan[] = { - 0x1c, 0x1d, 0x35, - 0x37 | SCAN_PREFIX_SHIFT, /* PrintScreen */ - 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f, - 0x50, 0x51, 0x52, 0x53, - 0x46, /* XXX Pause/Break */ - 0x5b, 0x5c, 0x5d, + /* 89 */ + 0x11c, /* Enter */ + /* 90-99 */ + 0x11d, /* Ctrl-R */ + 0x135, /* Divide */ + 0x137 | SCAN_PREFIX_SHIFT, /* PrintScreen */ + 0x138, /* Alt-R */ + 0x147, /* Home */ + 0x148, /* Up */ + 0x149, /* PageUp */ + 0x14b, /* Left */ + 0x14d, /* Right */ + 0x14f, /* End */ + /* 100-109 */ + 0x150, /* Down */ + 0x151, /* PageDown */ + 0x152, /* Insert */ + 0x153, /* Delete */ + 0x146, /* XXX Pause/Break */ + 0x15b, /* Win_L(Super_L) */ + 0x15c, /* Win_R(Super_R) */ + 0x15d, /* Application(Menu) */ + /* SUN TYPE 6 USB KEYBOARD */ - 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e, - 0x20, + 0x168, /* Sun Type 6 Help */ + 0x15e, /* Sun Type 6 Stop */ + /* 110 - 119 */ + 0x15f, /* Sun Type 6 Again */ + 0x160, /* Sun Type 6 Props */ + 0x161, /* Sun Type 6 Undo */ + 0x162, /* Sun Type 6 Front */ + 0x163, /* Sun Type 6 Copy */ + 0x164, /* Sun Type 6 Open */ + 0x165, /* Sun Type 6 Paste */ + 0x166, /* Sun Type 6 Find */ + 0x167, /* Sun Type 6 Cut */ + 0x125, /* Sun Type 6 Mute */ + /* 120 - 128 */ + 0x11f, /* Sun Type 6 VolumeDown */ + 0x11e, /* Sun Type 6 VolumeUp */ + 0x120, /* Sun Type 6 PowerDown */ + + /* Japanese 106/109 keyboard */ + 0x73, /* Keyboard Intl' 1 (backslash / underscore) */ + 0x70, /* Keyboard Intl' 2 (Katakana / Hiragana) */ + 0x7d, /* Keyboard Intl' 3 (Yen sign) (Not using in jp106/109) */ + 0x79, /* Keyboard Intl' 4 (Henkan) */ + 0x7b, /* Keyboard Intl' 5 (Muhenkan) */ + 0x5c, /* Keyboard Intl' 6 (Keypad ,) (For PC-9821 layout) */ }; if ((code >= 89) && (code < (89 + (sizeof(scan) / sizeof(scan[0]))))) { - code = scan[code - 89] | SCAN_PREFIX_E0; + code = scan[code - 89]; } /* Pause/Break */ if ((code == 104) && (!(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))) { From 68f7de574ed3e43ee50f19d3a9e8bc69635cd3ee Mon Sep 17 00:00:00 2001 From: Mark Murray Date: Mon, 12 Oct 2009 21:10:28 +0000 Subject: [PATCH 141/646] We haven't installed usbdevs for many moons now, and it doesn't work any more anyway. Add it to the "obsolete" list. --- ObsoleteFiles.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 5cfd75e1fce..ef00999486d 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -503,6 +503,8 @@ OLD_FILES+=usr/include/dev/usb/usb_quirks.h OLD_FILES+=usr/include/dev/usb/usbcdc.h OLD_FILES+=usr/include/dev/usb/usbdivar.h OLD_FILES+=usr/include/dev/usb/uxb360gp_rdesc.h +OLD_FILES+=usr/sbin/usbdevs +OLD_FILES+=usr/share/man/man8/usbdevs.8.gz # 20090203: removal of pccard header files OLD_FILES+=usr/include/pccard/cardinfo.h OLD_FILES+=usr/include/pccard/cis.h From 7590eb54ce4fc6759ba1ce7d890cf59f885658bd Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 12 Oct 2009 21:11:50 +0000 Subject: [PATCH 142/646] Use printb() to display the "nd6 options=" line. --- sbin/ifconfig/af_nd6.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c index 4fde0c4a0fd..e6b920af7bd 100644 --- a/sbin/ifconfig/af_nd6.c +++ b/sbin/ifconfig/af_nd6.c @@ -56,17 +56,9 @@ static const char rcsid[] = #include "ifconfig.h" #define MAX_SYSCTL_TRY 5 - -static struct nd6_opt_list { - const char *label; - u_int mask; -} nd6_opts[] = { - { "IFDISABLED", ND6_IFF_IFDISABLED, }, - { "PERFORMNUD", ND6_IFF_PERFORMNUD, }, - { "ACCEPT_RTADV", ND6_IFF_ACCEPT_RTADV, }, - { "PREFER_SOURCE", ND6_IFF_PREFER_SOURCE, }, - { "AUTO_LINKLOCAL", ND6_IFF_AUTO_LINKLOCAL, }, -}; +#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ + "\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \ + "\020DEFAULTIF" static int isnd6defif(int); void setnd6flags(const char *, int, int, const struct afswtch *); @@ -153,9 +145,8 @@ nd6_status(int s) char *buf, *next; int mib[6], ntry; int s6; - int i, error; + int error; int isinet6, isdefif; - int nopts; /* Check if the interface has at least one IPv6 address. */ mib[0] = CTL_NET; @@ -220,22 +211,9 @@ nd6_status(int s) close(s6); if (nd.ndi.flags == 0 && !isdefif) return; - - nopts = 0; - printf("\tnd6 options=%d<", nd.ndi.flags); - for (i=0; i < sizeof(nd6_opts)/sizeof(nd6_opts[0]); i++) { - if (nd.ndi.flags & nd6_opts[i].mask) { - if (nopts++) - printf(","); - printf("%s", nd6_opts[i].label); - } - } - if (isdefif) { - if (nopts) - printf(","); - printf("DEFAULTIF"); - } - printf(">\n"); + printb("\tnd6 options", + (unsigned int)(nd.ndi.flags | (isdefif << 15)), ND6BITS); + putchar('\n'); } static struct afswtch af_nd6 = { From b6d632e4e841420ed82872edac3e3e8b03e60cd1 Mon Sep 17 00:00:00 2001 From: Alexander Nedotsukov Date: Tue, 13 Oct 2009 05:38:08 +0000 Subject: [PATCH 143/646] Chase dependency changes in libgssapi_krb5 module introruced by revision r197995. --- Makefile.inc1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 49537bb3818..8c40eefd5ed 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1122,7 +1122,7 @@ lib/libradius__L secure/lib/libssl__L: secure/lib/libcrypto__L _secure_lib_libssh= secure/lib/libssh secure/lib/libssh__L: lib/libz__L secure/lib/libcrypto__L lib/libcrypt__L .if ${MK_KERBEROS} != "no" -kerberos5/lib/libgssapi_krb5__L: kerberos5/lib/libkrb5__L \ +kerberos5/lib/libgssapi_krb5__L: lib/libgssapi__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libhx509__L kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libmd__L kerberos5/lib/libroken__L secure/lib/libcrypto__L \ lib/libcrypt__L From 2e76e4c9b5ec3a27b6d8282f101b81c449c4a6b1 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 13 Oct 2009 06:25:53 +0000 Subject: [PATCH 144/646] Make number(6) build with WARNS=6. --- games/number/Makefile | 2 ++ games/number/number.c | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/games/number/Makefile b/games/number/Makefile index 8e75f71a785..08e9be8e730 100644 --- a/games/number/Makefile +++ b/games/number/Makefile @@ -4,4 +4,6 @@ PROG= number MAN= number.6 +WARNS?= 6 + .include diff --git a/games/number/number.c b/games/number/number.c index 243fc8ddc86..d195a4f1e78 100644 --- a/games/number/number.c +++ b/games/number/number.c @@ -88,9 +88,7 @@ void usage(void); int lflag; int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int ch, first; char line[256]; @@ -275,7 +273,7 @@ void pfract(len) int len; { - static char *pref[] = { "", "ten-", "hundred-" }; + static char const * const pref[] = { "", "ten-", "hundred-" }; switch(len) { case 1: From 03ce247827c59ed64331407c8f4d638d3e8facea Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 13 Oct 2009 09:21:20 +0000 Subject: [PATCH 145/646] EXPORT_SYMS is not, in fact, required, for a dependent module to access non-static symbols in a module they depend on, so remove dtrace symbols from nfsclient's EXPORT_SYMS again. Suggested by: jhb --- sys/modules/nfsclient/Makefile | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile index d41dadc3fea..c53e3d5f98a 100644 --- a/sys/modules/nfsclient/Makefile +++ b/sys/modules/nfsclient/Makefile @@ -41,14 +41,4 @@ NFS_ROOT= 1 SRCS+= nfs_diskless.c .endif -EXPORT_SYMS= \ - dtrace_nfsclient_accesscache_flush_done_probe \ - dtrace_nfsclient_accesscache_get_hit_probe \ - dtrace_nfsclient_accesscache_get_miss_probe \ - dtrace_nfsclient_accesscache_load_done_probe \ - nfsclient_accesscache_flush_done_id \ - nfsclient_accesscache_get_hit_id \ - nfsclient_accesscache_get_miss_id \ - nfsclient_accesscache_load_done_id - .include From fe1b9e2ada099961279042e5c3f3741c82d0c800 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Tue, 13 Oct 2009 10:43:17 +0000 Subject: [PATCH 146/646] Properly initialize the mesh conf capabilities byte. MFC after: 2 days --- sys/net80211/ieee80211_mesh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index a1b594b9286..52a9e244f55 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -2398,6 +2398,7 @@ ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap) if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) *frm |= IEEE80211_MESHCONF_FORM_MP; frm += 1; + *frm = 0; if (ms->ms_flags & IEEE80211_MESHFLAGS_AP) *frm |= IEEE80211_MESHCONF_CAP_AP; if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) From 9599da5de85ceb6a067810985b1e35255e6d8912 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 13 Oct 2009 12:23:28 +0000 Subject: [PATCH 147/646] Correct a copy/paste bug in a comment. lptclose() checks once a second to see if the ppc hardware has gone idle rather than four times a second. --- sys/dev/ppbus/lpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c index 77ebaea561f..56b43788401 100644 --- a/sys/dev/ppbus/lpt.c +++ b/sys/dev/ppbus/lpt.c @@ -624,7 +624,7 @@ lptclose(struct cdev *dev, int flags, int fmt, struct thread *td) while ((ppb_rstr(ppbus) & (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) != (LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt) - /* wait 1/4 second, give up if we get a signal */ + /* wait 1 second, give up if we get a signal */ if (ppb_sleep(ppbus, lptdev, LPPRI | PCATCH, "lpclose", hz) != EWOULDBLOCK) break; From 6ff4bdaef59c24d1766535543f74b5171a5ea90d Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 13 Oct 2009 12:56:23 +0000 Subject: [PATCH 148/646] Correct typo: thetime -> the time PR: docs/139447 Submitted by: Guido Falsi mad at madpilot dot net --- usr.sbin/ntp/doc/ntpd.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/ntp/doc/ntpd.8 b/usr.sbin/ntp/doc/ntpd.8 index 5194b758c6d..a55fe43de29 100644 --- a/usr.sbin/ntp/doc/ntpd.8 +++ b/usr.sbin/ntp/doc/ntpd.8 @@ -121,7 +121,7 @@ Normally, .Nm exits with a message to the system log if the offset exceeds the panic threshold, which is 1000 s by default. -This option allows thetime to be set to any value without restriction; +This option allows the time to be set to any value without restriction; however, this can happen only once. If the threshold is exceeded after that, .Nm From 8c8ee3d3b8c51a97a1c194939b983d4cb112d9d4 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 13 Oct 2009 17:57:06 +0000 Subject: [PATCH 149/646] Add C message catalogue entries for newer errnos: EBADMSG, EMULTIHOP, ENOLINK, EPROTO, ENOTCAPABLE. Submitted by: Alan R. S. Bueno MFC after: 3 days (most) --- lib/libc/nls/C.msg | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/libc/nls/C.msg b/lib/libc/nls/C.msg index aa2c4cc881a..b25e83f330a 100644 --- a/lib/libc/nls/C.msg +++ b/lib/libc/nls/C.msg @@ -181,6 +181,16 @@ $ ENOATTR 87 Attribute not found $ EDOOFUS 88 Programming error +$ EBADMSG +89 Bad message +$ EMULTIHOP +90 Multihop attempted +$ ENOLINK +91 Link has been severed +$ EPROTO +92 Protocol error +$ ENOTCAPABLE +93 Capabilities insufficient $ $ strsignal() support catalog $ From 5c1f214c377831225206f419a031fc4dcddaac6a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 13 Oct 2009 18:07:56 +0000 Subject: [PATCH 150/646] Fix this module so it at least builds. Note that it isn't hooked up to the build however, and ubser(4) is also not present in any kernel configs (including NOTES). --- sys/modules/ubser/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/modules/ubser/Makefile b/sys/modules/ubser/Makefile index 41a0bc3f01d..8807bed8b91 100644 --- a/sys/modules/ubser/Makefile +++ b/sys/modules/ubser/Makefile @@ -1,9 +1,9 @@ # $FreeBSD$ S= ${.CURDIR}/../.. -.PATH: $S/dev/usb +.PATH: $S/dev/usb/serial KMOD= ubser -SRCS= ubser.c ubser.h opt_usb.h device_if.h bus_if.h usbdevs.h +SRCS= ubser.c opt_usb.h device_if.h bus_if.h usbdevs.h .include From 55b6a401ef3ca04dec5323efce8833a015a36970 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 13 Oct 2009 19:02:03 +0000 Subject: [PATCH 151/646] Move the USB wireless drivers down into their own section next to the USB ethernet drivers. Submitted by: Glen Barber glen.j.barber @ gmail MFC after: 1 month --- sys/amd64/conf/GENERIC | 9 +++++---- sys/i386/conf/GENERIC | 9 +++++---- sys/pc98/conf/GENERIC | 9 +++++---- sys/sparc64/conf/GENERIC | 9 +++++---- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index f03df9b4e99..fe477e2184f 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -297,10 +297,6 @@ device ukbd # Keyboard device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da device ums # Mouse -device rum # Ralink Technology RT2501USB wireless NICs -device uath # Atheros AR5523 wireless NICs -device ural # Ralink Technology RT2500USB wireless NICs -device zyd # ZyDAS zb1211/zb1211b wireless NICs device urio # Diamond Rio 500 MP3 player # USB Serial devices device uark # Technologies ARK3116 based serial adapters @@ -319,6 +315,11 @@ device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet device udav # Davicom DM9601E USB +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs # FireWire support device firewire # FireWire bus code diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 8098bf47ee8..5dbfd6f4153 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -310,10 +310,6 @@ device ukbd # Keyboard device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da device ums # Mouse -device rum # Ralink Technology RT2501USB wireless NICs -device ural # Ralink Technology RT2500USB wireless NICs -device uath # Atheros AR5523 wireless NICs -device zyd # ZyDAS zb1211/zb1211b wireless NICs device urio # Diamond Rio 500 MP3 player # USB Serial devices device u3g # USB-based 3G modems (Option, Huawei, Sierra) @@ -333,6 +329,11 @@ device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet device udav # Davicom DM9601E USB +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs # FireWire support device firewire # FireWire bus code diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 64c58790fba..5212e775d54 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -264,10 +264,6 @@ device bpf # Berkeley packet filter #device ulpt # Printer #device umass # Disks/Mass storage - Requires scbus and da #device ums # Mouse -#device rum # Ralink Technology RT2501USB wireless NICs -#device uath # Atheros AR5523 wireless NICs -#device ural # Ralink Technology RT2500USB wireless NICs -#device zyd # ZyDAS zb1211/zb1211b wireless NICs #device urio # Diamond Rio 500 MP3 player # USB Serial devices #device uark # Technologies ARK3116 based serial adapters @@ -287,6 +283,11 @@ device bpf # Berkeley packet filter #device kue # Kawasaki LSI USB Ethernet #device rue # RealTek RTL8150 USB Ethernet #device udav # Davicom DM9601E USB +# USB Wireless +#device rum # Ralink Technology RT2501USB wireless NICs +#device uath # Atheros AR5523 wireless NICs +#device ural # Ralink Technology RT2500USB wireless NICs +#device zyd # ZyDAS zb1211/zb1211b wireless NICs # FireWire support #device firewire # FireWire bus code diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index ecf640cc439..33e7838a577 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -239,10 +239,6 @@ device ukbd # Keyboard device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da device ums # Mouse -device rum # Ralink Technology RT2501USB wireless NICs -device uath # Atheros AR5523 wireless NICs -device ural # Ralink Technology RT2500USB wireless NICs -device zyd # ZyDAS zb1211/zb1211b wireless NICs device urio # Diamond Rio 500 MP3 player # USB Serial devices device uark # Technologies ARK3116 based serial adapters @@ -261,6 +257,11 @@ device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet device udav # Davicom DM9601E USB +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs # FireWire support device firewire # FireWire bus code From b675ebba104cb67855c6a1dac6364efb91701d40 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 13 Oct 2009 19:04:01 +0000 Subject: [PATCH 152/646] Sync with other GENERIC kernel configs: - Move USB serial drivers earlier to match their placement in other kernel configs. - Add descriptions to various USB drivers. - Move the USB wireless drivers into a new section. - Add ulscom to the list of USB serial drivers. --- sys/arm/conf/HL200 | 28 ++++++++++++++++------------ sys/arm/conf/KB920X | 26 +++++++++++++++----------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200 index 61f74cf6287..8d0f4c100a4 100644 --- a/sys/arm/conf/HL200 +++ b/sys/arm/conf/HL200 @@ -100,9 +100,17 @@ device usb # USB Bus (required) device uhid # "Human Interface Devices" device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da -device ural # Ralink Technology RT2500USB wireless NICs -device rum # Ralink Technology RT2501USB wireless NICs device urio # Diamond Rio 500 MP3 player +# USB Serial devices +device uark # Technologies ARK3116 based serial adapters +device ubsa # Belkin F5U103 and compatible serial adapters +#device ubser # not yet converted. +device uftdi # For FTDI usb serial adapters +device uipaq # Some WinCE based devices +device uplcom # Prolific PL-2303 serial adapters +device uslcom # SI Labs CP2101/CP2102 serial adapters +device uvisor # Visor and Palm devices +device uvscom # USB serial support for DDI pocket's PHS # USB Ethernet, requires miibus device miibus device aue # ADMtek USB Ethernet @@ -111,16 +119,12 @@ device cdce # Generic USB over Ethernet device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet -device udav -# usb serial -device uark -device ubsa -#device ubser # not yet converted. -device uftdi -device uipaq -device uplcom -device uvisor -device uvscom +device udav # Davicom DM9601E USB +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs # SCSI peripherals device scbus # SCSI bus (required for SCSI) device da # Direct Access (disks) diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X index 31f00962244..a6d6ef255a0 100644 --- a/sys/arm/conf/KB920X +++ b/sys/arm/conf/KB920X @@ -101,9 +101,16 @@ device usb # USB Bus (required) device uhid # "Human Interface Devices" device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da -device ural # Ralink Technology RT2500USB wireless NICs -device rum # Ralink Technology RT2501USB wireless NICs device urio # Diamond Rio 500 MP3 player +# USB Serial devices +device uark # Technologies ARK3116 based serial adapters +device ubsa # Belkin F5U103 and compatible serial adapters +device uftdi # For FTDI usb serial adapters +device uipaq # Some WinCE based devices +device uplcom # Prolific PL-2303 serial adapters +device uslcom # SI Labs CP2101/CP2102 serial adapters +device uvisor # Visor and Palm devices +device uvscom # USB serial support for DDI pocket's PHS # USB Ethernet, requires miibus device miibus device aue # ADMtek USB Ethernet @@ -112,15 +119,12 @@ device cdce # Generic USB over Ethernet device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet -device udav -# usb serial -device uark -device ubsa -device uftdi -device uipaq -device uplcom -device uvisor -device uvscom +device udav # Davicom DM9601E USB +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs # SCSI peripherals device scbus # SCSI bus (required for SCSI) device da # Direct Access (disks) From 44b636910bf0d98e317f40176fb06e4e45ce8f77 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 13 Oct 2009 20:22:12 +0000 Subject: [PATCH 153/646] Immediately after clearing a pending callout that didn't make it due to the lock we hold, disable interrupts, and announce to the firmware that we are shutting down. Especially do this before disabling blocks. This makes some types of machines with asf enabled no longer hang upon boot, when we start configuring the interface. PR: i386/96382, kern/100410, kern/122252, kern/116328 Reported by: erwin Hardware provided by: TDC A/S Reviewed by: stas Tested by: stas --- sys/dev/bge/if_bge.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 1fabee01b73..865a0d68ea4 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -4270,6 +4270,16 @@ bge_stop(struct bge_softc *sc) callout_stop(&sc->bge_stat_ch); + /* Disable host interrupts. */ + BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); + + /* + * Tell firmware we're shutting down. + */ + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + /* * Disable all of the receiver blocks. */ @@ -4309,16 +4319,6 @@ bge_stop(struct bge_softc *sc) BGE_CLRBIT(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); } - /* Disable host interrupts. */ - BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); - - /* - * Tell firmware we're shutting down. - */ - - 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); From 852da713c3ceda8a5b086f22a5c6c2822fbe2f71 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 13 Oct 2009 20:29:14 +0000 Subject: [PATCH 154/646] Compare pointer to NULL rather than 0. MFC after: 1 month --- sys/netinet/ip_icmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index fcb9ca6ceaa..b13bc7ca827 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -367,7 +367,7 @@ icmp_input(struct mbuf *m, int off) goto freeit; } i = hlen + min(icmplen, ICMP_ADVLENMIN); - if (m->m_len < i && (m = m_pullup(m, i)) == 0) { + if (m->m_len < i && (m = m_pullup(m, i)) == NULL) { ICMPSTAT_INC(icps_tooshort); return; } From 680db4952ed4c54df72ebb8123132e6f26884525 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 13 Oct 2009 20:58:22 +0000 Subject: [PATCH 155/646] Make getcwd(3) faster, simpler and more compliant using *at syscalls. It is no longer necessary to construct long paths consisting of repeated "../" which may be slow to process and may exceed PATH_MAX. --- lib/libc/gen/getcwd.c | 63 +++++++++++++------------------------------ 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/lib/libc/gen/getcwd.c b/lib/libc/gen/getcwd.c index 0cd32085391..c886dde98fe 100644 --- a/lib/libc/gen/getcwd.c +++ b/lib/libc/gen/getcwd.c @@ -62,13 +62,14 @@ getcwd(pt, size) dev_t dev; ino_t ino; int first; - char *bpt, *bup; + char *bpt; struct stat s; dev_t root_dev; ino_t root_ino; - size_t ptsize, upsize; + size_t ptsize; int save_errno; - char *ept, *eup, *up, c; + char *ept, c; + int fd; /* * If no buffer specified by the user, allocate one as necessary. @@ -106,18 +107,6 @@ getcwd(pt, size) bpt = ept - 1; *bpt = '\0'; - /* - * Allocate 1024 bytes for the string of "../"'s. - * Should always be enough. If it's not, allocate - * as necessary. Special case the first stat, it's ".", not "..". - */ - if ((up = malloc(upsize = 1024)) == NULL) - goto err; - eup = up + upsize; - bup = up; - up[0] = '.'; - up[1] = '\0'; - /* Save root values, so know when to stop. */ if (stat("/", &s)) goto err; @@ -128,7 +117,7 @@ getcwd(pt, size) for (first = 1;; first = 0) { /* Stat the current level. */ - if (lstat(up, &s)) + if (dir != NULL ? _fstat(dirfd(dir), &s) : lstat(".", &s)) goto err; /* Save current node values. */ @@ -144,32 +133,22 @@ getcwd(pt, size) * been that way and stuff would probably break. */ bcopy(bpt, pt, ept - bpt); - free(up); + if (dir) + (void) closedir(dir); return (pt); } - /* - * Build pointer to the parent directory, allocating memory - * as necessary. Max length is 3 for "../", the largest - * possible component name, plus a trailing NUL. - */ - while (bup + 3 + MAXNAMLEN + 1 >= eup) { - if ((up = reallocf(up, upsize *= 2)) == NULL) - goto err; - bup = up; - eup = up + upsize; - } - *bup++ = '.'; - *bup++ = '.'; - *bup = '\0'; - /* Open and stat parent directory. */ - if (!(dir = opendir(up)) || _fstat(dirfd(dir), &s)) + fd = _openat(dir != NULL ? dirfd(dir) : AT_FDCWD, + "..", O_RDONLY); + if (fd == -1) goto err; - - /* Add trailing slash for next directory. */ - *bup++ = '/'; - *bup = '\0'; + if (dir) + (void) closedir(dir); + if (!(dir = fdopendir(fd)) || _fstat(dirfd(dir), &s)) { + _close(fd); + goto err; + } /* * If it's a mount point, have to stat each element because @@ -190,10 +169,10 @@ getcwd(pt, size) goto notfound; if (ISDOT(dp)) continue; - bcopy(dp->d_name, bup, dp->d_namlen + 1); /* Save the first error for later. */ - if (lstat(up, &s)) { + if (fstatat(dirfd(dir), dp->d_name, &s, + AT_SYMLINK_NOFOLLOW)) { if (!save_errno) save_errno = errno; errno = 0; @@ -227,11 +206,6 @@ getcwd(pt, size) *--bpt = '/'; bpt -= dp->d_namlen; bcopy(dp->d_name, bpt, dp->d_namlen); - (void) closedir(dir); - dir = NULL; - - /* Truncate any file name. */ - *bup = '\0'; } notfound: @@ -250,7 +224,6 @@ err: free(pt); if (dir) (void) closedir(dir); - free(up); errno = save_errno; return (NULL); From a19285149615c60009a9c5190c260de14b2293f7 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 13 Oct 2009 21:27:35 +0000 Subject: [PATCH 156/646] Import ACPICA 20091013. --- changes.txt | 69 +++- common/adfile.c | 24 +- common/adisasm.c | 159 ++------- common/adwalk.c | 34 +- common/dmextern.c | 646 ++++++++++++++++++++++++++++++++++ common/dmtable.c | 3 +- common/getopt.c | 8 +- compiler/Makefile | 1 + compiler/aslload.c | 9 +- debugger/dbcmds.c | 44 ++- debugger/dbinput.c | 2 +- disassembler/dmutils.c | 118 ------- disassembler/dmwalk.c | 104 +----- dispatcher/dswload.c | 54 ++- events/evregion.c | 69 +++- include/acapps.h | 26 +- include/acdebug.h | 10 +- include/acdisasm.h | 74 ++-- include/acglobal.h | 1 + include/aclocal.h | 23 ++ include/acpixf.h | 2 +- namespace/nsrepair.c | 113 ++++-- tools/acpisrc/astable.c | 1 + tools/acpixtract/acpixtract.c | 178 +++++++--- utilities/utglobal.c | 4 + 25 files changed, 1240 insertions(+), 536 deletions(-) create mode 100644 common/dmextern.c diff --git a/changes.txt b/changes.txt index 177ae98ee26..9e8ff8961a7 100644 --- a/changes.txt +++ b/changes.txt @@ -1,10 +1,69 @@ ---------------------------------------- -03 September 2009. Summary of changes for version 20090903: +13 October 2009. Summary of changes for version 20091013: This release is available at www.acpica.org/downloads 1) ACPI CA Core Subsystem: +Fixed a problem where an Operation Region _REG method could be executed more +than once. If a custom address space handler is installed by the host before +the "initialize operation regions" phase of the ACPICA initialization, any +_REG methods for that address space could be executed twice. This change +fixes the problem. ACPICA BZ 427. Lin Ming. + +Fixed a possible memory leak for the Scope() ASL operator. When the exact +invocation of "Scope(\)" is executed (change scope to root), one internal +operand object was leaked. Lin Ming. + +Implemented a run-time repair for the _MAT predefined method. If the _MAT +return value is defined as a Field object in the AML, and the field +size is less than or equal to the default width of an integer (32 or 64),_MAT +can incorrectly return an Integer instead of a Buffer. ACPICA now +automatically repairs this problem. ACPICA BZ 810. + +Implemented a run-time repair for the _BIF and _BIX predefined methods. The +"OEM Information" field is often incorrectly returned as an Integer with +value zero if the field is not supported by the platform. This is due to an +ambiguity in the ACPI specification. The field should always be a string. +ACPICA now automatically repairs this problem by returning a NULL string +within the returned Package. ACPICA BZ 807. + +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The +debug version of the code includes the debug output trace mechanism and has a +much larger code and data size. + + Previous Release: + Non-Debug Version: 85.6K Code, 18.0K Data, 103.6K Total + Debug Version: 161.7K Code, 50.9K Data, 212.6K Total + Current Release: + Non-Debug Version: 85.8K Code, 18.0K Data, 103.8K Total + Debug Version: 161.8K Code, 50.6K Data, 212.4K Total + +2) iASL Compiler/Disassembler and Tools: + +Disassembler: Fixed a problem where references to external symbols that +contained one or more parent-prefixes (carats) were not handled correctly, +possibly causing a fault. ACPICA BZ 806. Lin Ming. + +Disassembler: Restructured the code so that all functions that handle +external symbols are in a single module. One new file is added, +common/dmextern.c. + +AML Debugger: Added a max count argument for the Batch command (which +executes multiple predefined methods within the namespace.) + +iASL: Updated the compiler documentation (User Reference.) Available at +http://www.acpica.org/documentation/. ACPICA BZ 750. + +AcpiXtract: Updated for Lint and other formatting changes. Close all open +files. + +---------------------------------------- +03 September 2009. Summary of changes for version 20090903: + +1) ACPI CA Core Subsystem: + For Windows Vista compatibility, added the automatic execution of an _INI method located at the namespace root (\_INI). This method is executed at table load time. This support is in addition to the automatic execution of @@ -74,8 +133,6 @@ subtables. ---------------------------------------- 30 July 2009. Summary of changes for version 20090730: -This release is available at www.acpica.org/downloads - The ACPI 4.0 implementation for ACPICA is complete with this release. 1) ACPI CA Core Subsystem: @@ -146,8 +203,6 @@ changes to existing tables. ACPICA BZ 775. ---------------------------------------- 25 June 2009. Summary of changes for version 20090625: -This release is available at www.acpica.org/downloads - The ACPI 4.0 Specification was released on June 16 and is available at www.acpi.info. ACPICA implementation of ACPI 4.0 is underway and will continue for the next few releases. @@ -224,8 +279,6 @@ predefined names and control methods (31 total). ACPICA BZ 769. ---------------------------------------- 21 May 2009. Summary of changes for version 20090521: -This release is available at www.acpica.org/downloads - 1) ACPI CA Core Subsystem: Disabled the preservation of the SCI enable bit in the PM1 control register. @@ -297,8 +350,6 @@ after an invalid sub-table ID. ---------------------------------------- 22 April 2009. Summary of changes for version 20090422: -This release is available at www.acpica.org/downloads - 1) ACPI CA Core Subsystem: Fixed a compatibility issue with the recently released I/O port protection diff --git a/common/adfile.c b/common/adfile.c index 1de4b248f8d..b5a6afcd3fe 100644 --- a/common/adfile.c +++ b/common/adfile.c @@ -119,7 +119,6 @@ #include "acapps.h" #include -#include #define _COMPONENT ACPI_TOOLS @@ -135,12 +134,13 @@ AdWriteBuffer ( char FilenameBuf[20]; + /****************************************************************************** * * FUNCTION: AfGenerateFilename * - * PARAMETERS: Prefix - prefix string - * TableId - The table ID + * PARAMETERS: Prefix - prefix string + * TableId - The table ID * * RETURN: Pointer to the completed string * @@ -180,9 +180,9 @@ AdGenerateFilename ( * * FUNCTION: AfWriteBuffer * - * PARAMETERS: Filename - name of file - * Buffer - data to write - * Length - length of data + * PARAMETERS: Filename - name of file + * Buffer - data to write + * Length - length of data * * RETURN: Actual number of bytes written * @@ -217,10 +217,10 @@ AdWriteBuffer ( * * FUNCTION: AfWriteTable * - * PARAMETERS: Table - pointer to the ACPI table - * Length - length of the table - * TableName - the table signature - * OemTableID - from the table header + * PARAMETERS: Table - pointer to the ACPI table + * Length - length of the table + * TableName - the table signature + * OemTableID - from the table header * * RETURN: None * @@ -272,7 +272,7 @@ FlGenerateFilename ( * Copy the original filename to a new buffer. Leave room for the worst case * where we append the suffix, an added dot and the null terminator. */ - NewFilename = ACPI_ALLOCATE_ZEROED ( + NewFilename = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) strlen (InputFilename) + strlen (Suffix) + 2); strcpy (NewFilename, InputFilename); @@ -314,7 +314,7 @@ FlStrdup ( char *NewString; - NewString = ACPI_ALLOCATE (strlen (String) + 1); + NewString = ACPI_ALLOCATE ((ACPI_SIZE) strlen (String) + 1); if (!NewString) { return (NULL); diff --git a/common/adisasm.c b/common/adisasm.c index 8aaa3b4bb53..63c56840b48 100644 --- a/common/adisasm.c +++ b/common/adisasm.c @@ -132,14 +132,18 @@ #define _COMPONENT ACPI_TOOLS ACPI_MODULE_NAME ("adisasm") -extern int AslCompilerdebug; + +extern int AslCompilerdebug; +extern char *Gbl_ExternalFilename; + ACPI_STATUS LsDisplayNamespace ( void); void -LsSetupNsList (void * Handle); +LsSetupNsList ( + void *Handle); /* Local prototypes */ @@ -153,14 +157,6 @@ void AdDisassemblerHeader ( char *Filename); -void -AdAddExternalsToNamespace ( - void); - -UINT32 -AdMethodExternalCount ( - void); - ACPI_STATUS AdDeferredParse ( ACPI_PARSE_OBJECT *Op, @@ -171,8 +167,6 @@ ACPI_STATUS AdParseDeferredOps ( ACPI_PARSE_OBJECT *Root); -ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; - /* Stubs for ASL compiler */ @@ -192,7 +186,6 @@ AcpiDsMethodError ( { return (Status); } - #endif ACPI_STATUS @@ -238,18 +231,19 @@ AcpiDsMethodDataInitArgs ( } -ACPI_TABLE_DESC LocalTables[1]; +static ACPI_TABLE_DESC LocalTables[1]; +static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; /******************************************************************************* * * FUNCTION: AdInitialize * - * PARAMETERS: None. + * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: CA initialization + * DESCRIPTION: ACPICA and local initialization * ******************************************************************************/ @@ -296,89 +290,15 @@ AdInitialize ( } -/******************************************************************************* - * - * FUNCTION: AdAddExternalsToNamespace - * - * PARAMETERS: - * - * RETURN: None - * - * DESCRIPTION: - * - ******************************************************************************/ - -void -AdAddExternalsToNamespace ( - void) -{ - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *Node; - ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; - ACPI_OPERAND_OBJECT *MethodDesc; - - - while (External) - { - Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, - ACPI_IMODE_LOAD_PASS1, ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, - NULL, &Node); - - if (External->Type == ACPI_TYPE_METHOD) - { - MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); - MethodDesc->Method.ParamCount = (UINT8) External->Value; - Node->Object = MethodDesc; - } - - External = External->Next; - } -} - - -/******************************************************************************* - * - * FUNCTION: AdMethodExternalCount - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Return the number of externals that have been generated - * - ******************************************************************************/ - -UINT32 -AdMethodExternalCount ( - void) -{ - ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; - UINT32 Count = 0; - - - while (External) - { - if (External->Type == ACPI_TYPE_METHOD) - { - Count++; - } - - External = External->Next; - } - - return (Count); -} - - /****************************************************************************** * * FUNCTION: AdAmlDisassemble * - * PARAMETERS: Filename - AML input filename - * OutToFile - TRUE if output should go to a file - * Prefix - Path prefix for output - * OutFilename - where the filename is returned - * GetAllTables - TRUE if all tables are desired + * PARAMETERS: Filename - AML input filename + * OutToFile - TRUE if output should go to a file + * Prefix - Path prefix for output + * OutFilename - where the filename is returned + * GetAllTables - TRUE if all tables are desired * * RETURN: Status * @@ -386,8 +306,6 @@ AdMethodExternalCount ( * *****************************************************************************/ -extern char *Gbl_ExternalFilename; - ACPI_STATUS AdAmlDisassemble ( BOOLEAN OutToFile, @@ -403,12 +321,11 @@ AdAmlDisassemble ( ACPI_TABLE_HEADER *Table = NULL; ACPI_TABLE_HEADER *ExternalTable; ACPI_OWNER_ID OwnerId; - ACPI_EXTERNAL_LIST *NextExternal; /* - * Input: AML Code from either a file, - * or via GetTables (memory or registry) + * Input: AML code from either a file or via GetTables (memory or + * registry) */ if (Filename) { @@ -462,13 +379,7 @@ AdAmlDisassemble ( /* Clear external list generated by Scope in external tables */ - while (AcpiGbl_ExternalList) - { - NextExternal = AcpiGbl_ExternalList->Next; - ACPI_FREE (AcpiGbl_ExternalList->Path); - ACPI_FREE (AcpiGbl_ExternalList); - AcpiGbl_ExternalList = NextExternal; - } + AcpiDmClearExternalList (); } } else @@ -501,8 +412,7 @@ AdAmlDisassemble ( } /* - * Output: ASL code. - * Redirect to a file if requested + * Output: ASL code. Redirect to a file if requested */ if (OutToFile) { @@ -589,11 +499,11 @@ AdAmlDisassemble ( * tree with the new information (namely, the number of arguments per * method) */ - if (AdMethodExternalCount ()) + if (AcpiDmGetExternalMethodCount ()) { fprintf (stderr, "\nFound %d external control methods, reparsing with new information\n", - AdMethodExternalCount()); + AcpiDmGetExternalMethodCount ()); /* * Reparse, rebuild namespace. no need to xref namespace @@ -611,7 +521,7 @@ AdAmlDisassemble ( AcpiGbl_RootNodeStruct.Flags = ANOBJ_END_OF_PEER_LIST; Status = AcpiNsRootInitialize (); - AdAddExternalsToNamespace (); + AcpiDmAddExternalsToNamespace (); /* Parse table. No need to reload it, however (FALSE) */ @@ -855,9 +765,9 @@ AdDisplayTables ( * * FUNCTION: AdDeferredParse * - * PARAMETERS: Op - Root Op of the deferred opcode - * Aml - Pointer to the raw AML - * AmlLength - Length of the AML + * PARAMETERS: Op - Root Op of the deferred opcode + * Aml - Pointer to the raw AML + * AmlLength - Length of the AML * * RETURN: Status * @@ -981,7 +891,7 @@ AdDeferredParse ( * * FUNCTION: AdParseDeferredOps * - * PARAMETERS: Root - Root of the parse tree + * PARAMETERS: Root - Root of the parse tree * * RETURN: Status * @@ -1055,8 +965,8 @@ AdParseDeferredOps ( * * FUNCTION: AdGetLocalTables * - * PARAMETERS: Filename - Not used - * GetAllTables - TRUE if all tables are desired + * PARAMETERS: Filename - Not used + * GetAllTables - TRUE if all tables are desired * * RETURN: Status * @@ -1138,6 +1048,11 @@ AdGetLocalTables ( Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 0, &TableIndex); + if (ACPI_FAILURE (Status)) + { + fprintf (stderr, "Could not store DSDT\n"); + return AE_NO_ACPI_TABLES; + } } else { @@ -1169,10 +1084,10 @@ AdGetLocalTables ( * * FUNCTION: AdParseTable * - * PARAMETERS: Table - Pointer to the raw table - * OwnerId - Returned OwnerId of the table - * LoadTable - If add table to the global table list - * External - If this is an external table + * PARAMETERS: Table - Pointer to the raw table + * OwnerId - Returned OwnerId of the table + * LoadTable - If add table to the global table list + * External - If this is an external table * * RETURN: Status * diff --git a/common/adwalk.c b/common/adwalk.c index 67d9b113894..e69eadb2df0 100644 --- a/common/adwalk.c +++ b/common/adwalk.c @@ -118,7 +118,6 @@ #include "accommon.h" #include "acparser.h" #include "amlcode.h" -#include "acdebug.h" #include "acdisasm.h" #include "acdispat.h" #include "acnamesp.h" @@ -184,7 +183,7 @@ AcpiDmResourceDescendingOp ( * * FUNCTION: AcpiDmDumpTree * - * PARAMETERS: Origin - Starting object + * PARAMETERS: Origin - Starting object * * RETURN: None * @@ -218,7 +217,7 @@ AcpiDmDumpTree ( * * FUNCTION: AcpiDmFindOrphanMethods * - * PARAMETERS: Origin - Starting object + * PARAMETERS: Origin - Starting object * * RETURN: None * @@ -426,7 +425,6 @@ AcpiDmDumpDescending ( void *Context) { ACPI_OP_WALK_INFO *Info = Context; - const ACPI_OPCODE_INFO *OpInfo; char *Path; @@ -435,11 +433,9 @@ AcpiDmDumpDescending ( return (AE_OK); } - OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); - Info->Count++; - /* Most of the information (count, level, name) here */ + Info->Count++; AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level); AcpiDmIndent (Level); AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode)); @@ -472,7 +468,7 @@ AcpiDmDumpDescending ( case AML_METHOD_OP: case AML_DEVICE_OP: case AML_INT_NAMEDFIELD_OP: - AcpiOsPrintf ("%4.4s", &Op->Named.Name); + AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name)); break; default: @@ -536,7 +532,7 @@ AcpiDmFindOrphanDescending ( { /* This NamePath has no args, assume it is an integer */ - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); return (AE_OK); } @@ -547,11 +543,11 @@ AcpiDmFindOrphanDescending ( { /* One Arg means this is just a Store(Name,Target) */ - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); return (AE_OK); } - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); } break; #endif @@ -567,7 +563,7 @@ AcpiDmFindOrphanDescending ( { /* This NamePath has no args, assume it is an integer */ - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); return (AE_OK); } @@ -576,11 +572,11 @@ AcpiDmFindOrphanDescending ( { /* One Arg means this is just a Store(Name,Target) */ - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); return (AE_OK); } - AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); } break; @@ -611,7 +607,7 @@ AcpiDmFindOrphanDescending ( /* And namepath is the first argument */ (ParentOp->Common.Value.Arg == Op)) { - AcpiDmAddToExternalList (Op->Common.Value.String, ACPI_TYPE_INTEGER, 0); + AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0); break; } } @@ -621,7 +617,7 @@ AcpiDmFindOrphanDescending ( * operator) - it *must* be a method invocation, nothing else is * grammatically possible. */ - AcpiDmAddToExternalList (Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); } break; @@ -858,7 +854,7 @@ AcpiDmXrefDescendingOp ( { if (Status == AE_NOT_FOUND) { - AcpiDmAddToExternalList (Path, (UINT8) ObjectType, 0); + AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0); /* * We could install this into the namespace, but we catch duplicate @@ -888,12 +884,12 @@ AcpiDmXrefDescendingOp ( if (ObjectType2 == ACPI_TYPE_METHOD) { - AcpiDmAddToExternalList (Path, ACPI_TYPE_METHOD, + AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_METHOD, Object->Method.ParamCount); } else { - AcpiDmAddToExternalList (Path, (UINT8) ObjectType2, 0); + AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, 0); } Op->Common.Node = Node; diff --git a/common/dmextern.c b/common/dmextern.c new file mode 100644 index 00000000000..74dc65a3a52 --- /dev/null +++ b/common/dmextern.c @@ -0,0 +1,646 @@ +/****************************************************************************** + * + * Module Name: dmextern - Support for External() ASL statements + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + *****************************************************************************/ + +#include "acpi.h" +#include "accommon.h" +#include "amlcode.h" +#include "acnamesp.h" +#include "acdisasm.h" + + +/* + * This module is used for application-level code (iASL disassembler) only. + * + * It contains the code to create and emit any necessary External() ASL + * statements for the module being disassembled. + */ +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmextern") + + +/* + * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL + * ObjectTypeKeyword. Used to generate typed external declarations + */ +static const char *AcpiGbl_DmTypeNames[] = +{ + /* 00 */ "", /* Type ANY */ + /* 01 */ ", IntObj", + /* 02 */ ", StrObj", + /* 03 */ ", BuffObj", + /* 04 */ ", PkgObj", + /* 05 */ ", FieldUnitObj", + /* 06 */ ", DeviceObj", + /* 07 */ ", EventObj", + /* 08 */ ", MethodObj", + /* 09 */ ", MutexObj", + /* 10 */ ", OpRegionObj", + /* 11 */ ", PowerResObj", + /* 12 */ ", ProcessorObj", + /* 13 */ ", ThermalZoneObj", + /* 14 */ ", BuffFieldObj", + /* 15 */ ", DDBHandleObj", + /* 16 */ "", /* Debug object */ + /* 17 */ ", FieldUnitObj", + /* 18 */ ", FieldUnitObj", + /* 19 */ ", FieldUnitObj" +}; + + +/* Local prototypes */ + +static const char * +AcpiDmGetObjectTypeName ( + ACPI_OBJECT_TYPE Type); + +static char * +AcpiDmNormalizeParentPrefix ( + ACPI_PARSE_OBJECT *Op, + char *Path); + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetObjectTypeName + * + * PARAMETERS: Type - An ACPI_OBJECT_TYPE + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Map an object type to the ASL object type string. + * + ******************************************************************************/ + +static const char * +AcpiDmGetObjectTypeName ( + ACPI_OBJECT_TYPE Type) +{ + + if (Type == ACPI_TYPE_LOCAL_SCOPE) + { + Type = ACPI_TYPE_DEVICE; + } + + else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) + { + return (""); + } + + return (AcpiGbl_DmTypeNames[Type]); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmNormalizeParentPrefix + * + * PARAMETERS: Op - Parse op + * Path - Path with parent prefix + * + * RETURN: The full pathname to the object (from the namespace root) + * + * DESCRIPTION: Returns the full pathname of a path with parent prefix + * The caller must free the fullpath returned. + * + ******************************************************************************/ + +static char * +AcpiDmNormalizeParentPrefix ( + ACPI_PARSE_OBJECT *Op, + char *Path) +{ + ACPI_NAMESPACE_NODE *Node; + char *Fullpath; + char *ParentPath; + ACPI_SIZE Length; + + + /* Search upwards in the parse tree until we reach a namespace node */ + + while (Op) + { + if (Op->Common.Node) + { + break; + } + + Op = Op->Common.Parent; + } + + if (!Op) + { + return (NULL); + } + + /* + * Find the actual parent node for the reference: + * Remove all carat prefixes from the input path. + * There may be multiple parent prefixes (For example, ^^^M000) + */ + Node = Op->Common.Node; + while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) + { + Node = AcpiNsGetParentNode (Node); + Path++; + } + + if (!Node) + { + return (NULL); + } + + /* Get the full pathname for the parent node */ + + ParentPath = AcpiNsGetExternalPathname (Node); + if (!ParentPath) + { + return (NULL); + } + + Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); + Fullpath = ACPI_ALLOCATE_ZEROED (Length); + if (!Fullpath) + { + goto Cleanup; + } + + /* + * Concatenate parent fullpath and path. For example, + * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" + * + * Copy the parent path + */ + ACPI_STRCAT (Fullpath, ParentPath); + + /* Add dot separator (don't need dot if parent fullpath is a single "\") */ + + if (ParentPath[1]) + { + ACPI_STRCAT (Fullpath, "."); + } + + /* Copy child path (carat parent prefix(es) were skipped above) */ + + ACPI_STRCAT (Fullpath, Path); + +Cleanup: + ACPI_FREE (ParentPath); + return (Fullpath); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddToExternalList + * + * PARAMETERS: Op - Current parser Op + * Path - Internal (AML) path to the object + * Type - ACPI object type to be added + * Value - Arg count if adding a Method object + * + * RETURN: None + * + * DESCRIPTION: Insert a new name into the global list of Externals which + * will in turn be later emitted as an External() declaration + * in the disassembled output. + * + ******************************************************************************/ + +void +AcpiDmAddToExternalList ( + ACPI_PARSE_OBJECT *Op, + char *Path, + UINT8 Type, + UINT32 Value) +{ + char *ExternalPath; + char *Fullpath = NULL; + ACPI_EXTERNAL_LIST *NewExternal; + ACPI_EXTERNAL_LIST *NextExternal; + ACPI_EXTERNAL_LIST *PrevExternal = NULL; + ACPI_STATUS Status; + + + if (!Path) + { + return; + } + + /* Externalize the ACPI path */ + + Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, + NULL, &ExternalPath); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Get the full pathname from root if "Path" has a parent prefix */ + + if (*Path == (UINT8) AML_PARENT_PREFIX) + { + Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); + if (Fullpath) + { + /* Set new external path */ + + ACPI_FREE (ExternalPath); + ExternalPath = Fullpath; + } + } + + /* Check all existing externals to ensure no duplicates */ + + NextExternal = AcpiGbl_ExternalList; + while (NextExternal) + { + if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) + { + /* Duplicate method, check that the Value (ArgCount) is the same */ + + if ((NextExternal->Type == ACPI_TYPE_METHOD) && + (NextExternal->Value != Value)) + { + ACPI_ERROR ((AE_INFO, + "Argument count mismatch for method %s %d %d", + NextExternal->Path, NextExternal->Value, Value)); + } + + /* Allow upgrade of type from ANY */ + + else if (NextExternal->Type == ACPI_TYPE_ANY) + { + NextExternal->Type = Type; + NextExternal->Value = Value; + } + + ACPI_FREE (ExternalPath); + return; + } + + NextExternal = NextExternal->Next; + } + + /* Allocate and init a new External() descriptor */ + + NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); + if (!NewExternal) + { + ACPI_FREE (ExternalPath); + return; + } + + NewExternal->Path = ExternalPath; + NewExternal->Type = Type; + NewExternal->Value = Value; + NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); + + /* Was the external path with parent prefix normalized to a fullpath? */ + + if (Fullpath == ExternalPath) + { + /* Get new internal path */ + + Status = AcpiNsInternalizeName (ExternalPath, &Path); + if (ACPI_FAILURE (Status)) + { + ACPI_FREE (ExternalPath); + ACPI_FREE (NewExternal); + return; + } + + /* Set flag to indicate External->InternalPath need to be freed */ + + NewExternal->Flags |= ACPI_IPATH_ALLOCATED; + } + + NewExternal->InternalPath = Path; + + /* Link the new descriptor into the global list, ordered by string length */ + + NextExternal = AcpiGbl_ExternalList; + while (NextExternal) + { + if (NewExternal->Length <= NextExternal->Length) + { + if (PrevExternal) + { + PrevExternal->Next = NewExternal; + } + else + { + AcpiGbl_ExternalList = NewExternal; + } + + NewExternal->Next = NextExternal; + return; + } + + PrevExternal = NextExternal; + NextExternal = NextExternal->Next; + } + + if (PrevExternal) + { + PrevExternal->Next = NewExternal; + } + else + { + AcpiGbl_ExternalList = NewExternal; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddExternalsToNamespace + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Add all externals to the namespace. Allows externals to be + * "resolved". + * + ******************************************************************************/ + +void +AcpiDmAddExternalsToNamespace ( + void) +{ + ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *Node; + ACPI_OPERAND_OBJECT *MethodDesc; + ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; + + + while (External) + { + /* Add the external name (object) into the namespace */ + + Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, + ACPI_IMODE_LOAD_PASS1, + ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, + NULL, &Node); + + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "while adding external to namespace [%s]", + External->Path)); + } + else if (External->Type == ACPI_TYPE_METHOD) + { + /* For methods, we need to save the argument count */ + + MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); + MethodDesc->Method.ParamCount = (UINT8) External->Value; + Node->Object = MethodDesc; + } + + External = External->Next; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetExternalMethodCount + * + * PARAMETERS: None + * + * RETURN: The number of control method externals in the external list + * + * DESCRIPTION: Return the number of method externals that have been generated. + * If any control method externals have been found, we must + * re-parse the entire definition block with the new information + * (number of arguments for the methods.) This is limitation of + * AML, we don't know the number of arguments from the control + * method invocation itself. + * + ******************************************************************************/ + +UINT32 +AcpiDmGetExternalMethodCount ( + void) +{ + ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; + UINT32 Count = 0; + + + while (External) + { + if (External->Type == ACPI_TYPE_METHOD) + { + Count++; + } + + External = External->Next; + } + + return (Count); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmClearExternalList + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Free the entire External info list + * + ******************************************************************************/ + +void +AcpiDmClearExternalList ( + void) +{ + ACPI_EXTERNAL_LIST *NextExternal; + + + while (AcpiGbl_ExternalList) + { + NextExternal = AcpiGbl_ExternalList->Next; + ACPI_FREE (AcpiGbl_ExternalList->Path); + ACPI_FREE (AcpiGbl_ExternalList); + AcpiGbl_ExternalList = NextExternal; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmEmitExternals + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Emit an External() ASL statement for each of the externals in + * the global external info list. + * + ******************************************************************************/ + +void +AcpiDmEmitExternals ( + void) +{ + ACPI_EXTERNAL_LIST *NextExternal; + + + if (!AcpiGbl_ExternalList) + { + return; + } + + /* + * Walk the list of externals (unresolved references) + * found during the AML parsing + */ + while (AcpiGbl_ExternalList) + { + AcpiOsPrintf (" External (%s%s", + AcpiGbl_ExternalList->Path, + AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); + + if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) + { + AcpiOsPrintf (") // %d Arguments\n", + AcpiGbl_ExternalList->Value); + } + else + { + AcpiOsPrintf (")\n"); + } + + /* Free this external info block and move on to next external */ + + NextExternal = AcpiGbl_ExternalList->Next; + if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) + { + ACPI_FREE (AcpiGbl_ExternalList->InternalPath); + } + + ACPI_FREE (AcpiGbl_ExternalList->Path); + ACPI_FREE (AcpiGbl_ExternalList); + AcpiGbl_ExternalList = NextExternal; + } + + AcpiOsPrintf ("\n"); +} + diff --git a/common/dmtable.c b/common/dmtable.c index 9b0e1e50a3d..0c83a4e9993 100644 --- a/common/dmtable.c +++ b/common/dmtable.c @@ -218,7 +218,6 @@ static const char *AcpiDmIvrsSubnames[] = }; - #define ACPI_FADT_PM_RESERVED 8 static const char *AcpiDmFadtProfiles[] = @@ -954,7 +953,7 @@ AcpiDmCheckAscii ( for (i = 0; i < Count; i++) { - RepairedName[i] = Name[i]; + RepairedName[i] = (char) Name[i]; if (!Name[i]) { diff --git a/common/getopt.c b/common/getopt.c index 54cff3ec2db..d675583fd9f 100644 --- a/common/getopt.c +++ b/common/getopt.c @@ -195,9 +195,9 @@ AcpiGetopt( if (*++OptsPtr == ':') { - if (argv[AcpiGbl_Optind][CurrentCharPtr+1] != '\0') + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') { - AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][CurrentCharPtr+1]; + AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)]; } else if (++AcpiGbl_Optind >= argc) { @@ -218,9 +218,9 @@ AcpiGetopt( else if (*OptsPtr == '^') { - if (argv[AcpiGbl_Optind][CurrentCharPtr+1] != '\0') + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') { - AcpiGbl_Optarg = &argv[AcpiGbl_Optind][CurrentCharPtr+1]; + AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)]; } else { diff --git a/compiler/Makefile b/compiler/Makefile index 740842c0231..597d1ffcbeb 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -71,6 +71,7 @@ SRCS= aslcompilerparse.c aslcompilerlex.c aslanalyze.c aslcodegen.c \ ../common/adfile.c \ ../common/adisasm.c \ ../common/adwalk.c \ + ../common/dmextern.c \ ../common/dmrestag.c \ ../common/dmtable.c \ ../common/dmtbinfo.c \ diff --git a/compiler/aslload.c b/compiler/aslload.c index 8d06544e7d4..fab67ccca95 100644 --- a/compiler/aslload.c +++ b/compiler/aslload.c @@ -575,7 +575,9 @@ LdNamespace1Begin ( goto FinishNode; } - AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); + AslCoreSubsystemError (Op, Status, + "Failure from namespace lookup", FALSE); + goto Exit; } @@ -718,7 +720,7 @@ LdNamespace1Begin ( else { AslCoreSubsystemError (Op, Status, - "Failure from lookup %s\n", FALSE); + "Failure from namespace lookup", FALSE); goto Exit; } } @@ -885,7 +887,8 @@ LdNamespace2Begin ( return (AE_OK); } - AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); + AslCoreSubsystemError (Op, Status, + "Failure from namespace lookup", FALSE); return (AE_OK); } diff --git a/debugger/dbcmds.c b/debugger/dbcmds.c index 5504535af3c..6c0f8234afd 100644 --- a/debugger/dbcmds.c +++ b/debugger/dbcmds.c @@ -130,6 +130,7 @@ #define _COMPONENT ACPI_CA_DEBUGGER ACPI_MODULE_NAME ("dbcmds") + /* Local prototypes */ static ACPI_STATUS @@ -501,7 +502,7 @@ AcpiDbWalkForExecute ( void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; - UINT32 *Count = (UINT32 *) Context; + ACPI_EXECUTE_WALK *Info = (ACPI_EXECUTE_WALK *) Context; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; char *Pathname; @@ -542,7 +543,6 @@ AcpiDbWalkForExecute ( if (ObjInfo->Type == ACPI_TYPE_METHOD) { - /* Setup default parameters */ for (i = 0; i < ObjInfo->ParamCount; i++) @@ -556,11 +556,9 @@ AcpiDbWalkForExecute ( } ACPI_FREE (ObjInfo); - ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; - /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; @@ -569,11 +567,21 @@ AcpiDbWalkForExecute ( AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); AcpiGbl_MethodExecuting = FALSE; - ACPI_FREE (Pathname); - (*Count)++; - return (AE_OK); + /* Ignore status from method execution */ + + Status = AE_OK; + + /* Update count, check if we have executed enough methods */ + + Info->Count++; + if (Info->Count >= Info->MaxCount) + { + Status = AE_CTRL_TERMINATE; + } + + return (Status); } @@ -581,27 +589,37 @@ AcpiDbWalkForExecute ( * * FUNCTION: AcpiDbBatchExecute * - * PARAMETERS: None + * PARAMETERS: CountArg - Max number of methods to execute * * RETURN: None * - * DESCRIPTION: Namespace batch execution. + * DESCRIPTION: Namespace batch execution. Execute predefined names in the + * namespace, up to the max count, if specified. * ******************************************************************************/ void AcpiDbBatchExecute ( - void) + char *CountArg) { - UINT32 Count = 0; + ACPI_EXECUTE_WALK Info; + + + Info.Count = 0; + Info.MaxCount = ACPI_UINT32_MAX; + + if (CountArg) + { + Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0); + } /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForExecute, (void *) &Count, NULL); + AcpiDbWalkForExecute, (void *) &Info, NULL); - AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Count); + AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Info.Count); } diff --git a/debugger/dbinput.c b/debugger/dbinput.c index a64d547fdc8..74b2dca6edd 100644 --- a/debugger/dbinput.c +++ b/debugger/dbinput.c @@ -644,7 +644,7 @@ AcpiDbCommandDispatch ( break; case CMD_BATCH: - AcpiDbBatchExecute (); + AcpiDbBatchExecute (AcpiGbl_DbArgs[1]); break; case CMD_BREAKPOINT: diff --git a/disassembler/dmutils.c b/disassembler/dmutils.c index 75794b9f705..111c785ceea 100644 --- a/disassembler/dmutils.c +++ b/disassembler/dmutils.c @@ -129,9 +129,6 @@ ACPI_MODULE_NAME ("dmutils") -ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList = NULL; - - /* Data used in keeping track of fields */ #if 0 const char *AcpiGbl_FENames[] = @@ -202,121 +199,6 @@ const char *AcpiGbl_IrqDecode[] = }; -#ifdef ACPI_ASL_COMPILER -/******************************************************************************* - * - * FUNCTION: AcpiDmAddToExternalList - * - * PARAMETERS: Path - Internal (AML) path to the object - * - * RETURN: None - * - * DESCRIPTION: Insert a new path into the list of Externals which will in - * turn be emitted as an External() declaration in the disassembled - * output. - * - ******************************************************************************/ - -void -AcpiDmAddToExternalList ( - char *Path, - UINT8 Type, - UINT32 Value) -{ - char *ExternalPath; - ACPI_EXTERNAL_LIST *NewExternal; - ACPI_EXTERNAL_LIST *NextExternal; - ACPI_EXTERNAL_LIST *PrevExternal = NULL; - ACPI_STATUS Status; - - - if (!Path) - { - return; - } - - /* Externalize the ACPI path */ - - Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, - NULL, &ExternalPath); - if (ACPI_FAILURE (Status)) - { - return; - } - - /* Ensure that we don't have duplicate externals */ - - NextExternal = AcpiGbl_ExternalList; - while (NextExternal) - { - /* Allow upgrade of type from ANY */ - - if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) - { - /* Duplicate method, check that the Value (ArgCount) is the same */ - - if ((NextExternal->Type == ACPI_TYPE_METHOD) && - (NextExternal->Value != Value)) - { - ACPI_ERROR ((AE_INFO, "Argument count mismatch for method %s %d %d", - NextExternal->Path, NextExternal->Value, Value)); - } - if (NextExternal->Type == ACPI_TYPE_ANY) - { - NextExternal->Type = Type; - NextExternal->Value = Value; - } - ACPI_FREE (ExternalPath); - return; - } - NextExternal = NextExternal->Next; - } - - /* Allocate and init a new External() descriptor */ - - NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); - NewExternal->InternalPath = Path; - NewExternal->Path = ExternalPath; - NewExternal->Type = Type; - NewExternal->Value = Value; - NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); - - /* Link the new descriptor into the global list, ordered by string length */ - - NextExternal = AcpiGbl_ExternalList; - while (NextExternal) - { - if (NewExternal->Length <= NextExternal->Length) - { - if (PrevExternal) - { - PrevExternal->Next = NewExternal; - } - else - { - AcpiGbl_ExternalList = NewExternal; - } - - NewExternal->Next = NextExternal; - return; - } - - PrevExternal = NextExternal; - NextExternal = NextExternal->Next; - } - - if (PrevExternal) - { - PrevExternal->Next = NewExternal; - } - else - { - AcpiGbl_ExternalList = NewExternal; - } -} -#endif - - /******************************************************************************* * * FUNCTION: AcpiDmDecodeAttribute diff --git a/disassembler/dmwalk.c b/disassembler/dmwalk.c index 156e2dd5b11..ddc0e35cd62 100644 --- a/disassembler/dmwalk.c +++ b/disassembler/dmwalk.c @@ -130,6 +130,17 @@ #define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: " +/* Stub for non-compiler code */ + +#ifndef ACPI_ASL_COMPILER +void +AcpiDmEmitExternals ( + void) +{ + return; +} +#endif + /* Local prototypes */ static ACPI_STATUS @@ -148,68 +159,6 @@ static UINT32 AcpiDmBlockType ( ACPI_PARSE_OBJECT *Op); -static const char * -AcpiDmGetObjectTypeName ( - ACPI_OBJECT_TYPE Type); - -/* - * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL - * ObjectTypeKeyword. Used to generate typed external declarations - */ -static const char *AcpiGbl_DmTypeNames[] = -{ - /* 00 */ "", /* Type ANY */ - /* 01 */ ", IntObj", - /* 02 */ ", StrObj", - /* 03 */ ", BuffObj", - /* 04 */ ", PkgObj", - /* 05 */ ", FieldUnitObj", - /* 06 */ ", DeviceObj", - /* 07 */ ", EventObj", - /* 08 */ ", MethodObj", - /* 09 */ ", MutexObj", - /* 10 */ ", OpRegionObj", - /* 11 */ ", PowerResObj", - /* 12 */ ", ProcessorObj", - /* 13 */ ", ThermalZoneObj", - /* 14 */ ", BuffFieldObj", - /* 15 */ ", DDBHandleObj", - /* 16 */ "", /* Debug object */ - /* 17 */ ", FieldUnitObj", - /* 18 */ ", FieldUnitObj", - /* 19 */ ", FieldUnitObj" -}; - - -/******************************************************************************* - * - * FUNCTION: AcpiDmGetObjectTypeName - * - * PARAMETERS: Type - An ACPI_OBJECT_TYPE - * - * RETURN: Pointer to a string - * - * DESCRIPTION: Map an object type to the ASL object type string. - * - ******************************************************************************/ - -static const char * -AcpiDmGetObjectTypeName ( - ACPI_OBJECT_TYPE Type) -{ - - if (Type == ACPI_TYPE_LOCAL_SCOPE) - { - Type = ACPI_TYPE_DEVICE; - } - - else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) - { - return (""); - } - - return (AcpiGbl_DmTypeNames[Type]); -} /******************************************************************************* @@ -522,7 +471,6 @@ AcpiDmDescendingOp ( const ACPI_OPCODE_INFO *OpInfo; UINT32 Name; ACPI_PARSE_OBJECT *NextOp; - ACPI_EXTERNAL_LIST *NextExternal; if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) @@ -554,35 +502,7 @@ AcpiDmDescendingOp ( /* Emit all External() declarations here */ - if (AcpiGbl_ExternalList) - { - /* - * Walk the list of externals (unresolved references) - * found during parsing - */ - while (AcpiGbl_ExternalList) - { - AcpiOsPrintf (" External (%s%s", - AcpiGbl_ExternalList->Path, - AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); - - if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) - { - AcpiOsPrintf (") // %d Arguments\n", AcpiGbl_ExternalList->Value); - } - else - { - AcpiOsPrintf (")\n"); - } - - NextExternal = AcpiGbl_ExternalList->Next; - ACPI_FREE (AcpiGbl_ExternalList->Path); - ACPI_FREE (AcpiGbl_ExternalList); - AcpiGbl_ExternalList = NextExternal; - } - AcpiOsPrintf ("\n"); - } - + AcpiDmEmitExternals (); return (AE_OK); } } diff --git a/dispatcher/dswload.c b/dispatcher/dswload.c index 2c067f14d9b..bb92847e788 100644 --- a/dispatcher/dswload.c +++ b/dispatcher/dswload.c @@ -263,7 +263,7 @@ AcpiDsLoad1BeginOp ( * Target of Scope() not found. Generate an External for it, and * insert the name into the namespace. */ - AcpiDmAddToExternalList (Path, ACPI_TYPE_DEVICE, 0); + AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0); Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, &Node); @@ -732,29 +732,45 @@ AcpiDsLoad2BeginOp ( break; case AML_SCOPE_OP: - /* - * The Path is an object reference to an existing object. - * Don't enter the name into the namespace, but look it up - * for use later. - */ - Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType, + + /* Special case for Scope(\) -> refers to the Root node */ + + if (Op && (Op->Named.Node == AcpiGbl_RootNode)) + { + Node = Op->Named.Node; + + Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } + else + { + /* + * The Path is an object reference to an existing object. + * Don't enter the name into the namespace, but look it up + * for use later. + */ + Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); - if (ACPI_FAILURE (Status)) - { + if (ACPI_FAILURE (Status)) + { #ifdef ACPI_ASL_COMPILER - if (Status == AE_NOT_FOUND) - { - Status = AE_OK; - } - else - { - ACPI_ERROR_NAMESPACE (BufferPtr, Status); - } + if (Status == AE_NOT_FOUND) + { + Status = AE_OK; + } + else + { + ACPI_ERROR_NAMESPACE (BufferPtr, Status); + } #else - ACPI_ERROR_NAMESPACE (BufferPtr, Status); + ACPI_ERROR_NAMESPACE (BufferPtr, Status); #endif - return_ACPI_STATUS (Status); + return_ACPI_STATUS (Status); + } } /* diff --git a/events/evregion.c b/events/evregion.c index 32d7b642f99..4cfbc0c224e 100644 --- a/events/evregion.c +++ b/events/evregion.c @@ -128,6 +128,11 @@ /* Local prototypes */ +static BOOLEAN +AcpiEvHasDefaultHandler ( + ACPI_NAMESPACE_NODE *Node, + ACPI_ADR_SPACE_TYPE SpaceId); + static ACPI_STATUS AcpiEvRegRun ( ACPI_HANDLE ObjHandle, @@ -231,6 +236,57 @@ UnlockAndExit: } +/******************************************************************************* + * + * FUNCTION: AcpiEvHasDefaultHandler + * + * PARAMETERS: Node - Namespace node for the device + * SpaceId - The address space ID + * + * RETURN: TRUE if default handler is installed, FALSE otherwise + * + * DESCRIPTION: Check if the default handler is installed for the requested + * space ID. + * + ******************************************************************************/ + +static BOOLEAN +AcpiEvHasDefaultHandler ( + ACPI_NAMESPACE_NODE *Node, + ACPI_ADR_SPACE_TYPE SpaceId) +{ + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_OPERAND_OBJECT *HandlerObj; + + + /* Must have an existing internal object */ + + ObjDesc = AcpiNsGetAttachedObject (Node); + if (ObjDesc) + { + HandlerObj = ObjDesc->Device.Handler; + + /* Walk the linked list of handlers for this object */ + + while (HandlerObj) + { + if (HandlerObj->AddressSpace.SpaceId == SpaceId) + { + if (HandlerObj->AddressSpace.HandlerFlags & + ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) + { + return (TRUE); + } + } + + HandlerObj = HandlerObj->AddressSpace.Next; + } + } + + return (FALSE); +} + + /******************************************************************************* * * FUNCTION: AcpiEvInitializeOpRegions @@ -266,11 +322,16 @@ AcpiEvInitializeOpRegions ( for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { /* - * TBD: Make sure handler is the DEFAULT handler, otherwise - * _REG will have already been run. + * Make sure the installed handler is the DEFAULT handler. If not the + * default, the _REG methods will have already been run (when the + * handler was installed) */ - Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode, - AcpiGbl_DefaultAddressSpaces[i]); + if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, + AcpiGbl_DefaultAddressSpaces[i])) + { + Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode, + AcpiGbl_DefaultAddressSpaces[i]); + } } (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); diff --git a/include/acapps.h b/include/acapps.h index e1f31b791b7..c5ebef1d4af 100644 --- a/include/acapps.h +++ b/include/acapps.h @@ -124,21 +124,20 @@ #define FILE_SUFFIX_DISASSEMBLY "dsl" #define ACPI_TABLE_FILE_SUFFIX ".dat" -extern UINT8 *DsdtPtr; -extern UINT32 AcpiDsdtLength; -extern UINT8 *AmlStart; -extern UINT32 AmlLength; - - -extern int AcpiGbl_Optind; -extern char *AcpiGbl_Optarg; +/* + * getopt + */ int AcpiGetopt( int argc, char **argv, char *opts); +extern int AcpiGbl_Optind; +extern char *AcpiGbl_Optarg; + + /* * adisasm */ @@ -151,7 +150,8 @@ AdAmlDisassemble ( BOOLEAN GetAllTables); void -AdPrintStatistics (void); +AdPrintStatistics ( + void); ACPI_STATUS AdFindDsdt( @@ -159,7 +159,8 @@ AdFindDsdt( UINT32 *DsdtLength); void -AdDumpTables (void); +AdDumpTables ( + void); ACPI_STATUS AdGetLocalTables ( @@ -179,7 +180,9 @@ AdDisplayTables ( ACPI_TABLE_HEADER *Table); ACPI_STATUS -AdDisplayStatistics (void); +AdDisplayStatistics ( + void); + /* * adwalk @@ -209,6 +212,7 @@ AcpiDmConvertResourceIndexes ( ACPI_PARSE_OBJECT *ParseTreeRoot, ACPI_NAMESPACE_NODE *NamespaceRoot); + /* * adfile */ diff --git a/include/acdebug.h b/include/acdebug.h index dedaa649eae..82f2b6d49c1 100644 --- a/include/acdebug.h +++ b/include/acdebug.h @@ -126,13 +126,19 @@ typedef struct CommandInfo } COMMAND_INFO; - typedef struct ArgumentInfo { char *Name; /* Argument Name */ } ARGUMENT_INFO; +typedef struct acpi_execute_walk +{ + UINT32 Count; + UINT32 MaxCount; + +} ACPI_EXECUTE_WALK; + #define PARAM_LIST(pl) pl #define DBTEST_OUTPUT_LEVEL(lvl) if (AcpiGbl_DbOpt_verbose) @@ -265,7 +271,7 @@ AcpiDbCheckPredefinedNames ( void AcpiDbBatchExecute ( - void); + char *CountArg); /* * dbdisply - debug display commands diff --git a/include/acdisasm.h b/include/acdisasm.h index 50c5f677c78..de198ff5742 100644 --- a/include/acdisasm.h +++ b/include/acdisasm.h @@ -125,18 +125,6 @@ #define BLOCK_COMMA_LIST 4 #define ACPI_DEFAULT_RESNAME *(UINT32 *) "__RD" -typedef struct acpi_external_list -{ - char *Path; - char *InternalPath; - struct acpi_external_list *Next; - UINT32 Value; - UINT16 Length; - UINT8 Type; - -} ACPI_EXTERNAL_LIST; - -extern ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList; typedef const struct acpi_dmtable_info { @@ -475,14 +463,6 @@ void AcpiDmMatchOp ( ACPI_PARSE_OBJECT *Op); -BOOLEAN -AcpiDmCommaIfListMember ( - ACPI_PARSE_OBJECT *Op); - -void -AcpiDmCommaIfFieldMember ( - ACPI_PARSE_OBJECT *Op); - /* * dmnames @@ -555,6 +535,33 @@ AcpiDmIsStringBuffer ( ACPI_PARSE_OBJECT *Op); +/* + * dmextern + */ +void +AcpiDmAddToExternalList ( + ACPI_PARSE_OBJECT *Op, + char *Path, + UINT8 Type, + UINT32 Value); + +void +AcpiDmAddExternalsToNamespace ( + void); + +UINT32 +AcpiDmGetExternalMethodCount ( + void); + +void +AcpiDmClearExternalList ( + void); + +void +AcpiDmEmitExternals ( + void); + + /* * dmresrc */ @@ -589,18 +596,10 @@ ACPI_STATUS AcpiDmIsResourceTemplate ( ACPI_PARSE_OBJECT *Op); -void -AcpiDmIndent ( - UINT32 Level); - void AcpiDmBitList ( UINT16 Mask); -void -AcpiDmDecodeAttribute ( - UINT8 Attribute); - void AcpiDmDescriptorName ( void); @@ -727,10 +726,21 @@ AcpiDmVendorSmallDescriptor ( * dmutils */ void -AcpiDmAddToExternalList ( - char *Path, - UINT8 Type, - UINT32 Value); +AcpiDmDecodeAttribute ( + UINT8 Attribute); + +void +AcpiDmIndent ( + UINT32 Level); + +BOOLEAN +AcpiDmCommaIfListMember ( + ACPI_PARSE_OBJECT *Op); + +void +AcpiDmCommaIfFieldMember ( + ACPI_PARSE_OBJECT *Op); + /* * dmrestag diff --git a/include/acglobal.h b/include/acglobal.h index 42b0d82c9a4..82fe445169d 100644 --- a/include/acglobal.h +++ b/include/acglobal.h @@ -446,6 +446,7 @@ ACPI_EXTERN UINT8 AcpiGbl_DbOutputFlags; ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_disasm; ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_verbose; +ACPI_EXTERN ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList; #endif diff --git a/include/aclocal.h b/include/aclocal.h index b8ea4f14325..52dbec3a6dc 100644 --- a/include/aclocal.h +++ b/include/aclocal.h @@ -1216,6 +1216,29 @@ typedef struct acpi_port_info #define ACPI_ASCII_ZERO 0x30 +/***************************************************************************** + * + * Disassembler + * + ****************************************************************************/ + +typedef struct acpi_external_list +{ + char *Path; + char *InternalPath; + struct acpi_external_list *Next; + UINT32 Value; + UINT16 Length; + UINT8 Type; + UINT8 Flags; + +} ACPI_EXTERNAL_LIST; + +/* Values for Flags field above */ + +#define ACPI_IPATH_ALLOCATED 0x01 + + /***************************************************************************** * * Debugger diff --git a/include/acpixf.h b/include/acpixf.h index 14f9b433811..88135a783bc 100644 --- a/include/acpixf.h +++ b/include/acpixf.h @@ -120,7 +120,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090903 +#define ACPI_CA_VERSION 0x20091013 #include "actypes.h" #include "actbl.h" diff --git a/namespace/nsrepair.c b/namespace/nsrepair.c index ae534264ab0..695a93f5ead 100644 --- a/namespace/nsrepair.c +++ b/namespace/nsrepair.c @@ -118,6 +118,7 @@ #include "acpi.h" #include "accommon.h" #include "acnamesp.h" +#include "acinterp.h" #include "acpredef.h" #define _COMPONENT ACPI_NAMESPACE @@ -153,8 +154,14 @@ AcpiNsRepairObject ( ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_OPERAND_OBJECT *NewObject; ACPI_SIZE Length; + ACPI_STATUS Status; + /* + * At this point, we know that the type of the returned object was not + * one of the expected types for this predefined name. Attempt to + * repair the object. Only a limited number of repairs are possible. + */ switch (ReturnObject->Common.Type) { case ACPI_TYPE_BUFFER: @@ -193,45 +200,101 @@ AcpiNsRepairObject ( */ ACPI_MEMCPY (NewObject->String.Pointer, ReturnObject->Buffer.Pointer, Length); + break; - /* - * If the original object is a package element, we need to: - * 1. Set the reference count of the new object to match the - * reference count of the old object. - * 2. Decrement the reference count of the original object. - */ - if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) + + case ACPI_TYPE_INTEGER: + + /* 1) Does the method/object legally return a buffer? */ + + if (ExpectedBtypes & ACPI_RTYPE_BUFFER) { - NewObject->Common.ReferenceCount = - ReturnObject->Common.ReferenceCount; - - if (ReturnObject->Common.ReferenceCount > 1) + /* + * Convert the Integer to a packed-byte buffer. _MAT needs + * this sometimes, if a read has been performed on a Field + * object that is less than or equal to the global integer + * size (32 or 64 bits). + */ + Status = AcpiExConvertToBuffer (ReturnObject, &NewObject); + if (ACPI_FAILURE (Status)) { - ReturnObject->Common.ReferenceCount--; + return (Status); + } + } + + /* 2) Does the method/object legally return a string? */ + + else if (ExpectedBtypes & ACPI_RTYPE_STRING) + { + /* + * The only supported Integer-to-String conversion is to convert + * an integer of value 0 to a NULL string. The last element of + * _BIF and _BIX packages occasionally need this fix. + */ + if (ReturnObject->Integer.Value != 0) + { + return (AE_AML_OPERAND_TYPE); } - ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, - "Converted Buffer to expected String at index %u", - PackageIndex)); + /* Allocate a new NULL string object */ + + NewObject = AcpiUtCreateStringObject (0); + if (!NewObject) + { + return (AE_NO_MEMORY); + } } else { - ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, - "Converted Buffer to expected String")); + return (AE_AML_OPERAND_TYPE); } + break; - /* Delete old object, install the new return object */ - - AcpiUtRemoveReference (ReturnObject); - *ReturnObjectPtr = NewObject; - Data->Flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); default: - break; + + /* We cannot repair this object */ + + return (AE_AML_OPERAND_TYPE); } - return (AE_AML_OPERAND_TYPE); + /* Object was successfully repaired */ + + /* + * If the original object is a package element, we need to: + * 1. Set the reference count of the new object to match the + * reference count of the old object. + * 2. Decrement the reference count of the original object. + */ + if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) + { + NewObject->Common.ReferenceCount = + ReturnObject->Common.ReferenceCount; + + if (ReturnObject->Common.ReferenceCount > 1) + { + ReturnObject->Common.ReferenceCount--; + } + + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Converted %s to expected %s at index %u", + AcpiUtGetObjectTypeName (ReturnObject), + AcpiUtGetObjectTypeName (NewObject), PackageIndex)); + } + else + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Converted %s to expected %s", + AcpiUtGetObjectTypeName (ReturnObject), + AcpiUtGetObjectTypeName (NewObject))); + } + + /* Delete old object, install the new return object */ + + AcpiUtRemoveReference (ReturnObject); + *ReturnObjectPtr = NewObject; + Data->Flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); } diff --git a/tools/acpisrc/astable.c b/tools/acpisrc/astable.c index 6003fffc29e..33dbc42fcac 100644 --- a/tools/acpisrc/astable.c +++ b/tools/acpisrc/astable.c @@ -281,6 +281,7 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = { {"ACPI_EXCEPTION_HANDLER", SRC_TYPE_SIMPLE}, {"ACPI_EXDUMP_INFO", SRC_TYPE_STRUCT}, {"ACPI_EXECUTE_TYPE", SRC_TYPE_SIMPLE}, + {"ACPI_EXECUTE_WALK", SRC_TYPE_STRUCT}, {"ACPI_EXTERNAL_LIST", SRC_TYPE_STRUCT}, {"ACPI_FADT_INFO", SRC_TYPE_STRUCT}, {"ACPI_FADT_PM_INFO", SRC_TYPE_STRUCT}, diff --git a/tools/acpixtract/acpixtract.c b/tools/acpixtract/acpixtract.c index 324db12c92f..01b77802b69 100644 --- a/tools/acpixtract/acpixtract.c +++ b/tools/acpixtract/acpixtract.c @@ -119,20 +119,20 @@ #include #include -#define VERSION 0x20060324 +/* Note: This is a 32-bit program only */ + +#define VERSION 0x20091002 #define FIND_HEADER 0 #define EXTRACT_DATA 1 #define BUFFER_SIZE 256 -char Filename[16]; -unsigned char Data[16]; /* Local prototypes */ void CheckAscii ( - unsigned char *Name, + char *Name, int Count); void @@ -174,6 +174,20 @@ DisplayUsage ( void); +typedef struct acpi_table_header +{ + char Signature[4]; + int Length; + unsigned char Revision; + unsigned char Checksum; + char OemId[6]; + char OemTableId[8]; + int OemRevision; + char AslCompilerId[4]; + int AslCompilerRevision; + +} ACPI_TABLE_HEADER; + struct TableInfo { unsigned int Signature; @@ -183,6 +197,8 @@ struct TableInfo }; struct TableInfo *ListHead = NULL; +char Filename[16]; +unsigned char Data[16]; /****************************************************************************** @@ -226,7 +242,7 @@ DisplayUsage ( void CheckAscii ( - unsigned char *Name, + char *Name, int Count) { int i; @@ -246,7 +262,7 @@ CheckAscii ( * * FUNCTION: NormalizeSignature * - * PARAMETERS: Name - Ascii string + * PARAMETERS: Name - Ascii string containing an ACPI signature * * RETURN: None * @@ -270,6 +286,11 @@ NormalizeSignature ( * * FUNCTION: ConvertLine * + * PARAMETERS: InputLine - One line from the input acpidump file + * OutputData - Where the converted data is returned + * + * RETURN: The number of bytes actually converted + * * DESCRIPTION: Convert one line of ascii text binary (up to 16 bytes) * ******************************************************************************/ @@ -290,7 +311,7 @@ ConvertLine ( End = strstr (InputLine + 2, " "); if (!End) { - return 0; /* Don't understand the format */ + return (0); /* Don't understand the format */ } *End = 0; @@ -323,7 +344,12 @@ ConvertLine ( * * FUNCTION: GetTableHeader * - * DESCRIPTION: Extract and convert a table heaader + * PARAMETERS: InputFile - Handle for the input acpidump file + * OutputData - Where the table header is returned + * + * RETURN: The actual number of bytes converted + * + * DESCRIPTION: Extract and convert an ACPI table header * ******************************************************************************/ @@ -344,7 +370,7 @@ GetTableHeader ( { if (!fgets (Buffer, BUFFER_SIZE, InputFile)) { - return TotalConverted; + return (TotalConverted); } BytesConverted = ConvertLine (Buffer, OutputData); @@ -353,11 +379,11 @@ GetTableHeader ( if (BytesConverted != 16) { - return TotalConverted; + return (TotalConverted); } } - return TotalConverted; + return (TotalConverted); } @@ -365,7 +391,13 @@ GetTableHeader ( * * FUNCTION: CountTableInstances * - * DESCRIPTION: Count the instances of table within the input file + * PARAMETERS: InputPathname - Filename for acpidump file + * Signature - Requested signature to count + * + * RETURN: The number of instances of the signature + * + * DESCRIPTION: Count the instances of tables with the given signature within + * the input acpidump file. * ******************************************************************************/ @@ -383,7 +415,7 @@ CountTableInstances ( if (!InputFile) { printf ("Could not open %s\n", InputPathname); - return 0; + return (0); } /* Count the number of instances of this signature */ @@ -406,7 +438,7 @@ CountTableInstances ( } fclose (InputFile); - return Instances; + return (Instances); } @@ -414,7 +446,16 @@ CountTableInstances ( * * FUNCTION: GetNextInstance * - * DESCRIPTION: + * PARAMETERS: InputPathname - Filename for acpidump file + * Signature - Requested ACPI signature + * + * RETURN: The next instance number for this signature. Zero if this + * is the first instance of this signature. + * + * DESCRIPTION: Get the next instance number of the specified table. If this + * is the first instance of the table, create a new instance + * block. Note: only SSDT and PSDT tables can have multiple + * instances. * ******************************************************************************/ @@ -439,12 +480,18 @@ GetNextInstance ( if (!Info) { + /* Signature not found, create new table info block */ + Info = malloc (sizeof (struct TableInfo)); + if (!Info) + { + printf ("Could not allocate memory\n"); + exit (0); + } Info->Signature = *(unsigned int *) Signature; Info->Instances = CountTableInstances (InputPathname, Signature); Info->NextInstance = 1; - Info->Next = ListHead; ListHead = Info; } @@ -462,6 +509,13 @@ GetNextInstance ( * * FUNCTION: ExtractTables * + * PARAMETERS: InputPathname - Filename for acpidump file + * Signature - Requested ACPI signature to extract. + * NULL means extract ALL tables. + * MinimumInstances - Min instances that are acceptable + * + * RETURN: Status + * * DESCRIPTION: Convert text ACPI tables to binary * ******************************************************************************/ @@ -483,6 +537,7 @@ ExtractTables ( unsigned int Instances = 0; unsigned int ThisInstance; char ThisSignature[4]; + int Status = 0; /* Open input in text mode, output is in binary mode */ @@ -491,7 +546,7 @@ ExtractTables ( if (!InputFile) { printf ("Could not open %s\n", InputPathname); - return -1; + return (-1); } if (Signature) @@ -504,12 +559,13 @@ ExtractTables ( if (Instances < MinimumInstances) { printf ("Table %s was not found in %s\n", Signature, InputPathname); - return -1; + Status = -1; + goto CleanupAndExit; } if (Instances == 0) { - return 0; + goto CleanupAndExit; } } @@ -542,8 +598,10 @@ ExtractTables ( } } - /* Get the instance # for this signature */ - + /* + * Get the instance number for this signature. Only the + * SSDT and PSDT tables can have multiple instances. + */ ThisInstance = GetNextInstance (InputPathname, ThisSignature); /* Build an output filename and create/open the output file */ @@ -561,7 +619,8 @@ ExtractTables ( if (!OutputFile) { printf ("Could not open %s\n", Filename); - return -1; + Status = -1; + goto CleanupAndExit; } State = EXTRACT_DATA; @@ -580,7 +639,7 @@ ExtractTables ( OutputFile = NULL; State = FIND_HEADER; - printf ("Acpi table [%4.4s] - % 6d bytes written to %s\n", + printf ("Acpi table [%4.4s] - % 7d bytes written to %s\n", ThisSignature, TotalBytesWritten, Filename); continue; } @@ -596,14 +655,17 @@ ExtractTables ( { printf ("Write error on %s\n", Filename); fclose (OutputFile); - return -1; + OutputFile = NULL; + Status = -1; + goto CleanupAndExit; } TotalBytesWritten += BytesConverted; continue; default: - return -1; + Status = -1; + goto CleanupAndExit; } } @@ -612,6 +674,9 @@ ExtractTables ( printf ("Table %s was not found in %s\n", Signature, InputPathname); } + +CleanupAndExit: + if (OutputFile) { fclose (OutputFile); @@ -619,13 +684,13 @@ ExtractTables ( { /* Received an EOF while extracting data */ - printf ("Acpi table [%4.4s] - % 6d bytes written to %s\n", + printf ("Acpi table [%4.4s] - % 7d bytes written to %s\n", ThisSignature, TotalBytesWritten, Filename); } } fclose (InputFile); - return 0; + return (Status); } @@ -633,7 +698,12 @@ ExtractTables ( * * FUNCTION: ListTables * - * DESCRIPTION: Display info for all ACPI tables found in input + * PARAMETERS: InputPathname - Filename for acpidump file + * + * RETURN: Status + * + * DESCRIPTION: Display info for all ACPI tables found in input. Does not + * perform an actual extraction of the tables. * ******************************************************************************/ @@ -646,6 +716,7 @@ ListTables ( size_t HeaderSize; unsigned char Header[48]; int TableCount = 0; + ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) Header; /* Open input in text mode, output is in binary mode */ @@ -654,10 +725,13 @@ ListTables ( if (!InputFile) { printf ("Could not open %s\n", InputPathname); - return -1; + return (-1); } - printf ("\nSignature Length OemId OemTableId OemRevision CompilerId CompilerRevision\n\n"); + /* Dump the headers for all tables found in the input file */ + + printf ("\nSignature Length Revision OemId OemTableId" + " OemRevision CompilerId CompilerRevision\n\n"); while (fgets (Buffer, BUFFER_SIZE, InputFile)) { @@ -679,15 +753,15 @@ ListTables ( /* RSDP has an oddball signature and header */ - if (!strncmp ((char *) Header, "RSD PTR ", 8)) + if (!strncmp (TableHeader->Signature, "RSD PTR ", 8)) { - CheckAscii (&Header[9], 6); - printf ("%8.4s \"%6.6s\"\n", "RSDP", &Header[9]); + CheckAscii ((char *) &Header[9], 6); + printf ("%8.4s \"%6.6s\"\n", "RSDP", &Header[9]); TableCount++; continue; } - /* Minimum size */ + /* Minimum size for table with standard header */ if (HeaderSize < 36) { @@ -697,11 +771,11 @@ ListTables ( /* Signature and Table length */ TableCount++; - printf ("%8.4s % 7d", Header, *(int *) &Header[4]); + printf ("%8.4s % 7d", TableHeader->Signature, TableHeader->Length); /* FACS has only signature and length */ - if (!strncmp ((char *) Header, "FACS", 4)) + if (!strncmp (TableHeader->Signature, "FACS", 4)) { printf ("\n"); continue; @@ -709,18 +783,19 @@ ListTables ( /* OEM IDs and Compiler IDs */ - CheckAscii (&Header[10], 6); - CheckAscii (&Header[16], 8); - CheckAscii (&Header[28], 4); + CheckAscii (TableHeader->OemId, 6); + CheckAscii (TableHeader->OemTableId, 8); + CheckAscii (TableHeader->AslCompilerId, 4); - printf (" \"%6.6s\" \"%8.8s\" %8.8X \"%4.4s\" %8.8X\n", - &Header[10], &Header[16], *(int *) &Header[24], - &Header[28], *(int *) &Header[32]); + printf (" %2.2X \"%6.6s\" \"%8.8s\" %8.8X \"%4.4s\" %8.8X\n", + TableHeader->Revision, TableHeader->OemId, + TableHeader->OemTableId, TableHeader->OemRevision, + TableHeader->AslCompilerId, TableHeader->AslCompilerRevision); } printf ("\nFound %d ACPI tables [%8.8X]\n", TableCount, VERSION); fclose (InputFile); - return 0; + return (0); } @@ -743,7 +818,7 @@ main ( if (argc < 2) { DisplayUsage (); - return 0; + return (0); } if (argv[1][0] == '-') @@ -751,23 +826,32 @@ main ( if (argc < 3) { DisplayUsage (); - return 0; + return (0); } switch (argv[1][1]) { case 'a': + + /* Extract all tables found */ + return (ExtractTables (argv[2], NULL, 0)); case 'l': + + /* List tables only, do not extract */ + return (ListTables (argv[2])); case 's': + + /* Extract only tables with this signature */ + return (ExtractTables (argv[2], &argv[1][2], 1)); default: DisplayUsage (); - return 0; + return (0); } } @@ -778,7 +862,7 @@ main ( Status = ExtractTables (argv[1], "DSDT", 1); if (Status) { - return Status; + return (Status); } Status = ExtractTables (argv[1], "SSDT", 0); diff --git a/utilities/utglobal.c b/utilities/utglobal.c index b61b3fb5ba0..b49ce352fbc 100644 --- a/utilities/utglobal.c +++ b/utilities/utglobal.c @@ -949,6 +949,10 @@ AcpiUtInitGlobals ( AcpiGbl_RootNodeStruct.Flags = ANOBJ_END_OF_PEER_LIST; +#ifdef ACPI_DISASSEMBLER + AcpiGbl_ExternalList = NULL; +#endif + #ifdef ACPI_DEBUG_OUTPUT AcpiGbl_LowestStackPointer = ACPI_CAST_PTR (ACPI_SIZE, ACPI_SIZE_MAX); #endif From 5c3743e3bb9c564d48b54be00b9c6e3852b33b02 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 13 Oct 2009 21:51:50 +0000 Subject: [PATCH 157/646] ls: Make -p not inhibit following symlinks. According to the man page, when neither -H/-L nor -F/-d/-l are given, -H is implied. This agrees with POSIX, GNU ls and Solaris ls. This means that -p, although it is very similar to -F, does not prevent the implicit following of symlinks. PR: standards/128546 --- bin/ls/ls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 644bc96eb5f..5338071fa54 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -399,7 +399,7 @@ main(int argc, char *argv[]) * If not -F, -d or -l options, follow any symbolic links listed on * the command line. */ - if (!f_longform && !f_listdir && !f_type) + if (!f_longform && !f_listdir && (!f_type || f_slash)) fts_options |= FTS_COMFOLLOW; /* From 382e8b5ad90782db8f6eabd30ca9ee17309eb800 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 14 Oct 2009 11:55:55 +0000 Subject: [PATCH 158/646] Unbreak the VIMAGE build with IPSEC, broken with r197952 by virtualizing the pfil hooks. For consistency add the V_ to virtualize the pfil hooks in here as well. MFC after: 55 days X-MFC after: julian MFCed r197952. --- sys/net/if_enc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c index a49c5dc5b23..b1fc0383a46 100644 --- a/sys/net/if_enc.c +++ b/sys/net/if_enc.c @@ -243,9 +243,9 @@ ipsec_filter(struct mbuf **mp, int dir, int flags) } /* Skip pfil(9) if no filters are loaded */ - if (!(PFIL_HOOKED(&inet_pfil_hook) + if (!(PFIL_HOOKED(&V_inet_pfil_hook) #ifdef INET6 - || PFIL_HOOKED(&inet6_pfil_hook) + || PFIL_HOOKED(&V_inet6_pfil_hook) #endif )) { return (0); @@ -271,7 +271,7 @@ ipsec_filter(struct mbuf **mp, int dir, int flags) ip->ip_len = ntohs(ip->ip_len); ip->ip_off = ntohs(ip->ip_off); - error = pfil_run_hooks(&inet_pfil_hook, mp, + error = pfil_run_hooks(&V_inet_pfil_hook, mp, encif, dir, NULL); if (*mp == NULL || error != 0) @@ -285,7 +285,7 @@ ipsec_filter(struct mbuf **mp, int dir, int flags) #ifdef INET6 case 6: - error = pfil_run_hooks(&inet6_pfil_hook, mp, + error = pfil_run_hooks(&V_inet6_pfil_hook, mp, encif, dir, NULL); break; #endif From 14c129fc3e42d91b1b75348e6307614f01535843 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 14 Oct 2009 12:01:11 +0000 Subject: [PATCH 159/646] Explicitly compare to a return code. Discussed with: philip (after we both misread the logic there the 1st time) MFC after: 6 weeks --- sys/netinet6/icmp6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 04810c36273..ae52f1193bd 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -870,7 +870,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) break; } deliver: - if (icmp6_notify_error(&m, off, icmp6len, code)) { + if (icmp6_notify_error(&m, off, icmp6len, code) != 0) { /* In this case, m should've been freed. */ return (IPPROTO_DONE); } From a944fb4cc3de366d852a7b4b8d8226650bbb950f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 14 Oct 2009 14:13:42 +0000 Subject: [PATCH 160/646] Use zfs_read() instead of xfsread() to read /boot.config. xfsread() fails short read requests, so the result was that a /boot.config smaller than 512 bytes was ignored. boot2 uses fsread() instead of xfsread() to read /boot.config already, so this makes zfsboot more like boot2. Submitted by: Johny Mattsson johny-freebsd of earthmagic org Reviewed by: dfr MFC after: 3 days --- sys/boot/i386/zfsboot/zfsboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index ca035683dd7..a654393f184 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -609,7 +609,7 @@ main(void) if (zfs_lookup(spa, PATH_CONFIG, &dn) == 0) { off = 0; - xfsread(&dn, &off, cmd, sizeof(cmd)); + zfs_read(spa, &dn, &off, cmd, sizeof(cmd)); } if (*cmd) { From 27831515704103a1cdecaf2c7f595b86c7a289d9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 14 Oct 2009 15:58:59 +0000 Subject: [PATCH 161/646] Add a manual page for BUS_BIND_INTR() and bus_bind_intr(). MFC after: 1 week --- share/man/man9/BUS_BIND_INTR.9 | 96 ++++++++++++++++++++++++++++++++++ share/man/man9/Makefile | 2 + 2 files changed, 98 insertions(+) create mode 100644 share/man/man9/BUS_BIND_INTR.9 diff --git a/share/man/man9/BUS_BIND_INTR.9 b/share/man/man9/BUS_BIND_INTR.9 new file mode 100644 index 00000000000..93f0c1600f0 --- /dev/null +++ b/share/man/man9/BUS_BIND_INTR.9 @@ -0,0 +1,96 @@ +.\" -*- nroff -*- +.\" +.\" Copyright (c) 2009 Advanced Computing Technologies LLC +.\" Written by: John H. Baldwin +.\" 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 October 14, 2009 +.Dt BUS_BIND_INTR 9 +.Os +.Sh NAME +.Nm BUS_BIND_INTR , +.Nm bus_bind_intr +.Nd "bind an interrupt resource to a specific CPU" +.Sh SYNOPSIS +.In sys/param.h +.In sys/bus.h +.Ft int +.Fo BUS_BIND_INTR +.Fa "device_t dev" "device_t child" "struct resource *irq" "int cpu" +.Fc +.Ft int +.Fn bus_bind_intr "device_t dev" "struct resource *irq" "int cpu" +.Sh DESCRIPTION +The +.Fn BUS_BIND_INTR +method allows an interrupt resource to be pinned to a specific CPU. +The interrupt resource must have an interrupt handler attached via +.Xr BUS_SETUP_INTR 9 . +The +.Fa cpu +parameter corresponds to the ID of a valid CPU in the system. +Binding an interrupt restricts the +.Xr cpuset 2 +of any associated interrupt threads to only include the specified CPU. +It may also direct the low-level interrupt handling of the interrupt to the +specified CPU as well, +but this behavior is platform-dependent. +If the value +.Dv NOCPU +is used for +.Fa cpu , +then the interrupt will be +.Dq unbound +which restores any associated interrupt threads back to the default cpuset. +.Pp +Non-sleepable locks such as mutexes should not be held across calls to these +functions. +.Pp +The +.Fn bus_bind_intr +function is a simple wrapper around +.Fn BUS_BIND_INTR . +.Pp +Note that currently there is no attempt made to arbitrate between +multiple bind requests for the same interrupt from either the same +device or multiple devices. +There is also no arbitration between interrupt binding requests submitted +by userland via +.Xr cpuset 2 +and +.Fn BUS_BIND_INTR . +The most recent binding request is the one that will be in effect. +.Sh SEE ALSO +.Xr BUS_SETUP_INTR 9 , +.Xr cpuset 2 , +.Xr device 9 +.Sh HISTORY +The +.Fn BUS_BIND_INTR +method and +.Fn bus_bind_intr +functions first appeared in +.Fx 7.2 . diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 2b1969d50ba..ae8b55f485e 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -23,6 +23,7 @@ MAN= accept_filter.9 \ bus_activate_resource.9 \ BUS_ADD_CHILD.9 \ bus_alloc_resource.9 \ + BUS_BIND_INTR.9 \ bus_child_present.9 \ BUS_CONFIG_INTR.9 \ bus_dma.9 \ @@ -403,6 +404,7 @@ MLINKS+=bpf.9 bpf_filter.9 \ MLINKS+=buf.9 bp.9 MLINKS+=bus_activate_resource.9 bus_deactivate_resource.9 MLINKS+=bus_alloc_resource.9 bus_alloc_resource_any.9 +MLINKS+=BUS_BIND_INTR.9 bus_bind_intr.9 MLINKS+=bus_dma.9 busdma.9 \ bus_dma.9 bus_dmamap_create.9 \ bus_dma.9 bus_dmamap_destroy.9 \ From 38d3501a8e2a970c5a06a80b8d7af75897d2c568 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 14 Oct 2009 16:00:20 +0000 Subject: [PATCH 162/646] Oops, add a return values section to note that these routines return an error on failure or zero on success. --- share/man/man9/BUS_BIND_INTR.9 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/man/man9/BUS_BIND_INTR.9 b/share/man/man9/BUS_BIND_INTR.9 index 93f0c1600f0..2e22dea9ae1 100644 --- a/share/man/man9/BUS_BIND_INTR.9 +++ b/share/man/man9/BUS_BIND_INTR.9 @@ -83,6 +83,8 @@ by userland via and .Fn BUS_BIND_INTR . The most recent binding request is the one that will be in effect. +.Sh RETURN VALUES +Zero is returned on success, otherwise an appropriate error is returned. .Sh SEE ALSO .Xr BUS_SETUP_INTR 9 , .Xr cpuset 2 , From e80d42dda2602799d64b157454aa365f02fa3946 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 14 Oct 2009 19:24:01 +0000 Subject: [PATCH 163/646] Set the active flag in the PMBR when we install bootcode on a GPT partitioned disk. Some BIOS require this to be set before they will boot the device. Approved by: marcel MFC after: 2 weeks --- sys/geom/part/g_part_gpt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index 61f9c7aa257..f62b46774f5 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -382,6 +382,9 @@ g_part_gpt_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp) codesz = MIN(codesz, gpp->gpp_codesize); if (codesz > 0) bcopy(gpp->gpp_codeptr, table->mbr, codesz); + + /* Mark the PMBR active since some BIOS require it */ + table->mbr[DOSPARTOFF] = 0x80; /* status */ return (0); } From db63fc93ccf306dffd2b2f855358da211aa2389e Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Wed, 14 Oct 2009 20:09:09 +0000 Subject: [PATCH 164/646] fixes a TX hang bug that it could happen when if_start callback didn't be restarted by full of the output queue. MFC after: 3 days Tested by: bsduser --- sys/dev/usb/wlan/if_rum.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 7abd10473f5..e7c387c5fa7 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -826,6 +826,9 @@ tr_setup: usbd_transfer_submit(xfer); } + RUM_UNLOCK(sc); + rum_start(ifp); + RUM_LOCK(sc); break; default: /* Error */ @@ -930,8 +933,8 @@ tr_setup: * the private mutex of a device! That is why we do the * "ieee80211_input" here, and not some lines up! */ + RUM_UNLOCK(sc); if (m) { - RUM_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { @@ -941,8 +944,11 @@ tr_setup: } else (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR); - RUM_LOCK(sc); } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + rum_start(ifp); + RUM_LOCK(sc); return; default: /* Error */ From 941da6d392a037a1e43942f20d6b2512bbea00c7 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Wed, 14 Oct 2009 20:30:27 +0000 Subject: [PATCH 165/646] fixes a TX hang that could be possible to happen when the trasfers are in the high speed that some drivers don't call if_start callback after marking ~IFF_DRV_OACTIVE. MFC after: 3 days --- sys/dev/usb/wlan/if_uath.c | 3 +++ sys/dev/usb/wlan/if_upgt.c | 3 +++ sys/dev/usb/wlan/if_ural.c | 10 ++++++++-- sys/dev/usb/wlan/if_urtw.c | 3 +++ sys/dev/usb/wlan/if_zyd.c | 6 ++++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index ca9beb36c59..686f9b629e9 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -2762,6 +2762,9 @@ setup: m = NULL; desc = NULL; } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + uath_start(ifp); UATH_LOCK(sc); break; default: diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index c04c3985b5b..67e6980701b 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -2291,6 +2291,9 @@ setup: (void) ieee80211_input_all(ic, m, rssi, nf); m = NULL; } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + upgt_start(ifp); UPGT_LOCK(sc); break; default: diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index f9a90a2a7b7..c2e6d75a68d 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -837,6 +837,9 @@ tr_setup: usbd_transfer_submit(xfer); } + RAL_UNLOCK(sc); + ural_start(ifp); + RAL_LOCK(sc); break; default: /* Error */ @@ -945,8 +948,8 @@ tr_setup: * the private mutex of a device! That is why we do the * "ieee80211_input" here, and not some lines up! */ + RAL_UNLOCK(sc); if (m) { - RAL_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { @@ -954,8 +957,11 @@ tr_setup: ieee80211_free_node(ni); } else (void) ieee80211_input_all(ic, m, rssi, nf); - RAL_LOCK(sc); } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + ural_start(ifp); + RAL_LOCK(sc); return; default: /* Error */ diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 391a32c3942..2c8b7c20ba5 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -4072,6 +4072,9 @@ setup: (void) ieee80211_input_all(ic, m, rssi, nf); m = NULL; } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + urtw_start(ifp); URTW_LOCK(sc); break; default: diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 493c5fad16a..6fa07c7af2f 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -2322,6 +2322,9 @@ tr_setup: } else (void)ieee80211_input_all(ic, m, rssi, nf); } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + zyd_start(ifp); ZYD_LOCK(sc); break; @@ -2431,6 +2434,9 @@ tr_setup: usbd_xfer_set_priv(xfer, data); usbd_transfer_submit(xfer); } + ZYD_UNLOCK(sc); + zyd_start(ifp); + ZYD_LOCK(sc); break; default: /* Error */ From 93704ac5d738d1ba176f56af8a95c37aca69850e Mon Sep 17 00:00:00 2001 From: Qing Li Date: Thu, 15 Oct 2009 06:12:04 +0000 Subject: [PATCH 166/646] This patch fixes the following issues in the ARP operation: 1. There is a regression issue in the ARP code. The incomplete ARP entry was timing out too quickly (1 second timeout), as such, a new entry is created each time arpresolve() is called. Therefore the maximum attempts made is always 1. Consequently the error code returned to the application is always 0. 2. Set the expiration of each incomplete entry to a 20-second lifetime. 3. Return "incomplete" entries to the application. Reviewed by: kmacy MFC after: 3 days --- sys/netinet/if_ether.c | 17 ++++++++++------- sys/netinet/in.c | 11 ++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index be6292161c2..45cee89ff72 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -88,11 +88,14 @@ VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for /* timer values */ static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20 * minutes */ +static VNET_DEFINE(int, arpt_down) = 20; /* keep incomplete entries for + * 20 seconds */ static VNET_DEFINE(int, arp_maxtries) = 5; static VNET_DEFINE(int, arp_proxyall); static VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */ #define V_arpt_keep VNET(arpt_keep) +#define V_arpt_down VNET(arpt_down) #define V_arp_maxtries VNET(arp_maxtries) #define V_arp_proxyall VNET(arp_proxyall) #define V_arpstat VNET(arpstat) @@ -309,7 +312,7 @@ retry: } if ((la->la_flags & LLE_VALID) && - ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { + ((la->la_flags & LLE_STATIC) || la->la_expire > time_second)) { bcopy(&la->ll_addr, desten, ifp->if_addrlen); /* * If entry has an expiry time and it is approaching, @@ -317,7 +320,7 @@ retry: * arpt_down interval. */ if (!(la->la_flags & LLE_STATIC) && - time_uptime + la->la_preempt > la->la_expire) { + time_second + la->la_preempt > la->la_expire) { arprequest(ifp, NULL, &SIN(dst)->sin_addr, IF_LLADDR(ifp)); @@ -337,7 +340,7 @@ retry: goto done; } - renew = (la->la_asked == 0 || la->la_expire != time_uptime); + renew = (la->la_asked == 0 || la->la_expire != time_second); if ((renew || m != NULL) && (flags & LLE_EXCLUSIVE) == 0) { flags |= LLE_EXCLUSIVE; LLE_RUNLOCK(la); @@ -370,12 +373,12 @@ retry: error = EWOULDBLOCK; /* First request. */ else error = - (rt0->rt_flags & RTF_GATEWAY) ? EHOSTDOWN : EHOSTUNREACH; + (rt0->rt_flags & RTF_GATEWAY) ? EHOSTUNREACH : EHOSTDOWN; if (renew) { LLE_ADDREF(la); - la->la_expire = time_uptime; - callout_reset(&la->la_timer, hz, arptimer, la); + la->la_expire = time_second; + callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la); la->la_asked++; LLE_WUNLOCK(la); arprequest(ifp, NULL, &SIN(dst)->sin_addr, @@ -687,7 +690,7 @@ match: EVENTHANDLER_INVOKE(arp_update_event, la); if (!(la->la_flags & LLE_STATIC)) { - la->la_expire = time_uptime + V_arpt_keep; + la->la_expire = time_second + V_arpt_keep; callout_reset(&la->la_timer, hz * V_arpt_keep, arptimer, la); } diff --git a/sys/netinet/in.c b/sys/netinet/in.c index dc4a8e1eb46..c124513558c 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1440,7 +1440,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr) struct sockaddr_dl *sdl; /* skip deleted entries */ - if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID) + if ((lle->la_flags & LLE_DELETED) == LLE_DELETED) continue; /* Skip if jailed and not a valid IP of the prison. */ if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0) @@ -1472,10 +1472,15 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr) sdl = &arpc.sdl; sdl->sdl_family = AF_LINK; sdl->sdl_len = sizeof(*sdl); - sdl->sdl_alen = ifp->if_addrlen; sdl->sdl_index = ifp->if_index; sdl->sdl_type = ifp->if_type; - bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen); + if ((lle->la_flags & LLE_VALID) == LLE_VALID) { + sdl->sdl_alen = ifp->if_addrlen; + bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen); + } else { + sdl->sdl_alen = 0; + bzero(LLADDR(sdl), ifp->if_addrlen); + } arpc.rtm.rtm_rmx.rmx_expire = lle->la_flags & LLE_STATIC ? 0 : lle->la_expire; From 9a7ee195f5f6fbca83d1b850bbc492cd87d1ca07 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Thu, 15 Oct 2009 07:58:01 +0000 Subject: [PATCH 167/646] Bump version numbers and update descriptions for the 9-CURRENT world. The %[no]include.historic knobs are removed because they are not used for a long time. --- release/doc/README | 7 ++-- .../doc/en_US.ISO8859-1/errata/article.sgml | 1 - release/doc/share/mk/doc.relnotes.mk | 17 -------- release/doc/share/sgml/release.dsl | 41 ------------------- release/doc/share/sgml/release.ent | 17 ++++---- 5 files changed, 12 insertions(+), 71 deletions(-) diff --git a/release/doc/README b/release/doc/README index 6ed0291f225..b57b10a671d 100644 --- a/release/doc/README +++ b/release/doc/README @@ -99,9 +99,10 @@ element will be included. For example: SPARC64-specific text -The currently-supported architectures are i386, sparc64, and -ia64. An element may appear for multiple architectures by specifying -a comma-separated list of architectures (i.e. arch="sparc64,ia64"). +The currently-supported architectures are amd64, arm, i386, ia64, +pc98, powerpc, and sparc64. An element may appear for multiple +architectures by specifying a comma-separated list of architectures +(i.e. arch="sparc64,ia64"). When creating a translation, make a new directory under this directory with a language code (paralleling the DocProj directory diff --git a/release/doc/en_US.ISO8859-1/errata/article.sgml b/release/doc/en_US.ISO8859-1/errata/article.sgml index a765881d722..edb454306b7 100644 --- a/release/doc/en_US.ISO8859-1/errata/article.sgml +++ b/release/doc/en_US.ISO8859-1/errata/article.sgml @@ -16,7 +16,6 @@ %release; - ]>
diff --git a/release/doc/share/mk/doc.relnotes.mk b/release/doc/share/mk/doc.relnotes.mk index 95d1e495787..d05e35923ea 100644 --- a/release/doc/share/mk/doc.relnotes.mk +++ b/release/doc/share/mk/doc.relnotes.mk @@ -10,23 +10,6 @@ EXTRA_CATALOGS+= ${RELN_ROOT}/share/sgml/catalog DSLHTML?= ${RELN_ROOT}/share/sgml/default.dsl DSLPRINT?= ${RELN_ROOT}/share/sgml/default.dsl -# -# Tweakable Makefile variables -# -# INCLUDE_HISTORIC Used by relnotes document only. When set, -# causes all release notes entries to be printed, -# even those marked as "historic". If not set -# (the default), only print "non-historic" -# release note entries. To designate a release -# note entry as "historic", add a role="historic" -# attribute to the applicable element(s). -# -.if defined(INCLUDE_HISTORIC) -JADEFLAGS+= -iinclude.historic -.else -JADEFLAGS+= -ino.include.historic -.endif - # # Automatic device list generation: # diff --git a/release/doc/share/sgml/release.dsl b/release/doc/share/sgml/release.dsl index dd6ac3e1dfe..66e9ae24a41 100644 --- a/release/doc/share/sgml/release.dsl +++ b/release/doc/share/sgml/release.dsl @@ -3,8 +3,6 @@ - - %release.ent; @@ -14,14 +12,6 @@ -; Configure behavior of this stylesheet - - - ; String manipulation functions (define (split-string-to-list STR) ;; return list of STR separated with char #\ or #\, @@ -54,36 +44,6 @@ ((equal? STR (car s)) #t) (else (loop (cdr s)))))) -; Deal with conditional inclusion of text via entities. -(default - (let* ((role (attribute-string (normalize "role"))) - (for-arch (entity-text "arch"))) - (cond - - ;; If role=historic, and we're not printing historic things, then - ;; don't output this element. - ((and (equal? role "historic") - (not %include-historic%)) - (empty-sosofo)) - - ;; None of the above - (else (next-match))))) - -(mode qandatoc - (default - (let* ((role (attribute-string (normalize "role"))) - (for-arch (entity-text "arch"))) - (cond - - ;; If role=historic, and we're not printing historic things, then - ;; don't output this element. - ((and (equal? role "historic") - (not %include-historic%)) - (empty-sosofo)) - - ;; None of the above - (else (next-match)))))) - ; We might have some sect1 level elements where the modification times ; are significant. An example of this is the "What's New" section in ; the release notes. We enable the printing of pubdate entry in @@ -198,7 +158,6 @@ (u (string-append "&release.man.url;?query=" (data r) "&" "sektion=" (data m)))) (case v - (("xfree86") (string-append u "&" "manpath=XFree86+&release.manpath.xfree86;" )) (("xorg") (string-append u "&" "manpath=Xorg+&release.manpath.xorg;" )) (("netbsd") (string-append u "&" "manpath=NetBSD+&release.manpath.netbsd;")) (("ports") (string-append u "&" "manpath=FreeBSD+&release.manpath.freebsd-ports;")) diff --git a/release/doc/share/sgml/release.ent b/release/doc/share/sgml/release.ent index 03017d58994..c6a60dc465f 100644 --- a/release/doc/share/sgml/release.ent +++ b/release/doc/share/sgml/release.ent @@ -6,23 +6,23 @@ - + - + - + - + - + @@ -36,11 +36,10 @@ - - - + + - + From c8359dde47baffd9559076d194e6aadc4b4bac4e Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 15 Oct 2009 10:31:24 +0000 Subject: [PATCH 168/646] Print routing statistics as unsigned short rather than unsigned int, otherwise sign extension leads to unlikely values when in the negative range of the signed short structure fields that hold the statistics. The type used to hold routing statistics is arguably also incorrect. MFC after: 3 days --- usr.bin/netstat/route.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 735612b867a..2e9e919f109 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -1008,11 +1008,11 @@ rt_stats(u_long rtsaddr, u_long rttaddr) #define p(f, m) if (rtstat.f || sflag <= 1) \ printf(m, rtstat.f, plural(rtstat.f)) - p(rts_badredirect, "\t%u bad routing redirect%s\n"); - p(rts_dynamic, "\t%u dynamically created route%s\n"); - p(rts_newgateway, "\t%u new gateway%s due to redirects\n"); - p(rts_unreach, "\t%u destination%s found unreachable\n"); - p(rts_wildcard, "\t%u use%s of a wildcard route\n"); + p(rts_badredirect, "\t%hu bad routing redirect%s\n"); + p(rts_dynamic, "\t%hu dynamically created route%s\n"); + p(rts_newgateway, "\t%hu new gateway%s due to redirects\n"); + p(rts_unreach, "\t%hu destination%s found unreachable\n"); + p(rts_wildcard, "\t%hu use%s of a wildcard route\n"); #undef p if (rttrash || sflag <= 1) From a2ef0aff1043408d2edf7ae3eb9a8e5187a9b9f6 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 15 Oct 2009 11:32:05 +0000 Subject: [PATCH 169/646] Use our standard section 4 SYNOPSIS. MFC after: 3 days --- share/man/man4/sbp_targ.4 | 20 ++++++++++++++------ share/man/man4/targ.4 | 7 ++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/share/man/man4/sbp_targ.4 b/share/man/man4/sbp_targ.4 index 11283807483..f9c58ef366c 100644 --- a/share/man/man4/sbp_targ.4 +++ b/share/man/man4/sbp_targ.4 @@ -38,16 +38,24 @@ .Nm sbp_targ .Nd Serial Bus Protocol 2 (SBP-2) Target Mode devices driver .Sh SYNOPSIS -.Cd "kldload firewire" -.Cd "kldload cam" -.Cd "kldload sbp_targ" -.Pp -or -.Pp +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent .Cd "device sbp_targ" .Cd "device firewire" .Cd "device scbus" .Cd "device targ" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following lines in +.Xr loader.conf 5 : +.Bd -literal -offset indent +firewire_load="YES" +cam_load="YES" +sbp_targ_load"YES" +.Ed .Sh DESCRIPTION The .Nm diff --git a/share/man/man4/targ.4 b/share/man/man4/targ.4 index a1fa449d0f0..9bb376277f2 100644 --- a/share/man/man4/targ.4 +++ b/share/man/man4/targ.4 @@ -31,7 +31,12 @@ .Nm targ .Nd SCSI target emulator driver .Sh SYNOPSIS -.Cd device targ +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device targ" +.Ed .Sh DESCRIPTION The .Nm From a0f1535205b5b23672cf0bed68f3e1119a06d44a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 15 Oct 2009 11:41:12 +0000 Subject: [PATCH 170/646] Fix a sign bug in the handling of nice priorities when computing the interactive score for a thread. Submitted by: Taku YAMAMOTO taku of tackymt.homeip.net Reviewed by: jeff MFC after: 3 days --- sys/kern/sched_ule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index fd14fc4021a..e0cff5f3647 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -1406,7 +1406,7 @@ sched_priority(struct thread *td) * score. Negative nice values make it easier for a thread to be * considered interactive. */ - score = imax(0, sched_interact_score(td) - td->td_proc->p_nice); + score = imax(0, sched_interact_score(td) + td->td_proc->p_nice); if (score < sched_interact) { pri = PRI_MIN_REALTIME; pri += ((PRI_MAX_REALTIME - PRI_MIN_REALTIME) / sched_interact) From 54dd21686df08177e6b5dbea46332680d28aac18 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Thu, 15 Oct 2009 14:18:35 +0000 Subject: [PATCH 171/646] A small change to avoid calling gettimeofday() too often (hardwired to once every 20us at most). I found out that on many machines round here, i could only get 300-400kpps with netsend even on loopback and a 'deny' rule in the firewall, while reducing the number of calls to gettimeofday() brings the value to 900kpps and more. This code is just a quick fix for the problem. Of course it could be done better, with proper getopt() parsing and the like, but since this applies to the entire program i'll postpone that to when i have more time. Reviewed by: rwatson MFC after: 1 month --- tools/tools/netrate/netsend/netsend.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tools/tools/netrate/netsend/netsend.c b/tools/tools/netrate/netsend/netsend.c index 8a335b648d8..b47c5090ea4 100644 --- a/tools/tools/netrate/netsend/netsend.c +++ b/tools/tools/netrate/netsend/netsend.c @@ -124,6 +124,9 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, u_int32_t counter; long finishtime; long send_errors, send_calls; + /* do not call gettimeofday more than every 20us */ + long minres_ns = 20000; + int ic, gettimeofday_cycles; if (clock_getres(CLOCK_REALTIME, &tmptime) == -1) { perror("clock_getres"); @@ -132,8 +135,15 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, if (timespec_ge(&tmptime, &interval)) fprintf(stderr, - "warning: interval less than resolution (%jd.%09ld)\n", + "warning: interval (%jd.%09ld) less than resolution (%jd.%09ld)\n", + (intmax_t)interval.tv_sec, interval.tv_nsec, (intmax_t)tmptime.tv_sec, tmptime.tv_nsec); + if (tmptime.tv_nsec < minres_ns) { + gettimeofday_cycles = minres_ns/(tmptime.tv_nsec + 1); + fprintf(stderr, + "calling time every %d cycles\n", gettimeofday_cycles); + } else + gettimeofday_cycles = 0; if (clock_gettime(CLOCK_REALTIME, &starttime) == -1) { perror("clock_gettime"); @@ -151,10 +161,14 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, send_errors = send_calls = 0; counter = 0; waited = 0; + ic = gettimeofday_cycles; while (1) { timespec_add(&nexttime, &interval); - if (wait_time(nexttime, &tmptime, &waited) == -1) - return (-1); + if (--ic <= 0) { + ic = gettimeofday_cycles; + if (wait_time(nexttime, &tmptime, &waited) == -1) + return (-1); + } /* * We maintain and, if there's room, send a counter. Note * that even if the error is purely local, we still increment @@ -236,8 +250,9 @@ main(int argc, char *argv[]) /* * Specify an arbitrary limit. It's exactly that, not selected by - .* any particular strategy. '0' is a special value meaning "blast", + * any particular strategy. '0' is a special value meaning "blast", * and avoids the cost of a timing loop. + * XXX 0 is not actually implemented. */ rate = strtoul(argv[4], &dummy, 10); if (rate < 1 || *dummy != '\0') From 37b8ef16cddbe2381080d5d710d7accb37c14870 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 15 Oct 2009 14:54:35 +0000 Subject: [PATCH 172/646] Add a facility for associating optional descriptions with active interrupt handlers. This is primarily intended as a way to allow devices that use multiple interrupts (e.g. MSI) to meaningfully distinguish the various interrupt handlers. - Add a new BUS_DESCRIBE_INTR() method to the bus interface to associate a description with an active interrupt handler setup by BUS_SETUP_INTR. It has a default method (bus_generic_describe_intr()) which simply passes the request up to the parent device. - Add a bus_describe_intr() wrapper around BUS_DESCRIBE_INTR() that supports printf(9) style formatting using var args. - Reserve MAXCOMLEN bytes in the intr_handler structure to hold the name of an interrupt handler and copy the name passed to intr_event_add_handler() into that buffer instead of just saving the pointer to the name. - Add a new intr_event_describe_handler() which appends a description string to an interrupt handler's name. - Implement support for interrupt descriptions on amd64 and i386 by having the nexus(4) driver supply a custom bus_describe_intr method that invokes a new intr_describe() MD routine which in turn looks up the associated interrupt event and invokes intr_event_describe_handler(). Requested by: many Reviewed by: scottl MFC after: 2 weeks --- share/man/man9/BUS_DESCRIBE_INTR.9 | 104 +++++++++++++++++++++++++++++ share/man/man9/Makefile | 2 + sys/amd64/amd64/intr_machdep.c | 17 +++++ sys/amd64/amd64/nexus.c | 12 ++++ sys/amd64/include/intr_machdep.h | 1 + sys/i386/i386/intr_machdep.c | 17 +++++ sys/i386/i386/nexus.c | 12 ++++ sys/i386/include/intr_machdep.h | 1 + sys/kern/bus_if.m | 20 +++++- sys/kern/kern_intr.c | 59 +++++++++++++++- sys/kern/subr_bus.c | 40 +++++++++++ sys/sys/bus.h | 5 ++ sys/sys/interrupt.h | 4 +- 13 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 share/man/man9/BUS_DESCRIBE_INTR.9 diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9 new file mode 100644 index 00000000000..3da7c429bdd --- /dev/null +++ b/share/man/man9/BUS_DESCRIBE_INTR.9 @@ -0,0 +1,104 @@ +.\" -*- nroff -*- +.\" +.\" Copyright (c) 2009 Advanced Computing Technologies LLC +.\" Written by: John H. Baldwin +.\" 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 October 14, 2009 +.Dt BUS_DESCRIBE_INTR 9 +.Os +.Sh NAME +.Nm BUS_DESCRIBE_INTR , +.Nm bus_describe_intr +.Nd "associate a description with an active interrupt handler" +.Sh SYNOPSIS +.In sys/param.h +.In sys/bus.h +.Ft int +.Fo BUS_BIND_INTR +.Fa "device_t dev" "device_t child" "struct resource *irq" "void *cookie" +.Fa "const char *descr" +.Fc +.Ft int +.Fo bus_describe_intr +.Fa "device_t dev" "struct resource *irq" "void *cookie" "const char *fmt" +.Fa ... +.Fc +.Sh DESCRIPTION +The +.Fn BUS_DESCRIBE_INTR +method associates a description with an active interrupt handler. +The +.Fa cookie +parameter must be the value returned by a successful call to +.Xr BUS_SETUP_INTR 9 +for the interrupt +.Fa irq . +.Pp +The +.Fn bus_describe_intr +function is a simple wrapper around +.Fn BUS_DESCRIBE_INTR . +As a convenience, +.Fn bus_describe_intr +allows the caller to use +.Xr printf 9 +style formatting to build the description string using +.Fa fmt . +.Pp +When an interrupt handler is established by +.Xr BUS_SETUP_INTR 9 , +the handler is named after the device the handler is established for. +This name is then used in various places such as interrupt statistics +displayed by +.Xr systat 1 +and +.Xr vmstat 8 . +For devices that use a single interrupt, +the device name is sufficiently unique to identify the interrupt handler. +However, for devices that use multiple interrupts it can be useful to +distinguish the interrupt handlers. +When a description is set for an active interrupt handler, +a colon followed by the description is appended to the device name to form +the interrupt handler name. +.Sh RETURN VALUES +Zero is returned on success, otherwise an appropriate error is returned. +.Sh SEE ALSO +.Xr BUS_SETUP_INTR 9 , +.Xr device 9 , +.Xr printf 9 , +.Xr systat 1 , +.Xr vmstat 8 +.Sh HISTORY +The +.Fn BUS_DESCRIBE_INTR +method and +.Fn bus_describe_intr +functions first appeared in +.Fx 9.0 . +.Sh BUGS +It is not currently possible to remove a description from an active interrupt +handler. diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index ae8b55f485e..072827a2e0f 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -26,6 +26,7 @@ MAN= accept_filter.9 \ BUS_BIND_INTR.9 \ bus_child_present.9 \ BUS_CONFIG_INTR.9 \ + BUS_DESCRIBE_INTR.9 \ bus_dma.9 \ bus_generic_attach.9 \ bus_generic_detach.9 \ @@ -405,6 +406,7 @@ MLINKS+=buf.9 bp.9 MLINKS+=bus_activate_resource.9 bus_deactivate_resource.9 MLINKS+=bus_alloc_resource.9 bus_alloc_resource_any.9 MLINKS+=BUS_BIND_INTR.9 bus_bind_intr.9 +MLINKS+=BUS_DESCRIBE_INTR.9 bus_describe_intr.9 MLINKS+=bus_dma.9 busdma.9 \ bus_dma.9 bus_dmamap_create.9 \ bus_dma.9 bus_dmamap_destroy.9 \ diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index 212ac0d7b26..e72e13ab2c1 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -466,6 +466,23 @@ intr_bind(u_int vector, u_char cpu) return (intr_event_bind(isrc->is_event, cpu)); } +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + /* * Add a CPU to our mask of valid CPUs that can be destinations of * interrupts. diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c index 5eafd3baf97..61cb58775ae 100644 --- a/sys/amd64/amd64/nexus.c +++ b/sys/amd64/amd64/nexus.c @@ -92,6 +92,9 @@ static int nexus_bind_intr(device_t, device_t, struct resource *, int); #endif static int nexus_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +static int nexus_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, @@ -135,6 +138,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_describe_intr, nexus_describe_intr), DEVMETHOD(bus_get_resource_list, nexus_get_reslist), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), @@ -479,6 +483,14 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, return (intr_config_intr(irq, trig, pol)); } +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + return (intr_describe(rman_get_start(irq), cookie, descr)); +} + static struct resource_list * nexus_get_reslist(device_t dev, device_t child) { diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h index 634db19c5a5..6cd4eee6664 100644 --- a/sys/amd64/include/intr_machdep.h +++ b/sys/amd64/include/intr_machdep.h @@ -151,6 +151,7 @@ int intr_bind(u_int vector, u_char cpu); #endif int intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol); +int intr_describe(u_int vector, void *ih, const char *descr); void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); u_int intr_next_cpu(void); struct intsrc *intr_lookup_source(int vector); diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c index 3d1b0c49dfc..5a74a9d5830 100644 --- a/sys/i386/i386/intr_machdep.c +++ b/sys/i386/i386/intr_machdep.c @@ -432,6 +432,23 @@ intr_bind(u_int vector, u_char cpu) return (intr_event_bind(isrc->is_event, cpu)); } +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + /* * Add a CPU to our mask of valid CPUs that can be destinations of * interrupts. diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c index 98adc933a23..8eacc6a7601 100644 --- a/sys/i386/i386/nexus.c +++ b/sys/i386/i386/nexus.c @@ -96,6 +96,9 @@ static int nexus_bind_intr(device_t, device_t, struct resource *, int); #endif static int nexus_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +static int nexus_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, @@ -141,6 +144,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_describe_intr, nexus_describe_intr), DEVMETHOD(bus_get_resource_list, nexus_get_reslist), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), @@ -526,6 +530,14 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, return (intr_config_intr(irq, trig, pol)); } +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + return (intr_describe(rman_get_start(irq), cookie, descr)); +} + static struct resource_list * nexus_get_reslist(device_t dev, device_t child) { diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index f21e0bcfb7b..bcff6c22e6e 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -138,6 +138,7 @@ int intr_bind(u_int vector, u_char cpu); #endif int intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol); +int intr_describe(u_int vector, void *ih, const char *descr); void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); u_int intr_next_cpu(void); struct intsrc *intr_lookup_source(int vector); diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m index c1c0e348eb0..c0924c882ab 100644 --- a/sys/kern/bus_if.m +++ b/sys/kern/bus_if.m @@ -509,7 +509,6 @@ METHOD int bind_intr { int _cpu; } DEFAULT bus_generic_bind_intr; - /** * @brief Allow (bus) drivers to specify the trigger mode and polarity * of the specified interrupt. @@ -526,6 +525,25 @@ METHOD int config_intr { enum intr_polarity _pol; } DEFAULT bus_generic_config_intr; +/** + * @brief Allow drivers to associate a description with an active + * interrupt handler. + * + * @param _dev the parent device of @p _child + * @param _child the device which allocated the resource + * @param _irq the resource representing the interrupt + * @param _cookie the cookie value returned when the interrupt + * was originally registered + * @param _descr the description to associate with the interrupt + */ +METHOD int describe_intr { + device_t _dev; + device_t _child; + struct resource *_irq; + void *_cookie; + const char *_descr; +} DEFAULT bus_generic_describe_intr; + /** * @brief Notify a (bus) driver about a child that the hints mechanism * believes it has discovered. diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index 3eb2c6ca3f8..42d5f167bd4 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -524,7 +524,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, ih->ih_filter = filter; ih->ih_handler = handler; ih->ih_argument = arg; - ih->ih_name = name; + strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); ih->ih_event = ie; ih->ih_pri = pri; if (flags & INTR_EXCL) @@ -597,7 +597,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, ih->ih_filter = filter; ih->ih_handler = handler; ih->ih_argument = arg; - ih->ih_name = name; + strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); ih->ih_event = ie; ih->ih_pri = pri; if (flags & INTR_EXCL) @@ -664,6 +664,61 @@ intr_event_add_handler(struct intr_event *ie, const char *name, } #endif +/* + * Append a description preceded by a ':' to the name of the specified + * interrupt handler. + */ +int +intr_event_describe_handler(struct intr_event *ie, void *cookie, + const char *descr) +{ + struct intr_handler *ih; + size_t space; + char *start; + + mtx_lock(&ie->ie_lock); +#ifdef INVARIANTS + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (ih == cookie) + break; + } + if (ih == NULL) { + mtx_unlock(&ie->ie_lock); + panic("handler %p not find in interrupt event %p", cookie, ie); + } +#endif + ih = cookie; + + /* + * Look for an existing description by checking for an + * existing ":". This assumes device names do not include + * colons. If one is found, prepare to insert the new + * description at that point. If one is not found, find the + * end of the name to use as the insertion point. + */ + start = index(ih->ih_name, ':'); + if (start == NULL) + start = index(ih->ih_name, 0); + + /* + * See if there is enough remaining room in the string for the + * description + ":". The "- 1" leaves room for the trailing + * '\0'. The "+ 1" accounts for the colon. + */ + space = sizeof(ih->ih_name) - (start - ih->ih_name) - 1; + if (strlen(descr) + 1 > space) { + mtx_unlock(&ie->ie_lock); + return (ENOSPC); + } + + /* Append a colon followed by the description. */ + *start = ':'; + strcpy(start + 1, descr); + intr_event_update(ie); + mtx_unlock(&ie->ie_lock); + return (0); +} + /* * Return the ie_source field from the intr_event an intr_handler is * associated with. diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 3f51c5cada8..e4d1f9b5a0d 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -3519,6 +3519,24 @@ bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig, return (EINVAL); } +/** + * @brief Helper function for implementing BUS_DESCRIBE_INTR(). + * + * This simple implementation of BUS_DESCRIBE_INTR() simply calls the + * BUS_DESCRIBE_INTR() method of the parent of @p dev. + */ +int +bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + /* Propagate up the bus hierarchy until someone handles it. */ + if (dev->parent) + return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie, + descr)); + return (EINVAL); +} + /** * @brief Helper function for implementing BUS_GET_DMA_TAG(). * @@ -3823,6 +3841,28 @@ bus_bind_intr(device_t dev, struct resource *r, int cpu) return (BUS_BIND_INTR(dev->parent, dev, r, cpu)); } +/** + * @brief Wrapper function for BUS_DESCRIBE_INTR(). + * + * This function first formats the requested description into a + * temporary buffer and then calls the BUS_DESCRIBE_INTR() method of + * the parent of @p dev. + */ +int +bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char *fmt, ...) +{ + char descr[MAXCOMLEN]; + va_list ap; + + if (dev->parent == NULL) + return (EINVAL); + va_start(ap, fmt); + vsnprintf(descr, sizeof(descr), fmt, ap); + va_end(ap); + return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr)); +} + /** * @brief Wrapper function for BUS_SET_RESOURCE(). * diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 794dc47a8f1..454f5102537 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -292,6 +292,9 @@ int bus_generic_bind_intr(device_t dev, device_t child, int bus_generic_child_present(device_t dev, device_t child); int bus_generic_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +int bus_generic_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); int bus_generic_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r); int bus_generic_detach(device_t dev); @@ -363,6 +366,8 @@ int bus_setup_intr(device_t dev, struct resource *r, int flags, void *arg, void **cookiep); int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); int bus_bind_intr(device_t dev, struct resource *r, int cpu); +int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char *fmt, ...); int bus_set_resource(device_t dev, int type, int rid, u_long start, u_long count); int bus_get_resource(device_t dev, int type, int rid, diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h index 92c0f03bfcd..18f73d98968 100644 --- a/sys/sys/interrupt.h +++ b/sys/sys/interrupt.h @@ -47,7 +47,7 @@ struct intr_handler { driver_intr_t *ih_handler; /* Threaded handler function. */ void *ih_argument; /* Argument to pass to handlers. */ int ih_flags; - const char *ih_name; /* Name of handler. */ + char ih_name[MAXCOMLEN]; /* Name of handler. */ struct intr_event *ih_event; /* Event we are connected to. */ int ih_need; /* Needs service. */ TAILQ_ENTRY(intr_handler) ih_next; /* Next handler for this event. */ @@ -172,6 +172,8 @@ int intr_event_destroy(struct intr_event *ie); void intr_event_execute_handlers(struct proc *p, struct intr_event *ie); int intr_event_handle(struct intr_event *ie, struct trapframe *frame); int intr_event_remove_handler(void *cookie); +int intr_event_describe_handler(struct intr_event *ie, void *cookie, + const char *descr); int intr_getaffinity(int irq, void *mask); void *intr_handler_source(void *cookie); int intr_setaffinity(int irq, void *mask); From 8dfed8b0a1350b49e02598ae70c091736acc549b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 15 Oct 2009 14:55:11 +0000 Subject: [PATCH 173/646] Style fixes to the function prototypes for bus_alloc_resources() and bus_release_resources(). --- sys/sys/bus.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 454f5102537..92f4238e234 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -347,8 +347,10 @@ struct resource_spec { int flags; }; -int bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res); -void bus_release_resources(device_t dev, const struct resource_spec *rs, struct resource **res); +int bus_alloc_resources(device_t dev, struct resource_spec *rs, + struct resource **res); +void bus_release_resources(device_t dev, const struct resource_spec *rs, + struct resource **res); struct resource *bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end, u_long count, From ed8c4b44e6ee5a293cd80feb5fe3f0309c2cd325 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Thu, 15 Oct 2009 15:30:41 +0000 Subject: [PATCH 174/646] Support the specification of a range of destination ports e.g. netsend 127.0.0.1 6666-7777 [payloadsize] [packet_rate] [duration] This is useful to test the behaviour of systems that do some kind of flow classifications and so exhibit different behaviour depending on the number of flows that hit them. I plan to add a similar extension to sweep on a range of IP addresses, so we can issue a single command to flood (obviously, for testing purposes!) a number of different destinations. When there is only one destination, we do a preliminary connect() of the socket so we can use send() instead of sendto(). When we have multiple ports, the socket is not connect()'ed and we do a sendto() instead. There is a performance hit in this case, as the throughput on the loopback interface (with a firewall rule that blocks the transmission) goes down from 900kpps to 490kpps on my test machine. If the number of different destinations is limited, one option to explore is to have multiple connect()ed sockets. MFC after: 1 month --- tools/tools/netrate/netsend/netsend.c | 141 ++++++++++++++++---------- 1 file changed, 89 insertions(+), 52 deletions(-) diff --git a/tools/tools/netrate/netsend/netsend.c b/tools/tools/netrate/netsend/netsend.c index b47c5090ea4..5e41f2d743b 100644 --- a/tools/tools/netrate/netsend/netsend.c +++ b/tools/tools/netrate/netsend/netsend.c @@ -39,12 +39,23 @@ #include #include +/* program arguments */ +struct _a { + int s; + struct timespec interval; + int port, port_max; + long duration; + struct sockaddr_in sin; + int packet_len; + void *packet; +}; + static void usage(void) { fprintf(stderr, - "netsend [ip] [port] [payloadsize] [rate] [duration]\n"); + "netsend [ip] [port[-port_max]] [payloadsize] [packet_rate] [duration]\n"); exit(-1); } @@ -114,10 +125,12 @@ wait_time(struct timespec ts, struct timespec *wakeup_ts, long long *waited) * Calculate a second-aligned starting time for the packet stream. Busy * wait between our calculated interval and dropping the provided packet * into the socket. If we hit our duration limit, bail. + * We sweep the ports from a->port to a->port_max included. + * If the two ports are the same we connect() the socket upfront, which + * almost halves the cost of the sendto() call. */ static int -timing_loop(int s, struct timespec interval, long duration, u_char *packet, - u_int packet_len) +timing_loop(struct _a *a) { struct timespec nexttime, starttime, tmptime; long long waited; @@ -127,18 +140,19 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, /* do not call gettimeofday more than every 20us */ long minres_ns = 20000; int ic, gettimeofday_cycles; + int cur_port; if (clock_getres(CLOCK_REALTIME, &tmptime) == -1) { perror("clock_getres"); return (-1); } - if (timespec_ge(&tmptime, &interval)) + if (timespec_ge(&tmptime, &a->interval)) fprintf(stderr, "warning: interval (%jd.%09ld) less than resolution (%jd.%09ld)\n", - (intmax_t)interval.tv_sec, interval.tv_nsec, + (intmax_t)a->interval.tv_sec, a->interval.tv_nsec, (intmax_t)tmptime.tv_sec, tmptime.tv_nsec); - if (tmptime.tv_nsec < minres_ns) { + if (a->interval.tv_nsec < minres_ns) { gettimeofday_cycles = minres_ns/(tmptime.tv_nsec + 1); fprintf(stderr, "calling time every %d cycles\n", gettimeofday_cycles); @@ -156,14 +170,23 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, if (wait_time(starttime, NULL, NULL) == -1) return (-1); nexttime = starttime; - finishtime = starttime.tv_sec + duration; + finishtime = starttime.tv_sec + a->duration; send_errors = send_calls = 0; counter = 0; waited = 0; ic = gettimeofday_cycles; + cur_port = a->port; + if (a->port == a->port_max) { + if (connect(a->s, (struct sockaddr *)&a->sin, sizeof(a->sin))) { + perror("connect"); + return (-1); + } + } while (1) { - timespec_add(&nexttime, &interval); + int ret; + + timespec_add(&nexttime, &a->interval); if (--ic <= 0) { ic = gettimeofday_cycles; if (wait_time(nexttime, &tmptime, &waited) == -1) @@ -178,17 +201,28 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet, * previous send, the error will turn up the current send * operation, causing the current sequence number also to be * skipped. + * The counter is incremented only on the initial port number, + * so all destinations will see the same set of packets. * * XXXRW: Note alignment assumption. */ - if (packet_len >= 4) { - *((u_int32_t *)packet) = htonl(counter); + if (cur_port == a->port && a->packet_len >= 4) { + *((u_int32_t *)a->packet) = htonl(counter); counter++; } - if (send(s, packet, packet_len, 0) < 0) + if (a->port == a->port_max) { /* socket already bound */ + ret = send(a->s, a->packet, a->packet_len, 0); + } else { + a->sin.sin_port = htons(cur_port++); + if (cur_port > a->port_max) + cur_port = a->port; + ret = sendto(a->s, a->packet, a->packet_len, 0, + (struct sockaddr *)&a->sin, sizeof(a->sin)); + } + if (ret < 0) send_errors++; send_calls++; - if (duration != 0 && tmptime.tv_sec >= finishtime) + if (a->duration != 0 && tmptime.tv_sec >= finishtime) goto done; } @@ -205,11 +239,11 @@ done: tmptime.tv_nsec); printf("send calls: %ld\n", send_calls); printf("send errors: %ld\n", send_errors); - printf("approx send rate: %ld\n", (send_calls - send_errors) / - duration); + printf("approx send rate: %ld pps\n", (send_calls - send_errors) / + a->duration); printf("approx error rate: %ld\n", (send_errors / send_calls)); printf("waited: %lld\n", waited); - printf("approx waits/sec: %lld\n", (long long)(waited / duration)); + printf("approx waits/sec: %lld\n", (long long)(waited / a->duration)); printf("approx wait rate: %lld\n", (long long)(waited / send_calls)); return (0); @@ -218,27 +252,35 @@ done: int main(int argc, char *argv[]) { - long rate, payloadsize, port, duration; - struct timespec interval; - struct sockaddr_in sin; - char *dummy, *packet; - int s; + long rate, payloadsize, port; + char *dummy; + struct _a a; /* arguments */ + + bzero(&a, sizeof(a)); if (argc != 6) usage(); - bzero(&sin, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - if (inet_aton(argv[1], &sin.sin_addr) == 0) { + a.sin.sin_len = sizeof(a.sin); + a.sin.sin_family = AF_INET; + if (inet_aton(argv[1], &a.sin.sin_addr) == 0) { perror(argv[1]); return (-1); } port = strtoul(argv[2], &dummy, 10); - if (port < 1 || port > 65535 || *dummy != '\0') + if (port < 1 || port > 65535) usage(); - sin.sin_port = htons(port); + if (*dummy != '\0' && *dummy != '-') + usage(); + a.sin.sin_port = htons(port); + a.port = a.port_max = port; + if (*dummy == '-') { /* set high port */ + port = strtoul(dummy + 1, &dummy, 10); + if (port < a.port || port > 65535) + usage(); + a.port_max = port; + } payloadsize = strtoul(argv[3], &dummy, 10); if (payloadsize < 0 || *dummy != '\0') @@ -247,56 +289,51 @@ main(int argc, char *argv[]) fprintf(stderr, "payloadsize > 32768\n"); return (-1); } + a.packet_len = payloadsize; /* * Specify an arbitrary limit. It's exactly that, not selected by * any particular strategy. '0' is a special value meaning "blast", * and avoids the cost of a timing loop. - * XXX 0 is not actually implemented. */ rate = strtoul(argv[4], &dummy, 10); - if (rate < 1 || *dummy != '\0') + if (rate < 0 || *dummy != '\0') usage(); if (rate > MAX_RATE) { - fprintf(stderr, "rate > %d\n", MAX_RATE); + fprintf(stderr, "packet rate at most %d\n", MAX_RATE); return (-1); } - duration = strtoul(argv[5], &dummy, 10); - if (duration < 0 || *dummy != '\0') + a.duration = strtoul(argv[5], &dummy, 10); + if (a.duration < 0 || *dummy != '\0') usage(); - packet = malloc(payloadsize); - if (packet == NULL) { + a.packet = malloc(payloadsize); + if (a.packet == NULL) { perror("malloc"); return (-1); } - bzero(packet, payloadsize); - + bzero(a.packet, payloadsize); if (rate == 0) { - interval.tv_sec = 0; - interval.tv_nsec = 0; + a.interval.tv_sec = 0; + a.interval.tv_nsec = 0; } else if (rate == 1) { - interval.tv_sec = 1; - interval.tv_nsec = 0; + a.interval.tv_sec = 1; + a.interval.tv_nsec = 0; } else { - interval.tv_sec = 0; - interval.tv_nsec = ((1 * 1000000000) / rate); + a.interval.tv_sec = 0; + a.interval.tv_nsec = ((1 * 1000000000) / rate); } - printf("Sending packet of payload size %ld every %jd.%09lds for %ld " - "seconds\n", payloadsize, (intmax_t)interval.tv_sec, - interval.tv_nsec, duration); - s = socket(PF_INET, SOCK_DGRAM, 0); - if (s == -1) { + printf("Sending packet of payload size %ld every %jd.%09lds for %ld " + "seconds\n", payloadsize, (intmax_t)a.interval.tv_sec, + a.interval.tv_nsec, a.duration); + + a.s = socket(PF_INET, SOCK_DGRAM, 0); + if (a.s == -1) { perror("socket"); return (-1); } - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - perror("connect"); - return (-1); - } - - return (timing_loop(s, interval, duration, packet, payloadsize)); + return (timing_loop(&a)); } From 92573623b9898ff02bae432f0df1ef449d9271b6 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Thu, 15 Oct 2009 18:17:29 +0000 Subject: [PATCH 175/646] Removed redundant WARNS setting. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Ulrich Spテカrlein --- bin/cat/Makefile | 1 - bin/uuidgen/Makefile | 1 - 2 files changed, 2 deletions(-) diff --git a/bin/cat/Makefile b/bin/cat/Makefile index 689dd4d28d0..672a4eeeeff 100644 --- a/bin/cat/Makefile +++ b/bin/cat/Makefile @@ -2,6 +2,5 @@ # $FreeBSD$ PROG= cat -WARNS?= 6 .include diff --git a/bin/uuidgen/Makefile b/bin/uuidgen/Makefile index 370241d3ebd..0b27d20e980 100644 --- a/bin/uuidgen/Makefile +++ b/bin/uuidgen/Makefile @@ -1,6 +1,5 @@ # $FreeBSD$ PROG= uuidgen -WARNS?= 6 .include From d0c9a2916941ab7318ddddbada29e26ce9525758 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 15 Oct 2009 18:51:19 +0000 Subject: [PATCH 176/646] Use language more closely resembling English in a panic message. Pointy hat to: jhb Submitted by: pluknet --- sys/kern/kern_intr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index 42d5f167bd4..d22bfeaa311 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -684,7 +684,7 @@ intr_event_describe_handler(struct intr_event *ie, void *cookie, } if (ih == NULL) { mtx_unlock(&ie->ie_lock); - panic("handler %p not find in interrupt event %p", cookie, ie); + panic("handler %p not found in interrupt event %p", cookie, ie); } #endif ih = cookie; From 1def609a638f86847ece145013ffc2758a4360ae Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 15 Oct 2009 20:07:08 +0000 Subject: [PATCH 177/646] Workaround buggy BIOS code in USB regard. By doing the BIOS to OS handover for all host controllers at the same time, we avoid problems where the BIOS will actually write to the USB registers of all the USB host controllers every time we handover one of them, and consequently reset the OS programmed values. Submitted by: avg Reviewed by: jhb --- sys/dev/pci/pci.c | 121 +++++++++++++++++ sys/dev/usb/controller/ehci.c | 1 + sys/dev/usb/controller/ehci.h | 133 ------------------- sys/dev/usb/controller/ehci_ixp4xx.c | 1 + sys/dev/usb/controller/ehci_mbus.c | 1 + sys/dev/usb/controller/ehci_pci.c | 1 + sys/dev/usb/controller/ehcireg.h | 174 +++++++++++++++++++++++++ sys/dev/usb/controller/ohci.c | 1 + sys/dev/usb/controller/ohci.h | 89 ------------- sys/dev/usb/controller/ohci_atmelarm.c | 1 + sys/dev/usb/controller/ohci_pci.c | 1 + sys/dev/usb/controller/ohcireg.h | 131 +++++++++++++++++++ sys/dev/usb/controller/uhci.c | 1 + sys/dev/usb/controller/uhci.h | 60 --------- sys/dev/usb/controller/uhci_pci.c | 1 + sys/dev/usb/controller/uhcireg.h | 100 ++++++++++++++ 16 files changed, 535 insertions(+), 282 deletions(-) create mode 100644 sys/dev/usb/controller/ehcireg.h create mode 100644 sys/dev/usb/controller/ohcireg.h create mode 100644 sys/dev/usb/controller/uhcireg.h diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 47aedbde0dd..e60ee234c85 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -62,6 +62,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include +#include + #include "pcib_if.h" #include "pci_if.h" @@ -270,6 +274,13 @@ TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist); SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD, &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI"); +static int pci_usb_takeover = 1; +TUNABLE_INT("hw.pci.usb_early_takeover", &pci_usb_takeover); +SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RD | CTLFLAG_TUN, + &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\ +Disable this if you depend on BIOS emulation of USB devices, that is\n\ +you use USB devices (like keyboard or mouse) but do not load USB drivers"); + /* Find a device_t by bus/slot/function in domain 0 */ device_t @@ -2569,6 +2580,106 @@ pci_assign_interrupt(device_t bus, device_t dev, int force_route) resource_list_add(&dinfo->resources, SYS_RES_IRQ, 0, irq, irq, 1); } +/* Perform early OHCI takeover from SMM. */ +static void +ohci_early_takeover(device_t self) +{ + struct resource *res; + uint32_t ctl; + int rid; + int i; + + rid = PCIR_BAR(0); + res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (res == NULL) + return; + + ctl = bus_read_4(res, OHCI_CONTROL); + if (ctl & OHCI_IR) { + if (bootverbose) + printf("ohci early: " + "SMM active, request owner change\n"); + bus_write_4(res, OHCI_COMMAND_STATUS, OHCI_OCR); + for (i = 0; (i < 100) && (ctl & OHCI_IR); i++) { + DELAY(1000); + ctl = bus_read_4(res, OHCI_CONTROL); + } + if (ctl & OHCI_IR) { + if (bootverbose) + printf("ohci early: " + "SMM does not respond, resetting\n"); + bus_write_4(res, OHCI_CONTROL, OHCI_HCFS_RESET); + } + } + + bus_release_resource(self, SYS_RES_MEMORY, rid, res); +} + +/* Perform early UHCI takeover from SMM. */ +static void +uhci_early_takeover(device_t self) +{ + /* + * Set the PIRQD enable bit and switch off all the others. We don't + * want legacy support to interfere with us XXX Does this also mean + * that the BIOS won't touch the keyboard anymore if it is connected + * to the ports of the root hub? + */ + pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2); +} + +/* Perform early EHCI takeover from SMM. */ +static void +ehci_early_takeover(device_t self) +{ + struct resource *res; + uint32_t cparams; + uint32_t eec; + uint8_t eecp; + uint8_t bios_sem; + int rid; + int i; + + rid = PCIR_BAR(0); + res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (res == NULL) + return; + + cparams = bus_read_4(res, EHCI_HCCPARAMS); + + /* Synchronise with the BIOS if it owns the controller. */ + for (eecp = EHCI_HCC_EECP(cparams); eecp != 0; + eecp = EHCI_EECP_NEXT(eec)) { + eec = pci_read_config(self, eecp, 4); + if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP) { + continue; + } + bios_sem = pci_read_config(self, eecp + + EHCI_LEGSUP_BIOS_SEM, 1); + if (bios_sem == 0) { + continue; + } + if (bootverbose) + printf("ehci early: " + "SMM active, request owner change\n"); + + pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 1, 1); + + for (i = 0; (i < 100) && (bios_sem != 0); i++) { + DELAY(1000); + bios_sem = pci_read_config(self, eecp + + EHCI_LEGSUP_BIOS_SEM, 1); + } + + if (bios_sem != 0) { + if (bootverbose) + printf("ehci early: " + "SMM does not respond\n"); + } + } + bus_release_resource(self, SYS_RES_MEMORY, rid, res); +} + void pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask) { @@ -2612,6 +2723,16 @@ pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask) pci_assign_interrupt(bus, dev, 0); #endif } + + if (pci_usb_takeover && pci_get_class(dev) == PCIC_SERIALBUS && + pci_get_subclass(dev) == PCIS_SERIALBUS_USB) { + if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_EHCI) + ehci_early_takeover(dev); + else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_OHCI) + ohci_early_takeover(dev); + else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_UHCI) + uhci_early_takeover(dev); + } } void diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 7dc5d312121..42b78c360a6 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -83,6 +83,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define EHCI_BUS2SC(bus) \ ((ehci_softc_t *)(((uint8_t *)(bus)) - \ diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h index 0868bc8f15a..32c08356a3b 100644 --- a/sys/dev/usb/controller/ehci.h +++ b/sys/dev/usb/controller/ehci.h @@ -40,139 +40,6 @@ #define EHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128) -/* PCI config registers */ -#define PCI_CBMEM 0x10 /* configuration base MEM */ -#define PCI_INTERFACE_EHCI 0x20 -#define PCI_USBREV 0x60 /* RO USB protocol revision */ -#define PCI_USB_REV_MASK 0xff -#define PCI_USB_REV_PRE_1_0 0x00 -#define PCI_USB_REV_1_0 0x10 -#define PCI_USB_REV_1_1 0x11 -#define PCI_USB_REV_2_0 0x20 -#define PCI_EHCI_FLADJ 0x61 /* RW Frame len adj, SOF=59488+6*fladj */ -#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */ - -/* EHCI Extended Capabilities */ -#define EHCI_EC_LEGSUP 0x01 -#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff) -#define EHCI_EECP_ID(x) ((x) & 0xff) - -/* Legacy support extended capability */ -#define EHCI_LEGSUP_BIOS_SEM 0x02 -#define EHCI_LEGSUP_OS_SEM 0x03 -#define EHCI_LEGSUP_USBLEGCTLSTS 0x04 - -/* EHCI capability registers */ -#define EHCI_CAPLENGTH 0x00 /* RO Capability register length field */ -/* reserved 0x01 */ -#define EHCI_HCIVERSION 0x02 /* RO Interface version number */ -#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */ -#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf) -#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000) -#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ -#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ -#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ -#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ -#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ -#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ -#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ -#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ -#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ -#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ -#define EHCI_HCSP_PORTROUTE 0x0c /* RO Companion port route description */ - -/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */ -#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */ -#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ -#define EHCI_CMD_ITC_1 0x00010000 -#define EHCI_CMD_ITC_2 0x00020000 -#define EHCI_CMD_ITC_4 0x00040000 -#define EHCI_CMD_ITC_8 0x00080000 -#define EHCI_CMD_ITC_16 0x00100000 -#define EHCI_CMD_ITC_32 0x00200000 -#define EHCI_CMD_ITC_64 0x00400000 -#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ -#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ -#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ -#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door - * bell */ -#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ -#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ -#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ -#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ -#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ -#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ -#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */ -#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ -#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ -#define EHCI_STS_REC 0x00002000 /* RO reclamation */ -#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ -#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ -#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ -#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ -#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ -#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ -#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ -#define EHCI_STS_INTRS(x) ((x) & 0x3f) - -/* - * NOTE: the doorbell interrupt is enabled, but the doorbell is never - * used! SiS chipsets require this. - */ -#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | \ - EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT) - -#define EHCI_USBINTR 0x08 /* RW Interrupt register */ -#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance - * ena */ -#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ -#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ -#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ -#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ -#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ - -#define EHCI_FRINDEX 0x0c /* RW Frame Index register */ - -#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */ - -#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */ -#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */ - -#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */ -#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ - -#define EHCI_PORTSC(n) (0x40+(4*(n))) /* RO, RW, RWC Port Status reg */ -#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ -#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ -#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ -#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ -#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ -#define EHCI_PS_PO 0x00002000 /* RW port owner */ -#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ -#define EHCI_PS_LS 0x00000c00 /* RO line status */ -#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400) -#define EHCI_PS_PR 0x00000100 /* RW port reset */ -#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ -#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ -#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ -#define EHCI_PS_OCA 0x00000010 /* RO over current active */ -#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ -#define EHCI_PS_PE 0x00000004 /* RW port enable */ -#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ -#define EHCI_PS_CS 0x00000001 /* RO connect status */ -#define EHCI_PS_CLEAR (EHCI_PS_OCC | EHCI_PS_PEC | EHCI_PS_CSC) - -#define EHCI_USBMODE 0x68 /* RW USB Device mode register */ -#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */ -#define EHCI_UM_CM_IDLE 0x0 /* Idle */ -#define EHCI_UM_CM_HOST 0x3 /* Host Controller */ -#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */ -#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */ -#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */ -#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */ - -#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ - /* * Alignment NOTE: structures must be aligned so that the hardware can index * without performing addition. diff --git a/sys/dev/usb/controller/ehci_ixp4xx.c b/sys/dev/usb/controller/ehci_ixp4xx.c index 7668d8608e0..9f866149c14 100644 --- a/sys/dev/usb/controller/ehci_ixp4xx.c +++ b/sys/dev/usb/controller/ehci_ixp4xx.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/dev/usb/controller/ehci_mbus.c b/sys/dev/usb/controller/ehci_mbus.c index 7076854d6f2..d3c0f4c45aa 100644 --- a/sys/dev/usb/controller/ehci_mbus.c +++ b/sys/dev/usb/controller/ehci_mbus.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c index 7978f4facff..fc2035bd297 100644 --- a/sys/dev/usb/controller/ehci_pci.c +++ b/sys/dev/usb/controller/ehci_pci.c @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define PCI_EHCI_VENDORID_ACERLABS 0x10b9 #define PCI_EHCI_VENDORID_AMD 0x1022 diff --git a/sys/dev/usb/controller/ehcireg.h b/sys/dev/usb/controller/ehcireg.h new file mode 100644 index 00000000000..182d9d6acab --- /dev/null +++ b/sys/dev/usb/controller/ehcireg.h @@ -0,0 +1,174 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net). + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _EHCIREG_H_ +#define _EHCIREG_H_ + +/* PCI config registers */ +#define PCI_CBMEM 0x10 /* configuration base MEM */ +#define PCI_INTERFACE_EHCI 0x20 +#define PCI_USBREV 0x60 /* RO USB protocol revision */ +#define PCI_USB_REV_MASK 0xff +#define PCI_USB_REV_PRE_1_0 0x00 +#define PCI_USB_REV_1_0 0x10 +#define PCI_USB_REV_1_1 0x11 +#define PCI_USB_REV_2_0 0x20 +#define PCI_EHCI_FLADJ 0x61 /* RW Frame len adj, SOF=59488+6*fladj */ +#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */ + +/* EHCI Extended Capabilities */ +#define EHCI_EC_LEGSUP 0x01 +#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff) +#define EHCI_EECP_ID(x) ((x) & 0xff) + +/* Legacy support extended capability */ +#define EHCI_LEGSUP_BIOS_SEM 0x02 +#define EHCI_LEGSUP_OS_SEM 0x03 +#define EHCI_LEGSUP_USBLEGCTLSTS 0x04 + +/* EHCI capability registers */ +#define EHCI_CAPLENGTH 0x00 /* RO Capability register length field */ +/* reserved 0x01 */ +#define EHCI_HCIVERSION 0x02 /* RO Interface version number */ +#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */ +#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf) +#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000) +#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ +#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ +#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ +#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ +#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ +#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ +#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ +#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ +#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ +#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ +#define EHCI_HCSP_PORTROUTE 0x0c /* RO Companion port route description */ + +/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */ +#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */ +#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ +#define EHCI_CMD_ITC_1 0x00010000 +#define EHCI_CMD_ITC_2 0x00020000 +#define EHCI_CMD_ITC_4 0x00040000 +#define EHCI_CMD_ITC_8 0x00080000 +#define EHCI_CMD_ITC_16 0x00100000 +#define EHCI_CMD_ITC_32 0x00200000 +#define EHCI_CMD_ITC_64 0x00400000 +#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ +#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ +#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ +#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door + * bell */ +#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ +#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ +#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ +#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ +#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ +#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ +#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */ +#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ +#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ +#define EHCI_STS_REC 0x00002000 /* RO reclamation */ +#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ +#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ +#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ +#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ +#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ +#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ +#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ +#define EHCI_STS_INTRS(x) ((x) & 0x3f) + +/* + * NOTE: the doorbell interrupt is enabled, but the doorbell is never + * used! SiS chipsets require this. + */ +#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | \ + EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT) + +#define EHCI_USBINTR 0x08 /* RW Interrupt register */ +#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance + * ena */ +#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ +#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ +#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ +#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ +#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ + +#define EHCI_FRINDEX 0x0c /* RW Frame Index register */ + +#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */ + +#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */ +#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */ + +#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */ +#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ + +#define EHCI_PORTSC(n) (0x40+(4*(n))) /* RO, RW, RWC Port Status reg */ +#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ +#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ +#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ +#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ +#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ +#define EHCI_PS_PO 0x00002000 /* RW port owner */ +#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ +#define EHCI_PS_LS 0x00000c00 /* RO line status */ +#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400) +#define EHCI_PS_PR 0x00000100 /* RW port reset */ +#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ +#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ +#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ +#define EHCI_PS_OCA 0x00000010 /* RO over current active */ +#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ +#define EHCI_PS_PE 0x00000004 /* RW port enable */ +#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ +#define EHCI_PS_CS 0x00000001 /* RO connect status */ +#define EHCI_PS_CLEAR (EHCI_PS_OCC | EHCI_PS_PEC | EHCI_PS_CSC) + +#define EHCI_USBMODE 0x68 /* RW USB Device mode register */ +#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */ +#define EHCI_UM_CM_IDLE 0x0 /* Idle */ +#define EHCI_UM_CM_HOST 0x3 /* Host Controller */ +#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */ +#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */ +#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */ +#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */ + +#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ + +#endif /* _EHCIREG_H_ */ diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index 30592c14751..637b639e3f6 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define OHCI_BUS2SC(bus) \ ((ohci_softc_t *)(((uint8_t *)(bus)) - \ diff --git a/sys/dev/usb/controller/ohci.h b/sys/dev/usb/controller/ohci.h index eeb49aabd41..60574bb9cad 100644 --- a/sys/dev/usb/controller/ohci.h +++ b/sys/dev/usb/controller/ohci.h @@ -41,95 +41,6 @@ #define OHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128) -/* PCI config registers */ -#define PCI_CBMEM 0x10 /* configuration base memory */ -#define PCI_INTERFACE_OHCI 0x10 - -/* OHCI registers */ -#define OHCI_REVISION 0x00 /* OHCI revision */ -#define OHCI_REV_LO(rev) ((rev) & 0xf) -#define OHCI_REV_HI(rev) (((rev)>>4) & 0xf) -#define OHCI_REV_LEGACY(rev) ((rev) & 0x100) -#define OHCI_CONTROL 0x04 -#define OHCI_CBSR_MASK 0x00000003 /* Control/Bulk Service Ratio */ -#define OHCI_RATIO_1_1 0x00000000 -#define OHCI_RATIO_1_2 0x00000001 -#define OHCI_RATIO_1_3 0x00000002 -#define OHCI_RATIO_1_4 0x00000003 -#define OHCI_PLE 0x00000004 /* Periodic List Enable */ -#define OHCI_IE 0x00000008 /* Isochronous Enable */ -#define OHCI_CLE 0x00000010 /* Control List Enable */ -#define OHCI_BLE 0x00000020 /* Bulk List Enable */ -#define OHCI_HCFS_MASK 0x000000c0 /* HostControllerFunctionalStat - * e */ -#define OHCI_HCFS_RESET 0x00000000 -#define OHCI_HCFS_RESUME 0x00000040 -#define OHCI_HCFS_OPERATIONAL 0x00000080 -#define OHCI_HCFS_SUSPEND 0x000000c0 -#define OHCI_IR 0x00000100 /* Interrupt Routing */ -#define OHCI_RWC 0x00000200 /* Remote Wakeup Connected */ -#define OHCI_RWE 0x00000400 /* Remote Wakeup Enabled */ -#define OHCI_COMMAND_STATUS 0x08 -#define OHCI_HCR 0x00000001 /* Host Controller Reset */ -#define OHCI_CLF 0x00000002 /* Control List Filled */ -#define OHCI_BLF 0x00000004 /* Bulk List Filled */ -#define OHCI_OCR 0x00000008 /* Ownership Change Request */ -#define OHCI_SOC_MASK 0x00030000 /* Scheduling Overrun Count */ -#define OHCI_INTERRUPT_STATUS 0x0c -#define OHCI_SO 0x00000001 /* Scheduling Overrun */ -#define OHCI_WDH 0x00000002 /* Writeback Done Head */ -#define OHCI_SF 0x00000004 /* Start of Frame */ -#define OHCI_RD 0x00000008 /* Resume Detected */ -#define OHCI_UE 0x00000010 /* Unrecoverable Error */ -#define OHCI_FNO 0x00000020 /* Frame Number Overflow */ -#define OHCI_RHSC 0x00000040 /* Root Hub Status Change */ -#define OHCI_OC 0x40000000 /* Ownership Change */ -#define OHCI_MIE 0x80000000 /* Master Interrupt Enable */ -#define OHCI_INTERRUPT_ENABLE 0x10 -#define OHCI_INTERRUPT_DISABLE 0x14 -#define OHCI_HCCA 0x18 -#define OHCI_PERIOD_CURRENT_ED 0x1c -#define OHCI_CONTROL_HEAD_ED 0x20 -#define OHCI_CONTROL_CURRENT_ED 0x24 -#define OHCI_BULK_HEAD_ED 0x28 -#define OHCI_BULK_CURRENT_ED 0x2c -#define OHCI_DONE_HEAD 0x30 -#define OHCI_FM_INTERVAL 0x34 -#define OHCI_GET_IVAL(s) ((s) & 0x3fff) -#define OHCI_GET_FSMPS(s) (((s) >> 16) & 0x7fff) -#define OHCI_FIT 0x80000000 -#define OHCI_FM_REMAINING 0x38 -#define OHCI_FM_NUMBER 0x3c -#define OHCI_PERIODIC_START 0x40 -#define OHCI_LS_THRESHOLD 0x44 -#define OHCI_RH_DESCRIPTOR_A 0x48 -#define OHCI_GET_NDP(s) ((s) & 0xff) -#define OHCI_PSM 0x0100 /* Power Switching Mode */ -#define OHCI_NPS 0x0200 /* No Power Switching */ -#define OHCI_DT 0x0400 /* Device Type */ -#define OHCI_OCPM 0x0800 /* Overcurrent Protection Mode */ -#define OHCI_NOCP 0x1000 /* No Overcurrent Protection */ -#define OHCI_GET_POTPGT(s) ((s) >> 24) -#define OHCI_RH_DESCRIPTOR_B 0x4c -#define OHCI_RH_STATUS 0x50 -#define OHCI_LPS 0x00000001 /* Local Power Status */ -#define OHCI_OCI 0x00000002 /* OverCurrent Indicator */ -#define OHCI_DRWE 0x00008000 /* Device Remote Wakeup Enable */ -#define OHCI_LPSC 0x00010000 /* Local Power Status Change */ -#define OHCI_CCIC 0x00020000 /* OverCurrent Indicator - * Change */ -#define OHCI_CRWE 0x80000000 /* Clear Remote Wakeup Enable */ -#define OHCI_RH_PORT_STATUS(n) (0x50 + ((n)*4)) /* 1 based indexing */ - -#define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE) -#define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | \ - OHCI_RD | OHCI_UE | OHCI_FNO | \ - OHCI_RHSC | OHCI_OC) -#define OHCI_NORMAL_INTRS (OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC) - -#define OHCI_FSMPS(i) (((i-210)*6/7) << 16) -#define OHCI_PERIODIC(i) ((i)*9/10) - #define OHCI_NO_INTRS 32 #define OHCI_HCCA_SIZE 256 diff --git a/sys/dev/usb/controller/ohci_atmelarm.c b/sys/dev/usb/controller/ohci_atmelarm.c index a4fe9f397b9..c235a8bd5c2 100644 --- a/sys/dev/usb/controller/ohci_atmelarm.c +++ b/sys/dev/usb/controller/ohci_atmelarm.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c index 3be6e42d43e..71891586f94 100644 --- a/sys/dev/usb/controller/ohci_pci.c +++ b/sys/dev/usb/controller/ohci_pci.c @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define PCI_OHCI_VENDORID_ACERLABS 0x10b9 #define PCI_OHCI_VENDORID_AMD 0x1022 diff --git a/sys/dev/usb/controller/ohcireg.h b/sys/dev/usb/controller/ohcireg.h new file mode 100644 index 00000000000..9127a02a36f --- /dev/null +++ b/sys/dev/usb/controller/ohcireg.h @@ -0,0 +1,131 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _OHCIREG_H_ +#define _OHCIREG_H_ + +/* PCI config registers */ +#define PCI_CBMEM 0x10 /* configuration base memory */ +#define PCI_INTERFACE_OHCI 0x10 + +/* OHCI registers */ +#define OHCI_REVISION 0x00 /* OHCI revision */ +#define OHCI_REV_LO(rev) ((rev) & 0xf) +#define OHCI_REV_HI(rev) (((rev)>>4) & 0xf) +#define OHCI_REV_LEGACY(rev) ((rev) & 0x100) +#define OHCI_CONTROL 0x04 +#define OHCI_CBSR_MASK 0x00000003 /* Control/Bulk Service Ratio */ +#define OHCI_RATIO_1_1 0x00000000 +#define OHCI_RATIO_1_2 0x00000001 +#define OHCI_RATIO_1_3 0x00000002 +#define OHCI_RATIO_1_4 0x00000003 +#define OHCI_PLE 0x00000004 /* Periodic List Enable */ +#define OHCI_IE 0x00000008 /* Isochronous Enable */ +#define OHCI_CLE 0x00000010 /* Control List Enable */ +#define OHCI_BLE 0x00000020 /* Bulk List Enable */ +#define OHCI_HCFS_MASK 0x000000c0 /* HostControllerFunctionalStat + * e */ +#define OHCI_HCFS_RESET 0x00000000 +#define OHCI_HCFS_RESUME 0x00000040 +#define OHCI_HCFS_OPERATIONAL 0x00000080 +#define OHCI_HCFS_SUSPEND 0x000000c0 +#define OHCI_IR 0x00000100 /* Interrupt Routing */ +#define OHCI_RWC 0x00000200 /* Remote Wakeup Connected */ +#define OHCI_RWE 0x00000400 /* Remote Wakeup Enabled */ +#define OHCI_COMMAND_STATUS 0x08 +#define OHCI_HCR 0x00000001 /* Host Controller Reset */ +#define OHCI_CLF 0x00000002 /* Control List Filled */ +#define OHCI_BLF 0x00000004 /* Bulk List Filled */ +#define OHCI_OCR 0x00000008 /* Ownership Change Request */ +#define OHCI_SOC_MASK 0x00030000 /* Scheduling Overrun Count */ +#define OHCI_INTERRUPT_STATUS 0x0c +#define OHCI_SO 0x00000001 /* Scheduling Overrun */ +#define OHCI_WDH 0x00000002 /* Writeback Done Head */ +#define OHCI_SF 0x00000004 /* Start of Frame */ +#define OHCI_RD 0x00000008 /* Resume Detected */ +#define OHCI_UE 0x00000010 /* Unrecoverable Error */ +#define OHCI_FNO 0x00000020 /* Frame Number Overflow */ +#define OHCI_RHSC 0x00000040 /* Root Hub Status Change */ +#define OHCI_OC 0x40000000 /* Ownership Change */ +#define OHCI_MIE 0x80000000 /* Master Interrupt Enable */ +#define OHCI_INTERRUPT_ENABLE 0x10 +#define OHCI_INTERRUPT_DISABLE 0x14 +#define OHCI_HCCA 0x18 +#define OHCI_PERIOD_CURRENT_ED 0x1c +#define OHCI_CONTROL_HEAD_ED 0x20 +#define OHCI_CONTROL_CURRENT_ED 0x24 +#define OHCI_BULK_HEAD_ED 0x28 +#define OHCI_BULK_CURRENT_ED 0x2c +#define OHCI_DONE_HEAD 0x30 +#define OHCI_FM_INTERVAL 0x34 +#define OHCI_GET_IVAL(s) ((s) & 0x3fff) +#define OHCI_GET_FSMPS(s) (((s) >> 16) & 0x7fff) +#define OHCI_FIT 0x80000000 +#define OHCI_FM_REMAINING 0x38 +#define OHCI_FM_NUMBER 0x3c +#define OHCI_PERIODIC_START 0x40 +#define OHCI_LS_THRESHOLD 0x44 +#define OHCI_RH_DESCRIPTOR_A 0x48 +#define OHCI_GET_NDP(s) ((s) & 0xff) +#define OHCI_PSM 0x0100 /* Power Switching Mode */ +#define OHCI_NPS 0x0200 /* No Power Switching */ +#define OHCI_DT 0x0400 /* Device Type */ +#define OHCI_OCPM 0x0800 /* Overcurrent Protection Mode */ +#define OHCI_NOCP 0x1000 /* No Overcurrent Protection */ +#define OHCI_GET_POTPGT(s) ((s) >> 24) +#define OHCI_RH_DESCRIPTOR_B 0x4c +#define OHCI_RH_STATUS 0x50 +#define OHCI_LPS 0x00000001 /* Local Power Status */ +#define OHCI_OCI 0x00000002 /* OverCurrent Indicator */ +#define OHCI_DRWE 0x00008000 /* Device Remote Wakeup Enable */ +#define OHCI_LPSC 0x00010000 /* Local Power Status Change */ +#define OHCI_CCIC 0x00020000 /* OverCurrent Indicator + * Change */ +#define OHCI_CRWE 0x80000000 /* Clear Remote Wakeup Enable */ +#define OHCI_RH_PORT_STATUS(n) (0x50 + ((n)*4)) /* 1 based indexing */ + +#define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE) +#define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | \ + OHCI_RD | OHCI_UE | OHCI_FNO | \ + OHCI_RHSC | OHCI_OC) +#define OHCI_NORMAL_INTRS (OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC) + +#define OHCI_FSMPS(i) (((i-210)*6/7) << 16) +#define OHCI_PERIODIC(i) ((i)*9/10) + +#endif /* _OHCIREG_H_ */ diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c index 2a2ff1cf2ce..4e2659cdc83 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define alt_next next #define UHCI_BUS2SC(bus) \ diff --git a/sys/dev/usb/controller/uhci.h b/sys/dev/usb/controller/uhci.h index f2ea246229c..f526431932d 100644 --- a/sys/dev/usb/controller/uhci.h +++ b/sys/dev/usb/controller/uhci.h @@ -41,64 +41,6 @@ #define UHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128) -/* PCI config registers */ -#define PCI_USBREV 0x60 /* USB protocol revision */ -#define PCI_USB_REV_MASK 0xff -#define PCI_USB_REV_PRE_1_0 0x00 -#define PCI_USB_REV_1_0 0x10 -#define PCI_USB_REV_1_1 0x11 -#define PCI_LEGSUP 0xc0 /* Legacy Support register */ -#define PCI_LEGSUP_USBPIRQDEN 0x2000 /* USB PIRQ D Enable */ -#define PCI_CBIO 0x20 /* configuration base IO */ -#define PCI_INTERFACE_UHCI 0x00 - -/* UHCI registers */ -#define UHCI_CMD 0x00 -#define UHCI_CMD_RS 0x0001 -#define UHCI_CMD_HCRESET 0x0002 -#define UHCI_CMD_GRESET 0x0004 -#define UHCI_CMD_EGSM 0x0008 -#define UHCI_CMD_FGR 0x0010 -#define UHCI_CMD_SWDBG 0x0020 -#define UHCI_CMD_CF 0x0040 -#define UHCI_CMD_MAXP 0x0080 -#define UHCI_STS 0x02 -#define UHCI_STS_USBINT 0x0001 -#define UHCI_STS_USBEI 0x0002 -#define UHCI_STS_RD 0x0004 -#define UHCI_STS_HSE 0x0008 -#define UHCI_STS_HCPE 0x0010 -#define UHCI_STS_HCH 0x0020 -#define UHCI_STS_ALLINTRS 0x003f -#define UHCI_INTR 0x04 -#define UHCI_INTR_TOCRCIE 0x0001 -#define UHCI_INTR_RIE 0x0002 -#define UHCI_INTR_IOCE 0x0004 -#define UHCI_INTR_SPIE 0x0008 -#define UHCI_FRNUM 0x06 -#define UHCI_FRNUM_MASK 0x03ff -#define UHCI_FLBASEADDR 0x08 -#define UHCI_SOF 0x0c -#define UHCI_SOF_MASK 0x7f -#define UHCI_PORTSC1 0x010 -#define UHCI_PORTSC2 0x012 -#define UHCI_PORTSC_CCS 0x0001 -#define UHCI_PORTSC_CSC 0x0002 -#define UHCI_PORTSC_PE 0x0004 -#define UHCI_PORTSC_POEDC 0x0008 -#define UHCI_PORTSC_LS 0x0030 -#define UHCI_PORTSC_LS_SHIFT 4 -#define UHCI_PORTSC_RD 0x0040 -#define UHCI_PORTSC_LSDA 0x0100 -#define UHCI_PORTSC_PR 0x0200 -#define UHCI_PORTSC_OCI 0x0400 -#define UHCI_PORTSC_OCIC 0x0800 -#define UHCI_PORTSC_SUSP 0x1000 - -#define URWMASK(x) ((x) & (UHCI_PORTSC_SUSP | \ - UHCI_PORTSC_PR | UHCI_PORTSC_RD | \ - UHCI_PORTSC_PE)) - #define UHCI_FRAMELIST_COUNT 1024 /* units */ #define UHCI_FRAMELIST_ALIGN 4096 /* bytes */ @@ -118,8 +60,6 @@ typedef uint32_t uhci_physaddr_t; #define UHCI_PTR_QH 0x00000002 #define UHCI_PTR_VF 0x00000004 -#define UHCI_QH_REMOVE_DELAY 5 /* us - QH remove delay */ - /* * The Queue Heads (QH) and Transfer Descriptors (TD) are accessed by * both the CPU and the USB-controller which run concurrently. Great diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c index ba155be3a7d..3956eada423 100644 --- a/sys/dev/usb/controller/uhci_pci.c +++ b/sys/dev/usb/controller/uhci_pci.c @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define PCI_UHCI_VENDORID_INTEL 0x8086 #define PCI_UHCI_VENDORID_VIA 0x1106 diff --git a/sys/dev/usb/controller/uhcireg.h b/sys/dev/usb/controller/uhcireg.h new file mode 100644 index 00000000000..eeabbf0eedc --- /dev/null +++ b/sys/dev/usb/controller/uhcireg.h @@ -0,0 +1,100 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _UHCIREG_H_ +#define _UHCIREG_H_ + +/* PCI config registers */ +#define PCI_USBREV 0x60 /* USB protocol revision */ +#define PCI_USB_REV_MASK 0xff +#define PCI_USB_REV_PRE_1_0 0x00 +#define PCI_USB_REV_1_0 0x10 +#define PCI_USB_REV_1_1 0x11 +#define PCI_LEGSUP 0xc0 /* Legacy Support register */ +#define PCI_LEGSUP_USBPIRQDEN 0x2000 /* USB PIRQ D Enable */ +#define PCI_CBIO 0x20 /* configuration base IO */ +#define PCI_INTERFACE_UHCI 0x00 + +/* UHCI registers */ +#define UHCI_CMD 0x00 +#define UHCI_CMD_RS 0x0001 +#define UHCI_CMD_HCRESET 0x0002 +#define UHCI_CMD_GRESET 0x0004 +#define UHCI_CMD_EGSM 0x0008 +#define UHCI_CMD_FGR 0x0010 +#define UHCI_CMD_SWDBG 0x0020 +#define UHCI_CMD_CF 0x0040 +#define UHCI_CMD_MAXP 0x0080 +#define UHCI_STS 0x02 +#define UHCI_STS_USBINT 0x0001 +#define UHCI_STS_USBEI 0x0002 +#define UHCI_STS_RD 0x0004 +#define UHCI_STS_HSE 0x0008 +#define UHCI_STS_HCPE 0x0010 +#define UHCI_STS_HCH 0x0020 +#define UHCI_STS_ALLINTRS 0x003f +#define UHCI_INTR 0x04 +#define UHCI_INTR_TOCRCIE 0x0001 +#define UHCI_INTR_RIE 0x0002 +#define UHCI_INTR_IOCE 0x0004 +#define UHCI_INTR_SPIE 0x0008 +#define UHCI_FRNUM 0x06 +#define UHCI_FRNUM_MASK 0x03ff +#define UHCI_FLBASEADDR 0x08 +#define UHCI_SOF 0x0c +#define UHCI_SOF_MASK 0x7f +#define UHCI_PORTSC1 0x010 +#define UHCI_PORTSC2 0x012 +#define UHCI_PORTSC_CCS 0x0001 +#define UHCI_PORTSC_CSC 0x0002 +#define UHCI_PORTSC_PE 0x0004 +#define UHCI_PORTSC_POEDC 0x0008 +#define UHCI_PORTSC_LS 0x0030 +#define UHCI_PORTSC_LS_SHIFT 4 +#define UHCI_PORTSC_RD 0x0040 +#define UHCI_PORTSC_LSDA 0x0100 +#define UHCI_PORTSC_PR 0x0200 +#define UHCI_PORTSC_OCI 0x0400 +#define UHCI_PORTSC_OCIC 0x0800 +#define UHCI_PORTSC_SUSP 0x1000 + +#define URWMASK(x) ((x) & (UHCI_PORTSC_SUSP | \ + UHCI_PORTSC_PR | UHCI_PORTSC_RD | \ + UHCI_PORTSC_PE)) + +#endif /* _UHCIREG_H_ */ From c3139ea6f9d192f4905eabb674a9d551af62c048 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 15 Oct 2009 20:09:27 +0000 Subject: [PATCH 178/646] Only poll ukbd if KDB is active. Submitted by: HPS --- sys/dev/usb/input/ukbd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 1687755e33e..8378cafc73d 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -328,6 +329,9 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait) { DPRINTFN(2, "polling\n"); + if (kdb_active == 0) + return; /* Only poll if KDB is active */ + while (sc->sc_inputs == 0) { usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER); From 290512231ace1cf864d7094a029a8677af51ccb6 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 15 Oct 2009 20:15:29 +0000 Subject: [PATCH 179/646] Correct offset calcluation for the NCM implementation. Submitted by: HPS --- sys/dev/usb/net/if_cdce.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 86f7a9b99bf..cb33249c8b8 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -1088,7 +1088,7 @@ cdce_ncm_fill_tx_frames(struct usb_xfer *xfer, uint8_t index) sc->sc_ncm.hdr.dwSignature[2] = 'M'; sc->sc_ncm.hdr.dwSignature[3] = 'H'; USETW(sc->sc_ncm.hdr.wHeaderLength, sizeof(sc->sc_ncm.hdr)); - USETW(sc->sc_ncm.hdr.wBlockLength, offset); + USETW(sc->sc_ncm.hdr.wBlockLength, last_offset); USETW(sc->sc_ncm.hdr.wSequence, sc->sc_ncm.tx_seq); USETW(sc->sc_ncm.hdr.wDptIndex, sizeof(sc->sc_ncm.hdr)); @@ -1243,25 +1243,24 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) offset = UGETW(sc->sc_ncm.dp[x].wFrameIndex); temp = UGETW(sc->sc_ncm.dp[x].wFrameLength); - if ((offset + temp) > actlen) { - DPRINTFN(1, "invalid frame detected (ignored)\n"); - m = NULL; - } else if (temp >= sizeof(struct ether_header)) { - /* - * allocate a suitable memory buffer, if - * possible - */ - if (temp > (MCLBYTES - ETHER_ALIGN)) { - m = NULL; - continue; - } if (temp > (MHLEN - ETHER_ALIGN)) { - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - } else { - m = m_gethdr(M_DONTWAIT, MT_DATA); - } + if ((offset == 0) || + (temp < sizeof(struct ether_header)) || + (temp > (MCLBYTES - ETHER_ALIGN))) { + DPRINTFN(1, "NULL frame detected at %d\n", x); + m = NULL; + /* silently ignore this frame */ + continue; + } else if ((offset + temp) > actlen) { + DPRINTFN(1, "invalid frame " + "detected at %d\n", x); + m = NULL; + /* silently ignore this frame */ + continue; + } else if (temp > (MHLEN - ETHER_ALIGN)) { + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); } else { - m = NULL; /* dump it */ + m = m_gethdr(M_DONTWAIT, MT_DATA); } DPRINTFN(16, "frame %u, offset = %u, length = %u \n", From 0e22665fc7c7c3485d5196accc5999316f8909d6 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Thu, 15 Oct 2009 23:20:23 +0000 Subject: [PATCH 180/646] Allow $name_program to override $command in a more robust way that will not cause the value to be null if $command is not set. --- etc/rc.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.subr b/etc/rc.subr index fa372ddf369..2e502dbf44c 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -616,7 +616,7 @@ run_rc_command() esac eval _override_command=\$${name}_program - command=${command:+${_override_command:-$command}} + command=${_override_command:-$command} _keywords="start stop restart rcvar $extra_commands" rc_pid= From 051f6f8a7a9f5a7624cc1b9fc49422153cec1bf4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 16 Oct 2009 12:00:59 +0000 Subject: [PATCH 181/646] Move intr_describe() out of #ifdef SMP; the function is always required. Reviewed by: jhb --- sys/amd64/amd64/intr_machdep.c | 34 +++++++++++++++++----------------- sys/i386/i386/intr_machdep.c | 34 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index e72e13ab2c1..6ab80df9d87 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -400,6 +400,23 @@ atpic_reset(void) } #endif +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + #ifdef DDB /* * Dump data about interrupt handlers @@ -466,23 +483,6 @@ intr_bind(u_int vector, u_char cpu) return (intr_event_bind(isrc->is_event, cpu)); } -/* Add a description to an active interrupt handler. */ -int -intr_describe(u_int vector, void *ih, const char *descr) -{ - struct intsrc *isrc; - int error; - - isrc = intr_lookup_source(vector); - if (isrc == NULL) - return (EINVAL); - error = intr_event_describe_handler(isrc->is_event, ih, descr); - if (error) - return (error); - intrcnt_updatename(isrc); - return (0); -} - /* * Add a CPU to our mask of valid CPUs that can be destinations of * interrupts. diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c index 5a74a9d5830..75be20593a3 100644 --- a/sys/i386/i386/intr_machdep.c +++ b/sys/i386/i386/intr_machdep.c @@ -366,6 +366,23 @@ intr_init(void *dummy __unused) } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + #ifdef DDB /* * Dump data about interrupt handlers @@ -432,23 +449,6 @@ intr_bind(u_int vector, u_char cpu) return (intr_event_bind(isrc->is_event, cpu)); } -/* Add a description to an active interrupt handler. */ -int -intr_describe(u_int vector, void *ih, const char *descr) -{ - struct intsrc *isrc; - int error; - - isrc = intr_lookup_source(vector); - if (isrc == NULL) - return (EINVAL); - error = intr_event_describe_handler(isrc->is_event, ih, descr); - if (error) - return (error); - intrcnt_updatename(isrc); - return (0); -} - /* * Add a CPU to our mask of valid CPUs that can be destinations of * interrupts. From 7024354df3bd9a34c6e399d1a83872a9afe07246 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 16 Oct 2009 12:32:07 +0000 Subject: [PATCH 182/646] Sort SEE ALSO. --- share/man/man9/BUS_DESCRIBE_INTR.9 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9 index 3da7c429bdd..989780fdc60 100644 --- a/share/man/man9/BUS_DESCRIBE_INTR.9 +++ b/share/man/man9/BUS_DESCRIBE_INTR.9 @@ -88,10 +88,10 @@ the interrupt handler name. Zero is returned on success, otherwise an appropriate error is returned. .Sh SEE ALSO .Xr BUS_SETUP_INTR 9 , -.Xr device 9 , -.Xr printf 9 , .Xr systat 1 , -.Xr vmstat 8 +.Xr vmstat 8 , +.Xr device 9 , +.Xr printf 9 .Sh HISTORY The .Fn BUS_DESCRIBE_INTR From f6196ed2d408495ffeada81f048cfe496fae9def Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 16 Oct 2009 16:17:57 +0000 Subject: [PATCH 183/646] sh: Show more information about syntax errors in command substitution: the line number where the command substitution started. This applies to both the $() and `` forms but is most useful for `` because the other line number is relative to the enclosed text there. (For older versions, -v can be used as a workaround.) --- bin/sh/parser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 9e861620e5f..8dd1e7a7236 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1308,11 +1308,16 @@ parsebackq: { struct jmploc *const savehandler = handler; int savelen; int saveprompt; + const int bq_startlinno = plinno; if (setjmp(jmploc.loc)) { if (str) ckfree(str); handler = savehandler; + if (exception == EXERROR) { + startlinno = bq_startlinno; + synerror("Error in command substitution"); + } longjmp(handler->loc, 1); } INTOFF; From 12ac99dc464609272f9b59fc41483cd03386b2d1 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 16 Oct 2009 19:30:48 +0000 Subject: [PATCH 184/646] Close a race with caching of -ve name lookups in the NFS client. Specifically, clients only trust -ve cache entries while the directory remains unchanged and discard any -ve cache entries for a directory when they notice that the modification time of a directory entry changes. The race involves two concurrent lookups as follows: - Thread A does a lookup for file 'foo' which sends a lookup RPC to the server. The lookup fails and the server replies. - The 'foo' file is created (either by the same client or a different client) updating the modification time on the parent directory of 'foo'. - Thread B does a lookup for a different file 'bar' which updates the cached attributes of the parent directory of 'foo' to reflect the new modification time after 'foo' was created. - Thread A finally resumes execution to parse the reply from the NFS server. It adds a -ve cache entry and sets the cached value of the directory's modification time that is used for invalidating -ve cached lookups to the new modification time set by thread B. At this point, future lookups of 'foo' will honor the -ve cached entry until the cached entry is pushed out of the name cache's LRU or the modification time of the parent directory is changed again by some other change. The fix is to read the directory's modification time before sending the lookup RPC and use that cached modification time when setting the directory's cached modification time. Also, we do not add a -ve cache entry if another thread has added -ve cache entry that set the directory's cached modification time to a newer value than the value we read before sending the lookup RPC. Reviewed by: rmacklem MFC after: 1 week --- sys/nfsclient/nfs_vnops.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 7dfd298da6d..dc619275aea 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -924,6 +924,7 @@ nfs_lookup(struct vop_lookup_args *ap) struct vnode **vpp = ap->a_vpp; struct mount *mp = dvp->v_mount; struct vattr vattr; + time_t dmtime; int flags = cnp->cn_flags; struct vnode *newvp; struct nfsmount *nmp; @@ -935,7 +936,7 @@ nfs_lookup(struct vop_lookup_args *ap) int error = 0, attrflag, fhsize, ltype; int v3 = NFS_ISV3(dvp); struct thread *td = cnp->cn_thread; - + *vpp = NULLVP; if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) @@ -992,6 +993,19 @@ nfs_lookup(struct vop_lookup_args *ap) np->n_dmtime = 0; mtx_unlock(&np->n_mtx); } + + /* + * Cache the modification time of the parent directory in case + * the lookup fails and results in adding the first negative + * name cache entry for the directory. Since this is reading + * a single time_t, don't bother with locking. The + * modification time may be a bit stale, but it must be read + * before performing the lookup RPC to prevent a race where + * another lookup updates the timestamp on the directory after + * the lookup RPC has been performed on the server but before + * n_dmtime is set at the end of this function. + */ + dmtime = np->n_vattr.va_mtime.tv_sec; error = 0; newvp = NULLVP; nfsstats.lookupcache_misses++; @@ -1130,13 +1144,25 @@ nfsmout: * Maintain n_dmtime as the modification time * of the parent directory when the oldest -ve * name cache entry for this directory was - * added. + * added. If a -ve cache entry has already + * been added with a newer modification time + * by a concurrent lookup, then don't bother + * adding a cache entry. The modification + * time of the directory might have changed + * due to the file this lookup failed to find + * being created. In that case a subsequent + * lookup would incorrectly use the entry + * added here instead of doing an extra + * lookup. */ mtx_lock(&np->n_mtx); - if (np->n_dmtime == 0) - np->n_dmtime = np->n_vattr.va_mtime.tv_sec; - mtx_unlock(&np->n_mtx); - cache_enter(dvp, NULL, cnp); + if (np->n_dmtime <= dmtime) { + if (np->n_dmtime == 0) + np->n_dmtime = dmtime; + mtx_unlock(&np->n_mtx); + cache_enter(dvp, NULL, cnp); + } else + mtx_unlock(&np->n_mtx); } return (ENOENT); } From c64b097bfcfe8f6fd04d5a3b982ab65d9634dfd6 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Fri, 16 Oct 2009 20:52:45 +0000 Subject: [PATCH 185/646] - If lstat()/stat() fails with an error other than ENOENT, don't ignore the error and assume that the file doesn't exist. Touch could return success with -c option even if the file existed and time was not set. - If the first utimes_f() call fails with -A option, give up and don't continue trying to set times to current time. [1] - Set exit status to 1 when setting of timestamps fails for a directory or symbolic link even though lstat()/stat() would succeed. - Don't print bogus error message when rw() succeeds. PR: bin/112213 Submitted by: jilles [1] Reviewed by: jilles Approved by: trasz (mentor) --- usr.bin/touch/touch.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/usr.bin/touch/touch.c b/usr.bin/touch/touch.c index 624ce05065e..5ceb1757201 100644 --- a/usr.bin/touch/touch.c +++ b/usr.bin/touch/touch.c @@ -164,6 +164,11 @@ main(int argc, char *argv[]) for (rval = 0; *argv; ++argv) { /* See if the file exists. */ if (stat_f(*argv, &sb) != 0) { + if (errno != ENOENT) { + rval = 1; + warn("%s", *argv); + continue; + } if (!cflag) { /* Create the file. */ fd = open(*argv, @@ -206,7 +211,7 @@ main(int argc, char *argv[]) continue; /* If the user specified a time, nothing else we can do. */ - if (timeset) { + if (timeset || Aflag) { rval = 1; warn("%s", *argv); continue; @@ -222,11 +227,13 @@ main(int argc, char *argv[]) continue; /* Try reading/writing. */ - if (!S_ISLNK(sb.st_mode) && !S_ISDIR(sb.st_mode) && - rw(*argv, &sb, fflag)) + if (!S_ISLNK(sb.st_mode) && !S_ISDIR(sb.st_mode)) { + if (rw(*argv, &sb, fflag)) + rval = 1; + } else { rval = 1; - else warn("%s", *argv); + } } exit(rval); } From 018a4f5fcfdabdc5a398b58dee86878216106234 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Sat, 17 Oct 2009 00:33:55 +0000 Subject: [PATCH 186/646] Add myself. Approved by: imp (mentor) --- share/misc/committers-src.dot | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index 626a3cb13ac..7636b66f243 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -138,6 +138,7 @@ mjacob [label="Matt Jacob\nmjacob@FreeBSD.org\n1997/08/13"] mlaier [label="Max Laier\nmlaier@FreeBSD.org\n2004/02/10"] mr [label="Michael Reifenberger\nmr@FreeBSD.org\n2001/09/30"] murray [label="Murray Stokely\nmurray@FreeBSD.org\n2000/04/05"] +neel [label="Neel Natu\nneel@FreeBSD.org\n2009/09/20"] netchild [label="Alexander Leidinger\nnetchild@FreeBSD.org\n2005/03/31"] njl [label="Nate Lawson\nnjl@FreeBSD.org\n2002/08/07"] nork [label="Norikatsu Shigemura\nnork@FreeBSD.org\n2009/06/09"] @@ -289,6 +290,7 @@ imp -> jon imp -> keichii imp -> mb imp -> mr +imp -> neel imp -> non imp -> nork imp -> onoe From 39410373b3d4a985f2263a688cebb667c5d55a5d Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 17 Oct 2009 08:59:41 +0000 Subject: [PATCH 187/646] Print backspaces after echoing an EOF. Applications like shells expect EOF to give no graphical output, while our implementation prints ^D by default (tunable with stty echoctl). Make the new implementation behave like the old TTY code. Print two backspaces afterwards. Reported by: koitsu MFC after: 1 month --- sys/kern/tty_ttydisc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c index d79a2b761d5..6afac8df5e9 100644 --- a/sys/kern/tty_ttydisc.c +++ b/sys/kern/tty_ttydisc.c @@ -624,15 +624,21 @@ ttydisc_echo_force(struct tty *tp, char c, int quote) /* * Only use ^X notation when ECHOCTL is turned on and * we've got an quoted control character. + * + * Print backspaces when echoing an end-of-file. */ - char ob[2] = { '^', '?' }; + char ob[4] = "^?\b\b"; /* Print ^X notation. */ if (c != 0x7f) ob[1] = c + 'A' - 1; - tp->t_column += 2; - return ttyoutq_write_nofrag(&tp->t_outq, ob, 2); + if (!quote && CMP_CC(VEOF, c)) { + return ttyoutq_write_nofrag(&tp->t_outq, ob, 4); + } else { + tp->t_column += 2; + return ttyoutq_write_nofrag(&tp->t_outq, ob, 2); + } } else { /* Can just be printed. */ tp->t_column++; From e95ee133aa3630fbb79363f2c3664848ddf3bd43 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 17 Oct 2009 15:53:15 +0000 Subject: [PATCH 188/646] Check error of dlfunc(3). MFC after: 3 days --- bin/csh/iconv_stub.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bin/csh/iconv_stub.c b/bin/csh/iconv_stub.c index 6bbbbb02a01..d1a9e475d87 100644 --- a/bin/csh/iconv_stub.c +++ b/bin/csh/iconv_stub.c @@ -61,9 +61,20 @@ dl_iconv_open(const char *tocode, const char *fromcode) if (iconvlib == NULL) return (iconv_t)-1; iconv_open = (iconv_open_t *)dlfunc(iconvlib, ICONV_OPEN); + if (iconv_open == NULL) + goto dlfunc_err; dl_iconv = (dl_iconv_t *)dlfunc(iconvlib, ICONV_ENGINE); + if (dl_iconv == NULL) + goto dlfunc_err; dl_iconv_close = (dl_iconv_close_t *)dlfunc(iconvlib, ICONV_CLOSE); + if (dl_iconv_close == NULL) + goto dlfunc_err; } return iconv_open(tocode, fromcode); + +dlfunc_err: + dlclose(iconvlib); + iconvlib = NULL; + return (iconv_t)-1; } From c5a82ce01d8b5d3477a021f76a933401339b1d85 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 17 Oct 2009 21:09:15 +0000 Subject: [PATCH 189/646] Remove a circular dependency on routing Submitted by: Mykola Dzham Approved by: hrs --- etc/rc.d/faith | 2 +- etc/rc.d/stf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/faith b/etc/rc.d/faith index a7f4cd8cdf8..9994114cd46 100755 --- a/etc/rc.d/faith +++ b/etc/rc.d/faith @@ -3,7 +3,7 @@ # # PROVIDE: faith -# REQUIRE: netif routing +# REQUIRE: netif # KEYWORD: nojail . /etc/rc.subr diff --git a/etc/rc.d/stf b/etc/rc.d/stf index 6f7347b98c5..bb7f5b5ea55 100755 --- a/etc/rc.d/stf +++ b/etc/rc.d/stf @@ -3,7 +3,7 @@ # # PROVIDE: stf -# REQUIRE: netif routing +# REQUIRE: netif # KEYWORD: nojail . /etc/rc.subr From a0585a1450ee64eb73f9d946149a12871f0788eb Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Sun, 18 Oct 2009 00:11:49 +0000 Subject: [PATCH 190/646] overhauls urtw(4) for supporting RTL8187B devices properly that there was major changes to initialize RF chipset and set H/W registers and removed a lot of magic numbers on code. Details are as follows: - uses the endpoint 0x89 to get TX status information which used to get TX complete or retry numbers or get a beacon interrupt. It's only valuable for RTL8187B. - removes urtw_write[8|16|32]_i functions that it's useless now. - uses ic->ic_updateslot to set SLOT, SIFS, DIES, EIFS, CW_VAL registers that doesn't set these whenever the channel is changed. - code for initializing RF chipset for RTL8187B changed a lot that there was many problems on TX transfers so it doesn't work properly even if just for a ping/pong. Now it becomes more stable than before that TX throughputs using netperf(1) were about 15 ~ 17Mbps/s though sometimes it encounters packet losses. - removes a lot of magic numbers that in the previous all of representing RX and TX descriptors were consisted of magic numbers and structures. It'd be more readable rather than before. - calculates TX duration more accurately for urtw(4) devices. - style(9) --- sys/dev/usb/wlan/if_urtw.c | 864 ++++++++++++++++++++-------------- sys/dev/usb/wlan/if_urtwreg.h | 159 ++++++- sys/dev/usb/wlan/if_urtwvar.h | 8 +- 3 files changed, 659 insertions(+), 372 deletions(-) diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 2c8b7c20ba5..938107ae6dd 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -76,6 +76,7 @@ enum { URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */ URTW_DEBUG_STAT = 0x00000040, /* statistic */ URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */ + URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */ URTW_DEBUG_ANY = 0xffffffff }; #define DPRINTF(sc, m, fmt, ...) do { \ @@ -326,13 +327,47 @@ static struct urtw_pair urtw_8225v2_rf_part1[] = { { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 } }; -static struct urtw_pair urtw_8225v2b_rf_part1[] = { +static struct urtw_pair urtw_8225v2b_rf_part0[] = { { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 }, { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a }, { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb }, { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 } }; +static struct urtw_pair urtw_8225v2b_rf_part1[] = { + {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00}, + {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43}, + {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46}, + {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00}, + {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00}, + {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00}, + {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b}, + {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09}, + {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff}, + {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e}, + {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03}, + {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06}, + {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00}, + {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68}, + {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d}, + {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08}, + {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04}, + {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23}, + {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08}, + {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08}, + {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08}, + {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56}, + {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f}, + {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24}, + {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07}, + {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12}, + {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a}, + {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80}, + {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03}, + {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01}, + {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00} +}; + static struct urtw_pair urtw_8225v2_rf_part2[] = { { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 }, { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 }, @@ -478,6 +513,7 @@ static const uint8_t urtw_8187b_reg_table[][3] = { static usb_callback_t urtw_bulk_rx_callback; static usb_callback_t urtw_bulk_tx_callback; +static usb_callback_t urtw_bulk_tx_status_callback; static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = { [URTW_8187B_BULK_RX] = { @@ -492,6 +528,18 @@ static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = { }, .callback = urtw_bulk_rx_callback }, + [URTW_8187B_BULK_TX_STATUS] = { + .type = UE_BULK, + .endpoint = 0x89, + .direction = UE_DIR_IN, + .bufsize = MCLBYTES, + .flags = { + .ext_buffer = 1, + .pipe_bof = 1, + .short_xfer_ok = 1 + }, + .callback = urtw_bulk_tx_status_callback + }, [URTW_8187B_BULK_TX_BE] = { .type = UE_BULK, .endpoint = URTW_8187B_TXPIPE_BE, @@ -703,9 +751,6 @@ static usb_error_t urtw_adapter_start(struct urtw_softc *); static usb_error_t urtw_adapter_start_b(struct urtw_softc *); static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t); static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *); -static usb_error_t urtw_write16_i(struct urtw_softc *, int, uint16_t, int); -static usb_error_t urtw_write8_i(struct urtw_softc *, int, uint8_t, int); -static usb_error_t urtw_write32_i(struct urtw_softc *, int, uint32_t, int); static usb_error_t urtw_do_request(struct urtw_softc *, struct usb_device_request *, void *); static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int); @@ -713,6 +758,10 @@ static usb_error_t urtw_led_off(struct urtw_softc *, int); static void urtw_abort_xfers(struct urtw_softc *); static struct urtw_data * urtw_getbuf(struct urtw_softc *sc); +static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t, + uint8_t); +static void urtw_updateslot(struct ifnet *); +static void urtw_updateslottask(void *, int); static int urtw_match(device_t dev) @@ -757,6 +806,7 @@ urtw_attach(device_t dev) MTX_DEF); usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0); TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc); + TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc); callout_init(&sc->sc_watchdog_ch, 0); if (sc->sc_flags & URTW_RTL8187B) { @@ -845,7 +895,7 @@ urtw_attach(device_t dev) ic->ic_scan_start = urtw_scan_start; ic->ic_scan_end = urtw_scan_end; ic->ic_set_channel = urtw_set_channel; - + ic->ic_updateslot = urtw_updateslot; ic->ic_vap_create = urtw_vap_create; ic->ic_vap_delete = urtw_vap_delete; ic->ic_update_mcast = urtw_update_mcast; @@ -878,6 +928,7 @@ urtw_detach(device_t dev) return (0); urtw_stop(ifp, 1); + ieee80211_draintask(ic, &sc->sc_updateslot_task); ieee80211_draintask(ic, &sc->sc_led_task); usb_callout_drain(&sc->sc_led_ch); @@ -1014,6 +1065,9 @@ urtw_init_locked(void *arg) if (error != 0) goto fail; + if (sc->sc_flags & URTW_RTL8187B) + usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -1036,7 +1090,6 @@ static usb_error_t urtw_adapter_start_b(struct urtw_softc *sc) { #define N(a) (sizeof(a) / sizeof((a)[0])) - int i; uint8_t data8; usb_error_t error; @@ -1068,81 +1121,12 @@ urtw_adapter_start_b(struct urtw_softc *sc) if (error) goto fail; - urtw_write16_m(sc, 0x2d, 0xfff); - urtw_read8_m(sc, URTW_CW_CONF, &data8); - urtw_write8_m(sc, URTW_CW_CONF, data8 | URTW_CW_CONF_PERPACKET_RETRY); - urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8); - data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN | - URTW_TX_AGC_CTL_PERPACKET_ANTSEL; - urtw_write8_m(sc, URTW_TX_AGC_CTL, data8); - - error = urtw_write16_i(sc, 0xe0, 0xfff, 1); - if (error) - goto fail; - - urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8); - urtw_write8_m(sc, URTW_RATE_FALLBACK, data8 | URTW_RATE_FALLBACK_ENABLE); - - urtw_write16_m(sc, URTW_ATIM_WND, 2); - urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100); - error = urtw_write16_i(sc, 0xd4, 0xffff, 1); - if (error) - goto fail; - - error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG); - if (error) - goto fail; - urtw_read8_m(sc, URTW_CONFIG1, &data8); - urtw_write8_m(sc, URTW_CONFIG1, (data8 & 0x3f) | 0x80); - error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); - if (error) - goto fail; - - urtw_write8_m(sc, URTW_WPA_CONFIG, 0); - for (i = 0; i < N(urtw_8187b_reg_table); i++) { - error = urtw_write8_i(sc, urtw_8187b_reg_table[i][0], - urtw_8187b_reg_table[i][1], urtw_8187b_reg_table[i][2]); - if (error) - goto fail; - } - - urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50); - urtw_write16_m(sc, URTW_INT_MIG, 0); - - error = urtw_write32_i(sc, 0xf0, 0, 1); - if (error) - goto fail; - error = urtw_write32_i(sc, 0xf4, 0, 1); - if (error) - goto fail; - error = urtw_write8_i(sc, 0xf8, 0, 1); - if (error) - goto fail; - - urtw_write32_m(sc, URTW_RF_TIMING, 0x00004001); - - error = urtw_write16_i(sc, 0x72, 0x569a, 2); - if (error) - goto fail; - - error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG); - if (error) - goto fail; - urtw_read8_m(sc, URTW_CONFIG3, &data8); - urtw_write8_m(sc, URTW_CONFIG3, data8 | URTW_CONFIG3_ANAPARAM_WRITE); - error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); - if (error) - goto fail; - - urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480); - urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488); - urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff); - usb_pause_mtx(&sc->sc_mtx, 100); - error = sc->sc_rf_init(sc); if (error != 0) goto fail; + urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE); + /* fix RTL8187B RX stall */ error = urtw_intr_enable(sc); if (error) goto fail; @@ -1171,42 +1155,21 @@ urtw_adapter_start_b(struct urtw_softc *sc) urtw_read8_m(sc, 0xdb, &data8); urtw_write8_m(sc, 0xdb, data8 | (1 << 2)); - error = urtw_write16_i(sc, 0x72, 0x59fa, 3); - if (error) - goto fail; - error = urtw_write16_i(sc, 0x74, 0x59d2, 3); - if (error) - goto fail; - error = urtw_write16_i(sc, 0x76, 0x59d2, 3); - if (error) - goto fail; - error = urtw_write16_i(sc, 0x78, 0x19fa, 3); - if (error) - goto fail; - error = urtw_write16_i(sc, 0x7a, 0x19fa, 3); - if (error) - goto fail; - error = urtw_write16_i(sc, 0x7c, 0x00d0, 3); - if (error) - goto fail; + urtw_write16_m(sc, 0x372, 0x59fa); + urtw_write16_m(sc, 0x374, 0x59d2); + urtw_write16_m(sc, 0x376, 0x59d2); + urtw_write16_m(sc, 0x378, 0x19fa); + urtw_write16_m(sc, 0x37a, 0x19fa); + urtw_write16_m(sc, 0x37c, 0x00d0); urtw_write8_m(sc, 0x61, 0); - error = urtw_write8_i(sc, 0x80, 0x0f, 1); - if (error) - goto fail; - error = urtw_write8_i(sc, 0x83, 0x03, 1); - if (error) - goto fail; + + urtw_write8_m(sc, 0x180, 0x0f); + urtw_write8_m(sc, 0x183, 0x03); urtw_write8_m(sc, 0xda, 0x10); - error = urtw_write8_i(sc, 0x4d, 0x08, 2); - if (error) - goto fail; - - urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321B); - - error = urtw_write16_i(sc, 0xec, 0x800, 1); - if (error) - goto fail; + urtw_write8_m(sc, 0x24d, 0x08); + urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b); + urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */ fail: return (error); #undef N @@ -1310,40 +1273,10 @@ urtw_8187b_cmd_reset(struct urtw_softc *sc) device_printf(sc->sc_dev, "reset timeout\n"); goto fail; } - - error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD); - if (error) - goto fail; - - for (i = 0; i < 20; i++) { - usb_pause_mtx(&sc->sc_mtx, 4); - urtw_read8_m(sc, URTW_EPROM_CMD, &data8); - if (!(data8 & URTW_EPROM_CMD_CONFIG)) - break; - } - if (i >= 20) { - device_printf(sc->sc_dev, "eeprom reset timeout\n"); - goto fail; - } - fail: return (error); } -static usb_error_t -urtw_write16_i(struct urtw_softc *sc, int val, uint16_t data, int idx) -{ - struct usb_device_request req; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, idx & 0x3); - USETW(req.wLength, sizeof(uint16_t)); - - return (urtw_do_request(sc, &req, &data)); -} - static usb_error_t urtw_do_request(struct urtw_softc *sc, struct usb_device_request *req, void *data) @@ -1367,34 +1300,6 @@ urtw_do_request(struct urtw_softc *sc, return (err); } -static usb_error_t -urtw_write8_i(struct urtw_softc *sc, int val, uint8_t data, int idx) -{ - struct usb_device_request req; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, idx & 0x3); - USETW(req.wLength, sizeof(uint8_t)); - - return (urtw_do_request(sc, &req, &data)); -} - -static usb_error_t -urtw_write32_i(struct urtw_softc *sc, int val, uint32_t data, int idx) -{ - struct usb_device_request req; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, idx & 0x3); - USETW(req.wLength, sizeof(uint32_t)); - - return (urtw_do_request(sc, &req, &data)); -} - static void urtw_stop_locked(struct ifnet *ifp, int disable) { @@ -1534,6 +1439,7 @@ urtw_start(struct ifnet *ifp) } sc->sc_txtimer = 5; + callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); } URTW_UNLOCK(sc); } @@ -1733,14 +1639,12 @@ static int urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct urtw_data *data, int prior) { - int xferlen; struct ifnet *ifp = sc->sc_ifp; struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); struct ieee80211_key *k; const struct ieee80211_txparam *tp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = ni->ni_vap; - struct urtw_8187b_txhdr *hdr; struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = { sc->sc_xfer[URTW_8187B_BULK_TX_BE], sc->sc_xfer[URTW_8187B_BULK_TX_BK], @@ -1748,6 +1652,10 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, sc->sc_xfer[URTW_8187B_BULK_TX_VO] }; struct usb_xfer *xfer; + int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate, + pkttime = 0, txdur = 0, isshort = 0, xferlen; + uint16_t acktime, rtstime, ctstime; + uint32_t flags; usb_error_t error; URTW_ASSERT_LOCKED(sc); @@ -1780,60 +1688,107 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, ieee80211_radiotap_tx(vap, m0); } + if ((wh->i_fc[10] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT || + (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) { + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; + rate = tp->mgmtrate; + } else { + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + /* for data frames */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) + rate = tp->mcastrate; + else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + rate = tp->ucastrate; + else + rate = urtw_rtl2rate(sc->sc_currate); + } + + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) + txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len + + IEEE80211_CRC_LEN, rate, 0, 0); + else { + acktime = urtw_compute_txtime(14, 2,0, 0); + if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) { + rtsenable = 1; + ctsenable = 0; + rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0); + ctstime = urtw_compute_txtime(14, 2, 0, 0); + pkttime = urtw_compute_txtime(m0->m_pkthdr.len + + IEEE80211_CRC_LEN, rate, 0, isshort); + rtsdur = ctstime + pkttime + acktime + + 3 * URTW_ASIFS_TIME; + txdur = rtstime + rtsdur; + } else { + rtsenable = ctsenable = rtsdur = 0; + pkttime = urtw_compute_txtime(m0->m_pkthdr.len + + IEEE80211_CRC_LEN, rate, 0, isshort); + txdur = pkttime + URTW_ASIFS_TIME + acktime; + } + + if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) + dur = urtw_compute_txtime(m0->m_pkthdr.len + + IEEE80211_CRC_LEN, rate, 0, isshort) + + 3 * URTW_ASIFS_TIME + + 2 * acktime; + else + dur = URTW_ASIFS_TIME + acktime; + } + *(uint16_t *)wh->i_dur = htole16(dur); + xferlen = m0->m_pkthdr.len; xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3); if ((0 == xferlen % 64) || (0 == xferlen % 512)) xferlen += 1; bzero(data->buf, URTW_TX_MAXSIZE); - data->buf[0] = m0->m_pkthdr.len & 0xff; - data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8; - data->buf[1] |= (1 << 7); - + flags = m0->m_pkthdr.len & 0xfff; + flags |= URTW_TX_FLAG_NO_ENC; if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) && (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) && (sc->sc_currate != 0)) - data->buf[2] |= 1; - if ((m0->m_pkthdr.len > vap->iv_rtsthreshold) && - prior == URTW_PRIORITY_LOW) { - device_printf(sc->sc_dev, "TODO tx.\n"); - return (EIO); - } + flags |= URTW_TX_FLAG_SPLCP; if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) - data->buf[2] |= (1 << 1); - /* RTS rate - 10 means we use a basic rate. */ - data->buf[2] |= (urtw_rate2rtl(2) << 3); - /* - * XXX currently TX rate control depends on the rate value of - * RX descriptor because I don't know how to we can control TX rate - * in more smart way. Please fix me you find a thing. - */ - data->buf[3] = sc->sc_currate; - if (prior == URTW_PRIORITY_NORMAL) { - tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - data->buf[3] = urtw_rate2rtl(tp->mcastrate); - else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) - data->buf[3] = urtw_rate2rtl(tp->ucastrate); - } + flags |= URTW_TX_FLAG_MOREFRAG; + + flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT; if (sc->sc_flags & URTW_RTL8187B) { - hdr = (struct urtw_8187b_txhdr *)data->buf; - hdr->rts_duration = 0; - hdr->len = 0; - hdr->retry = 3 | (7 << 4) | 11; - hdr->tx_duration = ieee80211_compute_duration(ic->ic_rt, - m0->m_pkthdr.len + IEEE80211_CRC_LEN, - urtw_rtl2rate(data->buf[3]), - (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0); - /* XXX MUST fill another variables like rts_duration, tx_.. */ - m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[32]); + struct urtw_8187b_txhdr *tx; + + tx = (struct urtw_8187b_txhdr *)data->buf; + if (ctsenable) + flags |= URTW_TX_FLAG_CTS; + if (rtsenable) { + flags |= URTW_TX_FLAG_RTS; + flags |= (urtw_rate2rtl(11) & 0xf) << + URTW_TX_FLAG_RTSRATE_SHIFT; + tx->rtsdur = rtsdur; + } + tx->flag = htole32(flags); + tx->txdur = txdur; + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT && + (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == + IEEE80211_FC0_SUBTYPE_PROBE_RESP) + tx->retry = 1; + else + tx->retry = URTW_TX_MAXRETRY; + m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1)); } else { - data->buf[8] = 3; /* CW minimum */ - data->buf[8] |= (7 << 4); /* CW maximum */ - data->buf[9] |= 11; /* retry limitation */ - m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]); + struct urtw_8187l_txhdr *tx; + + tx = (struct urtw_8187l_txhdr *)data->buf; + if (rtsenable) { + flags |= URTW_TX_FLAG_RTS; + tx->rtsdur = rtsdur; + } + flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT; + tx->flag = htole32(flags); + tx->retry = 3; /* CW minimum */ + tx->retry = 7 << 4; /* CW maximum */ + tx->retry = URTW_TX_MAXRETRY << 8; /* retry limitation */ + m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1)); } data->buflen = xferlen; @@ -2054,8 +2009,8 @@ urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data) req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = URTW_8187_GETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint8_t)); error = urtw_do_request(sc, &req, data); @@ -2072,8 +2027,8 @@ urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data) req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = URTW_8187_GETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint16_t)); error = urtw_do_request(sc, &req, data); @@ -2090,8 +2045,8 @@ urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data) req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = URTW_8187_GETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint32_t)); error = urtw_do_request(sc, &req, data); @@ -2107,8 +2062,8 @@ urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data) req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint8_t)); return (urtw_do_request(sc, &req, &data)); @@ -2123,8 +2078,8 @@ urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data) req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint16_t)); return (urtw_do_request(sc, &req, &data)); @@ -2139,8 +2094,8 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data) req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = URTW_8187_SETREGS_REQ; - USETW(req.wValue, val | 0xff00); - USETW(req.wIndex, 0); + USETW(req.wValue, (val & 0xff) | 0xff00); + USETW(req.wIndex, (val >> 8) & 0x3); USETW(req.wLength, sizeof(uint32_t)); return (urtw_do_request(sc, &req, &data)); @@ -2404,6 +2359,38 @@ urtw_get_rfchip(struct urtw_softc *sc) uint32_t data; usb_error_t error; + if (sc->sc_flags & URTW_RTL8187B) { + urtw_read8_m(sc, 0xe1, &data8); + switch (data8) { + case 0: + sc->sc_flags |= URTW_RTL8187B_REV_B; + break; + case 1: + sc->sc_flags |= URTW_RTL8187B_REV_D; + break; + case 2: + sc->sc_flags |= URTW_RTL8187B_REV_E; + break; + default: + device_printf(sc->sc_dev, "unknown type: %#x\n", data8); + sc->sc_flags |= URTW_RTL8187B_REV_B; + break; + } + } else { + urtw_read32_m(sc, URTW_TX_CONF, &data); + switch (data & URTW_TX_HWMASK) { + case URTW_TX_R8187vD_B: + sc->sc_flags |= URTW_RTL8187B; + break; + case URTW_TX_R8187vD: + break; + default: + device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n", + data & URTW_TX_HWMASK); + break; + } + } + error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data); if (error != 0) goto fail; @@ -2437,12 +2424,6 @@ urtw_get_rfchip(struct urtw_softc *sc) /* never reach */ } - if (sc->sc_flags & URTW_RTL8187B) { - urtw_read8_m(sc, 0xe1, &data8); - sc->sc_flags |= (data8 == 0) ? URTW_RTL8187B_REV_B : - (data8 == 1) ? URTW_RTL8187B_REV_D : URTW_RTL8187B_REV_E; - } - device_printf(sc->sc_dev, "%s rf %s hwrev %s\n", (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l", ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" : @@ -2762,8 +2743,6 @@ fail0: return (error); static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; - struct ieee80211_channel *c = ic->ic_curchan; usb_error_t error; error = urtw_8225_set_txpwrlvl(sc, chan); @@ -2771,27 +2750,6 @@ urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan) goto fail; urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]); usb_pause_mtx(&sc->sc_mtx, 10); - - urtw_write8_m(sc, URTW_SIFS, 0x22); - - if (sc->sc_state == IEEE80211_S_ASSOC && - ic->ic_flags & IEEE80211_F_SHSLOT) - urtw_write8_m(sc, URTW_SLOT, 0x9); - else - urtw_write8_m(sc, URTW_SLOT, 0x14); - - if (IEEE80211_IS_CHAN_G(c)) { - /* for G */ - urtw_write8_m(sc, URTW_DIFS, 0x14); - urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14); - urtw_write8_m(sc, URTW_CW_VAL, 0x73); - } else { - /* for B */ - urtw_write8_m(sc, URTW_DIFS, 0x24); - urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24); - urtw_write8_m(sc, URTW_CW_VAL, 0xa5); - } - fail: return (error); } @@ -3039,8 +2997,6 @@ fail: static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; - struct ieee80211_channel *c = ic->ic_curchan; usb_error_t error; error = urtw_8225v2_set_txpwrlvl(sc, chan); @@ -3049,27 +3005,6 @@ urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan) urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]); usb_pause_mtx(&sc->sc_mtx, 10); - - urtw_write8_m(sc, URTW_SIFS, 0x22); - - if(sc->sc_state == IEEE80211_S_ASSOC && - ic->ic_flags & IEEE80211_F_SHSLOT) - urtw_write8_m(sc, URTW_SLOT, 0x9); - else - urtw_write8_m(sc, URTW_SLOT, 0x14); - - if (IEEE80211_IS_CHAN_G(c)) { - /* for G */ - urtw_write8_m(sc, URTW_DIFS, 0x14); - urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14); - urtw_write8_m(sc, URTW_CW_VAL, 0x73); - } else { - /* for B */ - urtw_write8_m(sc, URTW_DIFS, 0x24); - urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24); - urtw_write8_m(sc, URTW_CW_VAL, 0xa5); - } - fail: return (error); } @@ -3272,53 +3207,156 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) { #define N(a) (sizeof(a) / sizeof((a)[0])) int i; + uint8_t data8; usb_error_t error; + error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG); + if (error) + goto fail; + + /* + * initialize extra registers on 8187 + */ + urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff); + + /* retry limit */ + urtw_read8_m(sc, URTW_CW_CONF, &data8); + data8 |= URTW_CW_CONF_PERPACKET_RETRY; + urtw_write8_m(sc, URTW_CW_CONF, data8); + + /* TX AGC */ + urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8); + data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN; + urtw_write8_m(sc, URTW_TX_AGC_CTL, data8); + + /* Auto Rate Fallback Control */ +#define URTW_ARFR 0x1e0 + urtw_write16_m(sc, URTW_ARFR, 0xfff); + urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8); + urtw_write8_m(sc, URTW_RATE_FALLBACK, + data8 | URTW_RATE_FALLBACK_ENABLE); + + urtw_read8_m(sc, URTW_MSR, &data8); + urtw_write8_m(sc, URTW_MSR, data8 & 0xf3); + urtw_read8_m(sc, URTW_MSR, &data8); + urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA); + urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl); + + urtw_write16_m(sc, URTW_ATIM_WND, 2); + urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100); +#define URTW_FEMR_FOR_8187B 0x1d4 + urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff); + + /* led type */ + urtw_read8_m(sc, URTW_CONFIG1, &data8); + data8 = (data8 & 0x3f) | 0x80; + urtw_write8_m(sc, URTW_CONFIG1, data8); + + /* applying MAC address again. */ + urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]); + urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff); + + error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); + if (error) + goto fail; + + urtw_write8_m(sc, URTW_WPA_CONFIG, 0); + + /* + * MAC configuration + */ for (i = 0; i < N(urtw_8225v2b_rf_part1); i++) - urtw_8225_write(sc, urtw_8225v2b_rf_part1[i].reg, + urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg, urtw_8225v2b_rf_part1[i].val); + urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50); + urtw_write16_m(sc, URTW_INT_MIG, 0x0000); + urtw_write32_m(sc, 0x1f0, 0); + urtw_write32_m(sc, 0x1f4, 0); + urtw_write8_m(sc, 0x1f8, 0); + urtw_write32_m(sc, URTW_RF_TIMING, 0x4001); - urtw_8225_write(sc, - URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1); +#define URTW_RFSW_CTRL 0x272 + urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a); - for (i = 0; i < N(urtw_8225v2b_rxgain); i++) { + /* + * initialize PHY + */ + error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG); + if (error) + goto fail; + urtw_read8_m(sc, URTW_CONFIG3, &data8); + urtw_write8_m(sc, URTW_CONFIG3, + data8 | URTW_CONFIG3_ANAPARAM_WRITE); + + error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); + if (error) + goto fail; + + /* setup RFE initial timing */ + urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480); + urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488); + urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff); + usb_pause_mtx(&sc->sc_mtx, 1100); + + for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) { + urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg, + urtw_8225v2b_rf_part0[i].val); + usb_pause_mtx(&sc->sc_mtx, 1); + } + urtw_8225_write(sc, 0x00, 0x01b7); + + for (i = 0; i < 95; i++) { urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1)); + usb_pause_mtx(&sc->sc_mtx, 1); urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225v2b_rxgain[i]); + usb_pause_mtx(&sc->sc_mtx, 1); } urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080); + usb_pause_mtx(&sc->sc_mtx, 1); urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004); + usb_pause_mtx(&sc->sc_mtx, 1); urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7); + usb_pause_mtx(&sc->sc_mtx, 1); + usb_pause_mtx(&sc->sc_mtx, 3000); urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d); + usb_pause_mtx(&sc->sc_mtx, 2000); urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d); + usb_pause_mtx(&sc->sc_mtx, 1); urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf); + usb_pause_mtx(&sc->sc_mtx, 1); urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03); urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07); urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03); urtw_8187_write_phy_ofdm(sc, 0x80, 0x12); - for (i = 0; i < N(urtw_8225z2_agc); i++) { - urtw_8187_write_phy_ofdm(sc, 0xf, urtw_8225z2_agc[i]); - urtw_8187_write_phy_ofdm(sc, 0xe, 0x80 + i); - urtw_8187_write_phy_ofdm(sc, 0xe, 0); + for (i = 0; i < 128; i++) { + uint32_t addr, data; + + data = (urtw_8225z2_agc[i] << 8) | 0x0000008f; + addr = ((i + 0x80) << 8) | 0x0000008e; + + urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff); + urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff); + urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00); } urtw_8187_write_phy_ofdm(sc, 0x80, 0x10); for (i = 0; i < N(urtw_8225v2b_rf_part2); i++) urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val); - urtw_write32_m(sc, 0xf0, (7 << 12) | (3 << 8) | 0x1c); - urtw_write32_m(sc, 0xf4, (7 << 12) | (3 << 8) | 0x1c); - urtw_write32_m(sc, 0xf8, (7 << 12) | (3 << 8) | 0x1c); - urtw_write32_m(sc, 0xfc, (7 << 12) | (3 << 8) | 0x1c); - urtw_write8_m(sc, URTW_ACM_CONTROL, 0); + urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c); + urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c); + urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c); + urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c); urtw_8187_write_phy_ofdm(sc, 0x97, 0x46); urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6); urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc); urtw_8187_write_phy_cck(sc, 0xc1, 0x88); + fail: return (error); #undef N @@ -3327,8 +3365,6 @@ fail: static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan) { - int ack; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; usb_error_t error; error = urtw_8225v2b_set_txpwrlvl(sc, chan); @@ -3337,33 +3373,6 @@ urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan) urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]); usb_pause_mtx(&sc->sc_mtx, 10); - - urtw_write8_m(sc, URTW_SIFS, 0xa); - if (ic->ic_flags & IEEE80211_F_SHSLOT) { - urtw_write8_m(sc, URTW_SLOT, 0x9); - urtw_write8_m(sc, URTW_DIFS, 0x1c); - /* In 8187B, BRSR + 1 ==> EIFS register */ - urtw_write8_m(sc, URTW_BRSR + 1, 0x53); - - ack = 112 + 48 + 0x1c; - ack += (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? - 72 : 144; - urtw_write8_m(sc, URTW_CARRIER_SCOUNT, - roundup2(ack, 4)); - } else { - urtw_write8_m(sc, URTW_SLOT, 0x14); - urtw_write8_m(sc, URTW_DIFS, 0x32); - /* In 8187B, BRSR + 1 ==> EIFS register */ - urtw_write8_m(sc, URTW_BRSR + 1, 0x5b); - - ack = 112 + 48 + 0x32; - ack += (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? - 72 : 144; - urtw_write8_m(sc, URTW_CARRIER_SCOUNT, - roundup2(ack, 4)); - - } - fail: return (error); } @@ -3819,8 +3828,10 @@ urtw_rx_enable(struct urtw_softc *sc) if (error != 0) goto fail; - urtw_read8_m(sc, URTW_CMD, &data); - urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE); + if ((sc->sc_flags & URTW_RTL8187B) == 0) { + urtw_read8_m(sc, URTW_CMD, &data); + urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE); + } fail: return (error); } @@ -3844,8 +3855,9 @@ urtw_tx_enable(struct urtw_softc *sc) (7 << 21); /* MAX TX DMA */ urtw_write32_m(sc, URTW_TX_CONF, data); - urtw_read8_m(sc, URTW_CMD, &data8); - urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE); + urtw_read8_m(sc, URTW_MSR, &data8); + data8 |= URTW_MSR_LINK_ENEDCA; + urtw_write8_m(sc, URTW_MSR, data8); return (error); } @@ -3929,14 +3941,13 @@ static struct mbuf * urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, int8_t *nf_p) { - int actlen, flen, len, nf = -95, rssi; + int actlen, flen, rssi; struct ieee80211_frame *wh; struct mbuf *m, *mnew; - struct urtw_8187b_rxhdr *bhdr; struct urtw_softc *sc = data->sc; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - uint8_t *desc, quality = 0, rate; + uint8_t noise = 0, rate; usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); @@ -3946,39 +3957,34 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, } if (sc->sc_flags & URTW_RTL8187B) { - len = actlen - (sizeof(struct urtw_8187b_rxhdr)); - bhdr = (struct urtw_8187b_rxhdr *)(data->buf + len); - desc = data->buf + len; - flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff); + struct urtw_8187b_rxhdr *rx; + + rx = (struct urtw_8187b_rxhdr *)(data->buf + + (actlen - (sizeof(struct urtw_8187b_rxhdr)))); + flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { ifp->if_ierrors++; return (NULL); } - rate = (le32toh(bhdr->flags) >> 20) & 0xf; - rssi = 14 + (bhdr->rssi / 2); - if (rssi > 95) - rssi = 95; + rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf; + /* XXX correct? */ + rssi = rx->rssi & URTW_RX_RSSI_MASK; + noise = rx->noise; } else { - /* 4 dword and 4 byte CRC */ - len = actlen - (4 * 4); - desc = data->buf + len; - flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff); + struct urtw_8187l_rxhdr *rx; + + rx = (struct urtw_8187l_rxhdr *)(data->buf + + (actlen - (sizeof(struct urtw_8187l_rxhdr)))); + flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { ifp->if_ierrors++; return (NULL); } - rate = (desc[2] & 0xf0) >> 4; - quality = desc[4] & 0xff; - /* XXX correct? */ - rssi = (desc[6] & 0xfe) >> 1; - if (!urtw_isbmode(rate)) { - rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi); - rssi = ((90 - rssi) * 100) / 65; - } else { - rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi); - rssi = ((95 - rssi) * 100) / 65; - } + rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf; + /* XXX correct? */ + rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK; + noise = rx->noise; } mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); @@ -3993,7 +3999,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, /* finalize mbuf */ m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = flen - 4; + m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN; if (ieee80211_radiotap_active(ic)) { struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -4007,12 +4013,9 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, wh = mtod(m, struct ieee80211_frame *); if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) sc->sc_currate = (rate > 0) ? rate : sc->sc_currate; - /* XXX correct? */ - if ((sc->sc_flags & URTW_RTL8187B) == 0) - nf = (quality > 64) ? 0 : ((64 - quality) * 100) / 64; *rssi_p = rssi; - *nf_p = nf; + *nf_p = noise; /* XXX correct? */ return (m); } @@ -4072,9 +4075,6 @@ setup: (void) ieee80211_input_all(ic, m, rssi, nf); m = NULL; } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - urtw_start(ifp); URTW_LOCK(sc); break; default: @@ -4093,6 +4093,62 @@ setup: } } +#define URTW_STATUS_TYPE_TXCLOSE 1 +#define URTW_STATUS_TYPE_BEACON_INTR 0 + +static void +urtw_txstatus_eof(struct usb_xfer *xfer) +{ + struct urtw_softc *sc = usbd_xfer_softc(xfer); + struct ifnet *ifp = sc->sc_ifp; + int actlen, type, pktretry, seq; + uint64_t val; + + usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); + + if (actlen != sizeof(uint64_t)) + return; + + val = le64toh(sc->sc_txstatus); + type = (val >> 30) & 0x3; + if (type == URTW_STATUS_TYPE_TXCLOSE) { + pktretry = val & 0xff; + seq = (val >> 16) & 0xff; + if (pktretry == URTW_TX_MAXRETRY) + ifp->if_oerrors++; + DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n", + pktretry, seq); + } +} + +static void +urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct urtw_softc *sc = usbd_xfer_softc(xfer); + struct ifnet *ifp = sc->sc_ifp; + + URTW_ASSERT_LOCKED(sc); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + urtw_txstatus_eof(xfer); + /* FALLTHROUGH */ + case USB_ST_SETUP: +setup: + usbd_xfer_set_frame_data(xfer, 0, &sc->sc_txstatus, + sizeof(int64_t)); + usbd_transfer_submit(xfer); + break; + default: + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + ifp->if_ierrors++; + goto setup; + } + break; + } +} + static void urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data) { @@ -4214,12 +4270,108 @@ static int urtw_isbmode(uint16_t rate) { - rate = urtw_rtl2rate(rate); - return ((rate <= 22 && rate != 12 && rate != 18) || rate == 44) ? (1) : (0); } +static uint16_t +urtw_rate2dbps(uint16_t rate) +{ + + switch(rate) { + case 12: + case 18: + case 24: + case 36: + case 48: + case 72: + case 96: + case 108: + return (rate * 2); + default: + break; + } + return (24); +} + +static int +urtw_compute_txtime(uint16_t framelen, uint16_t rate, + uint8_t ismgt, uint8_t isshort) +{ + uint16_t ceiling, frametime, n_dbps; + + if (urtw_isbmode(rate)) { + if (ismgt || !isshort || rate == 2) + frametime = (uint16_t)(144 + 48 + + (framelen * 8 / (rate / 2))); + else + frametime = (uint16_t)(72 + 24 + + (framelen * 8 / (rate / 2))); + if ((framelen * 8 % (rate / 2)) != 0) + frametime++; + } else { + n_dbps = urtw_rate2dbps(rate); + ceiling = (16 + 8 * framelen + 6) / n_dbps + + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0); + frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6); + } + return (frametime); +} + +/* + * Callback from the 802.11 layer to update the + * slot time based on the current setting. + */ +static void +urtw_updateslot(struct ifnet *ifp) +{ + struct urtw_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + + ieee80211_runtask(ic, &sc->sc_updateslot_task); +} + +static void +urtw_updateslottask(void *arg, int pending) +{ + struct urtw_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + int error; + + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + + URTW_LOCK(sc); + if (sc->sc_flags & URTW_RTL8187B) { + urtw_write8_m(sc, URTW_SIFS, 0x22); + if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) + urtw_write8_m(sc, URTW_SLOT, 0x9); + else + urtw_write8_m(sc, URTW_SLOT, 0x14); + urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b); + urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b); + } else { + urtw_write8_m(sc, URTW_SIFS, 0x22); + if (sc->sc_state == IEEE80211_S_ASSOC && + ic->ic_flags & IEEE80211_F_SHSLOT) + urtw_write8_m(sc, URTW_SLOT, 0x9); + else + urtw_write8_m(sc, URTW_SLOT, 0x14); + if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { + urtw_write8_m(sc, URTW_DIFS, 0x14); + urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14); + urtw_write8_m(sc, URTW_CW_VAL, 0x73); + } else { + urtw_write8_m(sc, URTW_DIFS, 0x24); + urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24); + urtw_write8_m(sc, URTW_CW_VAL, 0xa5); + } + } +fail: + URTW_UNLOCK(sc); +} + static device_method_t urtw_methods[] = { DEVMETHOD(device_probe, urtw_match), DEVMETHOD(device_attach, urtw_attach), diff --git a/sys/dev/usb/wlan/if_urtwreg.h b/sys/dev/usb/wlan/if_urtwreg.h index d3399b7eaf1..a0fe5ffd715 100644 --- a/sys/dev/usb/wlan/if_urtwreg.h +++ b/sys/dev/usb/wlan/if_urtwreg.h @@ -26,18 +26,29 @@ #define URTW_MAC3 0x0003 /* 1 byte */ #define URTW_MAC4 0x0004 /* 1 byte */ #define URTW_MAC5 0x0005 /* 1 byte */ +#define URTW_MAR 0x0008 /* 6 byte */ +#define URTW_RXFIFO_CNT 0x0010 /* 1 byte */ +#define URTW_TXFIFO_CNT 0x0012 /* 1 byte */ +#define URTW_BQREQ 0x0013 /* 1 byte */ +#define URTW_TSFT 0x0018 /* 6 byte */ +#define URTW_TLPDA 0x0020 /* 4 byte */ +#define URTW_TNPDA 0x0024 /* 4 byte */ +#define URTW_THPDA 0x0028 /* 4 byte */ #define URTW_BRSR 0x002c /* 2 byte */ #define URTW_BRSR_MBR_8185 (0x0fff) +#define URTW_8187B_EIFS 0x002d /* 1 byte for 8187B */ #define URTW_BSSID 0x002e /* 6 byte */ -#define URTW_RESP_RATE 0x0034 /* 1 byte */ +#define URTW_BRSR_8187B 0x0034 /* 2 byte for 8187B */ +#define URTW_RESP_RATE 0x0034 /* 1 byte for 8187L */ #define URTW_RESP_MAX_RATE_SHIFT (4) #define URTW_RESP_MIN_RATE_SHIFT (0) #define URTW_EIFS 0x0035 /* 1 byte */ -#define URTW_INTR_MASK 0x003c /* 2 byte */ #define URTW_CMD 0x0037 /* 1 byte */ #define URTW_CMD_TX_ENABLE (0x4) #define URTW_CMD_RX_ENABLE (0x8) #define URTW_CMD_RST (0x10) +#define URTW_INTR_MASK 0x003c /* 2 byte */ +#define URTW_INTR_STATUS 0x003e /* 2 byte */ #define URTW_TX_CONF 0x0040 /* 4 byte */ #define URTW_TX_LOOPBACK_SHIFT (17) #define URTW_TX_LOOPBACK_NONE (0 << URTW_TX_LOOPBACK_SHIFT) @@ -56,6 +67,9 @@ #define URTW_TX_MXDMA_SHIFT (21) #define URTW_TX_DISCW (1 << 20) #define URTW_TX_SWPLCPLEN (1 << 24) +#define URTW_TX_R8187vD (5 << 25) +#define URTW_TX_R8187vD_B (6 << 25) +#define URTW_TX_HWMASK (7 << 25) #define URTW_TX_DISREQQSIZE (1 << 28) #define URTW_TX_HW_SEQNUM (1 << 30) #define URTW_TX_CWMIN (1 << 31) @@ -94,6 +108,7 @@ #define URTW_MAX_RX_DMA_SHIFT (10) #define URTW_RCR_ONLYERLPKT (1 << 31) #define URTW_INT_TIMEOUT 0x0048 /* 4 byte */ +#define URTW_INT_TBDA 0x004c /* 4 byte */ #define URTW_EPROM_CMD 0x0050 /* 1 byte */ #define URTW_EPROM_CMD_NORMAL (0x0) #define URTW_EPROM_CMD_NORMAL_MODE \ @@ -109,6 +124,7 @@ #define URTW_EPROM_WRITEBIT (0x2) #define URTW_EPROM_CK (0x4) #define URTW_EPROM_CS (0x8) +#define URTW_CONFIG0 0x0051 /* 1 byte */ #define URTW_CONFIG1 0x0052 /* 1 byte */ #define URTW_CONFIG2 0x0053 /* 1 byte */ #define URTW_ANAPARAM 0x0054 /* 4 byte */ @@ -132,6 +148,7 @@ #define URTW_CONFIG4_VCOOFF (1 << 7) #define URTW_TESTR 0x005b /* 1 byte */ #define URTW_PSR 0x005e /* 1 byte */ +#define URTW_SECURITY 0x005f /* 1 byte */ #define URTW_ANAPARAM2 0x0060 /* 4 byte */ #define URTW_8225_ANAPARAM2_ON (0x860c7312) #define URTW_8225_ANAPARAM2_OFF (0x840dec11) @@ -141,6 +158,7 @@ #define URTW_ATIM_WND 0x0072 /* 2 byte */ #define URTW_BEACON_INTERVAL_TIME 0x0074 /* 2 byte */ #define URTW_ATIM_TR_ITV 0x0076 /* 2 byte */ +#define URTW_PHY_DELAY 0x0078 /* 1 byte */ #define URTW_CARRIER_SCOUNT 0x0079 /* 1 byte */ #define URTW_PHY_MAGIC1 0x007c /* 1 byte */ #define URTW_PHY_MAGIC2 0x007d /* 1 byte */ @@ -185,13 +203,23 @@ #define URTW_RATE_FALLBACK 0x00be /* 1 byte */ #define URTW_RATE_FALLBACK_ENABLE (0x80) #define URTW_ACM_CONTROL 0x00bf /* 1 byte */ +#define URTW_CONFIG5 0x00d8 /* 1 byte */ +#define URTW_TXDMA_POLLING 0x00d9 /* 1 byte */ +#define URTW_CWR 0x00dc /* 2 byte */ +#define URTW_RETRY_CTR 0x00de /* 1 byte */ #define URTW_INT_MIG 0x00e2 /* 2 byte */ +#define URTW_RDSAR 0x00e4 /* 4 byte */ #define URTW_TID_AC_MAP 0x00e8 /* 2 byte */ #define URTW_ANAPARAM3 0x00ee /* 1 byte */ #define URTW_8187B_8225_ANAPARAM3_ON (0x0) #define URTW_8187B_8225_ANAPARAM3_OFF (0x0) - +#define URTW_8187B_AC_VO 0x00f0 /* 4 byte for 8187B */ +#define URTW_FEMR 0x00f4 /* 2 byte */ +#define URTW_8187B_AC_VI 0x00f4 /* 4 byte for 8187B */ +#define URTW_8187B_AC_BE 0x00f8 /* 4 byte for 8187B */ +#define URTW_TALLY_CNT 0x00fa /* 2 byte */ #define URTW_TALLY_SEL 0x00fc /* 1 byte */ +#define URTW_8187B_AC_BK 0x00fc /* 4 byte for 8187B */ #define URTW_ADDR_MAGIC2 0x00fe /* 2 byte */ #define URTW_ADDR_MAGIC3 0x00ff /* 1 byte */ @@ -224,6 +252,7 @@ #define URTW_8225_ADDR_C_DATA_MAGIC2 (0x050) /* for EEPROM */ +#define URTW_EPROM_CHANPLAN 0x03 #define URTW_EPROM_TXPW_BASE 0x05 #define URTW_EPROM_RFCHIPID 0x06 #define URTW_EPROM_RFCHIPID_RTL8225U (5) @@ -278,26 +307,126 @@ #define URTW_DEFAULT_TX_RETRY 7 #define URTW_DEFAULT_RTS_THRESHOLD 2342U +#define URTW_ASIFS_TIME 10 +#define URTW_ACKCTS_LEN 14 /* len for ACK and CTS */ + struct urtw_8187b_rxhdr { - uint32_t flags; + uint32_t flag; +#define URTW_RX_FLAG_LEN /* 0 ~ 11 bits */ +#define URTW_RX_FLAG_ICV_ERR (1 << 12) +#define URTW_RX_FLAG_CRC32_ERR (1 << 13) +#define URTW_RX_FLAG_PM (1 << 14) +#define URTW_RX_FLAG_RX_ERR (1 << 15) +#define URTW_RX_FLAG_BCAST (1 << 16) +#define URTW_RX_FLAG_PAM (1 << 17) +#define URTW_RX_FLAG_MCAST (1 << 18) +#define URTW_RX_FLAG_QOS (1 << 19) /* only for RTL8187B */ +#define URTW_RX_FLAG_RXRATE /* 20 ~ 23 bits */ +#define URTW_RX_FLAG_RXRATE_SHIFT 20 +#define URTW_RX_FLAG_TRSW (1 << 24) /* only for RTL8187B */ +#define URTW_RX_FLAG_SPLCP (1 << 25) +#define URTW_RX_FLAG_FOF (1 << 26) +#define URTW_RX_FLAG_DMA_FAIL (1 << 27) +#define URTW_RX_FLAG_LAST (1 << 28) +#define URTW_RX_FLAG_FIRST (1 << 29) +#define URTW_RX_FLAG_EOR (1 << 30) +#define URTW_RX_FLAG_OWN (1 << 31) uint64_t mactime; - uint8_t sq; + uint8_t noise; uint8_t rssi; +#define URTW_RX_RSSI /* 0 ~ 6 bits */ +#define URTW_RX_RSSI_MASK 0x3f +#define URTW_RX_ANTENNA (1 << 7) uint8_t agc; - uint8_t flags2; - uint16_t unknown; + uint8_t flag2; +#define URTW_RX_FLAG2_DECRYPTED (1 << 0) +#define URTW_RX_FLAG2_WAKUP (1 << 1) +#define URTW_RX_FLAG2_SHIFT (1 << 2) +#define URTW_RX_FLAG2_RSVD0 /* 3 ~ 7 bits */ + uint16_t flag3; +#define URTW_RX_FLAG3_NUMMCSI /* 0 ~ 3 bits */ +#define URTW_RX_FLAG3_SNR_L2E /* 4 ~ 9 bits */ +#define URTW_RX_FLAG3_CFO_BIAS /* 10 ~ 15 bits */ int8_t pwdb; uint8_t fot; } __packed; struct urtw_8187b_txhdr { - uint32_t flags; - uint16_t rts_duration; + uint32_t flag; +#define URTW_TX_FLAG_PKTLEN /* 0 ~ 11 bits */ +#define URTW_TX_FLAG_RSVD0 /* 12 ~ 14 bits */ +#define URTW_TX_FLAG_NO_ENC (1 << 15) +#define URTW_TX_FLAG_SPLCP (1 << 16) +#define URTW_TX_FLAG_MOREFRAG (1 << 17) +#define URTW_TX_FLAG_CTS (1 << 18) +#define URTW_TX_FLAG_RTSRATE /* 19 ~ 22 bits */ +#define URTW_TX_FLAG_RTSRATE_SHIFT 19 +#define URTW_TX_FLAG_RTS (1 << 23) +#define URTW_TX_FLAG_TXRATE /* 24 ~ 27 bits */ +#define URTW_TX_FLAG_TXRATE_SHIFT 24 +#define URTW_TX_FLAG_LAST (1 << 28) +#define URTW_TX_FLAG_FIRST (1 << 29) +#define URTW_TX_FLAG_DMA (1 << 30) +#define URTW_TX_FLAG_OWN (1 << 31) + uint16_t rtsdur; uint16_t len; - uint32_t unknown1; - uint16_t unknown2; - uint16_t tx_duration; - uint32_t unknown3; - uint32_t retry; - uint32_t unknown4[2]; +#define URTW_TX_LEN /* 0 ~ 14 bits */ +#define URTW_TX_LEN_EXT (1 << 15) + uint32_t bufaddr; + uint16_t flag1; +#define URTW_TX_FLAG1_RXLEN /* 0 ~ 11 bits */ +#define URTW_TX_FLAG1_RSVD0 /* 12 ~ 14 bits */ +#define URTW_TX_FLAG1_MICCAL (1 << 15) + uint16_t txdur; + uint32_t nextdescaddr; + uint8_t rtsagc; + uint8_t retry; + uint16_t flag2; +#define URTW_TX_FLAG2_RTDB (1 << 0) +#define URTW_TX_FLAG2_NOACM (1 << 1) +#define URTW_TX_FLAG2_PIFS (1 << 2) +#define URTW_TX_FLAG2_RSVD0 /* 3 ~ 6 bits */ +#define URTW_TX_FLAG2_RTSRATEFALLBACK /* 7 ~ 10 bits */ +#define URTW_TX_FLAG2_RATEFALLBACK /* 11 ~ 15 bits */ + uint16_t delaybound; + uint16_t flag3; +#define URTW_TX_FLAG3_RSVD0 /* 0 ~ 3 bits */ +#define URTW_TX_FLAG3_AGC /* 4 ~ 11 bits */ +#define URTW_TX_FLAG3_ANTENNA (1 << 12) +#define URTW_TX_FLAG3_SPC /* 13 ~ 14 bits */ +#define URTW_TX_FLAG3_RSVD1 (1 << 15) + uint32_t flag4; +#define URTW_TX_FLAG4_LENADJUST /* 0 ~ 1 bits */ +#define URTW_TX_FLAG4_RSVD0 (1 << 2) +#define URTW_TX_FLAG4_TPCDESEN (1 << 3) +#define URTW_TX_FLAG4_TPCPOLARITY /* 4 ~ 5 bits */ +#define URTW_TX_FLAG4_TPCEN (1 << 6) +#define URTW_TX_FLAG4_PTEN (1 << 7) +#define URTW_TX_FLAG4_BCKEY /* 8 ~ 13 bits */ +#define URTW_TX_FLAG4_ENBCKEY (1 << 14) +#define URTW_TX_FLAG4_ENPMPD (1 << 15) +#define URTW_TX_FLAG4_FRAGQSZ /* 16 ~ 31 bits */ +} __packed; + +struct urtw_8187l_rxhdr { + uint32_t flag; + uint8_t noise; + uint8_t rssi; +#define URTW_RX_8187L_RSSI /* 0 ~ 6 bits */ +#define URTW_RX_8187L_RSSI_MASK 0x3f +#define URTW_RX_8187L_ANTENNA (1 << 7) + uint8_t agc; + uint8_t flag2; +#define URTW_RX_8187L_DECRYPTED (1 << 0) +#define URTW_RX_8187L_WAKEUP (1 << 1) +#define URTW_RX_8187L_SHIFT (1 << 2) +#define URTW_RX_8187L_RSVD0 /* 3 ~ 7 bits */ + uint64_t mactime; +} __packed; + +struct urtw_8187l_txhdr { + uint32_t flag; + uint16_t rtsdur; + uint16_t len; + uint32_t retry; } __packed; diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h index 975060c70df..6941abbb8b8 100644 --- a/sys/dev/usb/wlan/if_urtwvar.h +++ b/sys/dev/usb/wlan/if_urtwvar.h @@ -18,12 +18,13 @@ enum { URTW_8187B_BULK_RX, + URTW_8187B_BULK_TX_STATUS, URTW_8187B_BULK_TX_BE, URTW_8187B_BULK_TX_BK, URTW_8187B_BULK_TX_VI, URTW_8187B_BULK_TX_VO, URTW_8187B_BULK_TX_EP12, - URTW_8187B_N_XFERS = 6 + URTW_8187B_N_XFERS = 7 }; enum { @@ -54,6 +55,7 @@ typedef STAILQ_HEAD(, urtw_data) urtw_datahead; #define URTW_TX_DATA_LIST_COUNT 16 #define URTW_RX_MAXSIZE 0x9c4 #define URTW_TX_MAXSIZE 0x9c4 +#define URTW_TX_MAXRETRY 11 struct urtw_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -163,6 +165,10 @@ struct urtw_softc { uint8_t sc_txpwr_ofdm[URTW_MAX_CHANNELS]; uint8_t sc_txpwr_ofdm_base; + uint8_t sc_acmctl; + uint64_t sc_txstatus; /* only for 8187B */ + struct task sc_updateslot_task; + struct urtw_rx_radiotap_header sc_rxtap; int sc_rxtap_len; struct urtw_tx_radiotap_header sc_txtap; From c2d7acaf5de748a9bd065cfb2fc546602f173543 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Sun, 18 Oct 2009 00:46:59 +0000 Subject: [PATCH 191/646] adds devices supportted by urtw(4) and bumps date. --- share/man/man4/urtw.4 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/share/man/man4/urtw.4 b/share/man/man4/urtw.4 index 1eb6d7df46c..d1502e14dcd 100644 --- a/share/man/man4/urtw.4 +++ b/share/man/man4/urtw.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 2, 2009 +.Dd October 17, 2009 .Dt URTW 4 .Os .Sh NAME @@ -70,9 +70,15 @@ driver supports Realtek RTL8187B/L based wireless network devices, including: .Pp .Bl -column "Shuttle XPC Accessory PN20" "RTL8225" "USB" -compact -offset 6n .It Em "Card Radio Bus" +.It "Belkin F5D7050E RTL8225 USB" +.It "Linksys WUSB54GCv2 RTL8225 USB" .It "Netgear WG111v2 RTL8225 USB" +.It "Netgear WG111v3 RTL8225 USB" .It "Safehome WLG-1500SMA5 RTL8225 USB" .It "Shuttle XPC Accessory PN20 RTL8225 USB" +.It "Sitecom WL168v1 RTL8225 USB" +.It "Sitecom WL168v4 RTL8225 USB" +.It "SureCom EP-9001-g(2A) RTL8225 USB" .It "TRENDnet TEW-424UB V3.xR RTL8225 USB" .El .Sh EXAMPLES From 6426657e9f680673f2b79517a22a6f386576206f Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 18 Oct 2009 11:23:56 +0000 Subject: [PATCH 192/646] Rewrap ip_input() comment so that it prints more nicely. MFC after: 3 days --- sys/netinet/ip_input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 50b66b564e7..e96fa802576 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -530,9 +530,9 @@ tooshort: } if ((dchg = (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL)) != 0) { /* - * Directly ship on the packet. This allows to forward packets - * that were destined for us to some other directly connected - * host. + * Directly ship on the packet. This allows to forward + * packets that were destined for us to some other directly + * connected host. */ ip_forward(m, dchg); return; From a234abce8e4b8ec7a42d334505e2543dfb93d738 Mon Sep 17 00:00:00 2001 From: Max Khon Date: Sun, 18 Oct 2009 11:26:09 +0000 Subject: [PATCH 193/646] Exit with non-zero error code in case of errors when make is run with -k and not parallel (compat) make is run. --- usr.bin/make/job.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c index e37c62c621e..9453bdc8a0a 100644 --- a/usr.bin/make/job.c +++ b/usr.bin/make/job.c @@ -3380,6 +3380,8 @@ Compat_Run(Lst *targs) printf("`%s' not remade because of errors.\n", gn->name); makeErrors++; + } else if (gn->made == ERROR) { + makeErrors++; } } From 33c89765f15cbb17c34f612e89ecebbaaafc47b7 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 18 Oct 2009 11:27:34 +0000 Subject: [PATCH 194/646] Line-wrap pfil.c so that it prints more nicely. MFC after: 3 days --- sys/net/pfil.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 76ed664fb84..78c3ca9955f 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -49,12 +49,14 @@ static struct mtx pfil_global_lock; -MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", MTX_DEF); +MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", + MTX_DEF); static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int); static int pfil_list_remove(pfil_list_t *, - int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *); + int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), + void *); LIST_HEAD(pfilheadhead, pfil_head); VNET_DEFINE(struct pfilheadhead, pfil_head_list); @@ -77,7 +79,8 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, for (pfh = pfil_hook_get(dir, ph); pfh != NULL; pfh = TAILQ_NEXT(pfh, pfil_link)) { if (pfh->pfil_func != NULL) { - rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp); + rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, + inp); if (rv != 0 || m == NULL) break; } @@ -221,8 +224,8 @@ error: * hook list. */ int -pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), - void *arg, int flags, struct pfil_head *ph) +pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, + struct inpcb *), void *arg, int flags, struct pfil_head *ph) { int err = 0; @@ -273,7 +276,8 @@ pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flags) */ static int pfil_list_remove(pfil_list_t *list, - int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg) + int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), + void *arg) { struct packet_filter_hook *pfh; From ab5f4f723dbe884cc1b85441d921dbbb0330b21b Mon Sep 17 00:00:00 2001 From: Max Khon Date: Sun, 18 Oct 2009 11:28:31 +0000 Subject: [PATCH 195/646] Reset UPTODATE gnodes after remaking makefiles when make is not going to be restarted: such nodes could be marked UPTODATE without doing rebuild due to remakingMakefiles being TRUE. --- usr.bin/make/main.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 0e165062c1b..eec6bbf1e24 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -706,6 +706,7 @@ Main_AddSourceMakefile(const char *name) static void Remake_Makefiles(void) { + Lst cleanup; LstNode *ln; int error_cnt = 0; int remade_cnt = 0; @@ -716,6 +717,7 @@ Remake_Makefiles(void) Fatal("Failed to change directory to %s.", curdir); } + Lst_Init(&cleanup); LST_FOREACH(ln, &source_makefiles) { LstNode *ln2; struct GNode *gn; @@ -791,21 +793,7 @@ Remake_Makefiles(void) gn->name); error_cnt++; } else if (gn->made == UPTODATE) { - Lst examine; - - Lst_Init(&examine); - Lst_EnQueue(&examine, gn); - while (!Lst_IsEmpty(&examine)) { - LstNode *eln; - GNode *egn = Lst_DeQueue(&examine); - - egn->make = FALSE; - LST_FOREACH(eln, &egn->children) { - GNode *cgn = Lst_Datum(eln); - - Lst_EnQueue(&examine, cgn); - } - } + Lst_EnQueue(&cleanup, gn); } } @@ -827,6 +815,24 @@ Remake_Makefiles(void) } } + while (!Lst_IsEmpty(&cleanup)) { + GNode *gn = Lst_DeQueue(&cleanup); + + gn->unmade = 0; + gn->make = FALSE; + gn->made = UNMADE; + gn->childMade = FALSE; + gn->mtime = gn->cmtime = 0; + gn->cmtime_gn = NULL; + + LST_FOREACH(ln, &gn->children) { + GNode *cgn = Lst_Datum(ln); + + gn->unmade++; + Lst_EnQueue(&cleanup, cgn); + } + } + if (curdir != objdir) { if (chdir(objdir) < 0) Fatal("Failed to change directory to %s.", objdir); From 5c0e1c11a3a972ecdbdc66260841f77a85523efd Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 18 Oct 2009 12:55:39 +0000 Subject: [PATCH 196/646] Remove spurious call to priv_check(PRIV_VM_SWAP_NOQUOTA). Call priv_check(PRIV_VM_SWAP_NORLIMIT) only when per-uid limit is actually exceed. Both changes aim at calling priv_check(9) only for the cases when privilege is actually exercised by the process. Reported and tested by: rwatson Reviewed by: alc MFC after: 3 days --- sys/vm/swap_pager.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index de33ebaadda..229dac8585b 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -176,7 +176,7 @@ swap_reserve(vm_ooffset_t incr) int swap_reserve_by_uid(vm_ooffset_t incr, struct uidinfo *uip) { - vm_ooffset_t r, s, max; + vm_ooffset_t r, s; int res, error; static int curfail; static struct timeval lastfail; @@ -185,7 +185,6 @@ swap_reserve_by_uid(vm_ooffset_t incr, struct uidinfo *uip) panic("swap_reserve: & PAGE_MASK"); res = 0; - error = priv_check(curthread, PRIV_VM_SWAP_NOQUOTA); mtx_lock(&sw_dev_mtx); r = swap_reserved + incr; if (overcommit & SWAP_RESERVE_ALLOW_NONWIRED) { @@ -204,10 +203,9 @@ swap_reserve_by_uid(vm_ooffset_t incr, struct uidinfo *uip) if (res) { PROC_LOCK(curproc); UIDINFO_VMSIZE_LOCK(uip); - error = priv_check(curthread, PRIV_VM_SWAP_NORLIMIT); - max = (error != 0) ? lim_cur(curproc, RLIMIT_SWAP) : 0; - if (max != 0 && uip->ui_vmsize + incr > max && - (overcommit & SWAP_RESERVE_RLIMIT_ON) != 0) + if ((overcommit & SWAP_RESERVE_RLIMIT_ON) != 0 && + uip->ui_vmsize + incr > lim_cur(curproc, RLIMIT_SWAP) && + priv_check(curthread, PRIV_VM_SWAP_NORLIMIT)) res = 0; else uip->ui_vmsize += incr; From 7564c4ad9a585e00f4c88f72b030be0269e85d69 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 18 Oct 2009 12:57:48 +0000 Subject: [PATCH 197/646] If ET_DYN binary has non-zero base address for some reason, honour it and do not relocate the binary to ET_DYN_LOAD_ADDR. This allows for the binary author to influence address map of the process. In particular, when the binary is actually an interpeter, this allows to have almost usual process address map. Communicate the relocation bias of the mapping for interpeter-less ET_DYN binary, that is interperter itself, in AT_BASE aux entry. This way, rtld is able to find its dynamic structure and relocate itself. Note that mapbase in the rtld is still wrong and requires further fixing. Reported and tested by: rwatson Discussed with: kan MFC after: 3 days --- sys/kern/imgact_elf.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index e112fe1271d..56cd66f254f 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -688,9 +688,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) u_long text_size = 0, data_size = 0, total_size = 0; u_long text_addr = 0, data_addr = 0; u_long seg_size, seg_addr; - u_long addr, et_dyn_addr, entry = 0, proghdr = 0; + u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0; int32_t osrel = 0; - int error = 0, i; + int error = 0, i, n; const char *interp = NULL, *newinterp = NULL; Elf_Brandinfo *brand_info; char *path; @@ -719,14 +719,22 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); if (!aligned(phdr, Elf_Addr)) return (ENOEXEC); + n = 0; + baddr = 0; for (i = 0; i < hdr->e_phnum; i++) { + if (phdr[i].p_type == PT_LOAD) { + if (n == 0) + baddr = phdr[i].p_vaddr; + n++; + continue; + } if (phdr[i].p_type == PT_INTERP) { /* Path to interpreter */ if (phdr[i].p_filesz > MAXPATHLEN || phdr[i].p_offset + phdr[i].p_filesz > PAGE_SIZE) return (ENOEXEC); interp = imgp->image_header + phdr[i].p_offset; - break; + continue; } } @@ -739,7 +747,14 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (hdr->e_type == ET_DYN) { if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) return (ENOEXEC); - et_dyn_addr = ET_DYN_LOAD_ADDR; + /* + * Honour the base load address from the dso if it is + * non-zero for some reason. + */ + if (baddr == 0) + et_dyn_addr = ET_DYN_LOAD_ADDR; + else + et_dyn_addr = 0; } else et_dyn_addr = 0; sv = brand_info->sysvec; @@ -910,7 +925,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) return (error); } } else - addr = 0; + addr = et_dyn_addr; /* * Construct auxargs table (used by the fixup routine) From a430b967b58040ee5db99891d7e5f6de3b8650b0 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 18 Oct 2009 13:08:15 +0000 Subject: [PATCH 198/646] Change the load base to below 2GB so PIE binaries work including when compiled to use the Medium/Low code model, which we currently default to for the userland. GNU/Linux has moved their default to Medium/Middle some time ago, which probably explains why the current GNU ld(1) uses a base in the range between 32 and 44 bits instead. Submitted by: kib --- sys/sparc64/include/elf.h | 2 +- sys/sun4v/include/elf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/sparc64/include/elf.h b/sys/sparc64/include/elf.h index d35d736b1f6..2a666705d0f 100644 --- a/sys/sparc64/include/elf.h +++ b/sys/sparc64/include/elf.h @@ -97,6 +97,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH ELF_ARCH #define ELF_TARG_VER 1 -#define ET_DYN_LOAD_ADDR 0x150000000 +#define ET_DYN_LOAD_ADDR 0x100000 #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/sun4v/include/elf.h b/sys/sun4v/include/elf.h index d35d736b1f6..2a666705d0f 100644 --- a/sys/sun4v/include/elf.h +++ b/sys/sun4v/include/elf.h @@ -97,6 +97,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH ELF_ARCH #define ELF_TARG_VER 1 -#define ET_DYN_LOAD_ADDR 0x150000000 +#define ET_DYN_LOAD_ADDR 0x100000 #endif /* !_MACHINE_ELF_H_ */ From e5087dd893d0df6b10d1c593b730776aaa91cdcc Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sun, 18 Oct 2009 13:51:49 +0000 Subject: [PATCH 199/646] Fix KASSERT string to include the real module name. --- sys/dev/hwpmc/hwpmc_mod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 482db0edfcf..0c1d35b7e3b 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -504,7 +504,7 @@ pmc_ri_to_classdep(struct pmc_mdep *md, int ri, int *adjri) pcd = pmc_rowindex_to_classdep[ri]; KASSERT(pcd != NULL, - ("[amd,%d] ri %d null pcd", __LINE__, ri)); + ("[pmc,%d] ri %d null pcd", __LINE__, ri)); *adjri = ri - pcd->pcd_ri; From 6b95af36e0d50e7d05e77eeba88198f0b34e652f Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Sun, 18 Oct 2009 17:10:39 +0000 Subject: [PATCH 200/646] o OpenBSD 4.6 added. --- share/misc/bsd-family-tree | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index 5482dce357a..fa74abd61d9 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -230,7 +230,7 @@ FreeBSD 5.2 | | | | | FreeBSD 7.2 | NetBSD 5.0 OpenBSD 4.5 | | | | | | | | | | | | DragonFly 2.4.0 - | V | | | | + | V | | OpenBSD 4.6 | | | | | | FreeBSD 8 -current | NetBSD -current OpenBSD -current | | | | | | @@ -504,6 +504,7 @@ NetBSD 5.0 2009-04-29 [NBD] OpenBSD 4.5 2009-05-01 [OBD] FreeBSD 7.2 2009-05-04 [FBD] DragonFly 2.4.0 2009-09-16 [DFB] +OpenBSD 4.6 2009-10-18 [OBD] Bibliography ------------------------ From 635dc3f7ffc279095d5e971d785578849c72db95 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 18 Oct 2009 17:11:16 +0000 Subject: [PATCH 201/646] Work around a quirk with the G5 Xserve, which has a fake GMAC controller with an all-zero MAC address. In this case, don't attach. Discussed with: marius --- sys/dev/gem/if_gem_pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c index 05be3236ca7..051dbcc5bfb 100644 --- a/sys/dev/gem/if_gem_pci.c +++ b/sys/dev/gem/if_gem_pci.c @@ -295,6 +295,16 @@ gem_pci_attach(device_t dev) GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE, sc->sc_enaddr, ETHER_ADDR_LEN); #endif + /* + * The Xserve G5 has a fake GMAC with an all-zero MAC address. + * Check for this, and don't attach in this case. + */ + + for (i = 0; i < ETHER_ADDR_LEN && sc->sc_enaddr[i] == 0; i++) {} + if (i == ETHER_ADDR_LEN) { + device_printf(dev, "invalid MAC address\n"); + goto fail; + } if (gem_attach(sc) != 0) { device_printf(dev, "could not be attached\n"); From c7e1669396026eb0e379681cd3d9f0c2c4f4eaf8 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 18 Oct 2009 17:22:08 +0000 Subject: [PATCH 202/646] Don't assume that physical addresses are identity mapped. This allows the second processor on G5 systems to start. Note that SMP is still non-functional on these systems because of IPI delivery problems. --- sys/powerpc/aim/platform_chrp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/aim/platform_chrp.c b/sys/powerpc/aim/platform_chrp.c index 7a8fe3b9464..03955ab49ea 100644 --- a/sys/powerpc/aim/platform_chrp.c +++ b/sys/powerpc/aim/platform_chrp.c @@ -35,11 +35,14 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include #include +#include #include #include @@ -220,6 +223,7 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc) #ifdef SMP phandle_t cpu; volatile uint8_t *rstvec; + static volatile uint8_t *rstvec_virtbase = NULL; int res, reset, timeout; cpu = pc->pc_hwref; @@ -229,7 +233,10 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc) ap_pcpu = pc; - rstvec = (uint8_t *)(0x80000000 + reset); + if (rstvec_virtbase == NULL) + rstvec_virtbase = pmap_mapdev(0x80000000, PAGE_SIZE); + + rstvec = rstvec_virtbase + reset; *rstvec = 4; powerpc_sync(); From 99087885be1051d788b71bd67f1cdf5fa146a352 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 18 Oct 2009 19:45:44 +0000 Subject: [PATCH 203/646] Make lock devices work properly. It turned out I did add the code to use the init state devices to set the termios structure when opening the device, but it seems I totally forgot to add the bits required to force the actual locking of flags through the lock state devices. Reported by: ru MFC after: 1 week (to be discussed) --- sys/kern/tty.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 6990b8ff94f..25908df8acc 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -523,6 +523,34 @@ ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, goto done; } + if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { + struct termios *old = &tp->t_termios; + struct termios *new = (struct termios *)data; + struct termios *lock = TTY_CALLOUT(tp, dev) ? + &tp->t_termios_lock_out : &tp->t_termios_lock_in; + int cc; + + /* + * Lock state devices. Just overwrite the values of the + * commands that are currently in use. + */ + new->c_iflag = (old->c_iflag & lock->c_iflag) | + (new->c_iflag & ~lock->c_iflag); + new->c_oflag = (old->c_oflag & lock->c_oflag) | + (new->c_oflag & ~lock->c_oflag); + new->c_cflag = (old->c_cflag & lock->c_cflag) | + (new->c_cflag & ~lock->c_cflag); + new->c_lflag = (old->c_lflag & lock->c_lflag) | + (new->c_lflag & ~lock->c_lflag); + for (cc = 0; cc < NCCS; ++cc) + if (lock->c_cc[cc]) + new->c_cc[cc] = old->c_cc[cc]; + if (lock->c_ispeed) + new->c_ispeed = old->c_ispeed; + if (lock->c_ospeed) + new->c_ospeed = old->c_ospeed; + } + error = tty_ioctl(tp, cmd, data, td); done: tty_unlock(tp); From 5ed8d124435dcc3851a12e6943f9e727c91233d7 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 18 Oct 2009 19:48:53 +0000 Subject: [PATCH 204/646] Allow the buffer size to be configured for pseudo-like TTY devices. Devices that don't implement param() (which means they don't support hardware parameters such as flow control, baud rate) hardcode the baud rate to TTYDEF_SPEED. This means the buffer size cannot be configured, which is a little inconvenient when using canonical mode with big lines of input, etc. Make it adjustable, but do clamp it between B50 and B115200 to prevent awkward buffer sizes. Remove the baud rate assignment from /etc/gettytab. Trust the kernel to fill in a proper value. Reported by: Mikolaj Golub MFC after: 1 month --- etc/gettytab | 2 +- sys/kern/tty.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/etc/gettytab b/etc/gettytab index b75da3d1381..2d3a80abc9b 100644 --- a/etc/gettytab +++ b/etc/gettytab @@ -162,7 +162,7 @@ X|Xwindow|X window system:\ :fd@:nd@:cd@:rw:sp#9600: P|Pc|Pc console:\ - :ht:np:sp#115200: + :ht:np: # # Wierdo special case for fast crt's with hardcopy devices diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 25908df8acc..a3db944e7c4 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -870,8 +870,19 @@ static int ttydevsw_defparam(struct tty *tp, struct termios *t) { - /* Use a fake baud rate, we're not a real device. */ - t->c_ispeed = t->c_ospeed = TTYDEF_SPEED; + /* + * Allow the baud rate to be adjusted for pseudo-devices, but at + * least restrict it to 115200 to prevent excessive buffer + * usage. Also disallow 0, to prevent foot shooting. + */ + if (t->c_ispeed < B50) + t->c_ispeed = B50; + else if (t->c_ispeed > B115200) + t->c_ispeed = B115200; + if (t->c_ospeed < B50) + t->c_ospeed = B50; + else if (t->c_ospeed > B115200) + t->c_ospeed = B115200; return (0); } From f19fa944e6eea0f8de90e0934042cf9d321c6e1f Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 18 Oct 2009 19:50:15 +0000 Subject: [PATCH 205/646] Fix a typo in the jail(8) manpage. Submitted by: Jille Timmermans MFC after: 1 week --- usr.sbin/jail/jail.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index f3340bd0334..30500e4fb9f 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -377,7 +377,7 @@ Since raw sockets can be used to configure and interact with various network subsystems, extra caution should be used where privileged access to jails is given out to untrusted parties. .It Va allow.chflags -Normally, priveleged users inside a jail are treated as unprivileged by +Normally, privileged users inside a jail are treated as unprivileged by .Xr chflags 2 . When this parameter is set, such users are treated as privileged, and may manipulate system file flags subject to the usual constraints on From e79939add18f0c2e39f9b2bcdcdf41a308160592 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 18 Oct 2009 19:51:06 +0000 Subject: [PATCH 206/646] Fix qouting in a comment, to make it look more consistent Submitted by: Jille Timmermans MFC after: 1 week --- etc/rc.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.subr b/etc/rc.subr index 2e502dbf44c..f0a4b58eeb1 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -593,7 +593,7 @@ run_rc_command() rc_fast=yes rc_quiet=yes ;; - force*) # "force prefix; always run + force*) # "force" prefix; always run rc_force=yes _rc_prefix=force rc_arg=${rc_arg#${_rc_prefix}} From 5fd658af94c82ae82be0bd6f86dc88780711e7cf Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 18 Oct 2009 20:33:24 +0000 Subject: [PATCH 207/646] Don't forget to increment the man page date. Reported by: bz --- usr.sbin/jail/jail.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index 30500e4fb9f..4c1a963a7b0 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2009 +.Dd October 18, 2009 .Dt JAIL 8 .Os .Sh NAME From c9ddf688b6dc4a34e8d3f69871a23ffca40a1e59 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 18 Oct 2009 22:43:28 +0000 Subject: [PATCH 208/646] Sort function prototypes in pfil.h, clean up white space, and better align fields for printing. MFC after: 3 days --- sys/net/pfil.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/net/pfil.h b/sys/net/pfil.h index 48b1db860b6..70b50d9adf2 100644 --- a/sys/net/pfil.h +++ b/sys/net/pfil.h @@ -50,7 +50,7 @@ struct inpcb; struct packet_filter_hook { TAILQ_ENTRY(packet_filter_hook) pfil_link; int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int, - struct inpcb *); + struct inpcb *); void *pfil_arg; int pfil_flags; }; @@ -80,14 +80,13 @@ struct pfil_head { LIST_ENTRY(pfil_head) ph_list; }; +int pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, + int, struct inpcb *), void *, int, struct pfil_head *); +int pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, + int, struct inpcb *), void *, int, struct pfil_head *); int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); -int pfil_add_hook(int (*func)(void *, struct mbuf **, - struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *); -int pfil_remove_hook(int (*func)(void *, struct mbuf **, - struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *); - int pfil_head_register(struct pfil_head *); int pfil_head_unregister(struct pfil_head *); @@ -107,6 +106,7 @@ struct pfil_head *pfil_head_get(int, u_long); static __inline struct packet_filter_hook * pfil_hook_get(int dir, struct pfil_head *ph) { + if (dir == PFIL_IN) return (TAILQ_FIRST(&ph->ph_in)); else if (dir == PFIL_OUT) From 23b5fd2285b5e3fb24a0177b3ddbf849b6fcee6d Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 18 Oct 2009 22:54:09 +0000 Subject: [PATCH 209/646] Remove unused pfil_flags field in packet_filter_hook. MFC after: 3 days --- sys/net/pfil.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/pfil.h b/sys/net/pfil.h index 70b50d9adf2..6ac750ab129 100644 --- a/sys/net/pfil.h +++ b/sys/net/pfil.h @@ -52,7 +52,6 @@ struct packet_filter_hook { int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *); void *pfil_arg; - int pfil_flags; }; #define PFIL_IN 0x00000001 From 6015f6f35ab809eb00b4a97332d433a7caabf2b4 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 19 Oct 2009 07:17:37 +0000 Subject: [PATCH 210/646] Properly set the low watermarks when reducing the baud rate. Now that buffers are deallocated lazily, we should not use tty*q_getsize() to obtain the buffer size to calculate the low watermarks. Doing this may cause the watermark to be placed outside the typical buffer size. This caused some regressions after my previous commit to the TTY code, which allows pseudo-devices to resize the buffers as well. Reported by: yongari, dougb MFC after: 1 week --- sys/kern/tty.c | 4 ++-- sys/sys/ttyqueue.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index a3db944e7c4..81f674163f6 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -109,14 +109,14 @@ tty_watermarks(struct tty *tp) ttyinq_setsize(&tp->t_inq, tp, bs); /* Set low watermark at 10% (when 90% is available). */ - tp->t_inlow = (ttyinq_getsize(&tp->t_inq) * 9) / 10; + tp->t_inlow = (ttyinq_getallocatedsize(&tp->t_inq) * 9) / 10; /* Provide an ouput buffer for 0.2 seconds of data. */ bs = MIN(tp->t_termios.c_ospeed / 5, TTYBUF_MAX); ttyoutq_setsize(&tp->t_outq, tp, bs); /* Set low watermark at 10% (when 90% is available). */ - tp->t_outlow = (ttyoutq_getsize(&tp->t_outq) * 9) / 10; + tp->t_outlow = (ttyoutq_getallocatedsize(&tp->t_outq) * 9) / 10; } static int diff --git a/sys/sys/ttyqueue.h b/sys/sys/ttyqueue.h index aac6b3c011f..2d1a565af96 100644 --- a/sys/sys/ttyqueue.h +++ b/sys/sys/ttyqueue.h @@ -92,6 +92,13 @@ ttyinq_getsize(struct ttyinq *ti) return (ti->ti_nblocks * TTYINQ_DATASIZE); } +static __inline size_t +ttyinq_getallocatedsize(struct ttyinq *ti) +{ + + return (ti->ti_quota * TTYINQ_DATASIZE); +} + static __inline size_t ttyinq_bytesleft(struct ttyinq *ti) { @@ -142,6 +149,13 @@ ttyoutq_getsize(struct ttyoutq *to) return (to->to_nblocks * TTYOUTQ_DATASIZE); } +static __inline size_t +ttyoutq_getallocatedsize(struct ttyoutq *to) +{ + + return (to->to_quota * TTYOUTQ_DATASIZE); +} + static __inline size_t ttyoutq_bytesleft(struct ttyoutq *to) { From 6026385bf4c7fb93729c767915caff0339adfc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 19 Oct 2009 07:55:13 +0000 Subject: [PATCH 211/646] Remove redundant $FreeBSD$. --- tools/regression/lib/libutil/test-flopen.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/regression/lib/libutil/test-flopen.c b/tools/regression/lib/libutil/test-flopen.c index 30b1b894127..21d59d20b36 100644 --- a/tools/regression/lib/libutil/test-flopen.c +++ b/tools/regression/lib/libutil/test-flopen.c @@ -23,8 +23,6 @@ * 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$ */ #include From b146811680e7ae146a66dd841d9c5afc5b4e9429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 19 Oct 2009 07:56:03 +0000 Subject: [PATCH 212/646] Update copyright. --- tools/regression/lib/libutil/test-flopen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/regression/lib/libutil/test-flopen.c b/tools/regression/lib/libutil/test-flopen.c index 21d59d20b36..d6ecac3a315 100644 --- a/tools/regression/lib/libutil/test-flopen.c +++ b/tools/regression/lib/libutil/test-flopen.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2007 Dag-Erling Codan Smrgrav + * Copyright (c) 2007-2009 Dag-Erling Codan Smrgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without From 248389c80f469e032d3441fe13428e18350b32a3 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 19 Oct 2009 11:10:44 +0000 Subject: [PATCH 213/646] Partially revert the change to the gettytab made in r198214. By misinterpreting some data, I thought that getty wouldn't apply any baud rate to the syscons devices, but it uses the default entry instead. This means that the baud rate is set to 1200. This isn't too bad, except when using canonical mode. Make it use 9600 baud by default. MFC after: 1 week --- etc/gettytab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/gettytab b/etc/gettytab index 2d3a80abc9b..a7059e7768e 100644 --- a/etc/gettytab +++ b/etc/gettytab @@ -162,7 +162,7 @@ X|Xwindow|X window system:\ :fd@:nd@:cd@:rw:sp#9600: P|Pc|Pc console:\ - :ht:np: + :ht:np:sp#9600: # # Wierdo special case for fast crt's with hardcopy devices From 34413c0e2bf990be80bab4f280b3d3e7d1cb0e97 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 19 Oct 2009 11:17:46 +0000 Subject: [PATCH 214/646] HWMP fixes, namely: * fix the processing of RANN frames * the originator and target addresses were swapped and while it worked fine, it was not spec compliant. MFC after: 3 days --- sys/net80211/ieee80211_hwmp.c | 63 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c index df988505b7f..3481c3e7e94 100644 --- a/sys/net80211/ieee80211_hwmp.c +++ b/sys/net80211/ieee80211_hwmp.c @@ -148,7 +148,7 @@ typedef uint32_t ieee80211_hwmp_seq; struct ieee80211_hwmp_route { ieee80211_hwmp_seq hr_seq; /* last HWMP seq seen from dst*/ ieee80211_hwmp_seq hr_preqid; /* last PREQ ID seen from dst */ - ieee80211_hwmp_seq hr_targetseq; /* seq. no. on our latest PREQ*/ + ieee80211_hwmp_seq hr_origseq; /* seq. no. on our latest PREQ*/ int hr_preqretries; }; struct ieee80211_hwmp_state { @@ -733,12 +733,12 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, prep.prep_flags = 0; prep.prep_hopcount = 0; prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, preq->preq_origaddr); - prep.prep_targetseq = preq->preq_origseq; + IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr); + prep.prep_targetseq = ++hs->hs_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr); - prep.prep_origseq = ++hs->hs_seq; + IEEE80211_ADDR_COPY(prep.prep_origaddr, preq->preq_origaddr); + prep.prep_origseq = preq->preq_origseq; hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep); /* * Build the reverse path, if we don't have it already. @@ -784,13 +784,13 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, prep.prep_flags = 0; prep.prep_hopcount = 0; prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr); + IEEE80211_ADDR_COPY(prep.prep_origaddr, rootmac); prep.prep_origseq = preq->preq_origseq; - prep.prep_targetseq = ++hs->hs_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, rootmac); - prep.prep_targetseq = PREQ_TSEQ(0); + IEEE80211_ADDR_COPY(prep.prep_targetaddr, + vap->iv_myaddr); + prep.prep_targetseq = ++hs->hs_seq; hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &prep); } @@ -848,13 +848,13 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, prep.prep_hopcount = rt->rt_nhops + 1; prep.prep_ttl = ms->ms_ttl; IEEE80211_ADDR_COPY(&prep.prep_targetaddr, - preq->preq_origaddr); + PREQ_TADDR(0)); prep.prep_targetseq = hrorig->hr_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = rt->rt_metric + ms->ms_pmetric->mpm_metric(ni); IEEE80211_ADDR_COPY(&prep.prep_origaddr, - PREQ_TADDR(0)); + preq->preq_origaddr); prep.prep_origseq = hrorig->hr_seq; hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &prep); @@ -951,19 +951,19 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, return; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "received PREP from %s", ether_sprintf(prep->prep_origaddr)); + "received PREP from %s", ether_sprintf(prep->prep_targetaddr)); - rt = ieee80211_mesh_rt_find(vap, prep->prep_origaddr); + rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr); if (rt == NULL) { /* * If we have no entry this could be a reply to a root PREQ. */ if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) { - rt = ieee80211_mesh_rt_add(vap, prep->prep_origaddr); + rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr); if (rt == NULL) { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "unable to add PREP path to %s", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); vap->iv_stats.is_mesh_rtaddfailed++; return; } @@ -974,7 +974,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "add root path to %s nhops %d metric %d (PREP)", - ether_sprintf(prep->prep_origaddr), + ether_sprintf(prep->prep_targetaddr), rt->rt_nhops, rt->rt_metric); return; } @@ -984,30 +984,30 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, * Sequence number validation. */ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_LEQ(prep->prep_origseq, hr->hr_seq)) { + if (HWMP_SEQ_LEQ(prep->prep_targetseq, hr->hr_seq)) { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP from %s, old seq no %u <= %u", - ether_sprintf(prep->prep_origaddr), - prep->prep_origseq, hr->hr_seq); + ether_sprintf(prep->prep_targetaddr), + prep->prep_targetseq, hr->hr_seq); return; } - hr->hr_seq = prep->prep_origseq; + hr->hr_seq = prep->prep_targetseq; /* * If it's NOT for us, propagate the PREP. */ - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_targetaddr) && + if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) { struct ieee80211_meshprep_ie pprep; /* propagated PREP */ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "propagate PREP from %s", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); memcpy(&pprep, prep, sizeof(pprep)); pprep.prep_hopcount += 1; pprep.prep_ttl -= 1; pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); - IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr); + IEEE80211_ADDR_COPY(pprep.prep_targetaddr, vap->iv_myaddr); hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep); } hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); @@ -1015,9 +1015,9 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, /* NB: never clobber a proxy entry */; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP for %s, route is marked PROXY", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); vap->iv_stats.is_hwmp_proxy++; - } else if (prep->prep_targetseq == hr->hr_targetseq) { + } else if (prep->prep_origseq == hr->hr_origseq) { /* * Check if we already have a path to this node. * If we do, check if this path reply contains a @@ -1041,14 +1041,14 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, } else { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "ignore PREP for %s, hopcount %d:%d metric %d:%d", - ether_sprintf(prep->prep_origaddr), + ether_sprintf(prep->prep_targetaddr), rt->rt_nhops, prep->prep_hopcount, rt->rt_metric, prep->prep_metric); } } else { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP for %s, wrong seqno %u != %u", - ether_sprintf(prep->prep_origaddr), prep->prep_targetseq, + ether_sprintf(prep->prep_targetaddr), prep->prep_origseq, hr->hr_seq); vap->iv_stats.is_hwmp_wrongseq++; } @@ -1223,7 +1223,8 @@ hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni, struct ieee80211_meshrann_ie prann; if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) + ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || + IEEE80211_ADDR_EQ(rann->rann_addr, vap->iv_myaddr)) return; rt = ieee80211_mesh_rt_find(vap, rann->rann_addr); @@ -1305,8 +1306,8 @@ hwmp_discover(struct ieee80211vap *vap, hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { - if (hr->hr_targetseq == 0) - hr->hr_targetseq = ++hs->hs_seq; + if (hr->hr_origseq == 0) + hr->hr_origseq = ++hs->hs_seq; rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL; rt->rt_lifetime = ticks_to_msecs(ieee80211_hwmp_pathtimeout); @@ -1324,7 +1325,7 @@ hwmp_discover(struct ieee80211vap *vap, preq.preq_ttl = ms->ms_ttl; preq.preq_id = ++hs->hs_preqid; IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); - preq.preq_origseq = hr->hr_targetseq; + preq.preq_origseq = hr->hr_origseq; preq.preq_lifetime = rt->rt_lifetime; preq.preq_metric = rt->rt_metric; preq.preq_tcount = 1; From f807cca1a3f47b5d7d3720352ae377cf09d5e052 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 19 Oct 2009 14:04:19 +0000 Subject: [PATCH 215/646] Properly re-create "-s size" argument to newfs(8). --- sbin/dumpfs/dumpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c index 2f577d9bee2..4bcbe5fef03 100644 --- a/sbin/dumpfs/dumpfs.c +++ b/sbin/dumpfs/dumpfs.c @@ -413,7 +413,7 @@ marshal(const char *name) break; } /* -p..r unimplemented */ - printf("-s %jd ", (intmax_t)fs->fs_size); + printf("-s %jd ", (intmax_t)fsbtodb(fs, fs->fs_size)); printf("%s ", disk.d_name); printf("\n"); From 07ba0ec4ff8adbd7e356cd1865a9085bf38b8e5c Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 19 Oct 2009 14:36:12 +0000 Subject: [PATCH 216/646] Powercrypt and NetSec seem to be defunct (webpages point to link farms and a google search yields no alternative). Remove the links but keep the entries around for reference. PR: 139756 Submitted by: Patrick Oonk MFC after: 3 days --- share/man/man4/hifn.4 | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/share/man/man4/hifn.4 b/share/man/man4/hifn.4 index 9aeccfaf5f3..02b8e32b443 100644 --- a/share/man/man4/hifn.4 +++ b/share/man/man4/hifn.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 1, 2006 +.Dd October 19, 2009 .Dt HIFN 4 .Os .Sh NAME @@ -85,17 +85,11 @@ Came as 128KB SRAM model, or 2MB DRAM model. .It Hifn 7751 Reference board with 512KB SRAM. .It PowerCrypt -See -.Pa http://www.powercrypt.com/ . Comes with 512KB SRAM. .It XL-Crypt -See -.Pa http://www.powercrypt.com/ . Only board based on 7811 (which is faster than 7751 and has a random number generator). .It NetSec 7751 -See -.Pa http://www.netsec.net/ . Supports the most IPsec sessions, with 1MB SRAM. .It Soekris Engineering vpn1201 and vpn1211 See From cee8119875ba1e233df1e8ac6fc3224e0ddf6e60 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 19 Oct 2009 15:19:14 +0000 Subject: [PATCH 217/646] Clean up comments, white space, and style in pfil.c (especially new VNET bits). MFC after: 3 days (not VNET bits) --- sys/net/pfil.c | 58 ++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 78c3ca9955f..a11950f6480 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -86,14 +86,13 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, } } PFIL_RUNLOCK(ph, &rmpt); - *mp = m; return (rv); } /* - * pfil_head_register() registers a pfil_head with the packet filter - * hook mechanism. + * pfil_head_register() registers a pfil_head with the packet filter hook + * mechanism. */ int pfil_head_register(struct pfil_head *ph) @@ -105,7 +104,7 @@ pfil_head_register(struct pfil_head *ph) if (ph->ph_type == lph->ph_type && ph->ph_un.phu_val == lph->ph_un.phu_val) { PFIL_LIST_UNLOCK(); - return EEXIST; + return (EEXIST); } } PFIL_LOCK_INIT(ph); @@ -151,7 +150,6 @@ pfil_head_get(int type, u_long val) if (ph->ph_type == type && ph->ph_un.phu_val == val) break; PFIL_LIST_UNLOCK(); - return (ph); } @@ -208,7 +206,7 @@ pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, ph->ph_nhooks++; } PFIL_WUNLOCK(ph); - return 0; + return (0); locked_error: PFIL_WUNLOCK(ph); error: @@ -216,12 +214,12 @@ error: free(pfh1, M_IFADDR); if (pfh2 != NULL) free(pfh2, M_IFADDR); - return err; + return (err); } /* - * pfil_remove_hook removes a specific function from the packet filter - * hook list. + * pfil_remove_hook removes a specific function from the packet filter hook + * list. */ int pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, @@ -230,7 +228,6 @@ pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, int err = 0; PFIL_WLOCK(ph); - if (flags & PFIL_IN) { err = pfil_list_remove(&ph->ph_in, func, arg); if (err == 0) @@ -242,8 +239,7 @@ pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, ph->ph_nhooks--; } PFIL_WUNLOCK(ph); - - return err; + return (err); } static int @@ -257,17 +253,17 @@ pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flags) TAILQ_FOREACH(pfh, list, pfil_link) if (pfh->pfil_func == pfh1->pfil_func && pfh->pfil_arg == pfh1->pfil_arg) - return EEXIST; + return (EEXIST); + /* - * insert the input list in reverse order of the output list - * so that the same path is followed in or out of the kernel. + * Insert the input list in reverse order of the output list so that + * the same path is followed in or out of the kernel. */ if (flags & PFIL_IN) TAILQ_INSERT_HEAD(list, pfh1, pfil_link); else TAILQ_INSERT_TAIL(list, pfh1, pfil_link); - - return 0; + return (0); } /* @@ -285,30 +281,32 @@ pfil_list_remove(pfil_list_t *list, if (pfh->pfil_func == func && pfh->pfil_arg == arg) { TAILQ_REMOVE(list, pfh, pfil_link); free(pfh, M_IFADDR); - return 0; + return (0); } - return ENOENT; + return (ENOENT); } -/**************** - * Stuff that must be initialized for every instance - * (including the first of course). +/* + * Stuff that must be initialized for every instance (including the first of + * course). */ static int vnet_pfil_init(const void *unused) { + LIST_INIT(&V_pfil_head_list); return (0); } -/*********************** +/* * Called for the removal of each instance. */ static int vnet_pfil_uninit(const void *unused) { + /* XXX should panic if list is not empty */ - return 0; + return (0); } /* Define startup order. */ @@ -317,17 +315,17 @@ vnet_pfil_uninit(const void *unused) #define PFIL_VNET_ORDER (PFIL_MODEVENT_ORDER + 2) /* Later still. */ /* - * Starting up. + * Starting up. + * * VNET_SYSINIT is called for each existing vnet and each new vnet. */ VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, - vnet_pfil_init, NULL); + vnet_pfil_init, NULL); /* - * Closing up shop. These are done in REVERSE ORDER, - * Not called on reboot. + * Closing up shop. These are done in REVERSE ORDER. Not called on reboot. + * * VNET_SYSUNINIT is called for each exiting vnet as it exits. */ VNET_SYSUNINIT(vnet_pfil_uninit, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, - vnet_pfil_uninit, NULL); - + vnet_pfil_uninit, NULL); From 605c493e9080946e0ab6a361fdfb091a6b7fb5ca Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 19 Oct 2009 15:50:59 +0000 Subject: [PATCH 218/646] Clean up markup (mainly). --- sbin/geom/class/part/gpart.8 | 226 +++++++++++++++++++++++------------ 1 file changed, 149 insertions(+), 77 deletions(-) diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index 6deea8cd2ab..3de658c775b 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Nov 18, 2008 +.Dd November 18, 2008 .Dt GPART 8 .Os .Sh NAME @@ -43,20 +43,34 @@ lines in your kernel configuration file: .Cd "options GEOM_PART_VTOC8" .Ed .Pp -The GEOM_PART_APM option adds support for the Apple Partition Map (APM) +The +.Dv GEOM_PART_APM +option adds support for the Apple Partition Map (APM) found on Apple Macintosh computers. -The GEOM_PART_BSD option adds support for the traditional BSD disklabel. -The GEOM_PART_GPT option adds support for the GUID Partition Table (GPT) +The +.Dv GEOM_PART_BSD +option adds support for the traditional +.Bx +disklabel. +The +.Dv GEOM_PART_GPT +option adds support for the GUID Partition Table (GPT) found on Intel Itanium computers and Intel-based Macintosh computers. -The GEOM_PART_MBR option adds support for the Master Boot Record (MBR) +The +.Dv GEOM_PART_MBR +option adds support for the Master Boot Record (MBR) found on PCs and used on many removable media. -The GEOM_PART_PC98 option adds support for the MBR variant as used on +The +.Dv GEOM_PART_PC98 +option adds support for the MBR variant as used on NEC PC-98 computers. -The GEOM_PART_VTOC8 option adds support for Sun's SMI VTOC8 label as +The +.Dv GEOM_PART_VTOC8 +option adds support for Sun's SMI VTOC8 label as found on UltraSPARC-based computers. .Pp Usage of the -.Xr gpart 8 +.Ns Nm utility: .Pp .\" ==== ADD ==== @@ -123,7 +137,7 @@ utility: .Ar geom .\" ==== UNSET ==== .Nm -.Cm unset +.Cm unset .Fl a Ar attrib .Fl i Ar index .Op Fl f Ar flags @@ -134,7 +148,7 @@ The .Nm utility is used to partition GEOM providers, normally disks. The first argument of which is the action to be taken: -.Bl -tag -width ".Cm wwwwwww" +.Bl -tag -width ".Cm bootcode" .\" ==== ADD ==== .It Cm add Add a new partition to the partitioning scheme given by @@ -148,13 +162,15 @@ option. The type of the partition is given by the .Fl t Ar type option. -Partition types are discussed in the section entitled "Partition Types". +Partition types are discussed below in the section entitled +.Sx "PARTITION TYPES" . .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl i Ar index The index in the partition table at which the new partition is to be -placed. The index determines the name of the device special file used +placed. +The index determines the name of the device special file used to represent the partition. .It Fl l Ar label The label attached to the partition. @@ -162,7 +178,9 @@ This option is only valid when used on partitioning schemes that support partition labels. .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== BOOTCODE ==== @@ -185,7 +203,7 @@ The option specifies a file that contains the bootstrap code. The contents and size of the file are determined by the partitioning scheme. -For the MBR scheme, it's a 512 byte file of which the first 446 bytes +For the MBR scheme, it is a 512 byte file of which the first 446 bytes are installed as bootstrap code. The .Fl p Ar partcode @@ -196,11 +214,13 @@ The partition is specified by the option. The size of the file must be smaller than the size of the partition. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== COMMIT ==== @@ -229,8 +249,8 @@ option determines the scheme to use. The kernel needs to have support for a particular scheme before that scheme can be used to partition a disk. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl n Ar entries The number of entries in the partition table. Every partitioning scheme has a minimum and a maximum number of entries @@ -242,7 +262,9 @@ By default, partition tables are created with the minimum number of entries. .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== DELETE ==== @@ -254,11 +276,13 @@ and further identified by the option. The partition cannot be actively used by the kernel. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== DESTROY ==== @@ -266,11 +290,13 @@ about its use. Destroy the partitioning scheme as implemented by geom .Ar geom . .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== MODIFY ==== @@ -290,22 +316,26 @@ option. Not all partitioning schemes support labels and it is invalid to try to change a partition label in such cases. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== SET ==== .It Cm set Set the named attribute on the partition entry. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .\" ==== SHOW ==== @@ -314,7 +344,8 @@ Show the current partition information of the specified geoms or all geoms if none are specified. .\" ==== UNDO ==== .It Cm undo -Revert any pending changes. +Revert any pending changes for geom +.Ar geom . This action is the opposite of the .Cm commit action and can be used to undo any changes that have not been committed. @@ -322,11 +353,13 @@ action and can be used to undo any changes that have not been committed. .It Cm unset Clear the named attribute on the partition entry. .Pp -Addition options include: -.Bl -tag -width ".Fl w Ar wwwwwww" +Additional options include: +.Bl -tag -width 10n .It Fl f Ar flags Additional operational flags. -See the section entitled "Operational flags" below for a discussion +See the section entitled +.Sx "OPERATIONAL FLAGS" +below for a discussion about its use. .El .El @@ -338,47 +371,82 @@ utility uses symbolic names for common partition types to avoid that the user needs to know what the partitioning scheme in question is and what the actual number or identification needs to be used for a particular type. -the +The .Nm utility also allows the user to specify scheme-specific partition types -for partition types that don't have symbol names. +for partition types that do not have symbol names. The symbolic names currently understood are: -.Bl -tag -width "wwwwwwwwwwwww" -.It efi +.Bl -tag -width ".Cm freebsd-vinum" +.It Cm efi The system partition for computers that use the Extensible Firmware Interface (EFI). In such cases, the GPT partitioning scheme is being used and the actual partition type for the system partition can also be specified as -"!c12a7328-f81f-11d2-ba4b-00a0c93ec93ab". -.It freebsd -A FreeBSD partition that uses the BSD disklabel to sub-divide the +.Qq Li "!c12a7328-f81f-11d2-ba4b-00a0c93ec93ab" . +.It Cm freebsd +A +.Fx +partition that uses the +.Bx +disklabel to sub-divide the partition into file systems. This is a legacy partition type and should not be used for the APM or GPT schemes. -The scheme-specific types are "!165" for MBR, "!FreeBSD" for APM, and -"!516e7cb4-6ecf-11d6-8ff8-00022d09712b" for GPT. -.It freebsd-boot -A FreeBSD partition dedicated to bootstrap code. -The scheme-specific type is "!83bd6b9d-7f41-11dc-be0b-001560b84f0f" for GPT. -.It freebsd-swap -A FreeBSD partition dedicated to swap space. -The scheme-specific types are "!FreeBSD-swap" for APM, and -"!516e7cb5-6ecf-11d6-8ff8-00022d09712b" for GPT. -.It freebsd-ufs -A FreeBSD partition that contains a UFS or UFS2 file system. -the scheme-specific types are "!FreeBSD-UFS" for APM, and -"!516e7cb6-6ecf-11d6-8ff8-00022d09712b" for GPT. -.It freebsd-vinum -A FreeBSD partition that contains a Vinum volume. -The scheme-specific types are "!FreeBSD-Vinum" for APM, and -"!516e7cb8-6ecf-11d6-8ff8-00022d09712b" for GPT. -.It freebsd-zfs -A FreeBSD partition that contains a ZFS volume. -The scheme-specific types are "!FreeBSD-ZFS" for APM, and -"!516e7cba-6ecf-11d6-8ff8-00022d09712b" for GPT. -.It mbr +The scheme-specific types are +.Qq Li "!165" +for MBR, +.Qq Li "!FreeBSD" +for APM, and +.Qq Li "!516e7cb4-6ecf-11d6-8ff8-00022d09712b" +for GPT. +.It Cm freebsd-boot +A +.Fx +partition dedicated to bootstrap code. +The scheme-specific type is +.Qq Li "!83bd6b9d-7f41-11dc-be0b-001560b84f0f" +for GPT. +.It Cm freebsd-swap +A +.Fx +partition dedicated to swap space. +The scheme-specific types are +.Qq Li "!FreeBSD-swap" +for APM, and +.Qq Li "!516e7cb5-6ecf-11d6-8ff8-00022d09712b" +for GPT. +.It Cm freebsd-ufs +A +.Fx +partition that contains a UFS or UFS2 file system. +The scheme-specific types are +.Qq Li "!FreeBSD-UFS" +for APM, and +.Qq Li "!516e7cb6-6ecf-11d6-8ff8-00022d09712b" +for GPT. +.It Cm freebsd-vinum +A +.Fx +partition that contains a Vinum volume. +The scheme-specific types are +.Qq Li "!FreeBSD-Vinum" +for APM, and +.Qq Li "!516e7cb8-6ecf-11d6-8ff8-00022d09712b" +for GPT. +.It Cm freebsd-zfs +A +.Fx +partition that contains a ZFS volume. +The scheme-specific types are +.Qq Li "!FreeBSD-ZFS" +for APM, and +.Qq Li "!516e7cba-6ecf-11d6-8ff8-00022d09712b" +for GPT. +.It Cm mbr A partition that is sub-partitioned by a master boot record (MBR). -This type is known as "!024dee41-33e7-11d3-9d69-0008c781f39f" by GPT. +This type is known as +.Qq Li "!024dee41-33e7-11d3-9d69-0008c781f39f" +by GPT. .El .Sh OPERATIONAL FLAGS Actions other than the @@ -391,10 +459,12 @@ option. This option is used to specify action-specific operational flags. By default, the .Nm -utility defines the 'C' flag so that the action is immediately +utility defines the +.Ql C +flag so that the action is immediately committed. The user can specify -.Fl f Ar x +.Dq Fl f Cm x to have the action result in a pending change that can later, with other pending changes, be committed as a single compound change with the @@ -417,31 +487,33 @@ Embed GPT bootstrap code into protective MBR. .Ed .Pp Create a dedicated -.Pa freebsd-boot -partition that can boot FreeBSD from a -.Pa freebsd-ufs +.Cm freebsd-boot +partition that can boot +.Fx +from a +.Cm freebsd-ufs partition, and install bootstrap code into it. This partition must be larger than .Pa /boot/gptboot , or the GPT boot you are planning to write. A size of 15 blocks (7680 bytes) would be sufficient for -booting from UFS but lets use 128 blocks (64 KB) here in +booting from UFS but let's use 128 blocks (64 KB) here in this example, in order to reserve some space for potential -future need (e.g. from a ZFS partition). +future need (e.g.\& from a ZFS partition). .Bd -literal -offset indent /sbin/gpart add -b 34 -s 128 -t freebsd-boot ad0 /sbin/gpart bootcode -p /boot/gptboot -i 1 ad0 .Ed .Pp Create a 512MB-sized -.Pa freebsd-ufs +.Cm freebsd-ufs partition that would contain UFS where the system boot from. .Bd -literal -offset indent /sbin/gpart add -b 162 -s 1048576 -t freebsd-ufs ad0 .Ed .Sh SEE ALSO .Xr geom 4 , -.Xr geom 8 , +.Xr geom 8 .Sh HISTORY The .Nm From 106d839190bf604806e084ce5e7dd8ee8142c1d9 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 19 Oct 2009 16:00:24 +0000 Subject: [PATCH 219/646] Switch the default WARNS level for sbin/ to 6. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Ulrich Spテカrlein --- sbin/Makefile.inc | 2 +- sbin/adjkerntz/Makefile | 1 + sbin/atacontrol/Makefile | 1 - sbin/atm/atmconfig/Makefile | 2 -- sbin/badsect/Makefile | 1 + sbin/bsdlabel/Makefile | 1 + sbin/camcontrol/Makefile | 2 -- sbin/ccdconfig/Makefile | 1 - sbin/clri/Makefile | 1 + sbin/comcontrol/Makefile | 1 - sbin/conscontrol/Makefile | 1 + sbin/dhclient/Makefile | 2 ++ sbin/dmesg/Makefile | 2 -- sbin/dump/Makefile | 1 + sbin/dumpfs/Makefile | 1 + sbin/dumpon/Makefile | 1 - sbin/geom/Makefile | 1 + sbin/geom/Makefile.inc | 1 - sbin/ggate/Makefile.inc | 2 -- sbin/growfs/Makefile | 2 -- sbin/gvinum/Makefile | 1 + sbin/init/Makefile | 1 - sbin/ipf/Makefile.inc | 2 ++ sbin/iscontrol/Makefile | 1 + sbin/kldunload/Makefile | 1 - sbin/ldconfig/Makefile | 1 - sbin/md5/Makefile | 1 - sbin/mdconfig/Makefile | 1 + sbin/mdmfs/Makefile | 1 - sbin/mksnap_ffs/Makefile | 1 + sbin/mount/Makefile | 1 - sbin/mount_autofs/Makefile | 1 + sbin/mount_cd9660/Makefile | 1 - sbin/mount_ext2fs/Makefile | 1 + sbin/mount_msdosfs/Makefile | 1 - sbin/mount_nullfs/Makefile | 1 - sbin/mount_reiserfs/Makefile | 1 - sbin/mount_unionfs/Makefile | 1 - sbin/newfs_msdos/Makefile | 2 -- sbin/nfsiod/Makefile | 1 - sbin/pfctl/Makefile | 1 + sbin/rcorder/Makefile | 1 - sbin/reboot/Makefile | 1 - sbin/recoverdisk/Makefile | 1 - sbin/routed/Makefile | 4 +--- sbin/savecore/Makefile | 1 - sbin/sconfig/Makefile | 1 + sbin/shutdown/Makefile | 2 -- sbin/spppcontrol/Makefile | 1 + sbin/swapon/Makefile | 1 + sbin/tunefs/Makefile | 1 + 51 files changed, 25 insertions(+), 39 deletions(-) diff --git a/sbin/Makefile.inc b/sbin/Makefile.inc index 70d658416ea..e506f9c56ce 100644 --- a/sbin/Makefile.inc +++ b/sbin/Makefile.inc @@ -4,7 +4,7 @@ .include BINDIR?= /sbin -WARNS?= 2 +WARNS?= 6 .if ${MK_DYNAMICROOT} == "no" NO_SHARED?= YES diff --git a/sbin/adjkerntz/Makefile b/sbin/adjkerntz/Makefile index 27c128916f9..8e504e916eb 100644 --- a/sbin/adjkerntz/Makefile +++ b/sbin/adjkerntz/Makefile @@ -2,5 +2,6 @@ PROG= adjkerntz MAN= adjkerntz.8 +WARNS?= 2 .include diff --git a/sbin/atacontrol/Makefile b/sbin/atacontrol/Makefile index 73b916080d4..9881273c211 100644 --- a/sbin/atacontrol/Makefile +++ b/sbin/atacontrol/Makefile @@ -2,6 +2,5 @@ PROG= atacontrol MAN= atacontrol.8 -WARNS?= 6 .include diff --git a/sbin/atm/atmconfig/Makefile b/sbin/atm/atmconfig/Makefile index 1db0fa46dc0..8564d355efb 100644 --- a/sbin/atm/atmconfig/Makefile +++ b/sbin/atm/atmconfig/Makefile @@ -29,8 +29,6 @@ CLEANFILES+= oid.h .if ${MACHINE_ARCH} == "arm" WARNS?= 3 -.else -WARNS?= 6 .endif FILES= atmconfig.help atmconfig_device.help diff --git a/sbin/badsect/Makefile b/sbin/badsect/Makefile index a39227716b7..b6cb545e09f 100644 --- a/sbin/badsect/Makefile +++ b/sbin/badsect/Makefile @@ -5,5 +5,6 @@ PROG= badsect DPADD= ${LIBUFS} LDADD= -lufs MAN= badsect.8 +WARNS?= 2 .include diff --git a/sbin/bsdlabel/Makefile b/sbin/bsdlabel/Makefile index 562b0f38c1a..b60bbd03add 100644 --- a/sbin/bsdlabel/Makefile +++ b/sbin/bsdlabel/Makefile @@ -13,6 +13,7 @@ LINKS= ${BINDIR}/bsdlabel ${BINDIR}/disklabel MLINKS= bsdlabel.8 disklabel.8 .endif +WARNS?= 2 DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} LDADD= -lgeom -lbsdxml -lsbuf diff --git a/sbin/camcontrol/Makefile b/sbin/camcontrol/Makefile index 7a3d4213cba..31bbd46f4a5 100644 --- a/sbin/camcontrol/Makefile +++ b/sbin/camcontrol/Makefile @@ -9,8 +9,6 @@ CFLAGS+= -DMINIMALISTIC .endif .if ${MACHINE_ARCH} == "arm" WARNS?= 3 -.else -WARNS?= 6 .endif DPADD= ${LIBCAM} ${LIBSBUF} ${LIBUTIL} LDADD= -lcam -lsbuf -lutil diff --git a/sbin/ccdconfig/Makefile b/sbin/ccdconfig/Makefile index ac7558409ed..0feca5426de 100644 --- a/sbin/ccdconfig/Makefile +++ b/sbin/ccdconfig/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ PROG= ccdconfig -WARNS?= 6 MAN= ccdconfig.8 DPADD= ${LIBGEOM} diff --git a/sbin/clri/Makefile b/sbin/clri/Makefile index c68c312f269..1ae0cf45e73 100644 --- a/sbin/clri/Makefile +++ b/sbin/clri/Makefile @@ -3,5 +3,6 @@ PROG= clri MAN= clri.8 +WARNS?= 2 .include diff --git a/sbin/comcontrol/Makefile b/sbin/comcontrol/Makefile index a7720d81b41..d8757565b1a 100644 --- a/sbin/comcontrol/Makefile +++ b/sbin/comcontrol/Makefile @@ -3,6 +3,5 @@ PROG= comcontrol MAN= comcontrol.8 -WARNS?= 6 .include diff --git a/sbin/conscontrol/Makefile b/sbin/conscontrol/Makefile index ddd2434e6cc..9014d80ad55 100644 --- a/sbin/conscontrol/Makefile +++ b/sbin/conscontrol/Makefile @@ -2,5 +2,6 @@ PROG= conscontrol MAN= conscontrol.8 +WARNS?= 2 .include diff --git a/sbin/dhclient/Makefile b/sbin/dhclient/Makefile index 7e32326ff00..434335b5a07 100644 --- a/sbin/dhclient/Makefile +++ b/sbin/dhclient/Makefile @@ -40,4 +40,6 @@ SCRIPTS=dhclient-script MAN= dhclient.8 dhclient.conf.5 dhclient.leases.5 dhcp-options.5 \ dhclient-script.8 +WARNS?= 2 + .include diff --git a/sbin/dmesg/Makefile b/sbin/dmesg/Makefile index 8472f56c461..266551be576 100644 --- a/sbin/dmesg/Makefile +++ b/sbin/dmesg/Makefile @@ -4,8 +4,6 @@ PROG= dmesg MAN= dmesg.8 -WARNS?= 6 - LDADD= -lkvm DPADD= ${LIBKVM} diff --git a/sbin/dump/Makefile b/sbin/dump/Makefile index 608162aa570..e3d9aef6151 100644 --- a/sbin/dump/Makefile +++ b/sbin/dump/Makefile @@ -19,5 +19,6 @@ CFLAGS+=-DRDUMP SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c cache.c MAN= dump.8 MLINKS= dump.8 rdump.8 +WARNS?= 2 .include diff --git a/sbin/dumpfs/Makefile b/sbin/dumpfs/Makefile index 99faa77ad72..fe464e03f7b 100644 --- a/sbin/dumpfs/Makefile +++ b/sbin/dumpfs/Makefile @@ -2,6 +2,7 @@ # $FreeBSD$ PROG= dumpfs +WARNS?= 2 DPADD= ${LIBUFS} LDADD= -lufs MAN= dumpfs.8 diff --git a/sbin/dumpon/Makefile b/sbin/dumpon/Makefile index c273f93470a..d11ccc76112 100644 --- a/sbin/dumpon/Makefile +++ b/sbin/dumpon/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ PROG= dumpon -WARNS?= 6 MAN= dumpon.8 .include diff --git a/sbin/geom/Makefile b/sbin/geom/Makefile index fffb889bc2c..88b82404e10 100644 --- a/sbin/geom/Makefile +++ b/sbin/geom/Makefile @@ -11,6 +11,7 @@ PROG= geom SRCS= geom.c geom_label.c geom_part.c subr.c NO_MAN= +WARNS?= 2 CFLAGS+=-I${.CURDIR} -I${.CURDIR}/core -DSTATIC_GEOM_CLASSES DPADD= ${LIBGEOM} ${LIBSBUF} ${LIBBSDXML} ${LIBUTIL} diff --git a/sbin/geom/Makefile.inc b/sbin/geom/Makefile.inc index 94ca09f3889..bf9f05ed66a 100644 --- a/sbin/geom/Makefile.inc +++ b/sbin/geom/Makefile.inc @@ -1,6 +1,5 @@ # $FreeBSD$ -WARNS?= 6 CLASS_DIR?=/lib/geom .include "../Makefile.inc" diff --git a/sbin/ggate/Makefile.inc b/sbin/ggate/Makefile.inc index e55271f7ddc..265f86d1ed5 100644 --- a/sbin/ggate/Makefile.inc +++ b/sbin/ggate/Makefile.inc @@ -1,5 +1,3 @@ # $FreeBSD$ -WARNS?= 6 - .include "../Makefile.inc" diff --git a/sbin/growfs/Makefile b/sbin/growfs/Makefile index a5e9937e8f1..a875ce554c1 100644 --- a/sbin/growfs/Makefile +++ b/sbin/growfs/Makefile @@ -10,8 +10,6 @@ PROG= growfs SRCS= growfs.c MAN= growfs.8 -WARNS?= 6 - .if defined(GFSDBG) SRCS+= debug.c .endif diff --git a/sbin/gvinum/Makefile b/sbin/gvinum/Makefile index 6d414974dba..e4bf4a71449 100644 --- a/sbin/gvinum/Makefile +++ b/sbin/gvinum/Makefile @@ -4,6 +4,7 @@ PROG= gvinum SRCS= gvinum.c gvinum.h geom_vinum_share.c MAN= gvinum.8 +WARNS?= 2 CFLAGS+= -I${.CURDIR}/../../sys DPADD= ${LIBREADLINE} ${LIBTERMCAP} ${LIBDEVSTAT} ${LIBKVM} ${LIBGEOM} diff --git a/sbin/init/Makefile b/sbin/init/Makefile index 58a9e0ad0d2..7497a4b54fd 100644 --- a/sbin/init/Makefile +++ b/sbin/init/Makefile @@ -5,7 +5,6 @@ PROG= init MAN= init.8 PRECIOUSPROG= INSTALLFLAGS=-b -B.bak -WARNS?= 6 CFLAGS+=-DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT DPADD= ${LIBUTIL} ${LIBCRYPT} LDADD= -lutil -lcrypt diff --git a/sbin/ipf/Makefile.inc b/sbin/ipf/Makefile.inc index 3373b557bd8..0065ce7550c 100644 --- a/sbin/ipf/Makefile.inc +++ b/sbin/ipf/Makefile.inc @@ -1,5 +1,7 @@ # $FreeBSD$ +WARNS?= 2 + CFLAGS+= -I${.CURDIR}/../../../contrib/ipfilter CFLAGS+= -I${.CURDIR}/../../../contrib/ipfilter/tools CFLAGS+= -I${.CURDIR}/../../../sys diff --git a/sbin/iscontrol/Makefile b/sbin/iscontrol/Makefile index 2b09fa9aa37..446a5f48ab5 100644 --- a/sbin/iscontrol/Makefile +++ b/sbin/iscontrol/Makefile @@ -5,6 +5,7 @@ PROG= iscontrol DPADD= ${LIBCAM} ${LIBMD} LDADD= -lcam -lmd +WARNS?= 2 CFLAGS += -I${.CURDIR}/../../sys/dev/iscsi/initiator #CFLAGS += -g -DDEBUG diff --git a/sbin/kldunload/Makefile b/sbin/kldunload/Makefile index 48e5c035ccd..1a25a02351b 100644 --- a/sbin/kldunload/Makefile +++ b/sbin/kldunload/Makefile @@ -28,6 +28,5 @@ PROG= kldunload MAN= kldunload.8 -WARNS?= 6 .include diff --git a/sbin/ldconfig/Makefile b/sbin/ldconfig/Makefile index 442ae635071..15c3808520b 100644 --- a/sbin/ldconfig/Makefile +++ b/sbin/ldconfig/Makefile @@ -3,7 +3,6 @@ PROG= ldconfig SRCS= elfhints.c ldconfig.c shlib.c support.c LDDIR?= ${.CURDIR}/../../libexec/rtld-aout -WARNS?= 6 CFLAGS+=-I${LDDIR} -DFREEBSD_AOUT MAN= ldconfig.8 diff --git a/sbin/md5/Makefile b/sbin/md5/Makefile index 07c4109e0d7..7df4d859c93 100644 --- a/sbin/md5/Makefile +++ b/sbin/md5/Makefile @@ -11,7 +11,6 @@ MLINKS= md5.1 rmd160.1 \ md5.1 sha1.1 \ md5.1 sha256.1 -WARNS?= 6 WFORMAT?= 1 DPADD= ${LIBMD} diff --git a/sbin/mdconfig/Makefile b/sbin/mdconfig/Makefile index f4d8adcfde8..11223f22839 100644 --- a/sbin/mdconfig/Makefile +++ b/sbin/mdconfig/Makefile @@ -4,6 +4,7 @@ PROG= mdconfig MAN= mdconfig.8 MLINKS= mdconfig.8 vnconfig.8 +WARNS?= 2 DPADD= ${LIBUTIL} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} LDADD= -lutil -lgeom -lbsdxml -lsbuf diff --git a/sbin/mdmfs/Makefile b/sbin/mdmfs/Makefile index 1ef70845426..999793f0e10 100644 --- a/sbin/mdmfs/Makefile +++ b/sbin/mdmfs/Makefile @@ -4,6 +4,5 @@ PROG= mdmfs LINKS= ${BINDIR}/${PROG} ${BINDIR}/mount_mfs MAN= mdmfs.8 MLINKS+= mdmfs.8 mount_mfs.8 -WARNS?= 6 .include diff --git a/sbin/mksnap_ffs/Makefile b/sbin/mksnap_ffs/Makefile index 40b56b445da..9247cb278ed 100644 --- a/sbin/mksnap_ffs/Makefile +++ b/sbin/mksnap_ffs/Makefile @@ -6,6 +6,7 @@ PROG= mksnap_ffs SRCS= mksnap_ffs.c getmntopts.c MAN= mksnap_ffs.8 +WARNS?= 2 CFLAGS+=-I${.CURDIR}/../mount .if defined(NOSUID) diff --git a/sbin/mount/Makefile b/sbin/mount/Makefile index 4186f00f6fd..8f6299af3ff 100644 --- a/sbin/mount/Makefile +++ b/sbin/mount/Makefile @@ -3,7 +3,6 @@ PROG= mount SRCS= mount.c mount_fs.c getmntopts.c vfslist.c -WARNS?= 6 MAN= mount.8 # We do NOT install the getmntopts.3 man page. diff --git a/sbin/mount_autofs/Makefile b/sbin/mount_autofs/Makefile index e7d040d4d08..b05d9613df7 100644 --- a/sbin/mount_autofs/Makefile +++ b/sbin/mount_autofs/Makefile @@ -4,5 +4,6 @@ PROG=mount_autofs MAN=mount_autofs.8 BINDIR?=/sbin +WARNS?= 2 .include diff --git a/sbin/mount_cd9660/Makefile b/sbin/mount_cd9660/Makefile index 0602d9bbd29..b889174ffa0 100644 --- a/sbin/mount_cd9660/Makefile +++ b/sbin/mount_cd9660/Makefile @@ -9,7 +9,6 @@ LDADD= -lkiconv MOUNT= ${.CURDIR}/../mount CFLAGS+= -I${MOUNT} -WARNS?= 6 # Needs to be dynamically linked for optional dlopen() access to # userland libiconv diff --git a/sbin/mount_ext2fs/Makefile b/sbin/mount_ext2fs/Makefile index 3eefb92eb8c..08a0c3c7e5a 100644 --- a/sbin/mount_ext2fs/Makefile +++ b/sbin/mount_ext2fs/Makefile @@ -5,6 +5,7 @@ PROG= mount_ext2fs SRCS= mount_ext2fs.c getmntopts.c MAN= mount_ext2fs.8 +WARNS?= 2 MOUNT= ${.CURDIR}/../mount CFLAGS+= -I${MOUNT} diff --git a/sbin/mount_msdosfs/Makefile b/sbin/mount_msdosfs/Makefile index 8752f0d848a..c3e416af21f 100644 --- a/sbin/mount_msdosfs/Makefile +++ b/sbin/mount_msdosfs/Makefile @@ -10,7 +10,6 @@ LDADD= -lkiconv MOUNT= ${.CURDIR}/../mount CFLAGS+= -I${MOUNT} -WARNS?= 6 # Needs to be dynamically linked for optional dlopen() access to # userland libiconv diff --git a/sbin/mount_nullfs/Makefile b/sbin/mount_nullfs/Makefile index 5e92c5b5c26..0b2ecc5834c 100644 --- a/sbin/mount_nullfs/Makefile +++ b/sbin/mount_nullfs/Makefile @@ -7,7 +7,6 @@ MAN= mount_nullfs.8 MOUNT= ${.CURDIR}/../mount CFLAGS+=-I${MOUNT} -WARNS?= 6 .PATH: ${MOUNT} diff --git a/sbin/mount_reiserfs/Makefile b/sbin/mount_reiserfs/Makefile index bd11a4b8ac6..686629fe184 100644 --- a/sbin/mount_reiserfs/Makefile +++ b/sbin/mount_reiserfs/Makefile @@ -7,7 +7,6 @@ MAN = mount_reiserfs.8 # mount_reiserfs needs mntopts.h and getmntopts.c from src/sbin/mount/ MOUNT ?= ${.CURDIR}/../mount CFLAGS += -I${MOUNT} -WARNS ?= 6 .PATH: ${MOUNT} diff --git a/sbin/mount_unionfs/Makefile b/sbin/mount_unionfs/Makefile index 35158ab9237..276fc7467d1 100644 --- a/sbin/mount_unionfs/Makefile +++ b/sbin/mount_unionfs/Makefile @@ -7,7 +7,6 @@ MAN= mount_unionfs.8 MOUNT= ${.CURDIR}/../mount CFLAGS+=-I${MOUNT} -WARNS?= 6 .PATH: ${MOUNT} diff --git a/sbin/newfs_msdos/Makefile b/sbin/newfs_msdos/Makefile index 5ee8277d42a..558f673edea 100644 --- a/sbin/newfs_msdos/Makefile +++ b/sbin/newfs_msdos/Makefile @@ -5,8 +5,6 @@ MAN= newfs_msdos.8 .if ${MACHINE_ARCH} == "arm" WARNS?= 3 -.else -WARNS?= 6 .endif .include diff --git a/sbin/nfsiod/Makefile b/sbin/nfsiod/Makefile index 22717c576f4..47cd290ec78 100644 --- a/sbin/nfsiod/Makefile +++ b/sbin/nfsiod/Makefile @@ -2,7 +2,6 @@ # $FreeBSD$ PROG= nfsiod -WARNS?= 6 MAN= nfsiod.8 .include diff --git a/sbin/pfctl/Makefile b/sbin/pfctl/Makefile index ee5705197e5..2475baf9481 100644 --- a/sbin/pfctl/Makefile +++ b/sbin/pfctl/Makefile @@ -12,6 +12,7 @@ SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c pfctl_qstats.c SRCS+= pfctl_optimize.c SRCS+= pf_ruleset.c +WARNS?= 2 CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized CFLAGS+= -Wstrict-prototypes -I${.CURDIR}/../../contrib/pf/pfctl diff --git a/sbin/rcorder/Makefile b/sbin/rcorder/Makefile index 2ca64cc90b5..b71aa4b83d3 100644 --- a/sbin/rcorder/Makefile +++ b/sbin/rcorder/Makefile @@ -8,7 +8,6 @@ MAN= rcorder.8 LDADD= -lutil DPADD= ${LIBUTIL} -WARNS?= 6 # XXX hack for make's hash.[ch] CFLAGS+= -DORDER -I. diff --git a/sbin/reboot/Makefile b/sbin/reboot/Makefile index 42f086887eb..fe02f26add0 100644 --- a/sbin/reboot/Makefile +++ b/sbin/reboot/Makefile @@ -2,7 +2,6 @@ # $FreeBSD$ PROG= reboot -WARNS?= 6 DPADD= ${LIBUTIL} LDADD= -lutil MAN= reboot.8 nextboot.8 diff --git a/sbin/recoverdisk/Makefile b/sbin/recoverdisk/Makefile index 6733a4f8fa2..136e570eb5a 100644 --- a/sbin/recoverdisk/Makefile +++ b/sbin/recoverdisk/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ PROG= recoverdisk -WARNS?= 6 .include diff --git a/sbin/routed/Makefile b/sbin/routed/Makefile index 99b07f59567..8c7559ffeb8 100644 --- a/sbin/routed/Makefile +++ b/sbin/routed/Makefile @@ -7,9 +7,7 @@ MAN= routed.8 SUBDIR= rtquery LDADD= -lmd DPADD= ${LIBMD} -.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" -WARNS?= 6 -.else +.if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH} != "amd64" WARNS?= 0 .endif diff --git a/sbin/savecore/Makefile b/sbin/savecore/Makefile index 525f281b598..f2574582602 100644 --- a/sbin/savecore/Makefile +++ b/sbin/savecore/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ PROG= savecore -WARNS?= 6 DPADD= ${LIBZ} LDADD= -lz MAN= savecore.8 diff --git a/sbin/sconfig/Makefile b/sbin/sconfig/Makefile index 5923692aad4..9698c04ddba 100644 --- a/sbin/sconfig/Makefile +++ b/sbin/sconfig/Makefile @@ -4,5 +4,6 @@ PROG= sconfig MAN= sconfig.8 MANSUBDIR= /i386 +WARNS?= 2 .include diff --git a/sbin/shutdown/Makefile b/sbin/shutdown/Makefile index b7f232d090b..09b0b3ebf01 100644 --- a/sbin/shutdown/Makefile +++ b/sbin/shutdown/Makefile @@ -4,8 +4,6 @@ PROG= shutdown MAN= shutdown.8 -WARNS?= 6 - BINOWN= root BINGRP= operator BINMODE=4550 diff --git a/sbin/spppcontrol/Makefile b/sbin/spppcontrol/Makefile index b394c39a4e8..3287fcf2412 100644 --- a/sbin/spppcontrol/Makefile +++ b/sbin/spppcontrol/Makefile @@ -2,5 +2,6 @@ PROG= spppcontrol MAN= spppcontrol.8 +WARNS?= 2 .include diff --git a/sbin/swapon/Makefile b/sbin/swapon/Makefile index 6f8e8df2e5a..09f54b7c581 100644 --- a/sbin/swapon/Makefile +++ b/sbin/swapon/Makefile @@ -8,6 +8,7 @@ LINKS+= ${BINDIR}/swapon ${BINDIR}/swapctl MLINKS= swapon.8 swapoff.8 MLINKS+=swapon.8 swapctl.8 +WARNS?= 2 DPADD= ${LIBUTIL} LDADD= -lutil diff --git a/sbin/tunefs/Makefile b/sbin/tunefs/Makefile index d501d104b4b..dc9fac6f561 100644 --- a/sbin/tunefs/Makefile +++ b/sbin/tunefs/Makefile @@ -5,5 +5,6 @@ PROG= tunefs DPADD= ${LIBUFS} LDADD= -lufs MAN= tunefs.8 +WARNS?= 2 .include From d093681c604c2903bfa854492334c1fde935dca7 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 19 Oct 2009 18:46:22 +0000 Subject: [PATCH 220/646] Implement the missing support for updating the mesh conf number of neighbors via ieee80211_beacon_notify(). MFC after: 3 days --- sys/net80211/ieee80211_mesh.c | 14 ++++++++++++++ sys/net80211/ieee80211_mesh.h | 2 ++ sys/net80211/ieee80211_output.c | 12 ++++++++++++ sys/net80211/ieee80211_proto.h | 4 +++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index 52a9e244f55..432ce231631 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -739,10 +739,12 @@ mesh_linkchange(struct ieee80211_node *ni, enum ieee80211_mesh_mlstate state) ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow")); ms->ms_neighbors++; + ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); } else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED && state != IEEE80211_NODE_MESH_ESTABLISHED) { KASSERT(ms->ms_neighbors > 0, ("neighbor count 0")); ms->ms_neighbors--; + ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); } ni->ni_mlstate = state; switch (state) { @@ -2553,6 +2555,18 @@ ieee80211_mesh_init_neighbor(struct ieee80211_node *ni, ieee80211_parse_meshid(ni, sp->meshid); } +void +ieee80211_mesh_update_beacon(struct ieee80211vap *vap, + struct ieee80211_beacon_offsets *bo) +{ + KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); + + if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) { + (void)ieee80211_add_meshconf(bo->bo_meshconf, vap); + clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF); + } +} + static int mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) { diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h index 72108ddcdab..de9b5c2a027 100644 --- a/sys/net80211/ieee80211_mesh.h +++ b/sys/net80211/ieee80211_mesh.h @@ -470,6 +470,8 @@ struct ieee80211_scanparams; void ieee80211_mesh_init_neighbor(struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_scanparams *); +void ieee80211_mesh_update_beacon(struct ieee80211vap *, + struct ieee80211_beacon_offsets *); /* * Return non-zero if proxy operation is enabled. diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index f1a21bce8f2..d2da01f6e96 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -2658,6 +2658,7 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm, #ifdef IEEE80211_SUPPORT_MESH if (vap->iv_opmode == IEEE80211_M_MBSS) { frm = ieee80211_add_meshid(frm, vap); + bo->bo_meshconf = frm; frm = ieee80211_add_meshconf(frm, vap); } #endif @@ -2874,6 +2875,11 @@ ieee80211_beacon_update(struct ieee80211_node *ni, ieee80211_tdma_update_beacon(vap, bo); } #endif +#ifdef IEEE80211_SUPPORT_MESH + if (vap->iv_opmode == IEEE80211_M_MBSS) + ieee80211_mesh_update_beacon(vap, bo); +#endif + if (vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_MBSS) { /* NB: no IBSS support*/ struct ieee80211_tim_ie *tie = @@ -2927,6 +2933,9 @@ ieee80211_beacon_update(struct ieee80211_node *ni, #endif #ifdef IEEE80211_TDMA_SUPPORT bo->bo_tdma += adjust; +#endif +#ifdef IEEE80211_MESH_SUPPORT + bo->bo_meshconf += adjust; #endif bo->bo_appie += adjust; bo->bo_wme += adjust; @@ -2978,6 +2987,9 @@ ieee80211_beacon_update(struct ieee80211_node *ni, #endif #ifdef IEEE80211_TDMA_SUPPORT bo->bo_tdma += sizeof(*csa); +#endif +#ifdef IEEE80211_MESH_SUPPORT + bo->bo_meshconf += sizeof(*csa); #endif bo->bo_appie += sizeof(*csa); bo->bo_csa_trailer_len += sizeof(*csa); diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 9bfbc61715f..e036dacea93 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -317,7 +317,8 @@ struct ieee80211_beacon_offsets { uint16_t bo_appie_len; /* AppIE length in bytes */ uint16_t bo_csa_trailer_len;; uint8_t *bo_csa; /* start of CSA element */ - uint8_t *bo_spare[4]; + uint8_t *bo_meshconf; /* start of MESHCONF element */ + uint8_t *bo_spare[3]; }; struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *, struct ieee80211_beacon_offsets *); @@ -345,6 +346,7 @@ enum { IEEE80211_BEACON_CSA = 7, /* Channel Switch Announcement */ IEEE80211_BEACON_TDMA = 9, /* TDMA Info */ IEEE80211_BEACON_ATH = 10, /* ATH parameters */ + IEEE80211_BEACON_MESHCONF = 11, /* Mesh Configuration */ }; int ieee80211_beacon_update(struct ieee80211_node *, struct ieee80211_beacon_offsets *, struct mbuf *, int mcast); From 72c042dfb56fec9f2f29177367688e0a77c6e210 Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Mon, 19 Oct 2009 20:51:27 +0000 Subject: [PATCH 221/646] Move mxge(4)'s NIC watchdog reset handler from a callout to a taskqueue --- sys/dev/mxge/if_mxge.c | 86 ++++++++++++++++++++++++++++---------- sys/dev/mxge/if_mxge_var.h | 2 + 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index 8a71c330609..ae78f84bc04 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include /* count xmits ourselves, rather than via drbr */ #define NO_SLOW_STATS @@ -3739,12 +3740,11 @@ mxge_read_reboot(mxge_softc_t *sc) return (pci_read_config(dev, vs + 0x14, 4)); } -static int -mxge_watchdog_reset(mxge_softc_t *sc, int slice) +static void +mxge_watchdog_reset(mxge_softc_t *sc) { struct pci_devinfo *dinfo; struct mxge_slice_state *ss; - mxge_tx_ring_t *tx; int err, running, s, num_tx_slices = 1; uint32_t reboot; uint16_t cmd; @@ -3771,7 +3771,6 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice) cmd = pci_read_config(sc->dev, PCIR_COMMAND, 2); if (cmd == 0xffff) { device_printf(sc->dev, "NIC disappeared!\n"); - return (err); } } if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) { @@ -3830,24 +3829,43 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice) } sc->watchdog_resets++; } else { - tx = &sc->ss[slice].tx; device_printf(sc->dev, - "NIC did not reboot, slice %d ring state:\n", - slice); - device_printf(sc->dev, - "tx.req=%d tx.done=%d, tx.queue_active=%d\n", - tx->req, tx->done, tx->queue_active); - device_printf(sc->dev, "tx.activate=%d tx.deactivate=%d\n", - tx->activate, tx->deactivate); - device_printf(sc->dev, "pkt_done=%d fw=%d\n", - tx->pkt_done, - be32toh(sc->ss->fw_stats->send_done_count)); - device_printf(sc->dev, "not resetting\n"); + "NIC did not reboot, not resetting\n"); + err = 0; } - if (err) + if (err) { device_printf(sc->dev, "watchdog reset failed\n"); + } else { + if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) + callout_reset(&sc->co_hdl, mxge_ticks, + mxge_tick, sc); + } +} - return (err); +static void +mxge_watchdog_task(void *arg, int pending) +{ + mxge_softc_t *sc = arg; + + + mtx_lock(&sc->driver_mtx); + mxge_watchdog_reset(sc); + mtx_unlock(&sc->driver_mtx); +} + +static void +mxge_warn_stuck(mxge_softc_t *sc, mxge_tx_ring_t *tx, int slice) +{ + tx = &sc->ss[slice].tx; + device_printf(sc->dev, "slice %d struck? ring state:\n", slice); + device_printf(sc->dev, + "tx.req=%d tx.done=%d, tx.queue_active=%d\n", + tx->req, tx->done, tx->queue_active); + device_printf(sc->dev, "tx.activate=%d tx.deactivate=%d\n", + tx->activate, tx->deactivate); + device_printf(sc->dev, "pkt_done=%d fw=%d\n", + tx->pkt_done, + be32toh(sc->ss->fw_stats->send_done_count)); } static int @@ -3871,8 +3889,11 @@ mxge_watchdog(mxge_softc_t *sc) tx->watchdog_req != tx->watchdog_done && tx->done == tx->watchdog_done) { /* check for pause blocking before resetting */ - if (tx->watchdog_rx_pause == rx_pause) - err = mxge_watchdog_reset(sc, i); + if (tx->watchdog_rx_pause == rx_pause) { + mxge_warn_stuck(sc, tx, i); + taskqueue_enqueue(sc->tq, &sc->watchdog_task); + return (ENXIO); + } else device_printf(sc->dev, "Flow control blocking " "xmits, check link partner\n"); @@ -4558,6 +4579,17 @@ mxge_attach(device_t dev) sc->dev = dev; mxge_fetch_tunables(sc); + TASK_INIT(&sc->watchdog_task, 1, mxge_watchdog_task, sc); + sc->tq = taskqueue_create_fast("mxge_taskq", M_WAITOK, + taskqueue_thread_enqueue, + &sc->tq); + if (sc->tq == NULL) { + err = ENOMEM; + goto abort_with_nothing; + } + taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq", + device_get_nameunit(sc->dev)); + err = bus_dma_tag_create(NULL, /* parent */ 1, /* alignment */ 0, /* boundary */ @@ -4574,7 +4606,7 @@ mxge_attach(device_t dev) if (err != 0) { device_printf(sc->dev, "Err %d allocating parent dmat\n", err); - goto abort_with_nothing; + goto abort_with_tq; } ifp = sc->ifp = if_alloc(IFT_ETHER); @@ -4736,7 +4768,12 @@ abort_with_lock: if_free(ifp); abort_with_parent_dmat: bus_dma_tag_destroy(sc->parent_dmat); - +abort_with_tq: + if (sc->tq != NULL) { + taskqueue_drain(sc->tq, &sc->watchdog_task); + taskqueue_free(sc->tq); + sc->tq = NULL; + } abort_with_nothing: return err; } @@ -4757,6 +4794,11 @@ mxge_detach(device_t dev) mxge_close(sc, 0); mtx_unlock(&sc->driver_mtx); ether_ifdetach(sc->ifp); + if (sc->tq != NULL) { + taskqueue_drain(sc->tq, &sc->watchdog_task); + taskqueue_free(sc->tq); + sc->tq = NULL; + } callout_drain(&sc->co_hdl); ifmedia_removeall(&sc->media); mxge_dummy_rdma(sc, 0); diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h index 698265b4abe..5c1627f71e5 100644 --- a/sys/dev/mxge/if_mxge_var.h +++ b/sys/dev/mxge/if_mxge_var.h @@ -270,6 +270,8 @@ struct mxge_softc { int dying; mxge_dma_t dmabench_dma; struct callout co_hdl; + struct taskqueue *tq; + struct task watchdog_task; struct sysctl_oid *slice_sysctl_tree; struct sysctl_ctx_list slice_sysctl_ctx; char *mac_addr_string; From 3219f535d98ad7c1a1b731f022c7b9ec4402094c Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 19 Oct 2009 20:58:10 +0000 Subject: [PATCH 222/646] Rewrite x86bios and update its dependent drivers. - Do not map entire real mode memory (1MB). Instead, we map IVT/BDA and ROM area separately. Most notably, ROM area is mapped as device memory (uncacheable) as it should be. User memory is dynamically allocated and free'ed with contigmalloc(9) and contigfree(9). Remove now redundant and potentially dangerous x86bios_alloc.c. If this emulator ever grows to support non-PC hardware, we may implement it with rman(9) later. - Move all host-specific initializations from x86emu_util.c to x86bios.c and remove now unnecessary x86emu_util.c. Currently, non-PC hardware is not supported. We may use bus_space(9) later when the KPI is fixed. - Replace all bzero() calls for emulated registers with more obviously named x86bios_init_regs(). This function also initializes DS and SS properly. - Add x86bios_get_intr(). This function checks if the interrupt vector is available for the platform. It is not necessary for PC-compatible hardware but it may be needed later. ;-) - Do not try turning off monitor if DPMS does not support the state. - Allocate stable memory for VESA OEM strings instead of just holding pointers to them. They may or may not be accessible always. Fix a memory leak of video mode table while I am here. - Add (experimental) BIOS POST call for vesa(4). This function calls VGA BIOS POST code from the current VGA option ROM. Some video controllers cannot save and restore the state properly even if it is claimed to be supported. Usually the symptom is blank display after resuming from suspend state. If the video mode does not match the previous mode after restoring, we try BIOS POST and force the known good initial state. Some magic was taken from NetBSD (and it was taken from vbetool, I believe.) - Add a loader tunable for vgapci(4) to give a hint to dpms(4) and vesa(4) to identify who owns the VESA BIOS. This is very useful for multi-display adapter setup. By default, the POST video controller is automatically probed and the tunable "hw.pci.default_vgapci_unit" is set to corresponding vgapci unit number. You may override it from loader but it is very unlikely to be necessary. Unfortunately only AGP/PCI/PCI-E controllers can be matched because ISA controller does not have necessary device IDs. - Fix a long standing bug in state save/restore function. The state buffer pointer should be ES:BX, not ES:DI according to VBE 3.0. If it ever worked, that's because BX was always zero. :-) - Clean up register initializations more clearer per VBE 3.0. - Fix a lot of style issues with vesa(4). --- sys/compat/x86bios/x86bios.c | 381 ++++++++++++-- sys/compat/x86bios/x86bios.h | 113 ++-- sys/compat/x86bios/x86bios_alloc.c | 81 --- sys/conf/files.amd64 | 2 - sys/conf/files.i386 | 2 - sys/contrib/x86emu/x86emu_util.c | 211 -------- sys/dev/atkbdc/atkbd.c | 15 +- sys/dev/dpms/dpms.c | 28 +- sys/dev/fb/vesa.c | 792 ++++++++++++++++++----------- sys/dev/pci/vga_pci.c | 21 + sys/modules/dpms/Makefile | 2 +- sys/modules/vesa/Makefile | 1 + sys/modules/x86bios/Makefile | 3 +- 13 files changed, 944 insertions(+), 708 deletions(-) delete mode 100644 sys/compat/x86bios/x86bios_alloc.c delete mode 100644 sys/contrib/x86emu/x86emu_util.c diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c index 1d1c48af01e..74c32a7ead1 100644 --- a/sys/compat/x86bios/x86bios.c +++ b/sys/compat/x86bios/x86bios.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2009 Alex Keda + * Copyright (c) 2009 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,7 +23,6 @@ * 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. - * */ #include @@ -31,29 +31,153 @@ __FBSDID("$FreeBSD$"); #include "opt_x86bios.h" #include +#include #include #include +#include #include #include - -#include -#include - -#include +#include #include #include #include -u_char *pbiosMem = NULL; -static u_char *pbiosStack = NULL; +#include +#include -int busySegMap[5]; +#include + +#include +#include + +#define X86BIOS_PAGE_SIZE 0x00001000 /* 4K */ + +#define X86BIOS_IVT_SIZE 0x00000500 /* 1K + 256 (BDA) */ +#define X86BIOS_SEG_SIZE 0x00010000 /* 64K */ +#define X86BIOS_MEM_SIZE 0x00100000 /* 1M */ + +#define X86BIOS_IVT_BASE 0x00000000 +#define X86BIOS_RAM_BASE 0x00001000 +#define X86BIOS_ROM_BASE 0x000a0000 /* XXX EBDA? */ + +#define X86BIOS_ROM_SIZE (X86BIOS_MEM_SIZE - X86BIOS_ROM_BASE) + +#define X86BIOS_PAGES (X86BIOS_MEM_SIZE / X86BIOS_PAGE_SIZE) + +#define X86BIOS_R_DS _pad1 +#define X86BIOS_R_SS _pad2 static struct x86emu x86bios_emu; static struct mtx x86bios_lock; +static void *x86bios_ivt; +static void *x86bios_rom; +static void *x86bios_seg; + +static vm_offset_t *x86bios_map; + +static vm_paddr_t x86bios_seg_phys; + +static void * +x86bios_get_pages(uint32_t offset, size_t size) +{ + int i; + + if (offset + size > X86BIOS_MEM_SIZE) + return (NULL); + + i = offset / X86BIOS_PAGE_SIZE; + if (x86bios_map[i] != 0) + return ((void *)(x86bios_map[i] + offset - + i * X86BIOS_PAGE_SIZE)); + + return (NULL); +} + +static void +x86bios_set_pages(vm_offset_t va, vm_paddr_t pa, size_t size) +{ + int i, j; + + for (i = pa / X86BIOS_PAGE_SIZE, j = 0; + j < howmany(size, X86BIOS_PAGE_SIZE); i++, j++) + x86bios_map[i] = va + j * X86BIOS_PAGE_SIZE; +} + +static uint8_t +x86bios_emu_rdb(struct x86emu *emu, uint32_t addr) +{ + uint8_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + return (*va); +} + +static uint16_t +x86bios_emu_rdw(struct x86emu *emu, uint32_t addr) +{ + uint16_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + return (le16toh(*va)); +} + +static uint32_t +x86bios_emu_rdl(struct x86emu *emu, uint32_t addr) +{ + uint32_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + return (le32toh(*va)); +} + +static void +x86bios_emu_wrb(struct x86emu *emu, uint32_t addr, uint8_t val) +{ + uint8_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + *va = val; +} + +static void +x86bios_emu_wrw(struct x86emu *emu, uint32_t addr, uint16_t val) +{ + uint16_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + *va = htole16(val); +} + +static void +x86bios_emu_wrl(struct x86emu *emu, uint32_t addr, uint32_t val) +{ + uint32_t *va; + + va = x86bios_get_pages(addr, sizeof(*va)); + if (va == NULL) + x86emu_halt_sys(emu); + + *va = htole32(val); +} + static uint8_t x86bios_emu_inb(struct x86emu *emu, uint16_t port) { @@ -62,6 +186,7 @@ x86bios_emu_inb(struct x86emu *emu, uint16_t port) return (0); if (port >= 0x80 && port < 0x88) /* POST status register */ return (0); + return (inb(port)); } @@ -71,6 +196,7 @@ x86bios_emu_inw(struct x86emu *emu, uint16_t port) if (port >= 0x80 && port < 0x88) /* POST status register */ return (0); + return (inw(port)); } @@ -80,6 +206,7 @@ x86bios_emu_inl(struct x86emu *emu, uint16_t port) if (port >= 0x80 && port < 0x88) /* POST status register */ return (0); + return (inl(port)); } @@ -91,6 +218,7 @@ x86bios_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val) return; if (port >= 0x80 && port < 0x88) /* POST status register */ return; + outb(port, val); } @@ -100,6 +228,7 @@ x86bios_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val) if (port >= 0x80 && port < 0x88) /* POST status register */ return; + outw(port, val); } @@ -109,9 +238,109 @@ x86bios_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val) if (port >= 0x80 && port < 0x88) /* POST status register */ return; + outl(port, val); } +static void +x86bios_emu_get_intr(struct x86emu *emu, int intno) +{ + uint16_t *sp; + uint32_t iv; + + emu->x86.R_SP -= 6; + + sp = (uint16_t *)((vm_offset_t)x86bios_seg + emu->x86.R_SP); + sp[0] = htole16(emu->x86.R_IP); + sp[1] = htole16(emu->x86.R_CS); + sp[2] = htole16(emu->x86.R_FLG); + + iv = x86bios_get_intr(intno); + emu->x86.R_IP = iv & 0x000f; + emu->x86.R_CS = (iv >> 12) & 0xffff; + emu->x86.R_FLG &= ~(F_IF | F_TF); +} + +void * +x86bios_alloc(uint32_t *offset, size_t size) +{ + void *vaddr; + + if (offset == NULL || size == 0) + return (NULL); + + vaddr = contigmalloc(size, M_DEVBUF, M_NOWAIT, X86BIOS_RAM_BASE, + X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0); + if (vaddr != NULL) { + *offset = vtophys(vaddr); + x86bios_set_pages((vm_offset_t)vaddr, *offset, size); + } + + return (vaddr); +} + +void +x86bios_free(void *addr, size_t size) +{ + vm_paddr_t paddr; + + if (addr == NULL || size == 0) + return; + + paddr = vtophys(addr); + if (paddr < X86BIOS_RAM_BASE || paddr >= X86BIOS_ROM_BASE || + paddr % X86BIOS_PAGE_SIZE != 0) + return; + + bzero(x86bios_map + paddr / X86BIOS_PAGE_SIZE, + sizeof(*x86bios_map) * howmany(size, X86BIOS_PAGE_SIZE)); + contigfree(addr, size, M_DEVBUF); +} + +void +x86bios_init_regs(struct x86regs *regs) +{ + + bzero(regs, sizeof(*regs)); + regs->X86BIOS_R_DS = regs->X86BIOS_R_SS = x86bios_seg_phys >> 4; +} + +void +x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off) +{ + + if (x86bios_map == NULL) + return; + + if (bootverbose) + printf("Calling 0x%05x (ax=0x%04x bx=0x%04x " + "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", + (seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX, + regs->R_DX, regs->R_ES, regs->R_DI); + + mtx_lock_spin(&x86bios_lock); + memcpy(&x86bios_emu.x86, regs, sizeof(*regs)); + x86emu_exec_call(&x86bios_emu, seg, off); + memcpy(regs, &x86bios_emu.x86, sizeof(*regs)); + mtx_unlock_spin(&x86bios_lock); + + if (bootverbose) + printf("Exiting 0x%05x (ax=0x%04x bx=0x%04x " + "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", + (seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX, + regs->R_DX, regs->R_ES, regs->R_DI); +} + +uint32_t +x86bios_get_intr(int intno) +{ + uint32_t *iv; + + iv = (uint32_t *)((vm_offset_t)x86bios_ivt + intno * 4); + + return (le32toh(*iv)); +} + void x86bios_intr(struct x86regs *regs, int intno) { @@ -119,6 +348,9 @@ x86bios_intr(struct x86regs *regs, int intno) if (intno < 0 || intno > 255) return; + if (x86bios_map == NULL) + return; + if (bootverbose) printf("Calling int 0x%x (ax=0x%04x bx=0x%04x " "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", @@ -126,11 +358,9 @@ x86bios_intr(struct x86regs *regs, int intno) regs->R_DX, regs->R_ES, regs->R_DI); mtx_lock_spin(&x86bios_lock); - memcpy(&x86bios_emu.x86, regs, sizeof(*regs)); x86emu_exec_intr(&x86bios_emu, intno); memcpy(regs, &x86bios_emu.x86, sizeof(*regs)); - mtx_unlock_spin(&x86bios_lock); if (bootverbose) @@ -141,24 +371,112 @@ x86bios_intr(struct x86regs *regs, int intno) } void * -x86bios_offset(uint32_t offs) +x86bios_offset(uint32_t offset) { - return (pbiosMem + offs); + return (x86bios_get_pages(offset, 1)); +} + +void * +x86bios_get_orm(uint32_t offset) +{ + uint8_t *p; + + /* Does the shadow ROM contain BIOS POST code for x86? */ + p = x86bios_offset(offset); + if (p == NULL || p[0] != 0x55 || p[1] != 0xaa || p[3] != 0xe9) + return (NULL); + + return (p); +} + +int +x86bios_match_device(uint32_t offset, device_t dev) +{ + uint8_t *p; + uint16_t device, vendor; + uint8_t class, progif, subclass; + + /* Does the shadow ROM contain BIOS POST code for x86? */ + p = x86bios_get_orm(offset); + if (p == NULL) + return (0); + + /* Does it contain PCI data structure? */ + p += le16toh(*(uint16_t *)(p + 0x18)); + if (bcmp(p, "PCIR", 4) != 0 || + le16toh(*(uint16_t *)(p + 0x0a)) < 0x18 || *(p + 0x14) != 0) + return (0); + + /* Does it match the vendor, device, and classcode? */ + vendor = le16toh(*(uint16_t *)(p + 0x04)); + device = le16toh(*(uint16_t *)(p + 0x06)); + progif = *(p + 0x0d); + subclass = *(p + 0x0e); + class = *(p + 0x0f); + if (vendor != pci_get_vendor(dev) || device != pci_get_device(dev) || + class != pci_get_class(dev) || subclass != pci_get_subclass(dev) || + progif != pci_get_progif(dev)) + return (0); + + return (1); +} + +static __inline int +x86bios_map_mem(void) +{ + + x86bios_ivt = pmap_mapdev(X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE); + if (x86bios_ivt == NULL) + return (1); + x86bios_rom = pmap_mapdev(X86BIOS_ROM_BASE, X86BIOS_ROM_SIZE); + if (x86bios_rom == NULL) { + pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE); + return (1); + } + x86bios_seg = contigmalloc(X86BIOS_SEG_SIZE, M_DEVBUF, M_WAITOK, + X86BIOS_RAM_BASE, X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0); + x86bios_seg_phys = vtophys(x86bios_seg); + + return (0); +} + +static __inline void +x86bios_unmap_mem(void) +{ + + pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE); + pmap_unmapdev((vm_offset_t)x86bios_rom, X86BIOS_ROM_SIZE); + contigfree(x86bios_seg, X86BIOS_SEG_SIZE, M_DEVBUF); } static void x86bios_init(void *arg __unused) { - int offs; + int i; mtx_init(&x86bios_lock, "x86bios lock", NULL, MTX_SPIN); - /* Can pbiosMem be NULL here? */ - pbiosMem = pmap_mapbios(0x0, MAPPED_MEMORY_SIZE); + if (x86bios_map_mem() != 0) + return; - memset(&x86bios_emu, 0, sizeof(x86bios_emu)); - x86emu_init_default(&x86bios_emu); + x86bios_map = malloc(sizeof(*x86bios_map) * X86BIOS_PAGES, M_DEVBUF, + M_WAITOK | M_ZERO); + x86bios_set_pages((vm_offset_t)x86bios_ivt, X86BIOS_IVT_BASE, + X86BIOS_IVT_SIZE); + x86bios_set_pages((vm_offset_t)x86bios_rom, X86BIOS_ROM_BASE, + X86BIOS_ROM_SIZE); + x86bios_set_pages((vm_offset_t)x86bios_seg, x86bios_seg_phys, + X86BIOS_SEG_SIZE); + + bzero(&x86bios_emu, sizeof(x86bios_emu)); + + x86bios_emu.emu_rdb = x86bios_emu_rdb; + x86bios_emu.emu_rdw = x86bios_emu_rdw; + x86bios_emu.emu_rdl = x86bios_emu_rdl; + x86bios_emu.emu_wrb = x86bios_emu_wrb; + x86bios_emu.emu_wrw = x86bios_emu_wrw; + x86bios_emu.emu_wrl = x86bios_emu_wrl; x86bios_emu.emu_inb = x86bios_emu_inb; x86bios_emu.emu_inw = x86bios_emu_inw; @@ -167,23 +485,24 @@ x86bios_init(void *arg __unused) x86bios_emu.emu_outw = x86bios_emu_outw; x86bios_emu.emu_outl = x86bios_emu_outl; - x86bios_emu.mem_base = (char *)pbiosMem; - x86bios_emu.mem_size = MAPPED_MEMORY_SIZE; - - memset(busySegMap, 0, sizeof(busySegMap)); - - pbiosStack = x86bios_alloc(1, &offs); + for (i = 0; i < 256; i++) + x86bios_emu._x86emu_intrTab[i] = x86bios_emu_get_intr; } static void x86bios_uninit(void *arg __unused) { + vm_offset_t *map = x86bios_map; - x86bios_free(pbiosStack, 1); + mtx_lock_spin(&x86bios_lock); + if (x86bios_map != NULL) { + free(x86bios_map, M_DEVBUF); + x86bios_map = NULL; + } + mtx_unlock_spin(&x86bios_lock); - if (pbiosMem) - pmap_unmapdev((vm_offset_t)pbiosMem, - MAPPED_MEMORY_SIZE); + if (map != NULL) + x86bios_unmap_mem(); mtx_destroy(&x86bios_lock); } @@ -191,7 +510,6 @@ x86bios_uninit(void *arg __unused) static int x86bios_modevent(module_t mod __unused, int type, void *data __unused) { - int err = 0; switch (type) { case MOD_LOAD: @@ -201,11 +519,10 @@ x86bios_modevent(module_t mod __unused, int type, void *data __unused) x86bios_uninit(NULL); break; default: - err = ENOTSUP; - break; + return (ENOTSUP); } - return (err); + return (0); } static moduledata_t x86bios_mod = { diff --git a/sys/compat/x86bios/x86bios.h b/sys/compat/x86bios/x86bios.h index 8d46d5be980..4ed15e07527 100644 --- a/sys/compat/x86bios/x86bios.h +++ b/sys/compat/x86bios/x86bios.h @@ -23,49 +23,51 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * $FreeBSD$ */ /* * x86 registers were borrowed from x86emu.h x86emu_regs.h * for compatability. - * - * $FreeBSD$ */ #ifndef _X86BIOS_H_ -#define _X86BIOS_H_ +#define _X86BIOS_H_ -#include #include #include +#include #ifdef __BIG_ENDIAN__ struct x86_register32 { - uint32_t e_reg; + uint32_t e_reg; }; struct x86_register16 { - uint16_t filler0; - uint16_t x_reg; + uint16_t filler0; + uint16_t x_reg; }; struct x86_register8 { - uint8_t filler0, filler1; - uint8_t h_reg, l_reg; + uint8_t filler0; + uint8_t filler1; + uint8_t h_reg; + uint8_t l_reg; }; #else /* !__BIG_ENDIAN__ */ struct x86_register32 { - uint32_t e_reg; + uint32_t e_reg; }; struct x86_register16 { - uint16_t x_reg; + uint16_t x_reg; }; struct x86_register8 { - uint8_t l_reg, h_reg; + uint8_t l_reg; + uint8_t h_reg; }; #endif /* __BIG_ENDIAN__ */ @@ -77,19 +79,19 @@ union x86_register { }; struct x86regs { - uint16_t padding; /* CS is unused. */ - uint16_t register_ds; + uint16_t _pad0; /* CS */ + uint16_t _pad1; /* DS */ uint16_t register_es; uint16_t register_fs; uint16_t register_gs; - uint16_t register_ss; + uint16_t _pad2; /* SS */ uint32_t register_flags; union x86_register register_a; union x86_register register_b; union x86_register register_c; union x86_register register_d; - union x86_register register_sp; + union x86_register _pad3; /* SP */ union x86_register register_bp; union x86_register register_si; union x86_register register_di; @@ -98,60 +100,57 @@ struct x86regs { typedef struct x86regs x86regs_t; /* 8 bit registers */ -#define R_AH register_a.I8_reg.h_reg -#define R_AL register_a.I8_reg.l_reg -#define R_BH register_b.I8_reg.h_reg -#define R_BL register_b.I8_reg.l_reg -#define R_CH register_c.I8_reg.h_reg -#define R_CL register_c.I8_reg.l_reg -#define R_DH register_d.I8_reg.h_reg -#define R_DL register_d.I8_reg.l_reg +#define R_AH register_a.I8_reg.h_reg +#define R_AL register_a.I8_reg.l_reg +#define R_BH register_b.I8_reg.h_reg +#define R_BL register_b.I8_reg.l_reg +#define R_CH register_c.I8_reg.h_reg +#define R_CL register_c.I8_reg.l_reg +#define R_DH register_d.I8_reg.h_reg +#define R_DL register_d.I8_reg.l_reg /* 16 bit registers */ -#define R_AX register_a.I16_reg.x_reg -#define R_BX register_b.I16_reg.x_reg -#define R_CX register_c.I16_reg.x_reg -#define R_DX register_d.I16_reg.x_reg +#define R_AX register_a.I16_reg.x_reg +#define R_BX register_b.I16_reg.x_reg +#define R_CX register_c.I16_reg.x_reg +#define R_DX register_d.I16_reg.x_reg /* 32 bit extended registers */ -#define R_EAX register_a.I32_reg.e_reg -#define R_EBX register_b.I32_reg.e_reg -#define R_ECX register_c.I32_reg.e_reg -#define R_EDX register_d.I32_reg.e_reg +#define R_EAX register_a.I32_reg.e_reg +#define R_EBX register_b.I32_reg.e_reg +#define R_ECX register_c.I32_reg.e_reg +#define R_EDX register_d.I32_reg.e_reg /* special registers */ -#define R_SP register_sp.I16_reg.x_reg -#define R_BP register_bp.I16_reg.x_reg -#define R_SI register_si.I16_reg.x_reg -#define R_DI register_di.I16_reg.x_reg -#define R_FLG register_flags +#define R_BP register_bp.I16_reg.x_reg +#define R_SI register_si.I16_reg.x_reg +#define R_DI register_di.I16_reg.x_reg +#define R_FLG register_flags /* special registers */ -#define R_ESP register_sp.I32_reg.e_reg -#define R_EBP register_bp.I32_reg.e_reg -#define R_ESI register_si.I32_reg.e_reg -#define R_EDI register_di.I32_reg.e_reg -#define R_EFLG register_flags +#define R_EBP register_bp.I32_reg.e_reg +#define R_ESI register_si.I32_reg.e_reg +#define R_EDI register_di.I32_reg.e_reg +#define R_EFLG register_flags /* segment registers */ -#define R_DS register_ds -#define R_SS register_ss -#define R_ES register_es -#define R_FS register_fs -#define R_GS register_gs +#define R_ES register_es +#define R_FS register_fs +#define R_GS register_gs -#define SEG_ADDR(x) (((x) >> 4) & 0x00F000) -#define SEG_OFF(x) ((x) & 0x0FFFF) -#define FARP(x) ((le32toh(x) & 0xffff) + ((le32toh(x) >> 12) & 0xffff00)) - -#define MAPPED_MEMORY_SIZE (1024 * 1024) -#define PAGE_RESERV (4096 * 5) +#define X86BIOS_PHYSTOSEG(x) (((x) >> 4) & 0xffff) +#define X86BIOS_PHYSTOOFF(x) ((x) & 0x000f) __BEGIN_DECLS -void *x86bios_alloc(int count, int *segs); -void x86bios_free(void *pbuf, int count); -void x86bios_intr(struct x86regs *regs, int intno); -void *x86bios_offset(uint32_t offs); +void *x86bios_alloc(uint32_t *offset, size_t size); +void x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off); +void x86bios_free(void *addr, size_t size); +uint32_t x86bios_get_intr(int intno); +void *x86bios_get_orm(uint32_t offset); +void x86bios_init_regs(struct x86regs *regs); +void x86bios_intr(struct x86regs *regs, int intno); +int x86bios_match_device(uint32_t offset, device_t dev); +void *x86bios_offset(uint32_t offset); __END_DECLS #endif /* !_X86BIOS_H_ */ diff --git a/sys/compat/x86bios/x86bios_alloc.c b/sys/compat/x86bios/x86bios_alloc.c deleted file mode 100644 index 0a364e7e4e0..00000000000 --- a/sys/compat/x86bios/x86bios_alloc.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (C) 1999 Egbert Eich - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of the authors not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. The authors makes no - * representations about the suitability of this software for any purpose. - * It is provided "as is" without express or implied warranty. - * - * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * xserver/hw/xfree86/int10/generic.c - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include - -extern u_char *pbiosMem; -extern int busySegMap[5]; - -void * -x86bios_alloc(int count, int *segs) -{ - int i; - int j; - - /* find the free segblock of page */ - for (i = 0; i < (PAGE_RESERV - count); i++) - { - if (busySegMap[i] == 0) - { - /* find the capacity of segblock */ - for (j = i; j < (i + count); j++) - { - if (busySegMap[j] == 1) - break; - } - - if (j == (i + count)) - break; - i += count; - } - } - - if (i == (PAGE_RESERV - count)) - return NULL; - - /* make the segblock is used */ - for (j = i; j < (i + count); j++) - busySegMap[i] = 1; - - *segs = i * 4096; - - return (pbiosMem + *segs); -} - -void -x86bios_free(void *pbuf, int count) -{ - int i; - int busySeg; - - busySeg = ((u_char *)pbuf - pbiosMem) / 4096; - - for (i = busySeg; i < (busySeg + count); i++) - busySegMap[i] = 0; -} diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 6fda086b772..fbf4d2856cb 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -301,6 +301,4 @@ libkern/memset.c standard # x86 real mode BIOS emulator, required by atkbdc/dpms/vesa # compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa -compat/x86bios/x86bios_alloc.c optional x86bios | atkbd | dpms | vesa contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa -contrib/x86emu/x86emu_util.c optional x86bios | atkbd | dpms | vesa diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 34d190a29e6..839955bfd3f 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -385,6 +385,4 @@ i386/xbox/pic16l.s optional xbox # x86 real mode BIOS emulator, required by atkbdc/dpms/vesa # compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa -compat/x86bios/x86bios_alloc.c optional x86bios | atkbd | dpms | vesa contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa -contrib/x86emu/x86emu_util.c optional x86bios | atkbd | dpms | vesa diff --git a/sys/contrib/x86emu/x86emu_util.c b/sys/contrib/x86emu/x86emu_util.c deleted file mode 100644 index 4172f94f135..00000000000 --- a/sys/contrib/x86emu/x86emu_util.c +++ /dev/null @@ -1,211 +0,0 @@ -/* $OpenBSD: x86emu_util.c,v 1.5 2009/06/18 14:19:21 pirofti Exp $ */ -/* $NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $ */ - -/* - * - * Realmode X86 Emulator Library - * - * Copyright (C) 1996-1999 SciTech Software, Inc. - * Copyright (C) David Mosberger-Tang - * Copyright (C) 1999 Egbert Eich - * Copyright (C) 2007 Joerg Sonnenberger - * - * ======================================================================== - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of the authors not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. The authors makes no - * representations about the suitability of this software for any purpose. - * It is provided "as is" without express or implied warranty. - * - * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include -#include - - - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * - * RETURNS: - * Byte value read from emulator memory. - * - * REMARKS: - * Reads a byte value from the emulator memory. - */ -static uint8_t -rdb(struct x86emu *emu, uint32_t addr) -{ - if (addr > emu->mem_size - 1) - x86emu_halt_sys(emu); - return emu->mem_base[addr]; -} - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * - * RETURNS: - * Word value read from emulator memory. - * - * REMARKS: - * Reads a word value from the emulator memory. - */ -static uint16_t -rdw(struct x86emu *emu, uint32_t addr) -{ - if (addr > emu->mem_size - 2) - x86emu_halt_sys(emu); -#ifdef __STRICT_ALIGNMENT - if (addr & 1) { - u_int8_t *a = emu->mem_base + addr; - u_int16_t r; - - r = ((*(a + 0) << 0) & 0x00ff) | - ((*(a + 1) << 8) & 0xff00); - return r; - } else - return le32toh(*(u_int32_t *)(emu->mem_base + addr)); -#else - return le16toh(*(u_int16_t *)(emu->mem_base + addr)); -#endif -} - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * - * RETURNS: - * Long value read from emulator memory. - * REMARKS: - * Reads a long value from the emulator memory. - */ -static uint32_t -rdl(struct x86emu *emu, uint32_t addr) -{ - if (addr > emu->mem_size - 4) - x86emu_halt_sys(emu); -#ifdef __STRICT_ALIGNMENT - if (addr & 3) { - u_int8_t *a = emu->mem_base + addr; - u_int32_t r; - - r = ((*(a + 0) << 0) & 0x000000ff) | - ((*(a + 1) << 8) & 0x0000ff00) | - ((*(a + 2) << 16) & 0x00ff0000) | - ((*(a + 3) << 24) & 0xff000000); - return r; - } else - return le32toh(*(u_int32_t *)(emu->mem_base + addr)); -#else - return le32toh(*(u_int32_t *)(emu->mem_base + addr)); -#endif -} - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * val - Value to store - * - * REMARKS: - * Writes a byte value to emulator memory. - */ -static void -wrb(struct x86emu *emu, uint32_t addr, uint8_t val) -{ - if (addr > emu->mem_size - 1) - x86emu_halt_sys(emu); - emu->mem_base[addr] = val; -} - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * val - Value to store - * - * REMARKS: - * Writes a word value to emulator memory. - */ -static void -wrw(struct x86emu *emu, uint32_t addr, uint16_t val) -{ - if (addr > emu->mem_size - 2) - x86emu_halt_sys(emu); -#ifdef __STRICT_ALIGNMENT - if (addr & 1) { - u_int8_t *a = emu->mem_base + addr; - - *((a + 0)) = (val >> 0) & 0xff; - *((a + 1)) = (val >> 8) & 0xff; - } else - *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); -#else - *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); -#endif -} - -/* - * PARAMETERS: - * addr - Emulator memory address to read - * val - Value to store - * - * REMARKS: - * Writes a long value to emulator memory. - */ -static void -wrl(struct x86emu *emu, uint32_t addr, uint32_t val) -{ - if (addr > emu->mem_size - 4) - x86emu_halt_sys(emu); -#ifdef __STRICT_ALIGNMENT - if (addr & 3) { - u_int8_t *a = emu->mem_base + addr; - - *((a + 0) = (val >> 0) & 0xff; - *((a + 1) = (val >> 8) & 0xff; - *((a + 2) = (val >> 16) & 0xff; - *((a + 3) = (val >> 24) & 0xff; - } else - *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); -#else - *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); -#endif -} - -/* Setup */ - -void -x86emu_init_default(struct x86emu *emu) -{ - int i; - - emu->emu_rdb = rdb; - emu->emu_rdw = rdw; - emu->emu_rdl = rdl; - emu->emu_wrb = wrb; - emu->emu_wrw = wrw; - emu->emu_wrl = wrl; - - for (i = 0; i < 256; i++) - emu->_x86emu_intrTab[i] = NULL; -} diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c index 59d96322a62..600020fae6d 100644 --- a/sys/dev/atkbdc/atkbd.c +++ b/sys/dev/atkbdc/atkbd.c @@ -1091,32 +1091,35 @@ get_typematic(keyboard_t *kbd) { #if defined(__i386__) || defined(__amd64__) /* - * Only some systems allow us to retrieve the keyboard repeat + * Only some systems allow us to retrieve the keyboard repeat * rate previously set via the BIOS... */ x86regs_t regs; uint8_t *p; + if (x86bios_get_intr(0x15) == 0 || x86bios_get_intr(0x16) == 0) + return (ENODEV); + /* Is BIOS system configuration table supported? */ - bzero(®s, sizeof(regs)); + x86bios_init_regs(®s); regs.R_AH = 0xc0; x86bios_intr(®s, 0x15); if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0) return (ENODEV); - /* Is int 16, function 0x09 supported? */ + /* Is int 0x16, function 0x09 supported? */ p = x86bios_offset((regs.R_ES << 4) + regs.R_BX); if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0) return (ENODEV); - /* Is int 16, function 0x0306 supported? */ - bzero(®s, sizeof(regs)); + /* Is int 0x16, function 0x0306 supported? */ + x86bios_init_regs(®s); regs.R_AH = 0x09; x86bios_intr(®s, 0x16); if ((regs.R_AL & 0x08) == 0) return (ENODEV); - bzero(®s, sizeof(regs)); + x86bios_init_regs(®s); regs.R_AX = 0x0306; x86bios_intr(®s, 0x16); kbd->kb_delay1 = typematic_delay(regs.R_BH << 5); diff --git a/sys/dev/dpms/dpms.c b/sys/dev/dpms/dpms.c index c0476c5d36e..58e2f377bc7 100644 --- a/sys/dev/dpms/dpms.c +++ b/sys/dev/dpms/dpms.c @@ -125,13 +125,13 @@ static void dpms_identify(driver_t *driver, device_t parent) { - /* - * XXX: The DPMS VBE only allows for manipulating a single - * monitor, but we don't know which one. Just attach to the - * first vgapci(4) device we encounter and hope it is the - * right one. - */ - if (devclass_get_device(dpms_devclass, 0) == NULL) + /* The DPMS VBE only allows for manipulating a single monitor. */ + if (devclass_get_device(dpms_devclass, 0) != NULL) + return; + + if ((x86bios_match_device(0xc0000, parent) && + device_get_flags(parent) != 0) || + x86bios_get_orm(0xc0000) != NULL) device_add_child(parent, "dpms", 0); } @@ -172,8 +172,11 @@ dpms_detach(device_t dev) static int dpms_suspend(device_t dev) { + struct dpms_softc *sc; - dpms_set_state(DPMS_OFF); + sc = device_get_softc(dev); + if ((sc->dpms_supported_states & DPMS_OFF) != 0) + dpms_set_state(DPMS_OFF); return (0); } @@ -192,15 +195,16 @@ dpms_call_bios(int subfunction, int *bh) { x86regs_t regs; - bzero(®s, sizeof(regs)); + if (x86bios_get_intr(0x10) == 0) + return (ENXIO); + + x86bios_init_regs(®s); regs.R_AX = VBE_DPMS_FUNCTION; regs.R_BL = subfunction; regs.R_BH = *bh; - regs.R_ES = 0; - regs.R_DI = 0; x86bios_intr(®s, 0x10); - if ((regs.R_EAX & 0xffff) != 0x004f) + if (regs.R_AX != 0x004f) return (ENXIO); *bh = regs.R_BH; diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index 8a613682866..11b95985d7d 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #ifndef VGA_NO_MODE_CHANGE #include +#include #include #include #include @@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -160,7 +163,9 @@ static char *vesa_revstr = NULL; #define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) static int int10_set_mode(int mode); +static int vesa_bios_post(void); static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); +static int vesa_bios_get_current_mode(void); static int vesa_bios_set_mode(int mode); static int vesa_bios_get_dac(void); static int vesa_bios_set_dac(int bits); @@ -222,12 +227,62 @@ int10_set_mode(int mode) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x0000 | mode; + x86bios_init_regs(®s); + regs.R_AL = mode; x86bios_intr(®s, 0x10); - return 0; + return (0); +} + +static int +vesa_bios_post(void) +{ + x86regs_t regs; + devclass_t dc; + device_t *devs; + device_t dev; + int count, i, is_pci; + + if (x86bios_get_orm(0xc0000) == NULL) + return (1); + + dev = NULL; + is_pci = 0; + + /* Find the matching PCI video controller. */ + dc = devclass_find("vgapci"); + if (dc != NULL && devclass_get_devices(dc, &devs, &count) == 0) { + for (dev = NULL, i = 0; dev == NULL && i < count; devs++, i++) + if (x86bios_match_device(0xc0000, *devs) && + device_get_flags(*devs) != 0) { + dev = *devs; + is_pci = 1; + break; + } + free(devs, M_TEMP); + } + + /* Try VGA if a PCI device is not found. */ + if (dev == NULL) { + dc = devclass_find(VGA_DRIVER_NAME); + if (dc != NULL) + dev = devclass_get_device(dc, 0); + } + + if (bootverbose) + printf("%s: calling BIOS POST\n", + dev == NULL ? "VESA" : device_get_nameunit(dev)); + + x86bios_init_regs(®s); + if (is_pci) { + regs.R_AH = pci_get_bus(dev); + regs.R_AL = (pci_get_slot(dev) << 3) | + (pci_get_function(dev) & 0x07); + } + regs.R_DL = 0x80; + x86bios_call(®s, 0xc000, 0x0003); + return (0); } /* VESA BIOS calls */ @@ -235,30 +290,47 @@ static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode) { x86regs_t regs; - int offs; - u_char *buf; + uint32_t offs; + void *buf; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f01; - regs.R_ECX = mode; + buf = x86bios_alloc(&offs, sizeof(*vmode)); + if (buf == NULL) + return (1); - buf = (u_char *)x86bios_alloc(1, &offs); + x86bios_init_regs(®s); + regs.R_AX = 0x4f01; + regs.R_CX = mode; - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - { - x86bios_free(buf, 1); - return 1; + if (regs.R_AX != 0x004f) { + x86bios_free(buf, sizeof(*vmode)); + return (1); } bcopy(buf, vmode, sizeof(*vmode)); - x86bios_free(buf, 1); + x86bios_free(buf, sizeof(*vmode)); - return 0; + return (0); +} + +static int +vesa_bios_get_current_mode(void) +{ + x86regs_t regs; + + x86bios_init_regs(®s); + regs.R_AX = 0x4f03; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (-1); + + return (regs.R_BX); } static int @@ -266,13 +338,13 @@ vesa_bios_set_mode(int mode) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f02; - regs.R_EBX = mode; + x86bios_init_regs(®s); + regs.R_AX = 0x4f02; + regs.R_BX = mode; x86bios_intr(®s, 0x10); - return ((regs.R_AX & 0xff) != 0x4f); + return (regs.R_AX != 0x004f); } static int @@ -280,16 +352,16 @@ vesa_bios_get_dac(void) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f08; - regs.R_EBX = 1; + x86bios_init_regs(®s); + regs.R_AX = 0x4f08; + regs.R_BL = 1; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return 6; + if (regs.R_AX != 0x004f) + return (6); - return ((regs.R_EBX >> 8) & 0x00ff); + return (regs.R_BH); } static int @@ -297,43 +369,45 @@ vesa_bios_set_dac(int bits) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f08; - regs.R_EBX = (bits << 8); + x86bios_init_regs(®s); + regs.R_AX = 0x4f08; + /* regs.R_BL = 0; */ + regs.R_BH = bits; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return 6; + if (regs.R_AX != 0x004f) + return (6); - return ((regs.R_EBX >> 8) & 0x00ff); + return (regs.R_BH); } static int vesa_bios_save_palette(int start, int colors, u_char *palette, int bits) { x86regs_t regs; - int offs; + uint32_t offs; u_char *p; int i; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f09; - regs.R_EBX = 1; - regs.R_ECX = colors; - regs.R_EDX = start; + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); - p = (u_char *)x86bios_alloc(1, &offs); + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + regs.R_BL = 1; + regs.R_CX = colors; + regs.R_DX = start; - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - { - x86bios_free(p, 1); - return 1; + if (regs.R_AX != 0x004f) { + x86bios_free(p, colors * 4); + return (1); } bits = 8 - bits; @@ -342,9 +416,9 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits) palette[i*3 + 1] = p[i*4 + 1] << bits; palette[i*3 + 2] = p[i*4] << bits; } + x86bios_free(p, colors * 4); - x86bios_free(p, 1); - return 0; + return (0); } static int @@ -352,27 +426,28 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits) { x86regs_t regs; - int offs; + uint32_t offs; u_char *p; int i; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f09; - regs.R_EBX = 1; - regs.R_ECX = colors; - regs.R_EDX = start; + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); - p = (u_char *)x86bios_alloc(1, &offs); + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + regs.R_BL = 1; + regs.R_CX = colors; + regs.R_DX = start; - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - { - x86bios_free(p, 1); - return 1; + if (regs.R_AX != 0x004f) { + x86bios_free(p, colors * 4); + return (1); } bits = 8 - bits; @@ -381,20 +456,31 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, g[i] = p[i*4 + 1] << bits; b[i] = p[i*4] << bits; } + x86bios_free(p, colors * 4); - x86bios_free(p, 1); - return 0; + return (0); } static int vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) { x86regs_t regs; - int offs; + uint32_t offs; u_char *p; int i; - p = (u_char *)x86bios_alloc(1, &offs); + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); + + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + /* regs.R_BL = 0; */ + regs.R_CX = colors; + regs.R_DX = start; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); bits = 8 - bits; for (i = 0; i < colors; ++i) { @@ -403,21 +489,10 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) p[i*4 + 2] = palette[i*3] >> bits; p[i*4 + 3] = 0; } - - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f09; - regs.R_EBX = 0; - regs.R_ECX = colors; - regs.R_EDX = start; - - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); - x86bios_intr(®s, 0x10); + x86bios_free(p, colors * 4); - x86bios_free(p, 1); - - return ((regs.R_AX & 0xff) != 0x4f); + return (regs.R_AX != 0x004f); } #ifdef notyet @@ -426,11 +501,22 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits) { x86regs_t regs; - int offs; + uint32_t offs; u_char *p; int i; - p = (u_char *)x86bios_alloc(1, &offs); + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); + + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + /* regs.R_BL = 0; */ + regs.R_CX = colors; + regs.R_DX = start; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); bits = 8 - bits; for (i = 0; i < colors; ++i) { @@ -439,21 +525,10 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, p[i*4 + 2] = r[i] >> bits; p[i*4 + 3] = 0; } - - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f09; - regs.R_EBX = 0; - regs.R_ECX = colors; - regs.R_EDX = start; - - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); - x86bios_intr(®s, 0x10); + x86bios_free(p, colors * 4); - x86bios_free(p, 1); - - return ((regs.R_AX & 0xff) != 0x4f); + return (regs.R_AX != 0x004f); } #endif @@ -462,48 +537,55 @@ vesa_bios_state_buf_size(void) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f04; - regs.R_ECX = STATE_ALL; - regs.R_EDX = STATE_SIZE; + x86bios_init_regs(®s); + regs.R_AX = 0x4f04; + /* regs.R_DL = STATE_SIZE; */ + regs.R_CX = STATE_ALL; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return 0; + if (regs.R_AX != 0x004f) + return (0); - return regs.R_BX * 64; + return (regs.R_BX * 64); } static int vesa_bios_save_restore(int code, void *p, size_t size) { x86regs_t regs; - int offs; - u_char *buf; + uint32_t offs; + void *buf; if (size > VESA_BIOS_BUFSIZE) return (1); - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f04; - regs.R_ECX = STATE_ALL; - regs.R_EDX = code; + if (code != STATE_SAVE && code != STATE_LOAD) + return (1); - buf = (u_char *)x86bios_alloc(1, &offs); + buf = x86bios_alloc(&offs, size); - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); + x86bios_init_regs(®s); + regs.R_AX = 0x4f04; + regs.R_DL = code; + regs.R_CX = STATE_ALL; - bcopy(p, buf, size); + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_BX = X86BIOS_PHYSTOOFF(offs); - x86bios_intr(®s, 0x10); + switch (code) { + case STATE_SAVE: + x86bios_intr(®s, 0x10); + bcopy(buf, p, size); + break; + case STATE_LOAD: + bcopy(p, buf, size); + x86bios_intr(®s, 0x10); + break; + } + x86bios_free(buf, size); - bcopy(buf, p, size); - - x86bios_free(p, 1); - - return ((regs.R_AX & 0xff) != 0x4f); + return (regs.R_AX != 0x004f); } static int @@ -511,16 +593,16 @@ vesa_bios_get_line_length(void) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f06; - regs.R_EBX = 1; + x86bios_init_regs(®s); + regs.R_AX = 0x4f06; + regs.R_BL = 1; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return -1; + if (regs.R_AX != 0x004f) + return (-1); - return regs.R_BX; + return (regs.R_BX); } static int @@ -528,25 +610,25 @@ vesa_bios_set_line_length(int pixel, int *bytes, int *lines) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f06; - regs.R_EBX = 0; - regs.R_ECX = pixel; + x86bios_init_regs(®s); + regs.R_AX = 0x4f06; + /* regs.R_BL = 0; */ + regs.R_CX = pixel; x86bios_intr(®s, 0x10); #if VESA_DEBUG > 1 printf("bx:%d, cx:%d, dx:%d\n", regs.R_BX, regs.R_CX, regs.R_DX); #endif - if ((regs.R_AX & 0xff) != 0x4f) - return -1; + if (regs.R_AX != 0x004f) + return (-1); - if (bytes) + if (bytes != NULL) *bytes = regs.R_BX; - if (lines) + if (lines != NULL) *lines = regs.R_DX; - return 0; + return (0); } #if 0 @@ -555,19 +637,19 @@ vesa_bios_get_start(int *x, int *y) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f07; - regs.R_EBX = 1; + x86bios_init_regs(®s); + regs.R_AX = 0x4f07; + regs.R_BL = 1; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return -1; + if (regs.R_AX != 0x004f) + return (-1); *x = regs.R_CX; *y = regs.R_DX; - return 0; + return (0); } #endif @@ -576,15 +658,15 @@ vesa_bios_set_start(int x, int y) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f07; - regs.R_EBX = 0x80; - regs.R_EDX = y; - regs.R_ECX = x; + x86bios_init_regs(®s); + regs.R_AX = 0x4f07; + regs.R_BL = 0x80; + regs.R_CX = x; + regs.R_DX = y; x86bios_intr(®s, 0x10); - return ((regs.R_AX & 0xff) != 0x4f); + return (regs.R_AX != 0x004f); } /* map a generic video mode to a known mode */ @@ -604,9 +686,9 @@ vesa_map_gen_mode_num(int type, int color, int mode) for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { if (mode_map[i].from == mode) - return mode_map[i].to; + return (mode_map[i].to); } - return mode; + return (mode); } static int @@ -628,7 +710,7 @@ vesa_translate_flags(u_int16_t vflags) flags |= (vflags & ftable[i].mask) ? ftable[i].set : ftable[i].reset; } - return flags; + return (flags); } static int @@ -649,9 +731,9 @@ vesa_translate_mmodel(u_int8_t vmodel) for (i = 0; mtable[i].mmodel >= 0; ++i) { if (mtable[i].vmodel == vmodel) - return mtable[i].mmodel; + return (mtable[i].mmodel); } - return V_INFO_MM_OTHER; + return (V_INFO_MM_OTHER); } static int @@ -685,6 +767,18 @@ vesa_get_line_width(video_info_t *info) return (len > 0 ? len : width); } +#define VESA_MAXSTR 256 + +#define VESA_STRCPY(dst, src) do { \ + char *str; \ + int i; \ + dst = malloc(VESA_MAXSTR, M_DEVBUF, M_WAITOK); \ + str = x86bios_offset(BIOS_SADDRTOLADDR(src)); \ + for (i = 0; i < VESA_MAXSTR - 1 && str[i] != '\0'; i++) \ + dst[i] = str[i]; \ + dst[i] = '\0'; \ +} while (0) + static int vesa_bios_init(void) { @@ -693,32 +787,50 @@ vesa_bios_init(void) video_info_t *p; x86regs_t regs; size_t bsize; - int offs; - u_char *vmbuf; + void *vmbuf; + uint32_t offs; + uint16_t vers; int is_via_cle266; int modes; int i; if (vesa_init_done) - return 0; + return (0); has_vesa_bios = FALSE; vesa_adp_info = NULL; vesa_vmode_max = 0; vesa_vmode[0].vi_mode = EOT; - vmbuf = (u_char *)x86bios_alloc(1, &offs); + /* + * If the VBE real mode interrupt vector is not found, try BIOS POST. + */ + if (x86bios_get_intr(0x10) == 0) { + if (vesa_bios_post() != 0) + return (1); + offs = x86bios_get_intr(0x10); + if (offs == 0) + return (1); + if (bootverbose) + printf("VESA: interrupt vector installed (0x%x)\n", + BIOS_SADDRTOLADDR(offs)); + } + + x86bios_init_regs(®s); + regs.R_AX = 0x4f00; + + vmbuf = x86bios_alloc(&offs, sizeof(buf)); + if (vmbuf == NULL) + return (1); + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); + bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */ - - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f00; - regs.R_ES = SEG_ADDR(offs); - regs.R_DI = SEG_OFF(offs); - x86bios_intr(®s, 0x10); - if (((regs.R_AX & 0xff) != 0x4f) || bcmp("VESA", vmbuf, 4)) - return 1; + if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0) + goto fail; bcopy(vmbuf, &buf, sizeof(buf)); @@ -727,34 +839,43 @@ vesa_bios_init(void) printf("VESA: information block\n"); dump_buffer((u_char *)&buf, sizeof(buf)); } - if (vesa_adp_info->v_version < 0x0102) { + + vers = buf.v_version = le16toh(buf.v_version); + buf.v_oemstr = le32toh(buf.v_oemstr); + buf.v_flags = le32toh(buf.v_flags); + buf.v_modetable = le32toh(buf.v_modetable); + buf.v_memsize = le16toh(buf.v_memsize); + buf.v_revision = le16toh(buf.v_revision); + buf.v_venderstr = le32toh(buf.v_venderstr); + buf.v_prodstr = le32toh(buf.v_prodstr); + buf.v_revstr = le32toh(buf.v_revstr); + + if (vers < 0x0102) { printf("VESA: VBE version %d.%d is not supported; " "version 1.2 or later is required.\n", - ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 - + ((vesa_adp_info->v_version & 0x0f00) >> 8), - ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 - + (vesa_adp_info->v_version & 0x000f)); - return 1; + ((vers & 0xf000) >> 12) * 10 + ((vers & 0x0f00) >> 8), + ((vers & 0x00f0) >> 4) * 10 + (vers & 0x000f)); + return (1); } - vesa_oemstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_oemstr)); - - is_via_cle266 = strcmp(vesa_oemstr, VESA_VIA_CLE266) == 0; - - if (vesa_adp_info->v_version >= 0x0200) { - vesa_venderstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_venderstr)); - vesa_prodstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_prodstr)); - vesa_revstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_revstr)); + VESA_STRCPY(vesa_oemstr, buf.v_oemstr); + if (vers >= 0x0200) { + VESA_STRCPY(vesa_venderstr, buf.v_venderstr); + VESA_STRCPY(vesa_prodstr, buf.v_prodstr); + VESA_STRCPY(vesa_revstr, buf.v_revstr); } + is_via_cle266 = strncmp(vesa_oemstr, VESA_VIA_CLE266, + sizeof(VESA_VIA_CLE266)) == 0; - vesa_vmodetab = (uint16_t *)x86bios_offset(FARP(vesa_adp_info->v_modetable)); + if (buf.v_modetable == 0) + goto fail; - if (vesa_vmodetab == NULL) - return 1; + vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf.v_modetable)); for (i = 0, modes = 0; (i < (M_VESA_MODE_MAX - M_VESA_BASE + 1)) && (vesa_vmodetab[i] != 0xffff); ++i) { + vesa_vmodetab[i] = le16toh(vesa_vmodetab[i]); if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) continue; @@ -888,16 +1009,36 @@ vesa_bios_init(void) } vesa_vmode[modes].vi_mode = EOT; - x86bios_free(vmbuf, 1); - if (bootverbose) printf("VESA: %d mode(s) found\n", modes); has_vesa_bios = (modes > 0); if (!has_vesa_bios) - return (1); + goto fail; + x86bios_free(vmbuf, sizeof(buf)); return (0); + +fail: + if (vmbuf != NULL) + x86bios_free(vmbuf, sizeof(buf)); + if (vesa_oemstr != NULL) { + free(vesa_oemstr, M_DEVBUF); + vesa_oemstr = NULL; + } + if (vesa_venderstr != NULL) { + free(vesa_venderstr, M_DEVBUF); + vesa_venderstr = NULL; + } + if (vesa_prodstr != NULL) { + free(vesa_prodstr, M_DEVBUF); + vesa_prodstr = NULL; + } + if (vesa_revstr != NULL) { + free(vesa_revstr, M_DEVBUF); + vesa_revstr = NULL; + } + return (1); } static void @@ -946,9 +1087,9 @@ vesa_configure(int flags) int i; if (vesa_init_done) - return 0; + return (0); if (flags & VIO_PROBE_ONLY) - return 0; /* XXX */ + return (0); /* * If the VESA module has already been loaded, abort loading @@ -956,10 +1097,11 @@ vesa_configure(int flags) */ for (i = 0; (adp = vid_get_adapter(i)) != NULL; ++i) { if (adp->va_flags & V_ADP_VESA) - return ENXIO; + return (ENXIO); if (adp->va_type == KD_VGA) break; } + /* * The VGA adapter is not found. This is because either * 1) the VGA driver has not been initialized, or 2) the VGA card @@ -968,7 +1110,7 @@ vesa_configure(int flags) */ if (adp == NULL) { vga_sub_configure = vesa_configure; - return ENODEV; + return (ENODEV); } /* count number of registered adapters */ @@ -980,7 +1122,7 @@ vesa_configure(int flags) vesa_adp = adp; if (vesa_bios_init()) { vesa_adp = NULL; - return ENXIO; + return (ENXIO); } vesa_adp->va_flags |= V_ADP_VESA; @@ -997,36 +1139,40 @@ vesa_configure(int flags) vesa_init_done = TRUE; } else { vesa_adp = NULL; - return error; + return (error); } - return 0; + return (0); } #if 0 static int vesa_nop(void) { - return 0; + + return (0); } #endif static int vesa_error(void) { - return 1; + + return (1); } static int vesa_probe(int unit, video_adapter_t **adpp, void *arg, int flags) { - return (*prevvidsw->probe)(unit, adpp, arg, flags); + + return ((*prevvidsw->probe)(unit, adpp, arg, flags)); } static int vesa_init(int unit, video_adapter_t *adp, int flags) { - return (*prevvidsw->init)(unit, adp, flags); + + return ((*prevvidsw->init)(unit, adp, flags)); } static int @@ -1035,10 +1181,10 @@ vesa_get_info(video_adapter_t *adp, int mode, video_info_t *info) int i; if ((*prevvidsw->get_info)(adp, mode, info) == 0) - return 0; + return (0); if (adp != vesa_adp) - return 1; + return (1); mode = vesa_map_gen_mode_num(vesa_adp->va_type, vesa_adp->va_flags & V_ADP_COLOR, mode); @@ -1047,10 +1193,10 @@ vesa_get_info(video_adapter_t *adp, int mode, video_info_t *info) continue; if (vesa_vmode[i].vi_mode == mode) { *info = vesa_vmode[i]; - return 0; + return (0); } } - return 1; + return (1); } static int @@ -1059,9 +1205,9 @@ vesa_query_mode(video_adapter_t *adp, video_info_t *info) int i; if ((*prevvidsw->query_mode)(adp, info) == 0) - return 0; + return (0); if (adp != vesa_adp) - return ENODEV; + return (ENODEV); for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { if ((info->vi_width != 0) @@ -1087,9 +1233,9 @@ vesa_query_mode(video_adapter_t *adp, video_info_t *info) && (info->vi_flags != vesa_vmode[i].vi_flags)) continue; *info = vesa_vmode[i]; - return 0; + return (0); } - return ENODEV; + return (ENODEV); } static int @@ -1098,7 +1244,7 @@ vesa_set_mode(video_adapter_t *adp, int mode) video_info_t info; if (adp != vesa_adp) - return (*prevvidsw->set_mode)(adp, mode); + return ((*prevvidsw->set_mode)(adp, mode)); mode = vesa_map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode); @@ -1129,11 +1275,11 @@ vesa_set_mode(video_adapter_t *adp, int mode) /* we may not need to handle this mode after all... */ if ((*prevvidsw->set_mode)(adp, mode) == 0) - return 0; + return (0); /* is the new mode supported? */ if (vesa_get_info(adp, mode, &info)) - return 1; + return (1); /* assert(VESA_MODE(mode)); */ #if VESA_DEBUG > 0 @@ -1144,7 +1290,7 @@ vesa_set_mode(video_adapter_t *adp, int mode) info.vi_flags &= ~V_INFO_LINEAR; if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0))) - return 1; + return (1); if (adp->va_info.vi_flags & V_INFO_LINEAR) vesa_unmap_buffer(adp->va_buffer, @@ -1190,29 +1336,32 @@ vesa_set_mode(video_adapter_t *adp, int mode) /* move hardware cursor out of the way */ (*vidsw[vesa_adp->va_index]->set_hw_cursor)(vesa_adp, -1, -1); - return 0; + return (0); } static int vesa_save_font(video_adapter_t *adp, int page, int fontsize, int fontwidth, u_char *data, int ch, int count) { - return (*prevvidsw->save_font)(adp, page, fontsize, fontwidth, data, - ch, count); + + return ((*prevvidsw->save_font)(adp, page, fontsize, fontwidth, data, + ch, count)); } static int vesa_load_font(video_adapter_t *adp, int page, int fontsize, int fontwidth, u_char *data, int ch, int count) { - return (*prevvidsw->load_font)(adp, page, fontsize, fontwidth, data, - ch, count); + + return ((*prevvidsw->load_font)(adp, page, fontsize, fontwidth, data, + ch, count)); } static int vesa_show_font(video_adapter_t *adp, int page) { - return (*prevvidsw->show_font)(adp, page); + + return ((*prevvidsw->show_font)(adp, page)); } static int @@ -1226,12 +1375,12 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette) bits = vesa_bios_get_dac(); error = vesa_bios_save_palette(0, 256, palette, bits); if (error == 0) - return 0; + return (0); if (bits != 6) - return error; + return (error); } - return (*prevvidsw->save_palette)(adp, palette); + return ((*prevvidsw->save_palette)(adp, palette)); } static int @@ -1245,48 +1394,67 @@ vesa_load_palette(video_adapter_t *adp, u_char *palette) && VESA_MODE(adp->va_mode) && ((bits = vesa_bios_set_dac(8)) > 6)) { error = vesa_bios_load_palette(0, 256, palette, bits); if (error == 0) - return 0; + return (0); if (vesa_bios_set_dac(6) != 6) - return 1; + return (1); } #endif /* notyet */ - return (*prevvidsw->load_palette)(adp, palette); + return ((*prevvidsw->load_palette)(adp, palette)); } static int vesa_set_border(video_adapter_t *adp, int color) { - return (*prevvidsw->set_border)(adp, color); + + return ((*prevvidsw->set_border)(adp, color)); } static int vesa_save_state(video_adapter_t *adp, void *p, size_t size) { + if (adp != vesa_adp) - return (*prevvidsw->save_state)(adp, p, size); + return ((*prevvidsw->save_state)(adp, p, size)); if (vesa_state_buf_size == 0) vesa_state_buf_size = vesa_bios_state_buf_size(); if (size == 0) return (sizeof(int) + vesa_state_buf_size); else if (size < (sizeof(int) + vesa_state_buf_size)) - return 1; + return (1); ((adp_state_t *)p)->sig = V_STATE_SIG; bzero(((adp_state_t *)p)->regs, vesa_state_buf_size); - return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs, - vesa_state_buf_size); + return (vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs, + vesa_state_buf_size)); } static int vesa_load_state(video_adapter_t *adp, void *p) { - if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG)) - return (*prevvidsw->load_state)(adp, p); + int flags, mode, ret; - return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, - vesa_state_buf_size); + if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG)) + return ((*prevvidsw->load_state)(adp, p)); + + ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, + vesa_state_buf_size); + + /* + * If the current mode is not restored properly, try BIOS POST and + * force setting the mode. + */ + flags = adp->va_info.vi_flags; + if (!(flags & V_INFO_GRAPHICS)) + flags &= ~V_INFO_LINEAR; + mode = adp->va_mode | ((flags & V_INFO_LINEAR) ? 0x4000 : 0); + if (vesa_bios_get_current_mode() != mode && vesa_bios_post() == 0 && + x86bios_get_intr(0x10) != 0) { + int10_set_mode(adp->va_initial_bios_mode); + vesa_bios_set_mode(mode); + } + return (ret); } #if 0 @@ -1295,17 +1463,17 @@ vesa_get_origin(video_adapter_t *adp, off_t *offset) { x86regs_t regs; - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f05; - regs.R_EBX = 0x10; + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_BL = 0x10; x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return 1; + if (regs.R_AX != 0x004f) + return (1); *offset = regs.DX * adp->va_window_gran; - return 0; + return (0); } #endif @@ -1321,99 +1489,107 @@ vesa_set_origin(video_adapter_t *adp, off_t offset) * detect error. */ if (adp != vesa_adp) - return (*prevvidsw->set_win_org)(adp, offset); + return ((*prevvidsw->set_win_org)(adp, offset)); /* if this is a linear frame buffer, do nothing */ if (adp->va_info.vi_flags & V_INFO_LINEAR) - return 0; + return (0); /* XXX */ if (adp->va_window_gran == 0) - return 1; + return (1); - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f05; - regs.R_EBX = 0; - regs.R_EDX = offset / adp->va_window_gran; + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_DX = offset / adp->va_window_gran; + x86bios_intr(®s, 0x10); - if ((regs.R_AX & 0xff) != 0x4f) - return 1; + if (regs.R_AX != 0x004f) + return (1); - bzero(®s, sizeof(regs)); - regs.R_EAX = 0x4f05; - regs.R_EBX = 1; - regs.R_EDX = offset / adp->va_window_gran; + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_BL = 1; + regs.R_DX = offset / adp->va_window_gran; x86bios_intr(®s, 0x10); adp->va_window_orig = (offset/adp->va_window_gran)*adp->va_window_gran; - return 0; /* XXX */ + return (0); /* XXX */ } static int vesa_read_hw_cursor(video_adapter_t *adp, int *col, int *row) { - return (*prevvidsw->read_hw_cursor)(adp, col, row); + + return ((*prevvidsw->read_hw_cursor)(adp, col, row)); } static int vesa_set_hw_cursor(video_adapter_t *adp, int col, int row) { - return (*prevvidsw->set_hw_cursor)(adp, col, row); + + return ((*prevvidsw->set_hw_cursor)(adp, col, row)); } static int vesa_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, int celsize, int blink) { - return (*prevvidsw->set_hw_cursor_shape)(adp, base, height, celsize, - blink); + + return ((*prevvidsw->set_hw_cursor_shape)(adp, base, height, celsize, + blink)); } static int vesa_blank_display(video_adapter_t *adp, int mode) { + /* XXX: use VESA DPMS */ - return (*prevvidsw->blank_display)(adp, mode); + return ((*prevvidsw->blank_display)(adp, mode)); } static int vesa_mmap(video_adapter_t *adp, vm_offset_t offset, vm_paddr_t *paddr, int prot) { + #if VESA_DEBUG > 0 printf("vesa_mmap(): window:0x%tx, buffer:0x%tx, offset:0x%tx\n", adp->va_info.vi_window, adp->va_info.vi_buffer, offset); #endif - if ((adp == vesa_adp) && (adp->va_info.vi_flags & V_INFO_LINEAR)) { + if ((adp == vesa_adp) && + (adp->va_info.vi_flags & V_INFO_LINEAR) != 0) { /* va_window_size == va_buffer_size/vi_planes */ /* XXX: is this correct? */ if (offset > adp->va_window_size - PAGE_SIZE) - return -1; + return (-1); *paddr = adp->va_info.vi_buffer + offset; - return 0; - } else { - return (*prevvidsw->mmap)(adp, offset, paddr, prot); + return (0); } + return ((*prevvidsw->mmap)(adp, offset, paddr, prot)); } static int vesa_clear(video_adapter_t *adp) { - return (*prevvidsw->clear)(adp); + + return ((*prevvidsw->clear)(adp)); } static int vesa_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) { - return (*prevvidsw->fill_rect)(adp, val, x, y, cx, cy); + + return ((*prevvidsw->fill_rect)(adp, val, x, y, cx, cy)); } static int vesa_bitblt(video_adapter_t *adp,...) { + /* FIXME */ - return 1; + return (1); } static int @@ -1427,15 +1603,15 @@ get_palette(video_adapter_t *adp, int base, int count, int error; if ((base < 0) || (base >= 256) || (count < 0) || (count > 256)) - return 1; + return (1); if ((base + count) > 256) - return 1; + return (1); if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)) - return 1; + return (1); bits = vesa_bios_get_dac(); if (bits <= 6) - return 1; + return (1); r = malloc(count*3, M_DEVBUF, M_WAITOK); g = r + count; @@ -1453,14 +1629,14 @@ get_palette(video_adapter_t *adp, int base, int count, free(r, M_DEVBUF); /* if error && bits != 6 at this point, we are in trouble... XXX */ - return error; + return (error); } static int set_palette(video_adapter_t *adp, int base, int count, u_char *red, u_char *green, u_char *blue, u_char *trans) { - return 1; + return (1); #ifdef notyet u_char *r; u_char *g; @@ -1469,10 +1645,10 @@ set_palette(video_adapter_t *adp, int base, int count, int error; if ((base < 0) || (base >= 256) || (base + count > 256)) - return 1; + return (1); if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode) || ((bits = vesa_bios_set_dac(8)) <= 6)) - return 1; + return (1); r = malloc(count*3, M_DEVBUF, M_WAITOK); g = r + count; @@ -1484,11 +1660,11 @@ set_palette(video_adapter_t *adp, int base, int count, error = vesa_bios_load_palette2(base, count, r, g, b, bits); free(r, M_DEVBUF); if (error == 0) - return 0; + return (0); /* if the following call fails, we are in trouble... XXX */ vesa_bios_set_dac(6); - return 1; + return (1); #endif /* notyet */ } @@ -1498,7 +1674,7 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) int bytes; if (adp != vesa_adp) - return (*prevvidsw->ioctl)(adp, cmd, arg); + return ((*prevvidsw->ioctl)(adp, cmd, arg)); switch (cmd) { case FBIO_SETWINORG: /* set frame buffer window origin */ @@ -1508,24 +1684,24 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) case FBIO_SETDISPSTART: /* set display start address */ if (!VESA_MODE(adp->va_mode)) - return (*prevvidsw->ioctl)(adp, cmd, arg); + return ((*prevvidsw->ioctl)(adp, cmd, arg)); if (vesa_bios_set_start(((video_display_start_t *)arg)->x, ((video_display_start_t *)arg)->y)) - return ENODEV; + return (ENODEV); adp->va_disp_start.x = ((video_display_start_t *)arg)->x; adp->va_disp_start.y = ((video_display_start_t *)arg)->y; - return 0; + return (0); case FBIO_SETLINEWIDTH: /* set line length in pixel */ if (!VESA_MODE(adp->va_mode)) - return (*prevvidsw->ioctl)(adp, cmd, arg); + return ((*prevvidsw->ioctl)(adp, cmd, arg)); if (vesa_bios_set_line_length(*(u_int *)arg, &bytes, NULL)) - return ENODEV; + return (ENODEV); adp->va_line_width = bytes; #if VESA_DEBUG > 1 printf("new line width:%d\n", adp->va_line_width); #endif - return 0; + return (0); case FBIO_GETPALETTE: /* get color palette */ if (get_palette(adp, ((video_color_palette_t *)arg)->index, @@ -1534,8 +1710,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) ((video_color_palette_t *)arg)->green, ((video_color_palette_t *)arg)->blue, ((video_color_palette_t *)arg)->transparent)) - return (*prevvidsw->ioctl)(adp, cmd, arg); - return 0; + return ((*prevvidsw->ioctl)(adp, cmd, arg)); + return (0); case FBIO_SETPALETTE: /* set color palette */ @@ -1545,8 +1721,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) ((video_color_palette_t *)arg)->green, ((video_color_palette_t *)arg)->blue, ((video_color_palette_t *)arg)->transparent)) - return (*prevvidsw->ioctl)(adp, cmd, arg); - return 0; + return ((*prevvidsw->ioctl)(adp, cmd, arg)); + return (0); case FBIOGETCMAP: /* get color palette */ if (get_palette(adp, ((struct fbcmap *)arg)->index, @@ -1554,8 +1730,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) ((struct fbcmap *)arg)->red, ((struct fbcmap *)arg)->green, ((struct fbcmap *)arg)->blue, NULL)) - return (*prevvidsw->ioctl)(adp, cmd, arg); - return 0; + return ((*prevvidsw->ioctl)(adp, cmd, arg)); + return (0); case FBIOPUTCMAP: /* set color palette */ if (set_palette(adp, ((struct fbcmap *)arg)->index, @@ -1563,11 +1739,11 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) ((struct fbcmap *)arg)->red, ((struct fbcmap *)arg)->green, ((struct fbcmap *)arg)->blue, NULL)) - return (*prevvidsw->ioctl)(adp, cmd, arg); - return 0; + return ((*prevvidsw->ioctl)(adp, cmd, arg)); + return (0); default: - return (*prevvidsw->ioctl)(adp, cmd, arg); + return ((*prevvidsw->ioctl)(adp, cmd, arg)); } } @@ -1579,15 +1755,15 @@ vesa_diag(video_adapter_t *adp, int level) /* call the previous handler first */ error = (*prevvidsw->diag)(adp, level); if (error) - return error; + return (error); if (adp != vesa_adp) - return 1; + return (1); if (level <= 0) - return 0; + return (0); - return 0; + return (0); } static int @@ -1597,15 +1773,16 @@ vesa_bios_info(int level) struct vesa_mode vmode; int i; #endif + uint16_t vers; + + vers = vesa_adp_info->v_version; if (bootverbose) { /* general adapter information */ printf( "VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n", - ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 + - ((vesa_adp_info->v_version & 0x0f00) >> 8), - ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 + - (vesa_adp_info->v_version & 0x000f), + (vers >> 12) * 10 + ((vers & 0x0f00) >> 8), + ((vers & 0x00f0) >> 4) * 10 + (vers & 0x000f), vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags, vesa_vmodetab, vesa_adp_info->v_modetable); @@ -1615,9 +1792,9 @@ vesa_bios_info(int level) } if (level <= 0) - return 0; + return (0); - if (vesa_adp_info->v_version >= 0x0200 && bootverbose) { + if (vers >= 0x0200 && bootverbose) { /* vender name, product name, product revision */ printf("VESA: %s %s %s\n", (vesa_venderstr != NULL) ? vesa_venderstr : "unknown", @@ -1664,7 +1841,7 @@ vesa_bios_info(int level) } #endif /* VESA_DEBUG > 1 */ - return 0; + return (0); } /* module loading */ @@ -1676,7 +1853,7 @@ vesa_load(void) int s; if (vesa_init_done) - return 0; + return (0); /* locate a VGA adapter */ s = spltty(); @@ -1687,7 +1864,7 @@ vesa_load(void) if (error == 0) vesa_bios_info(bootverbose); - return error; + return (error); } static int @@ -1700,7 +1877,7 @@ vesa_unload(void) /* if the adapter is currently in a VESA mode, don't unload */ if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode)) - return EBUSY; + return (EBUSY); /* * FIXME: if there is at least one vty which is in a VESA mode, * we shouldn't be unloading! XXX @@ -1725,21 +1902,30 @@ vesa_unload(void) } splx(s); - return error; + if (vesa_oemstr != NULL) + free(vesa_oemstr, M_DEVBUF); + if (vesa_venderstr != NULL) + free(vesa_venderstr, M_DEVBUF); + if (vesa_prodstr != NULL) + free(vesa_prodstr, M_DEVBUF); + if (vesa_revstr != NULL) + free(vesa_revstr, M_DEVBUF); + if (vesa_vmode != &vesa_vmode_empty) + free(vesa_vmode, M_DEVBUF); + return (error); } static int vesa_mod_event(module_t mod, int type, void *data) { + switch (type) { case MOD_LOAD: - return vesa_load(); + return (vesa_load()); case MOD_UNLOAD: - return vesa_unload(); - default: - return EOPNOTSUPP; + return (vesa_unload()); } - return 0; + return (EOPNOTSUPP); } static moduledata_t vesa_mod = { diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 3e5b1a64bdd..1467bbd116c 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -58,9 +59,19 @@ struct vga_pci_softc { struct vga_resource vga_res[PCIR_MAX_BAR_0 + 1]; }; +SYSCTL_DECL(_hw_pci); + +int vga_pci_default_unit = -1; +TUNABLE_INT("hw.pci.default_vgapci_unit", &vga_pci_default_unit); +SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RD, + &vga_pci_default_unit, -1, "Default VGA-compatible display"); + static int vga_pci_probe(device_t dev) { + device_t bdev; + int unit; + uint16_t bctl; switch (pci_get_class(dev)) { case PCIC_DISPLAY: @@ -72,6 +83,16 @@ vga_pci_probe(device_t dev) default: return (ENXIO); } + + /* Probe default display. */ + unit = device_get_unit(dev); + bdev = device_get_parent(device_get_parent(dev)); + bctl = pci_read_config(bdev, PCIR_BRIDGECTL_1, 2); + if (vga_pci_default_unit < 0 && (bctl & PCIB_BCR_VGA_ENABLE) != 0) + vga_pci_default_unit = unit; + if (vga_pci_default_unit == unit) + device_set_flags(dev, 1); + device_set_desc(dev, "VGA-compatible display"); return (BUS_PROBE_GENERIC); } diff --git a/sys/modules/dpms/Makefile b/sys/modules/dpms/Makefile index d1d58ffe607..4eabf14fc98 100644 --- a/sys/modules/dpms/Makefile +++ b/sys/modules/dpms/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ KMOD= dpms -SRCS= bus_if.h device_if.h +SRCS= bus_if.h device_if.h pci_if.h .PATH: ${.CURDIR}/../../dev/dpms SRCS+= dpms.c diff --git a/sys/modules/vesa/Makefile b/sys/modules/vesa/Makefile index 8b459159de5..69a0c330688 100644 --- a/sys/modules/vesa/Makefile +++ b/sys/modules/vesa/Makefile @@ -2,6 +2,7 @@ KMOD= vesa SRCS= opt_vga.h opt_vesa.h +SRCS+= bus_if.h device_if.h pci_if.h .PATH: ${.CURDIR}/../../dev/fb SRCS+= vesa.c diff --git a/sys/modules/x86bios/Makefile b/sys/modules/x86bios/Makefile index 8b5fa302a78..3cab2853172 100644 --- a/sys/modules/x86bios/Makefile +++ b/sys/modules/x86bios/Makefile @@ -2,9 +2,10 @@ KMOD= x86bios SRCS= opt_x86bios.h +SRCS+= bus_if.h device_if.h pci_if.h .PATH: ${.CURDIR}/../../contrib/x86emu .PATH: ${.CURDIR}/../../compat/x86bios -SRCS+= x86bios.c x86bios_alloc.c x86emu.c x86emu_util.c +SRCS+= x86bios.c x86emu.c .include From 5a0a9182fe36b1aae17ad71f6f7cdea5e35ce4e7 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 19 Oct 2009 21:01:42 +0000 Subject: [PATCH 223/646] Fix a copy-and-pasto in the previous commit. --- sys/compat/x86bios/x86bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c index 74c32a7ead1..be5788708be 100644 --- a/sys/compat/x86bios/x86bios.c +++ b/sys/compat/x86bios/x86bios.c @@ -426,7 +426,7 @@ static __inline int x86bios_map_mem(void) { - x86bios_ivt = pmap_mapdev(X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE); + x86bios_ivt = pmap_mapbios(X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE); if (x86bios_ivt == NULL) return (1); x86bios_rom = pmap_mapdev(X86BIOS_ROM_BASE, X86BIOS_ROM_SIZE); From 08c7e8c8797149bff625621be605863dfedc9af2 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 19 Oct 2009 21:24:19 +0000 Subject: [PATCH 224/646] When tzsetup is run as non-root and the "CMOS clock question on UTC" is answered as No, it would abort without properly ending the dialog session. MFC after: 1 week --- usr.sbin/tzsetup/tzsetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index 66a34c4d2f7..e00e3bddc43 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -709,9 +709,11 @@ main(int argc, char **argv) fd = open(_PATH_WALL_CMOS_CLOCK, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (fd < 0) + if (fd < 0) { + end_dialog(); err(1, "create %s", _PATH_WALL_CMOS_CLOCK); + } close(fd); } } From b89269048dd787becc4aa4fbcec29035eaef92fd Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 19 Oct 2009 21:37:31 +0000 Subject: [PATCH 225/646] Make the usage of the default zoneinfo file to install clearer. MFC after: 1 week --- usr.sbin/tzsetup/tzsetup.8 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8 index fd355b697f6..66afdd478e4 100644 --- a/usr.sbin/tzsetup/tzsetup.8 +++ b/usr.sbin/tzsetup/tzsetup.8 @@ -32,7 +32,7 @@ .Sh SYNOPSIS .Nm .Op Fl ns -.Op Ar default +.Op Ar zoneinfo file .Sh DESCRIPTION The .Nm @@ -56,10 +56,11 @@ 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 -.Ar default -on the command line; this is intended mainly for pre-configured -installation scripts. +It is possible to short-circuit the menu system by specifying the +location of a +.Ar zoneinfo file +on the command line; this is intended mainly for pre-configured installation +scripts. .Sh TIMEZONE DATABASE The contents of the timezone database are indexed by .Pa /usr/share/zoneinfo/zone.tab . From b20adc2b5ace57454bfdb41f1a9969cf480a71cd Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 19 Oct 2009 21:43:59 +0000 Subject: [PATCH 226/646] Remove the newly added uch341 driver, it will be merged into uchcom instead. Suggested by: takawata Submitted by: HPS --- sys/conf/files | 3 +- sys/dev/usb/serial/uch341.c | 530 -------------------------------- sys/modules/usb/Makefile | 4 +- sys/modules/usb/uch341/Makefile | 36 --- 4 files changed, 3 insertions(+), 570 deletions(-) delete mode 100644 sys/dev/usb/serial/uch341.c delete mode 100644 sys/modules/usb/uch341/Makefile diff --git a/sys/conf/files b/sys/conf/files index 52dc34a0880..033af70d769 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1645,7 +1645,6 @@ dev/usb/serial/u3g.c optional u3g dev/usb/serial/uark.c optional uark dev/usb/serial/ubsa.c optional ubsa dev/usb/serial/ubser.c optional ubser -dev/usb/serial/uch341.c optional uch341 dev/usb/serial/uchcom.c optional uchcom dev/usb/serial/ucycom.c optional ucycom dev/usb/serial/ufoma.c optional ufoma @@ -1661,7 +1660,7 @@ dev/usb/serial/uslcom.c optional uslcom dev/usb/serial/uvisor.c optional uvisor dev/usb/serial/uvscom.c optional uvscom dev/usb/serial/usb_serial.c optional ucom | \ - (u3g | uark | ubsa | ubser | uch341 | uchcom | ucycom | ufoma | uftdi | ugensa | uipaq | ulpt | umct | umodem | umoscom | uplcom | uslcom | uvisor | uvscom) + (u3g | uark | ubsa | ubser | uchcom | ucycom | ufoma | uftdi | ugensa | uipaq | ulpt | umct | umodem | umoscom | uplcom | uslcom | uvisor | uvscom) # # USB misc drivers # diff --git a/sys/dev/usb/serial/uch341.c b/sys/dev/usb/serial/uch341.c deleted file mode 100644 index 8f77ce2a03e..00000000000 --- a/sys/dev/usb/serial/uch341.c +++ /dev/null @@ -1,530 +0,0 @@ -/* $FreeBSD$ */ -/*- - * Copyright (c) 2007 Frank A Kingswood. All rights reserved. - * Copyright (c) 2008 Hans Petter Selasky. 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. - */ - -/* - * The ChipHead 341 programming details were taken from the ch341.c - * driver written by Frank A Kingswood. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define USB_DEBUG_VAR uch341_debug -#include -#include - -#include - -#if USB_DEBUG -static int uch341_debug = 0; - -SYSCTL_NODE(_hw_usb, OID_AUTO, uch341, CTLFLAG_RW, 0, "USB CH341"); -SYSCTL_INT(_hw_usb_uch341, OID_AUTO, debug, CTLFLAG_RW, - &uch341_debug, 0, "Debug level"); -#endif - -#define UCH341_CONFIG_INDEX 0 -#define UCH341_IFACE_INDEX 0 -#define UCH341_BUFSIZE 1024 - -enum { - UCH341_BULK_DT_WR, - UCH341_BULK_DT_RD, - UCH341_N_TRANSFER, -}; - -struct uch341_softc { - struct ucom_super_softc sc_super_ucom; - struct ucom_softc sc_ucom; - - struct usb_device *sc_udev; - struct usb_xfer *sc_xfer[UCH341_N_TRANSFER]; - device_t sc_dev; - struct mtx sc_mtx; - - uint8_t sc_dtr; - uint8_t sc_rts; - uint8_t sc_iface_index; - uint8_t sc_hdrlen; - uint8_t sc_msr; - uint8_t sc_lsr; - - uint8_t sc_name[16]; -}; - -/* prototypes */ - -static device_probe_t uch341_probe; -static device_attach_t uch341_attach; -static device_detach_t uch341_detach; - -static usb_callback_t uch341_write_callback; -static usb_callback_t uch341_read_callback; - -static void uch341_cfg_open(struct ucom_softc *); -static void uch341_cfg_set_dtr(struct ucom_softc *, uint8_t); -static void uch341_cfg_set_rts(struct ucom_softc *, uint8_t); -static void uch341_cfg_set_break(struct ucom_softc *, uint8_t); -static int uch341_pre_param(struct ucom_softc *, struct termios *); -static void uch341_cfg_param(struct ucom_softc *, struct termios *); -static void uch341_cfg_get_status(struct ucom_softc *, uint8_t *, - uint8_t *); -static void uch341_start_read(struct ucom_softc *); -static void uch341_stop_read(struct ucom_softc *); -static void uch341_start_write(struct ucom_softc *); -static void uch341_stop_write(struct ucom_softc *); -static void uch341_poll(struct ucom_softc *ucom); - -static const struct usb_config uch341_config[UCH341_N_TRANSFER] = { - - [UCH341_BULK_DT_WR] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = UCH341_BUFSIZE, - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, - .callback = &uch341_write_callback, - }, - - [UCH341_BULK_DT_RD] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = UCH341_BUFSIZE, - .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, - .callback = &uch341_read_callback, - }, -}; - -static const struct ucom_callback uch341_callback = { - .ucom_cfg_get_status = &uch341_cfg_get_status, - .ucom_cfg_set_dtr = &uch341_cfg_set_dtr, - .ucom_cfg_set_rts = &uch341_cfg_set_rts, - .ucom_cfg_set_break = &uch341_cfg_set_break, - .ucom_cfg_param = &uch341_cfg_param, - .ucom_cfg_open = &uch341_cfg_open, - .ucom_pre_param = &uch341_pre_param, - .ucom_start_read = &uch341_start_read, - .ucom_stop_read = &uch341_stop_read, - .ucom_start_write = &uch341_start_write, - .ucom_stop_write = &uch341_stop_write, - .ucom_poll = &uch341_poll, -}; - -static device_method_t uch341_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, uch341_probe), - DEVMETHOD(device_attach, uch341_attach), - DEVMETHOD(device_detach, uch341_detach), - - {0, 0} -}; - -static devclass_t uch341_devclass; - -static driver_t uch341_driver = { - .name = "uch341", - .methods = uch341_methods, - .size = sizeof(struct uch341_softc), -}; - -DRIVER_MODULE(uch341, uhub, uch341_driver, uch341_devclass, NULL, 0); -MODULE_DEPEND(uch341, ucom, 1, 1, 1); -MODULE_DEPEND(uch341, usb, 1, 1, 1); - -static struct usb_device_id uch341_devs[] = { - {USB_VPI(0x4348, 0x5523, 0)}, - {USB_VPI(0x1a86, 0x7523, 0)}, -}; - -static int -uch341_probe(device_t dev) -{ - struct usb_attach_arg *uaa = device_get_ivars(dev); - - if (uaa->usb_mode != USB_MODE_HOST) { - return (ENXIO); - } - if (uaa->info.bConfigIndex != UCH341_CONFIG_INDEX) { - return (ENXIO); - } - /* attach to all present interfaces */ - - return (usbd_lookup_id_by_uaa(uch341_devs, sizeof(uch341_devs), uaa)); -} - -static int -uch341_attach(device_t dev) -{ - struct usb_attach_arg *uaa = device_get_ivars(dev); - struct uch341_softc *sc = device_get_softc(dev); - int error; - - sc->sc_udev = uaa->device; - sc->sc_dev = dev; - - device_set_usb_desc(dev); - mtx_init(&sc->sc_mtx, "uch341", NULL, MTX_DEF); - - snprintf(sc->sc_name, sizeof(sc->sc_name), - "%s", device_get_nameunit(dev)); - - DPRINTF("\n"); - - sc->sc_iface_index = uaa->info.bIfaceIndex; - - error = usbd_transfer_setup(uaa->device, - &sc->sc_iface_index, sc->sc_xfer, uch341_config, - UCH341_N_TRANSFER, sc, &sc->sc_mtx); - - if (error) { - device_printf(dev, "allocating USB " - "transfers failed!\n"); - goto detach; - } - - /* clear stall at first run */ - mtx_lock(&sc->sc_mtx); - usbd_xfer_set_stall(sc->sc_xfer[UCH341_BULK_DT_WR]); - usbd_xfer_set_stall(sc->sc_xfer[UCH341_BULK_DT_RD]); - mtx_unlock(&sc->sc_mtx); - - error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, - &uch341_callback, &sc->sc_mtx); - if (error) { - goto detach; - } - return (0); /* success */ - -detach: - uch341_detach(dev); - return (ENXIO); -} - -static int -uch341_detach(device_t dev) -{ - struct uch341_softc *sc = device_get_softc(dev); - - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); - usbd_transfer_unsetup(sc->sc_xfer, UCH341_N_TRANSFER); - mtx_destroy(&sc->sc_mtx); - - return (0); -} - -static void -uch341_cfg_open(struct ucom_softc *ucom) -{ -} - -static void -uch341_write_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct uch341_softc *sc = usbd_xfer_softc(xfer); - struct usb_page_cache *pc; - uint32_t actlen; - - switch (USB_GET_STATE(xfer)) { - case USB_ST_SETUP: - case USB_ST_TRANSFERRED: -tr_setup: - pc = usbd_xfer_get_frame(xfer, 0); - if (ucom_get_data(&sc->sc_ucom, pc, - 0, usbd_xfer_max_len(xfer), &actlen)) { - - usbd_xfer_set_frame_len(xfer, 0, actlen); - usbd_transfer_submit(xfer); - } - return; - - default: /* Error */ - if (error != USB_ERR_CANCELLED) { - /* try to clear stall first */ - usbd_xfer_set_stall(xfer); - goto tr_setup; - } - return; - } -} - -static void -uch341_read_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct uch341_softc *sc = usbd_xfer_softc(xfer); - struct usb_page_cache *pc; - int actlen; - - usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - - if (actlen > 0) { - pc = usbd_xfer_get_frame(xfer, 0); - ucom_put_data(&sc->sc_ucom, pc, 0, actlen); - } - case USB_ST_SETUP: -tr_setup: - usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); - usbd_transfer_submit(xfer); - return; - - default: /* Error */ - if (error != USB_ERR_CANCELLED) { - /* try to clear stall first */ - usbd_xfer_set_stall(xfer); - goto tr_setup; - } - return; - } -} - -static void -uch341_control_out(struct uch341_softc *sc, uint8_t bRequest, - uint16_t wValue, uint16_t wIndex) -{ - struct usb_device_request req; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = bRequest; - USETW(req.wValue, wValue); - USETW(req.wIndex, wIndex); - USETW(req.wLength, 0); - ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, - &req, NULL, 0, 1000); -} - -static void -uch341_control_in(struct uch341_softc *sc, uint8_t bRequest, - uint16_t wValue, uint16_t wIndex, void *buf, uint16_t wLength) -{ - struct usb_device_request req; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = bRequest; - USETW(req.wValue, wValue); - USETW(req.wIndex, wIndex); - USETW(req.wLength, wLength); - ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, - &req, buf, USB_SHORT_XFER_OK, 1000); -} - -static void -uch341_cfg_set_rts_dtr(struct uch341_softc *sc) -{ - uch341_control_out(sc, 0xa4, ~((sc->sc_dtr ? (1<<5) : 0) | - (sc->sc_rts? (1<<6) : 0)), 0); -} - -static void -uch341_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) -{ - struct uch341_softc *sc = ucom->sc_parent; - - sc->sc_dtr = onoff; - - uch341_cfg_set_rts_dtr(sc); -} - -static void -uch341_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) -{ - struct uch341_softc *sc = ucom->sc_parent; - - sc->sc_rts = onoff; - - uch341_cfg_set_rts_dtr(sc); -} - -static void -uch341_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff) -{ - /* TODO */ -} - -static int -uch341_pre_param(struct ucom_softc *ucom, struct termios *t) -{ - DPRINTF("\n"); - - switch (t->c_ospeed) { - case 2400: - case 4800: - case 9600: - case 19200: - case 38400: - case 115200: - return (0); - default: - return (EINVAL); - } -} - -static void -uch341_set_baudrate(struct uch341_softc *sc, uint32_t rate) -{ - uint16_t a; - uint16_t b; - - DPRINTF("Baud = %d\n", rate); - - switch (rate) { - case 2400: - a = 0xd901; - b = 0x0038; - break; - case 4800: - a = 0x6402; - b = 0x001f; - break; - case 9600: - a = 0xb202; - b = 0x0013; - break; - case 19200: - a = 0xd902; - b = 0x000d; - break; - case 38400: - a = 0x6403; - b = 0x000a; - break; - case 115200: - a = 0xcc03; - b = 0x0008; - break; - default: - /* should not happen */ - a = 0; - b = 0; - break; - } - - uch341_control_out(sc, 0x9a, 0x1312, a); - uch341_control_out(sc, 0x9a, 0x0f2c, b); -} - -static void -uch341_get_status(struct uch341_softc *sc) -{ - uint8_t buf[8]; - uch341_control_in(sc, 0x95, 0x0706, 0, buf, sizeof(buf)); -} - -static void -uch341_cfg_param(struct ucom_softc *ucom, struct termios *t) -{ - struct uch341_softc *sc = ucom->sc_parent; - - uint8_t buf[8]; - - DPRINTF("\n"); - - uch341_control_in(sc, 0x5f, 0, 0, buf, sizeof(buf)); - uch341_control_out(sc, 0xa1, 0, 0); - uch341_set_baudrate(sc, t->c_ospeed); - uch341_control_in(sc, 0x95, 0x2518, 0, buf, sizeof(buf)); - uch341_control_out(sc, 0x9a, 0x2518, 0x0050); - uch341_get_status(sc); - uch341_control_out(sc, 0xa1, 0x501f, 0xd90a); - uch341_set_baudrate(sc, t->c_ospeed); - uch341_cfg_set_rts_dtr(sc); - uch341_get_status(sc); -} - -static void -uch341_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) -{ - struct uch341_softc *sc = ucom->sc_parent; - - DPRINTF("msr=0x%02x lsr=0x%02x\n", - sc->sc_msr, sc->sc_lsr); - - *msr = sc->sc_msr; - *lsr = sc->sc_lsr; -} - -static void -uch341_start_read(struct ucom_softc *ucom) -{ - struct uch341_softc *sc = ucom->sc_parent; - - usbd_transfer_start(sc->sc_xfer[UCH341_BULK_DT_RD]); -} - -static void -uch341_stop_read(struct ucom_softc *ucom) -{ - struct uch341_softc *sc = ucom->sc_parent; - - usbd_transfer_stop(sc->sc_xfer[UCH341_BULK_DT_RD]); -} - -static void -uch341_start_write(struct ucom_softc *ucom) -{ - struct uch341_softc *sc = ucom->sc_parent; - - usbd_transfer_start(sc->sc_xfer[UCH341_BULK_DT_WR]); -} - -static void -uch341_stop_write(struct ucom_softc *ucom) -{ - struct uch341_softc *sc = ucom->sc_parent; - - usbd_transfer_stop(sc->sc_xfer[UCH341_BULK_DT_WR]); -} - -static void -uch341_poll(struct ucom_softc *ucom) -{ - struct uch341_softc *sc = ucom->sc_parent; - usbd_transfer_poll(sc->sc_xfer, UCH341_N_TRANSFER); -} diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile index 9d54c48882e..2555b83c65b 100644 --- a/sys/modules/usb/Makefile +++ b/sys/modules/usb/Makefile @@ -29,8 +29,8 @@ SUBDIR = usb SUBDIR += ehci musb ohci uhci uss820dci ${_at91dci} ${_atmegadci} SUBDIR += rum uath upgt ural zyd ${_urtw} SUBDIR += uhid ukbd ums udbp ufm -SUBDIR += ucom u3g uark ubsa ubser uch341 uchcom ucycom ufoma uftdi ugensa \ - uipaq ulpt umct umodem umoscom uplcom uslcom uvisor uvscom +SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \ + umct umodem umoscom uplcom uslcom uvisor uvscom SUBDIR += uether aue axe cdce cue kue rue udav SUBDIR += usfs umass urio SUBDIR += quirk template diff --git a/sys/modules/usb/uch341/Makefile b/sys/modules/usb/uch341/Makefile deleted file mode 100644 index 41ab36f5a70..00000000000 --- a/sys/modules/usb/uch341/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# $FreeBSD$ -# -# Copyright (c) 2009 Hans Petter Selasky. 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. -# - -S= ${.CURDIR}/../../.. - -.PATH: $S/dev/usb/serial - -KMOD= uch341 -SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \ - uch341.c - -.include From 11f35cfaa70b64d4865280103eabdc909d8119bc Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 19 Oct 2009 21:52:02 +0000 Subject: [PATCH 227/646] Add support for newer WinChipHead CH341 chips, previously in the uch341 driver. Submitted by: HPS --- sys/dev/usb/serial/uchcom.c | 168 ++++++++++++------------------------ sys/dev/usb/usbdevs | 6 +- 2 files changed, 58 insertions(+), 116 deletions(-) diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index 9ed63eb1810..9fea8492fca 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -66,7 +66,8 @@ __FBSDID("$FreeBSD$"); /* - * driver for WinChipHead CH341/340, the worst USB-serial chip in the world. + * Driver for WinChipHead CH341/340, the worst USB-serial chip in the + * world. */ #include @@ -206,6 +207,7 @@ static const struct uchcom_divider_record dividers[] = static const struct usb_device_id uchcom_devs[] = { {USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)}, + {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)}, }; /* protypes */ @@ -213,6 +215,7 @@ static const struct usb_device_id uchcom_devs[] = { static int uchcom_pre_param(struct ucom_softc *, struct termios *); static void uchcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); +static void uchcom_cfg_open(struct ucom_softc *ucom); static void uchcom_cfg_param(struct ucom_softc *, struct termios *); static void uchcom_cfg_set_break(struct ucom_softc *, uint8_t); static void uchcom_cfg_set_dtr(struct ucom_softc *, uint8_t); @@ -224,12 +227,9 @@ static void uchcom_stop_write(struct ucom_softc *); static void uchcom_update_version(struct uchcom_softc *); static void uchcom_convert_status(struct uchcom_softc *, uint8_t); static void uchcom_update_status(struct uchcom_softc *); -static void uchcom_set_dtrrts(struct uchcom_softc *); +static void uchcom_set_dtr_rts(struct uchcom_softc *); static int uchcom_calc_divider_settings(struct uchcom_divider *, uint32_t); -static void uchcom_set_dte_rate(struct uchcom_softc *, uint32_t); -static void uchcom_set_line_control(struct uchcom_softc *, tcflag_t); -static void uchcom_clear_chip(struct uchcom_softc *); -static void uchcom_reset_chip(struct uchcom_softc *); +static void uchcom_set_baudrate(struct uchcom_softc *, uint32_t); static void uchcom_poll(struct ucom_softc *ucom); static device_probe_t uchcom_probe; @@ -275,6 +275,7 @@ static struct ucom_callback uchcom_callback = { .ucom_cfg_set_dtr = &uchcom_cfg_set_dtr, .ucom_cfg_set_rts = &uchcom_cfg_set_rts, .ucom_cfg_set_break = &uchcom_cfg_set_break, + .ucom_cfg_open = &uchcom_cfg_open, .ucom_cfg_param = &uchcom_cfg_param, .ucom_pre_param = &uchcom_pre_param, .ucom_start_read = &uchcom_start_read, @@ -341,17 +342,6 @@ uchcom_attach(device_t dev) "error=%s\n", usbd_errstr(error)); goto detach; } - /* - * Do the initialization during attach so that the system does not - * sleep during open: - */ - uchcom_update_version(sc); - uchcom_clear_chip(sc); - uchcom_reset_chip(sc); - uchcom_update_status(sc); - - sc->sc_dtr = 1; - sc->sc_rts = 1; /* clear stall at first run */ mtx_lock(&sc->sc_mtx); @@ -458,8 +448,7 @@ uchcom_get_version(struct uchcom_softc *sc, uint8_t *rver) { uint8_t buf[UCHCOM_INPUT_BUF_SIZE]; - uchcom_ctrl_read( - sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf)); + uchcom_ctrl_read(sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf)); if (rver) *rver = buf[0]; @@ -472,13 +461,13 @@ uchcom_get_status(struct uchcom_softc *sc, uint8_t *rval) } static void -uchcom_set_dtrrts_10(struct uchcom_softc *sc, uint8_t val) +uchcom_set_dtr_rts_10(struct uchcom_softc *sc, uint8_t val) { uchcom_write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val); } static void -uchcom_set_dtrrts_20(struct uchcom_softc *sc, uint8_t val) +uchcom_set_dtr_rts_20(struct uchcom_softc *sc, uint8_t val) { uchcom_ctrl_write(sc, UCHCOM_REQ_SET_DTRRTS, val, 0); } @@ -515,7 +504,7 @@ uchcom_update_status(struct uchcom_softc *sc) static void -uchcom_set_dtrrts(struct uchcom_softc *sc) +uchcom_set_dtr_rts(struct uchcom_softc *sc) { uint8_t val = 0; @@ -525,9 +514,9 @@ uchcom_set_dtrrts(struct uchcom_softc *sc) val |= UCHCOM_RTS_MASK; if (sc->sc_version < UCHCOM_VER_20) - uchcom_set_dtrrts_10(sc, ~val); + uchcom_set_dtr_rts_10(sc, ~val); else - uchcom_set_dtrrts_20(sc, ~val); + uchcom_set_dtr_rts_20(sc, ~val); } static void @@ -583,16 +572,16 @@ found: dp->dv_div = (uint8_t)-div; } - mod = UCHCOM_BPS_MOD_BASE / rate + UCHCOM_BPS_MOD_BASE_OFS; - mod = mod + mod / 2; + mod = (UCHCOM_BPS_MOD_BASE / rate) + UCHCOM_BPS_MOD_BASE_OFS; + mod = mod + (mod / 2); - dp->dv_mod = mod / 0x100; + dp->dv_mod = (mod + 0xFF) / 0x100; return (0); } static void -uchcom_set_dte_rate(struct uchcom_softc *sc, uint32_t rate) +uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate) { struct uchcom_divider dv; @@ -607,76 +596,6 @@ uchcom_set_dte_rate(struct uchcom_softc *sc, uint32_t rate) UCHCOM_REG_BPS_PAD, 0); } -static void -uchcom_set_line_control(struct uchcom_softc *sc, tcflag_t cflag) -{ - uint8_t lcr1 = 0; - uint8_t lcr2 = 0; - - uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2); - - lcr1 &= ~UCHCOM_LCR1_MASK; - lcr2 &= ~UCHCOM_LCR2_MASK; - - /* - * XXX: it is difficult to handle the line control appropriately: - * - CS8, !CSTOPB and any parity mode seems ok, but - * - the chip doesn't have the function to calculate parity - * in !CS8 mode. - * - it is unclear that the chip supports CS5,6 mode. - * - it is unclear how to handle stop bits. - */ - - if (cflag & PARENB) { - lcr1 |= UCHCOM_LCR1_PARENB; - if (cflag & PARODD) - lcr2 |= UCHCOM_LCR2_PARODD; - else - lcr2 |= UCHCOM_LCR2_PAREVEN; - } - uchcom_write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2); -} - -static void -uchcom_clear_chip(struct uchcom_softc *sc) -{ - DPRINTF("\n"); - uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0); -} - -static void -uchcom_reset_chip(struct uchcom_softc *sc) -{ - uint16_t val; - uint16_t idx; - uint8_t lcr1; - uint8_t lcr2; - uint8_t pre; - uint8_t div; - uint8_t mod; - - uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2); - uchcom_read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div); - uchcom_read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL); - - val = 0; - idx = 0; - val |= (uint16_t)(lcr1 & 0xF0) << 8; - val |= 0x01; - val |= (uint16_t)(lcr2 & 0x0F) << 8; - val |= 0x02; - idx |= pre & 0x07; - val |= 0x04; - idx |= (uint16_t)div << 8; - val |= 0x08; - idx |= mod & 0xF8; - val |= 0x10; - - DPRINTF("reset v=0x%04X, i=0x%04X\n", val, idx); - - uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, val, idx); -} - /* ---------------------------------------------------------------------- * methods for ucom */ @@ -699,7 +618,7 @@ uchcom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) DPRINTF("onoff = %d\n", onoff); sc->sc_dtr = onoff; - uchcom_set_dtrrts(sc); + uchcom_set_dtr_rts(sc); } static void @@ -710,7 +629,18 @@ uchcom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) DPRINTF("onoff = %d\n", onoff); sc->sc_rts = onoff; - uchcom_set_dtrrts(sc); + uchcom_set_dtr_rts(sc); +} + +static void +uchcom_cfg_open(struct ucom_softc *ucom) +{ + struct uchcom_softc *sc = ucom->sc_parent; + + DPRINTF("\n"); + + uchcom_update_version(sc); + uchcom_update_status(sc); } static int @@ -719,12 +649,10 @@ uchcom_pre_param(struct ucom_softc *ucom, struct termios *t) struct uchcom_divider dv; switch (t->c_cflag & CSIZE) { - case CS5: - case CS6: - case CS7: - return (EIO); - default: + case CS8: break; + default: + return (EIO); } if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) { @@ -738,8 +666,16 @@ uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t) { struct uchcom_softc *sc = ucom->sc_parent; - uchcom_set_line_control(sc, t->c_cflag); - uchcom_set_dte_rate(sc, t->c_ospeed); + uchcom_get_version(sc, 0); + uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0); + uchcom_set_baudrate(sc, t->c_ospeed); + uchcom_read_reg(sc, 0x18, 0, 0x25, 0); + uchcom_write_reg(sc, 0x18, 0x50, 0x25, 0x00); + uchcom_update_status(sc); + uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a); + uchcom_set_baudrate(sc, t->c_ospeed); + uchcom_set_dtr_rts(sc); + uchcom_update_status(sc); } static void @@ -840,14 +776,14 @@ uchcom_write_callback(struct usb_xfer *xfer, usb_error_t error) tr_setup: pc = usbd_xfer_get_frame(xfer, 0); if (ucom_get_data(&sc->sc_ucom, pc, 0, - UCHCOM_BULK_BUF_SIZE, &actlen)) { + usbd_xfer_max_len(xfer), &actlen)) { DPRINTF("actlen = %d\n", actlen); usbd_xfer_set_frame_len(xfer, 0, actlen); usbd_transfer_submit(xfer); } - return; + break; default: /* Error */ if (error != USB_ERR_CANCELLED) { @@ -855,8 +791,7 @@ tr_setup: usbd_xfer_set_stall(xfer); goto tr_setup; } - return; - + break; } } @@ -871,14 +806,17 @@ uchcom_read_callback(struct usb_xfer *xfer, usb_error_t error) switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - pc = usbd_xfer_get_frame(xfer, 0); - ucom_put_data(&sc->sc_ucom, pc, 0, actlen); + + if (actlen > 0) { + pc = usbd_xfer_get_frame(xfer, 0); + ucom_put_data(&sc->sc_ucom, pc, 0, actlen); + } case USB_ST_SETUP: tr_setup: usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); usbd_transfer_submit(xfer); - return; + break; default: /* Error */ if (error != USB_ERR_CANCELLED) { @@ -886,7 +824,7 @@ tr_setup: usbd_xfer_set_stall(xfer); goto tr_setup; } - return; + break; } } diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 4662107869b..9281462036d 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -626,6 +626,7 @@ vendor AMIT 0x18c5 AMIT vendor QCOM 0x18e8 Qcom vendor LINKSYS3 0x1915 Linksys vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated +vendor WCH2 0x1a86 QinHeng Electronics vendor STELERA 0x1a8d Stelera Wireless vendor MPMAN 0x1cae MpMan vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik @@ -2516,8 +2517,11 @@ product WACOM GRAPHIRE 0x0010 Graphire product WACOM GRAPHIRE3_4X5 0x0013 Graphire 3 4x5 product WACOM INTUOSA5 0x0021 Intuos A5 product WACOM GD0912U 0x0022 Intuos 9x12 Graphics Tablet -/* WCH products*/ + +/* WCH products */ product WCH CH341SER 0x5523 CH341/CH340 USB-Serial Bridge +product WCH2 CH341SER 0x7523 CH341/CH340 USB-Serial Bridge + /* Western Digital products */ product WESTERN COMBO 0x0200 Firewire USB Combo product WESTERN EXTHDD 0x0400 External HDD From c3514114c6d669804287cc9edda959207ad19eb3 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 19 Oct 2009 21:54:41 +0000 Subject: [PATCH 228/646] Add opt_gdb.h which is now needed by ucom. --- sys/modules/usb/ucom/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/usb/ucom/Makefile b/sys/modules/usb/ucom/Makefile index bda903c94b1..b7836a83aab 100644 --- a/sys/modules/usb/ucom/Makefile +++ b/sys/modules/usb/ucom/Makefile @@ -30,7 +30,7 @@ S= ${.CURDIR}/../../.. .PATH: $S/dev/usb/serial KMOD= ucom -SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \ +SRCS= opt_bus.h opt_usb.h opt_gdb.h device_if.h bus_if.h usb_if.h usbdevs.h \ usb_serial.c .include From 494d4d251b0ae699839bcbbc936adc1ad4fdf464 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 19 Oct 2009 23:09:39 +0000 Subject: [PATCH 229/646] Remove a redundant option ROM check, which was never meant to be committed. --- sys/dev/dpms/dpms.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/dev/dpms/dpms.c b/sys/dev/dpms/dpms.c index 58e2f377bc7..7e097c51f2f 100644 --- a/sys/dev/dpms/dpms.c +++ b/sys/dev/dpms/dpms.c @@ -129,9 +129,8 @@ dpms_identify(driver_t *driver, device_t parent) if (devclass_get_device(dpms_devclass, 0) != NULL) return; - if ((x86bios_match_device(0xc0000, parent) && - device_get_flags(parent) != 0) || - x86bios_get_orm(0xc0000) != NULL) + if (x86bios_match_device(0xc0000, parent) && + device_get_flags(parent) != 0) device_add_child(parent, "dpms", 0); } From d5e9eabeadd20b3c8de6d37c2a96d33553c8ab4f Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 19 Oct 2009 23:11:43 +0000 Subject: [PATCH 230/646] Fix a bug in composing PERR frames introduced by latest draft update. MFC after: 3 days --- sys/net80211/ieee80211_hwmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c index 3481c3e7e94..32ca163745c 100644 --- a/sys/net80211/ieee80211_hwmp.c +++ b/sys/net80211/ieee80211_hwmp.c @@ -548,7 +548,7 @@ hwmp_add_meshperr(uint8_t *frm, const struct ieee80211_meshperr_ie *perr) *frm++ = perr->perr_ttl; *frm++ = perr->perr_ndests; for (i = 0; i < perr->perr_ndests; i++) { - *frm += perr->perr_dests[i].dest_flags; + *frm++ = perr->perr_dests[i].dest_flags; IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr); frm += 6; ADDWORD(frm, perr->perr_dests[i].dest_seq); @@ -1114,6 +1114,7 @@ hwmp_peerdown(struct ieee80211_node *ni) "%s", "delete route entry"); perr.perr_ttl = ms->ms_ttl; perr.perr_ndests = 1; + PERR_DFLAGS(0) = 0; if (hr->hr_seq == 0) PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN; PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC; From 363b8ed74f8e07accef6a28fc4f05db661f29a24 Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Tue, 20 Oct 2009 02:35:12 +0000 Subject: [PATCH 231/646] Use callout_init_mtx on FreeBSD versions recent enough. This closes the race where interrupt thread can complete the request for which timeout has fired and while mpt_timeout has blocked on mpt_lock. Do a best effort to keep 4.x ang Giant-locked configurartions compiling still. Reported by: ups Reviewed by: scottl --- sys/dev/mpt/mpt.c | 10 +++++++++- sys/dev/mpt/mpt.h | 35 ++++++++++++++++++----------------- sys/dev/mpt/mpt_cam.c | 5 +++++ sys/dev/mpt/mpt_raid.c | 11 ++++++++--- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 1b44333bfb3..6a74dc3c54d 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -1238,7 +1238,6 @@ retry: req->state = REQ_STATE_ALLOCATED; req->chain = NULL; mpt_assign_serno(mpt, req); - mpt_callout_init(&req->callout); } else if (sleep_ok != 0) { mpt->getreqwaiter = 1; mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0); @@ -2251,6 +2250,7 @@ mpt_core_attach(struct mpt_softc *mpt) for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { request_t *req = &mpt->request_pool[val]; req->state = REQ_STATE_ALLOCATED; + mpt_callout_init(mpt, &req->callout); mpt_free_request(mpt, req); } MPT_UNLOCK(mpt); @@ -2334,10 +2334,18 @@ mpt_core_shutdown(struct mpt_softc *mpt) void mpt_core_detach(struct mpt_softc *mpt) { + int val; + /* * XXX: FREE MEMORY */ mpt_disable_ints(mpt); + + /* Make sure no request has pending timeouts. */ + for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { + request_t *req = &mpt->request_pool[val]; + mpt_callout_drain(mpt, &req->callout); + } } int diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h index 0a093efabd1..1fa2d1aaded 100644 --- a/sys/dev/mpt/mpt.h +++ b/sys/dev/mpt/mpt.h @@ -296,13 +296,6 @@ void mpt_map_rquest(void *, bus_dma_segment_t *, int, int); kthread_exit(status) #endif -/****************************** Timer Facilities ******************************/ -#if __FreeBSD_version > 500000 -#define mpt_callout_init(c) callout_init(c, /*mpsafe*/1); -#else -#define mpt_callout_init(c) callout_init(c); -#endif - /********************************** Endianess *********************************/ #define MPT_2_HOST64(ptr, tag) ptr->tag = le64toh(ptr->tag) #define MPT_2_HOST32(ptr, tag) ptr->tag = le32toh(ptr->tag) @@ -889,6 +882,10 @@ mpt_sleep(struct mpt_softc *mpt, void *ident, int priority, callout_reset(&(req)->callout, (ticks), (func), (arg)); #define mpt_req_untimeout(req, func, arg) \ callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init(c) +#define mpt_callout_drain(mpt, c) \ + callout_stop(c) #else #if 1 @@ -911,9 +908,13 @@ mpt_sleep(struct mpt_softc *mpt, void *ident, int priority, #define mpt_sleep(mpt, ident, priority, wmesg, timo) \ msleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo) #define mpt_req_timeout(req, ticks, func, arg) \ - callout_reset(&(req)->callout, (ticks), (func), (arg)); + callout_reset(&(req)->callout, (ticks), (func), (arg)) #define mpt_req_untimeout(req, func, arg) \ callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init_mtx(c, &(mpt)->mpt_lock, 0) +#define mpt_callout_drain(mpt, c) \ + callout_drain(c) #else @@ -926,18 +927,18 @@ mpt_sleep(struct mpt_softc *mpt, void *ident, int priority, #define MPTLOCK_2_CAMLOCK(mpt) #define CAMLOCK_2_MPTLOCK(mpt) +#define mpt_req_timeout(req, ticks, func, arg) \ + callout_reset(&(req)->callout, (ticks), (func), (arg)) +#define mpt_req_untimeout(req, func, arg) \ + callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init(c, 0) +#define mpt_callout_drain(mpt, c) \ + callout_drain(c) + static __inline int mpt_sleep(struct mpt_softc *, void *, int, const char *, int); -#define mpt_ccb_timeout(ccb, ticks, func, arg) \ - do { \ - (ccb)->ccb_h.timeout_ch = timeout((func), (arg), (ticks)); \ - } while (0) -#define mpt_ccb_untimeout(ccb, func, arg) \ - untimeout((func), (arg), (ccb)->ccb_h.timeout_ch) -#define mpt_ccb_timeout_init(ccb) \ - callout_handle_init(&(ccb)->ccb_h.timeout_ch) - static __inline int mpt_sleep(struct mpt_softc *mpt, void *i, int p, const char *w, int t) { diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index cd3048de664..6e1dfa440d1 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -1245,7 +1245,10 @@ mpt_timeout(void *arg) ccb = (union ccb *)arg; mpt = ccb->ccb_h.ccb_mpt_ptr; +#if __FreeBSD_version < 500000 MPT_LOCK(mpt); +#endif + MPT_LOCK_ASSERT(mpt); req = ccb->ccb_h.ccb_req_ptr; mpt_prt(mpt, "request %p:%u timed out for ccb %p (req->ccb %p)\n", req, req->serno, ccb, req->ccb); @@ -1256,7 +1259,9 @@ mpt_timeout(void *arg) req->state |= REQ_STATE_TIMEDOUT; mpt_wakeup_recovery_thread(mpt); } +#if __FreeBSD_version < 500000 MPT_UNLOCK(mpt); +#endif } /* diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index 6b7eb7b46c4..5185ec0d796 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -271,7 +271,7 @@ mpt_raid_attach(struct mpt_softc *mpt) mpt_handler_t handler; int error; - mpt_callout_init(&mpt->raid_timer); + mpt_callout_init(mpt, &mpt->raid_timer); error = mpt_spawn_raid_thread(mpt); if (error != 0) { @@ -320,10 +320,10 @@ mpt_raid_detach(struct mpt_softc *mpt) struct ccb_setasync csa; mpt_handler_t handler; - callout_stop(&mpt->raid_timer); + mpt_callout_drain(mpt, &mpt->raid_timer); + MPT_LOCK(mpt); mpt_terminate_raid_thread(mpt); - handler.reply_handler = mpt_raid_reply_handler; mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler, raid_handler_id); @@ -1570,9 +1570,14 @@ mpt_raid_timer(void *arg) struct mpt_softc *mpt; mpt = (struct mpt_softc *)arg; +#if __FreeBSD_version < 500000 MPT_LOCK(mpt); +#endif + MPT_LOCK_ASSERT(mpt); mpt_raid_wakeup(mpt); +#if __FreeBSD_version < 500000 MPT_UNLOCK(mpt); +#endif } void From ada5f18a1b161e4fd99966444f85ca51d5a3fd8a Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Tue, 20 Oct 2009 06:54:31 +0000 Subject: [PATCH 232/646] Instead of having to know which timezone was picked last time, you now can run "tzsetup -r" which will reinstall the last choice. This data is recorded in /var/db/zoneinfo. MFC after: 1 week --- usr.sbin/tzsetup/tzsetup.8 | 7 ++- usr.sbin/tzsetup/tzsetup.c | 89 +++++++++++++++++++++++++++++++------- 2 files changed, 80 insertions(+), 16 deletions(-) diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8 index 66afdd478e4..48ca8e83d1a 100644 --- a/usr.sbin/tzsetup/tzsetup.8 +++ b/usr.sbin/tzsetup/tzsetup.8 @@ -31,7 +31,7 @@ .Nd set local timezone .Sh SYNOPSIS .Nm -.Op Fl ns +.Op Fl nrs .Op Ar zoneinfo file .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 r +Reinstall the zoneinfo file installed last time. The name is obtained from +.Pa /var/db/zoneinfo . .It Fl s Skip the initial question about adjusting the clock if not set to .Tn UTC . @@ -106,6 +109,8 @@ mapping of directory for zoneinfo files .It Pa /usr/share/zoneinfo/zone.tab mapping of timezone file to country and location +.It Pa /var/db/zoneinfo +saved name of the timezone file installed last. .El .Sh SEE ALSO .Xr date 1 , diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index e00e3bddc43..b9ca8faa447 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -52,9 +53,11 @@ __FBSDID("$FreeBSD$"); #define _PATH_ISO3166 "/usr/share/misc/iso3166" #define _PATH_ZONEINFO "/usr/share/zoneinfo" #define _PATH_LOCALTIME "/etc/localtime" +#define _PATH_DB "/var/db/zoneinfo" #define _PATH_WALL_CMOS_CLOCK "/etc/wall_cmos_clock" static int reallydoit = 1; +static int reinstall = 0; static void usage(void); static int continent_country_menu(dialogMenuItem *); @@ -495,13 +498,14 @@ set_zone_menu(dialogMenuItem *dmi) } static int -install_zone_file(const char *filename) +install_zone_file(const char *filename, int usedialog) { char buf[1024]; char title[64], prompt[64]; struct stat sb; ssize_t len; int fd1, fd2, copymode; + FILE *f; if (lstat(_PATH_LOCALTIME, &sb) < 0) { /* Nothing there yet... */ @@ -519,7 +523,10 @@ install_zone_file(const char *filename) snprintf(prompt, sizeof(prompt), "Creating symbolic link " _PATH_LOCALTIME " to %s", filename); - dialog_notify(prompt); + if (usedialog) + dialog_notify(prompt); + else + fprintf(stderr, "%s\n", prompt); #endif if (reallydoit) { @@ -530,7 +537,10 @@ install_zone_file(const char *filename) snprintf(prompt, sizeof(prompt), "Could not open %s: %s", filename, strerror(errno)); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); return (DITEM_FAILURE | DITEM_RECREATE); } @@ -542,7 +552,10 @@ install_zone_file(const char *filename) snprintf(prompt, sizeof(prompt), "Could not open " _PATH_LOCALTIME ": %s", strerror(errno)); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); return (DITEM_FAILURE | DITEM_RECREATE); } @@ -554,7 +567,10 @@ install_zone_file(const char *filename) snprintf(prompt, sizeof(prompt), "Error copying %s to " _PATH_LOCALTIME ": %s", filename, strerror(errno)); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); /* Better to leave none than a corrupt one. */ unlink(_PATH_LOCALTIME); return (DITEM_FAILURE | DITEM_RECREATE); @@ -567,7 +583,10 @@ install_zone_file(const char *filename) snprintf(prompt, sizeof(prompt), "Cannot access %s: %s", filename, strerror(errno)); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); return (DITEM_FAILURE | DITEM_RECREATE); } unlink(_PATH_LOCALTIME); @@ -577,7 +596,10 @@ install_zone_file(const char *filename) "Cannot create symbolic link " _PATH_LOCALTIME " to %s: %s", filename, strerror(errno)); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); return (DITEM_FAILURE | DITEM_RECREATE); } } @@ -592,8 +614,18 @@ install_zone_file(const char *filename) else snprintf(prompt, sizeof(prompt), "Created symbolic link from " _PATH_LOCALTIME " to %s", filename); - dialog_mesgbox(title, prompt, 8, 72); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); #endif + + /* Save knowledge for later */ + if ((f = fopen(_PATH_DB, "w")) != NULL) { + fprintf(f, "%s\n", filename + strlen(_PATH_ZONEINFO) + 1); + fclose(f); + } + return (DITEM_LEAVE_MENU); } @@ -627,7 +659,7 @@ set_zone_multi(dialogMenuItem *dmi) return (DITEM_FAILURE | DITEM_RECREATE); asprintf(&fn, "%s/%s", _PATH_ZONEINFO, zp->filename); - rv = install_zone_file(fn); + rv = install_zone_file(fn, 1); free(fn); return (rv); } @@ -643,7 +675,7 @@ set_zone_whole_country(dialogMenuItem *dmi) return (DITEM_FAILURE | DITEM_RECREATE); asprintf(&fn, "%s/%s", _PATH_ZONEINFO, cp->filename); - rv = install_zone_file(fn); + rv = install_zone_file(fn, 1); free(fn); return (rv); } @@ -652,7 +684,7 @@ static void usage(void) { - fprintf(stderr, "usage: tzsetup [-ns]\n"); + fprintf(stderr, "usage: tzsetup [-nrs] [zoneinfo file]\n"); exit(1); } @@ -666,14 +698,17 @@ int main(int argc, char **argv) { char title[64], prompt[128]; - int c, fd, skiputc; + int c, fd, rv, skiputc; skiputc = 0; - while ((c = getopt(argc, argv, "ns")) != -1) { + while ((c = getopt(argc, argv, "nrs")) != -1) { switch(c) { case 'n': reallydoit = 0; break; + case 'r': + reinstall = 1; + break; case 's': skiputc = 1; break; @@ -693,6 +728,30 @@ main(int argc, char **argv) sort_countries(); make_menus(); + if (reinstall == 1) { + FILE *f; + char zonefile[MAXPATHLEN]; + + sprintf(zonefile, "%s/", _PATH_ZONEINFO); + if ((f = fopen(_PATH_DB, "r")) != NULL) { + if (fgets(zonefile + strlen(zonefile), + sizeof(zonefile) - strlen(zonefile), f) != NULL) { + zonefile[sizeof(zonefile) - 1] = 0; + if (strlen(zonefile) > 0) { + zonefile[strlen(zonefile) - 1] = 0; + rv = install_zone_file(zonefile, 0); + exit(rv & ~DITEM_LEAVE_MENU); + } + errx(1, "Error reading %s.\n", _PATH_DB); + } + fclose(f); + errx(1, + "Unable to determine earlier installed zoneinfo " + "file. Check %s", _PATH_DB); + } + errx(1, "Cannot open %s for reading. Does it exist?", _PATH_DB); + } + init_dialog(); if (skiputc == 0) { snprintf(title, sizeof(title), @@ -724,10 +783,10 @@ main(int argc, char **argv) snprintf(prompt, sizeof(prompt), "\nUse the default `%s' zone?", argv[optind]); if (!dialog_yesno(title, prompt, 7, 72)) { - install_zone_file(argv[optind]); + rv = install_zone_file(argv[optind], 1); dialog_clear(); end_dialog(); - return (0); + exit(rv & ~DITEM_LEAVE_MENU); } dialog_clear_norefresh(); } From fb32226b3dc73fd5a503494d3babdddd178dc37e Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Tue, 20 Oct 2009 07:00:00 +0000 Subject: [PATCH 233/646] Vendor import of tzdata2009o: - Somoa has not moved to DST this year (comment only) - Bangladesh stays on DST for now. - Pakistan went back to standard time in 1 October 2009 Obtained from: ftp://elsie.nci.nih.gov/pub/ --- asia | 81 ++++++++++++++++++++++++++++++++++++++++++++++------- australasia | 32 ++++++++++++++++++++- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/asia b/asia index fdd355142f9..7f063cb4bff 100644 --- a/asia +++ b/asia @@ -1,5 +1,5 @@ #
-# @(#)asia	8.41
+# @(#)asia	8.42
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -172,11 +172,30 @@ Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
 #
 # No DST end date has been announced yet.
 
-# From Arthur David Olson (2009-07-11):
-# Arbitrarily end DST at the end of 2009 so that a POSIX-sytle time zone string
-# can appear in the Dhaka binary file and for the benefit of old glibc
-# reimplementations of the time zone software that mishandle permanent DST.
-# A change will be required once the end date is known.
+# From Alexander Krivenyshev (2009-09-25):
+# Bangladesh won't go back to Standard Time from October 1, 2009, 
+# instead it will continue DST measure till the cabinet makes a fresh decision. 
+#
+# Following report by same newspaper-"The Daily Star Friday":
+# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
+# 
+# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
+# 
+
+# From Steffen Thorsen (2009-10-13):
+# IANS (Indo-Asian News Service) now reports:
+# Bangladesh has decided that the clock advanced by an hour to make 
+# maximum use of daylight hours as an energy saving measure would 
+# "continue for an indefinite period."
+#
+# One of many places where it is published:
+# 
+# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
+# 
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dhaka	6:01:40 -	LMT	1890
@@ -186,8 +205,7 @@ Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			6:30	-	BURT	1951 Sep 30
 			6:00	-	DACT	1971 Mar 26 # Dacca Time
 			6:00	-	BDT	2009 Jun 19 23:00 # Bangladesh Time
-			6:00	1:00	BDST	2010
-			6:00	-	BDT
+			6:00	1:00	BDST
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1684,13 +1702,56 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
 # http://www.thenews.com.pk/updates.asp?id=87168
 # 
 
+# From Alexander Krivenyshev (2009-09-28):
+# According to Associated Press Of Pakistan, it is confirmed that
+# Pakistan clocks across the country would be turned back by an hour from October
+# 1, 2009.
+#
+# "Clocks to go back one hour from 1 Oct"
+# 
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
+# 
+
+# From Steffen Thorsen (2009-09-29):
+# Alexander Krivenyshev wrote:
+# > According to Associated Press Of Pakistan, it is confirmed that
+# > Pakistan clocks across the country would be turned back by an hour from October
+# > 1, 2009.
+#
+# Now they seem to have changed their mind, November 1 is the new date:
+# 
+# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
+# 
+# "The country's clocks will be reversed by one hour on November 1.
+# Officials of Federal Ministry for Interior told this to Geo News on
+# Monday."
+#
+# And more importantly, it seems that these dates will be kept every year:
+# "It has now been decided that clocks will be wound forward by one hour
+# on April 15 and reversed by an hour on November 1 every year without
+# obtaining prior approval, the officials added."
+#
+# We have confirmed this year's end date with both with the Ministry of
+# Water and Power and the Pakistan Electric Power Company:
+# 
+# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
+# 
+
+# From Christoph Goehre (2009-10-01):
+# [T]he German Consulate General in Karachi reported me today that Pakistan
+# will go back to standard time on 1st of November.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
 Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	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	-	Oct	1	0:00	0	-
+Rule Pakistan	2009	max	-	Apr	15	0:00	1:00	S
+Rule Pakistan	2009	max	-	Nov	1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep
diff --git a/australasia b/australasia
index 86fac13d98e..a5a4331dc84 100644
--- a/australasia
+++ b/australasia
@@ -1,5 +1,5 @@
 # 
-# @(#)australasia	8.13
+# @(#)australasia	8.14
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -457,6 +457,36 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
 # http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
 # 
 
+# From Alexander Krivenyshev (2009-10-03):
+# First, my deepest condolences to people of Samoa islands and all families and
+# loved ones around the world who lost their lives in the earthquake and tsunami.
+#
+# Considering the recent devastation on Samoa by earthquake and tsunami and that
+# many government offices/ ministers are closed- not sure if "Daylight Saving
+# Bill 2009" will be implemented in next few days- on October 4, 2009.
+#
+# Here is reply from Consulate-General of Samoa in New Zealand
+# ---------------------------
+# Consul General
+# consulgeneral@samoaconsulate.org.nz
+#
+# Talofa Alexander,
+#
+# Thank you for your sympathy for our country but at this time we have not
+# been informed about the Daylight Savings Time Change.  Most Ministries in
+# Apia are closed or relocating due to weather concerns.
+#
+# When we do find out if they are still proceeding with the time change we
+# will advise you soonest.
+#
+# Kind Regards,
+# Lana
+# for: Consul General
+
+# From Steffen Thorsen (2009-10-05):
+# We have called a hotel in Samoa and asked about local time there - they 
+# are still on standard time.
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time

From df0151b780c0db7dc80448e68c0093c6c05a6c1e Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Tue, 20 Oct 2009 09:31:57 +0000
Subject: [PATCH 234/646] add amdtemp to i386 NOTES

essentially this is a MFamd64

Nod from:	rpaulo
---
 sys/i386/conf/NOTES | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index d85e3f6abc7..ead43eca200 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -792,8 +792,10 @@ device		ichwd
 # Temperature sensors:
 #
 # coretemp: on-die sensor on Intel Core and newer CPUs
+# amdtemp: on-die sensor on AMD K8/K10/K11 CPUs
 #
 device		coretemp
+device		amdtemp
 
 #
 # CPU control pseudo-device. Provides access to MSRs, CPUID info and

From cc48afe4e03f69219e2c168aeb9d47760511032d Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Tue, 20 Oct 2009 09:32:22 +0000
Subject: [PATCH 235/646] ichwd.4: remove a stray line

Nod from:	des
MFC after:	3 days
---
 share/man/man4/ichwd.4 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/share/man/man4/ichwd.4 b/share/man/man4/ichwd.4
index f9998dcddfc..38e2865f842 100644
--- a/share/man/man4/ichwd.4
+++ b/share/man/man4/ichwd.4
@@ -66,7 +66,6 @@ it believes the WDT is disabled.
 .Sh SEE ALSO
 .Xr watchdog 4 ,
 .Xr watchdog 8 ,
-.Xr watchdogd 8,
 .Xr watchdog 9
 .Rs
 .%T Using the Intel ICH Family Watchdog Timer (WDT)

From b352b7ccb93dc46009cc6864d75d94b8a6458802 Mon Sep 17 00:00:00 2001
From: Max Khon 
Date: Tue, 20 Oct 2009 11:54:06 +0000
Subject: [PATCH 236/646] Allow KMOD with hypens and dots.

MFC after:	1 week
---
 sys/tools/fw_stub.awk | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/sys/tools/fw_stub.awk b/sys/tools/fw_stub.awk
index ddcca017f42..5f6fe452148 100644
--- a/sys/tools/fw_stub.awk
+++ b/sys/tools/fw_stub.awk
@@ -118,6 +118,8 @@ if (!num_files || !opt_m)
 
 cfilename = opt_c;
 ctmpfilename = cfilename ".tmp";
+modname = opt_m;
+gsub(/[-\.]/, "_", modname);
 
 printc("#include \
 #include \
@@ -139,7 +141,7 @@ for (file_i = 0; file_i < num_files; file_i++) {
 }
 
 printc("\nstatic int\n"\
-opt_m "_fw_modevent(module_t mod, int type, void *unused)\
+modname "_fw_modevent(module_t mod, int type, void *unused)\
 {\
 	const struct firmware *fp, *parent;\
 	int error;\
@@ -206,14 +208,14 @@ printc("\t\treturn (error);\
 	return (EINVAL);\
 }\
 \
-static moduledata_t " opt_m "_fw_mod = {\
-        \"" opt_m "_fw\",\
-        " opt_m "_fw_modevent,\
+static moduledata_t " modname "_fw_mod = {\
+        \"" modname "_fw\",\
+        " modname "_fw_modevent,\
         0\
 };\
-DECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
-MODULE_VERSION(" opt_m "_fw, 1);\
-MODULE_DEPEND(" opt_m "_fw, firmware, 1, 1, 1);\
+DECLARE_MODULE(" modname "_fw, " modname "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
+MODULE_VERSION(" modname "_fw, 1);\
+MODULE_DEPEND(" modname "_fw, firmware, 1, 1, 1);\
 ");
 
 if (opt_c)

From 2b201a176744da1774f03019c1353c76f36650d1 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Tue, 20 Oct 2009 13:22:54 +0000
Subject: [PATCH 237/646] minor: fix sorting of some amd* entries in some
 makefiles

MFC after:	1 week
---
 share/man/man4/Makefile | 2 +-
 sys/modules/Makefile    | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 74d0c3d8b1d..defdf3ab276 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -30,8 +30,8 @@ MAN=	aac.4 \
 	ale.4 \
 	altq.4 \
 	amd.4 \
-	${_amdtemp.4} \
 	${_amdsmb.4} \
+	${_amdtemp.4} \
 	amr.4 \
 	an.4 \
 	arcmsr.4 \
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 88d02997814..9606a524472 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -18,10 +18,10 @@ SUBDIR=	${_3dfx} \
 	${_aic} \
 	aic7xxx \
 	aio \
-	${_amd} \
-	${_amdtemp} \
 	alc \
 	ale \
+	${_amd} \
+	${_amdtemp} \
 	amr \
 	${_an} \
 	${_aout} \

From b34c18a7dc84aeb7fcc4f542d67175f74abff8f2 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Tue, 20 Oct 2009 13:58:30 +0000
Subject: [PATCH 238/646] Update package list for 8.0-REL.

Reviewed by:	re@, portmgr@
MFC after:	1 day
---
 release/scripts/package-split.py | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/release/scripts/package-split.py b/release/scripts/package-split.py
index 6d895297c16..727262b0538 100644
--- a/release/scripts/package-split.py
+++ b/release/scripts/package-split.py
@@ -51,50 +51,53 @@ def disc1_packages():
 	    'misc/freebsd-doc-zh_tw']
 
     if doing_dvd:
-	pkgs.extend(['lang/perl5.8',
-	    'x11/xorg',
-	    'devel/imake',
-	    'emulators/linux_base-fc4',
-	    'x11/gnome2',
-	    'x11/kde4',
-	    'x11-wm/afterstep',
-	    'x11-wm/windowmaker',
-	    'x11-wm/fvwm2',
-	    'archivers/unzip',
+	pkgs.extend(['archivers/unzip',
 	    'astro/xearth',
 	    'devel/gmake',
+	    'devel/imake',
 	    'editors/emacs',
 	    'editors/vim-lite',
+	    'emulators/linux_base-f10',
 	    'emulators/mtools',
 	    'graphics/png',
 	    'graphics/xv',
 	    'irc/xchat',
+	    'lang/perl5.8',
+	    'mail/alpine',
 	    'mail/exim',
 	    'mail/fetchmail',
 	    'mail/mutt',
-	    'mail/alpine',
 	    'mail/popd',
-	    'mail/xfmail',
 	    'mail/postfix',
+	    'mail/xfmail',
 	    'net/cvsup-without-gui',
 	    'net/rsync',
 	    'net/samba3',
 	    'news/slrn',
 	    'news/tin',
+	    'ports-mgmt/p5-FreeBSD-Portindex',
+	    'ports-mgmt/portaudit',
+	    'ports-mgmt/portmaster',
 	    'ports-mgmt/portupgrade',
 	    'print/a2ps-letter',
 	    'print/apsfilter',
 	    'print/ghostscript7-nox11',
-	    'print/gv',
 	    'print/psutils-letter',
+	    'print/gv',
 	    'shells/bash',
 	    'shells/pdksh',
 	    'shells/zsh',
 	    'security/sudo',
+	    'sysutils/screen',
 	    'www/links',
 	    'www/lynx',
+	    'x11/gnome2',
+	    'x11/kde4',
 	    'x11/rxvt',
-	    'ports-mgmt/portaudit'])
+	    'x11/xorg',
+	    'x11-wm/afterstep',
+	    'x11-wm/fvwm2',
+	    'x11-wm/windowmaker'])
     return pkgs
 
 # The list of desired packages

From 782d6aff933ced2ed1d6e22415dc4723bfc9f56c Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Tue, 20 Oct 2009 14:06:07 +0000
Subject: [PATCH 239/646] ichwd.4: fix r198272, restore watchdogd(8) reference

In r198272 I didn't notice that watchdog(8) and watchdogd(8)
are different things and instead of fixing watchdogd markup
I simply nuked the line.

Noticed by:	emaste
Pointy hat to:	avg
---
 share/man/man4/ichwd.4 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/share/man/man4/ichwd.4 b/share/man/man4/ichwd.4
index 38e2865f842..497712c7c5d 100644
--- a/share/man/man4/ichwd.4
+++ b/share/man/man4/ichwd.4
@@ -66,6 +66,7 @@ it believes the WDT is disabled.
 .Sh SEE ALSO
 .Xr watchdog 4 ,
 .Xr watchdog 8 ,
+.Xr watchdogd 8 ,
 .Xr watchdog 9
 .Rs
 .%T Using the Intel ICH Family Watchdog Timer (WDT)

From 417612e0e4f7046cbafb25e82f515946e83ae6f3 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Tue, 20 Oct 2009 14:57:26 +0000
Subject: [PATCH 240/646] Fix comment typos.

Reviewed by:	rmacklem
Approved by:	trasz (mentor)
---
 sys/fs/nfsclient/nfs_clstate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 236432eeb82..67727e0c741 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -36,9 +36,9 @@ __FBSDID("$FreeBSD$");
  * - The correct granularity of an OpenOwner is not nearly so
  *   obvious. An OpenOwner does the following:
  *   - provides a serial sequencing of Open/Close/Lock-with-new-lockowner
- *   - is used to check for Open/SHare contention (not applicable to
+ *   - is used to check for Open/Share contention (not applicable to
  *     this client, since all Opens are Deny_None)
- *   As such, I considered both extrema.
+ *   As such, I considered both extreme.
  *   1 OpenOwner per ClientID - Simple to manage, but fully serializes
  *   all Open, Close and Lock (with a new lockowner) Ops.
  *   1 OpenOwner for each Open - This one results in an OpenConfirm for
@@ -50,8 +50,8 @@ __FBSDID("$FreeBSD$");
  *   which of these the vnodeop close applies to. This is handled by
  *   delaying the Close Op(s) until all of the Opens have been closed.
  *   (It is not yet obvious if this is the correct granularity.)
- * - How the code handles serailization:
- *   - For the ClientId, is uses an exclusive lock while getting its
+ * - How the code handles serialization:
+ *   - For the ClientId, it uses an exclusive lock while getting its
  *     SetClientId and during recovery. Otherwise, it uses a shared
  *     lock via a reference count.
  *   - For the rest of the data structures, it uses an SMP mutex

From 349af4de7ded6caee3530b2f5b62fa90ddb32afd Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Tue, 20 Oct 2009 15:01:46 +0000
Subject: [PATCH 241/646] Fix ordering of nfscl_modevent() and ncl_uninit().
 nfscl_modevent() must be called after ncl_uninit() when unloading the nfscl
 module because ncl_uninit() uses ncl_iod_mutex which is destroyed in
 nfscl_modevent().

Reviewed by:	rmacklem
Approved by:	trasz (mentor)
---
 sys/fs/nfsclient/nfs_clport.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 548ae410055..39f2f02c96b 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -1261,7 +1261,7 @@ static moduledata_t nfscl_mod = {
 	nfscl_modevent,
 	NULL,
 };
-DECLARE_MODULE(nfscl, nfscl_mod, SI_SUB_VFS, SI_ORDER_ANY);
+DECLARE_MODULE(nfscl, nfscl_mod, SI_SUB_VFS, SI_ORDER_FIRST);
 
 /* So that loader and kldload(2) can find us, wherever we are.. */
 MODULE_VERSION(nfscl, 1);

From dd697cbf6652199c2bd67b4345772b6955e986fb Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Tue, 20 Oct 2009 15:06:18 +0000
Subject: [PATCH 242/646] Unloading of the nfscl module is unsupported because
 newnfslock doesn't support unloading. It's not trivial to implement
 newnfslock unloading so for now just admit that unloading is unsupported and
 refuse to attempt unload in all nfscl module event handlers.

Reviewed by:	rmacklem
Approved by:	trasz (mentor)
---
 sys/fs/nfsclient/nfs_clport.c | 7 +++++++
 sys/fs/nfsclient/nfs_clsubs.c | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 39f2f02c96b..e81c3bf805b 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -1243,6 +1243,10 @@ nfscl_modevent(module_t mod, int type, void *data)
 			break;
 		}
 
+		/*
+		 * XXX: Unloading of nfscl module is unsupported.
+		 */
+#if 0
 		ncl_call_invalcaches = NULL;
 		nfsd_call_nfscl = NULL;
 		/* and get rid of the mutexes */
@@ -1250,6 +1254,9 @@ nfscl_modevent(module_t mod, int type, void *data)
 		mtx_destroy(&ncl_iod_mutex);
 		loaded = 0;
 		break;
+#else
+		/* FALLTHROUGH */
+#endif
 	default:
 		error = EOPNOTSUPP;
 		break;
diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c
index a217a21513a..3cd7e5c8685 100644
--- a/sys/fs/nfsclient/nfs_clsubs.c
+++ b/sys/fs/nfsclient/nfs_clsubs.c
@@ -87,6 +87,10 @@ extern struct nfsstats newnfsstats;
 int
 ncl_uninit(struct vfsconf *vfsp)
 {
+	/*
+	 * XXX: Unloading of nfscl module is unsupported.
+	 */
+#if 0
 	int i;
 
 	/*
@@ -104,6 +108,9 @@ ncl_uninit(struct vfsconf *vfsp)
 	mtx_unlock(&ncl_iod_mutex);
 	ncl_nhuninit();
 	return (0);
+#else
+	return (EOPNOTSUPP);
+#endif
 }
 
 void 

From e64585bdc269419485641134ed45d329363171e6 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Tue, 20 Oct 2009 16:36:51 +0000
Subject: [PATCH 243/646] Random number generator initialization cleanup:

- Introduce new SI_SUB_RANDOM point in boot sequence to make it
clear from where one may start using random(9).  It should be as
early as possible, so place it just after SI_SUB_CPU where we
have some randomness on most platforms via get_cyclecount().

- Move stack protector initialization to be after SI_SUB_RANDOM
as before this point we have no randomness at all.  This fixes
stack protector to actually protect stack with some random guard
value instead of a well-known one.

Note that this patch doesn't try to address arc4random(9) issues.
With current code, it will be implicitly seeded by stack protector
and hence will get the same entropy as random(9).  It will be
securely reseeded once /dev/random is feeded by some entropy from
userland.

Submitted by:	Maxim Dounin 
MFC after:	3 days
---
 sys/kern/init_main.c       | 13 +++++++++++++
 sys/kern/stack_protector.c |  3 +--
 sys/sys/kernel.h           |  1 +
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 0af22faa3a5..f1508c89737 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -570,6 +570,19 @@ proc0_post(void *dummy __unused)
 }
 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL);
 
+static void
+random_init(void *dummy __unused)
+{
+
+	/*
+	 * After CPU has been started we have some randomness on most
+	 * platforms via get_cyclecount().  For platforms that don't
+	 * we will reseed random(9) in proc0_post() as well.
+	 */
+	srandom(get_cyclecount());
+}
+SYSINIT(random, SI_SUB_RANDOM, SI_ORDER_FIRST, random_init, NULL);
+
 /*
  ***************************************************************************
  ****
diff --git a/sys/kern/stack_protector.c b/sys/kern/stack_protector.c
index 554d47d0a83..b5f9973e24c 100644
--- a/sys/kern/stack_protector.c
+++ b/sys/kern/stack_protector.c
@@ -28,5 +28,4 @@ __stack_chk_init(void *dummy __unused)
 	for (i = 0; i < __arraycount(guard); i++)
 		__stack_chk_guard[i] = guard[i];
 }
-/* SI_SUB_EVENTHANDLER is right after SI_SUB_LOCK used by arc4rand() init. */
-SYSINIT(stack_chk, SI_SUB_EVENTHANDLER, SI_ORDER_ANY, __stack_chk_init, NULL);
+SYSINIT(stack_chk, SI_SUB_RANDOM, SI_ORDER_ANY, __stack_chk_init, NULL);
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index 5461dfd2b96..1a9cb5cd003 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -109,6 +109,7 @@ enum sysinit_sub_id {
 	SI_SUB_VNET_PRELINK	= 0x1E00000,	/* vnet init before modules */
 	SI_SUB_KLD		= 0x2000000,	/* KLD and module setup */
 	SI_SUB_CPU		= 0x2100000,	/* CPU resource(s)*/
+	SI_SUB_RANDOM		= 0x2120000,	/* random number generator */
 	SI_SUB_KDTRACE		= 0x2140000,	/* Kernel dtrace hooks */
 	SI_SUB_MAC		= 0x2180000,	/* TrustedBSD MAC subsystem */
 	SI_SUB_MAC_POLICY	= 0x21C0000,	/* TrustedBSD MAC policies */

From fc023235632225f16bbdd680b3e209eea6a04ca0 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 20 Oct 2009 17:55:42 +0000
Subject: [PATCH 244/646] In the ARP callout timer expiration function, the
 current time_second is compared against the entry expiration time value (that
 was set based on time_second) to check if the current time is larger than the
 set expiration time. Due to the +/- timer granularity value, the comparison
 returns false, causing the alternative code to be executed. The alternative
 code path freed the memory without removing that entry from the table list,
 causing a use-after-free bug.

Reviewed by:	discussed with kmacy
MFC after:	immediately
Verified by:	rnoland, yongari
---
 sys/netinet/if_ether.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 45cee89ff72..4737b13ba94 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -175,18 +175,18 @@ arptimer(void *arg)
 	CURVNET_SET(ifp->if_vnet);
 	IF_AFDATA_LOCK(ifp);
 	LLE_WLOCK(lle);
-	if (((lle->la_flags & LLE_DELETED) ||
-	    (time_second >= lle->la_expire)) &&
-	    (!callout_pending(&lle->la_timer) &&
+	if ((!callout_pending(&lle->la_timer) &&
 	    callout_active(&lle->la_timer))) {
 		(void) llentry_free(lle);
 		ARPSTAT_INC(timeouts);
-	} else {
-		/*
-		 * Still valid, just drop our reference
-		 */
-		LLE_FREE_LOCKED(lle);
+	} 
+#ifdef DIAGNOSTICS
+	else {
+		struct sockaddr *l3addr = L3_ADDR(lle);
+		log(LOG_INFO, "arptimer issue: %p, IPv4 address: \"%s\"\n", lle,
+		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
 	}
+#endif
 	IF_AFDATA_UNLOCK(ifp);
 	CURVNET_RESTORE();
 }
@@ -377,7 +377,7 @@ retry:
 
 	if (renew) {
 		LLE_ADDREF(la);
-		la->la_expire = time_second;
+		la->la_expire = time_second + V_arpt_down;
 		callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la);
 		la->la_asked++;
 		LLE_WUNLOCK(la);

From 6b484a49cda35c8538aeda2ab2aafc0f0ec8c19f Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Tue, 20 Oct 2009 18:58:28 +0000
Subject: [PATCH 245/646] Make mxge do a better job recovering from NIC h/w
 faults by checking PCI config space when the NIC is not transmitting. 
 Previously, a h/w fault would not have been detected if the NIC was down, or
 handling an RX only workload.

---
 sys/dev/mxge/if_mxge.c | 50 +++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index ae78f84bc04..80d4840ef78 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -3640,7 +3640,6 @@ mxge_open(mxge_softc_t *sc)
 #endif
 	sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
 
 	return 0;
 
@@ -3661,7 +3660,6 @@ mxge_close(mxge_softc_t *sc, int down)
 	int slice;
 #endif
 
-	callout_stop(&sc->co_hdl);
 #ifdef IFNET_BUF_RING
 	for (slice = 0; slice < sc->num_slices; slice++) {
 		ss = &sc->ss[slice];
@@ -3836,9 +3834,9 @@ mxge_watchdog_reset(mxge_softc_t *sc)
 	if (err) {
 		device_printf(sc->dev, "watchdog reset failed\n");
 	} else {
-		if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
-			callout_reset(&sc->co_hdl, mxge_ticks,
-				      mxge_tick, sc);
+		if (sc->dying == 2)
+			sc->dying = 0;
+		callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
 	}
 }
 
@@ -3909,10 +3907,11 @@ mxge_watchdog(mxge_softc_t *sc)
 	return (err);
 }
 
-static void
+static u_long
 mxge_update_stats(mxge_softc_t *sc)
 {
 	struct mxge_slice_state *ss;
+	u_long pkts = 0;
 	u_long ipackets = 0;
 	u_long opackets = 0;
 #ifdef IFNET_BUF_RING
@@ -3934,6 +3933,8 @@ mxge_update_stats(mxge_softc_t *sc)
 #endif
 		oerrors += ss->oerrors;
 	}
+	pkts = (ipackets - sc->ifp->if_ipackets);
+	pkts += (opackets - sc->ifp->if_opackets);
 	sc->ifp->if_ipackets = ipackets;
 	sc->ifp->if_opackets = opackets;
 #ifdef IFNET_BUF_RING
@@ -3942,23 +3943,45 @@ mxge_update_stats(mxge_softc_t *sc)
 	sc->ifp->if_snd.ifq_drops = odrops;
 #endif
 	sc->ifp->if_oerrors = oerrors;
+	return pkts;
 }
 
 static void
 mxge_tick(void *arg)
 {
 	mxge_softc_t *sc = arg;
+	u_long pkts = 0;
 	int err = 0;
+	int running, ticks;
+	uint16_t cmd;
 
-	/* aggregate stats from different slices */
-	mxge_update_stats(sc);
-	if (!sc->watchdog_countdown) {
-		err = mxge_watchdog(sc);
-		sc->watchdog_countdown = 4;
+	ticks = mxge_ticks;
+	mtx_lock(&sc->driver_mtx);
+	running = sc->ifp->if_drv_flags & IFF_DRV_RUNNING;
+	mtx_unlock(&sc->driver_mtx);
+	if (running) {
+		/* aggregate stats from different slices */
+		pkts = mxge_update_stats(sc);
+		if (!sc->watchdog_countdown) {
+			err = mxge_watchdog(sc);
+			sc->watchdog_countdown = 4;
+		}
+		sc->watchdog_countdown--;
 	}
-	sc->watchdog_countdown--;
+	if (pkts == 0) {
+		/* ensure NIC did not suffer h/w fault while idle */
+		cmd = pci_read_config(sc->dev, PCIR_COMMAND, 2);		
+		if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
+			sc->dying = 2;
+			taskqueue_enqueue(sc->tq, &sc->watchdog_task);
+			err = ENXIO;
+		}
+		/* look less often if NIC is idle */
+		ticks *= 4;
+	}
+
 	if (err == 0)
-		callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
+		callout_reset(&sc->co_hdl, ticks, mxge_tick, sc);
 
 }
 
@@ -4747,6 +4770,7 @@ mxge_attach(device_t dev)
 	ifp->if_transmit = mxge_transmit;
 	ifp->if_qflush = mxge_qflush;
 #endif
+	callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
 	return 0;
 
 abort_with_rings:

From 2cf3d848b66655f62d61dac18b3f182de7921fcb Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 20 Oct 2009 21:08:32 +0000
Subject: [PATCH 246/646] Fix a case where rename actually succeeds, which is
 also expected behaviour according to POSIX. This fixes ZFS on Solaris
 testing.

Submitted by:	Milan Cermak 
---
 tools/regression/fstest/tests/rename/21.t | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/regression/fstest/tests/rename/21.t b/tools/regression/fstest/tests/rename/21.t
index 44697453662..2630f628e0e 100644
--- a/tools/regression/fstest/tests/rename/21.t
+++ b/tools/regression/fstest/tests/rename/21.t
@@ -6,7 +6,7 @@ desc="write access to subdirectory is required to move it to another directory"
 dir=`dirname $0`
 . ${dir}/../misc.sh
 
-echo "1..15"
+echo "1..16"
 
 n0=`namegen`
 n1=`namegen`
@@ -30,8 +30,9 @@ expect "0|EACCES" -u 65534 -g 65534 rename ${n2}/${n1} ${n2}/${n0}
 # to move ${n0} from ${n2} to ${n3}.
 expect "0|EACCES" -u 65534 -g 65534 rename ${n2}/${n0} ${n3}/${n1}
 
-expect 0 rmdir ${n2}/${n0}
+expect "0|ENOENT" rmdir ${n2}/${n0}
 expect ENOENT rmdir ${n2}/${n0}
+expect "0|ENOENT" rmdir ${n3}/${n1}
 expect ENOENT rmdir ${n3}/${n1}
 
 # Check that write permission on containing directory (${n2}) is enough

From 48d0c039cba343d3c9e5d4a4740c6cededbf29c3 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 20 Oct 2009 21:27:03 +0000
Subject: [PATCH 247/646] The flow-table function flowtable_route_flush() may
 be called during system initialization time. Since the flow-table is designed
 to maintain per CPU flow cache, the existing code did not check whether
 "smp_started" is true before calling sched_bind() and sched_unbind(), which
 triggers a page fault.

Reviewed by:	jeff
MFC after:	immediately
---
 sys/net/flowtable.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index b85ae268081..31c2acc19a9 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -930,16 +930,20 @@ flowtable_route_flush(struct flowtable *ft, struct rtentry *rt)
 		for (i = 0; i <= mp_maxid; i++) {
 			if (CPU_ABSENT(i))
 				continue;
-
-			thread_lock(curthread);
-			sched_bind(curthread, i);
-			thread_unlock(curthread);
+			
+			if (smp_started == 1) {
+				thread_lock(curthread);
+				sched_bind(curthread, i);
+				thread_unlock(curthread);
+			}
 
 			flowtable_free_stale(ft, rt);
 
-			thread_lock(curthread);
-			sched_unbind(curthread);
-			thread_unlock(curthread);
+			if (smp_started == 1) {
+				thread_lock(curthread);
+				sched_unbind(curthread);
+				thread_unlock(curthread);
+			}
 		}
 	} else {
 		flowtable_free_stale(ft, rt);

From 11cf5c2f8120f8c4f97f61d9efd8b8870dfc24f7 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Tue, 20 Oct 2009 21:29:46 +0000
Subject: [PATCH 248/646] Change from CAM_TID_INVALID to CAM_SEL_TIMEOUT error
 code when the usb device has been yanked, this works around a cam recounting
 bug when CAM_DEV_UNCONFIGURED is set late in the detach. In certain
 conditions the reference to the XPT device would not be released which would
 cause the usb explore thread to sleep forever on "simfree", preventing any
 new usb devices to be found/ejected on the bus.

This is intended to be a quick workaround to the problem without touching CAM
so it can be merged to 8.0.

Suggested by:	mav
MFC after:	3 days
---
 sys/dev/usb/storage/umass.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index ba9651339ed..914a36e9903 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -2860,8 +2860,9 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 {
 	struct umass_softc *sc = (struct umass_softc *)sim->softc;
 
-	if (sc == UMASS_GONE) {
-		ccb->ccb_h.status = CAM_TID_INVALID;
+	if (sc == UMASS_GONE ||
+	    (sc != NULL && !usbd_device_attached(sc->sc_udev))) {
+		ccb->ccb_h.status = CAM_SEL_TIMEOUT;
 		xpt_done(ccb);
 		return;
 	}

From 4e22046f33bf5fdbc0c84f64c7bf8f4cef5f7412 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 21 Oct 2009 09:22:40 +0000
Subject: [PATCH 249/646] Improve the description of the malofw kernel module
 installation.

PR:		132193
Submitted by:	Frank Staals 
Based on a patch by: gavin
MFC after:	3 days
---
 share/man/man4/malo.4 | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/share/man/man4/malo.4 b/share/man/man4/malo.4
index 60c9e3d89d9..f0545f44b4e 100644
--- a/share/man/man4/malo.4
+++ b/share/man/man4/malo.4
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"/
-.Dd March 26, 2009
+.Dd October 21, 2009
 .Dt MALO 4
 .Os
 .Sh NAME
@@ -71,14 +71,19 @@ For more information on configuring this device, see
 .Pp
 This driver requires the
 .Nm malofw
-be installed before it will work.
+firmware kernel module be installed before it will work.
 The firmware files are not publicly available.
-A package of the firmware which can be installed via
-.Xr pkg_add 1
-with:
+A port of the firmware can be found at:
 .Bd -literal -offset indent
 http://weongyo.org/project/malo/malo-firmware-1.4.tar.gz
 .Ed
+.Pp
+The firmware kernel module can be installed by extracting
+the archive and running
+.Ql make install clean
+in the
+.Pa malo-firmware-1.4
+directory.
 .Sh HARDWARE
 The following cards are among those supported by the
 .Nm

From e8097b1fbae3dba673235d6369b8748aedd6416a Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 21 Oct 2009 09:43:22 +0000
Subject: [PATCH 250/646] Add empty watchdogd_flags.

PR:		136620
Submitted by:	amdmi3
MFC after:	3 days
---
 etc/defaults/rc.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index de1a8d83a05..c094303de38 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -600,6 +600,7 @@ harvest_ethernet="YES"	# Entropy device harvests ethernet randomness
 harvest_p_to_p="YES"	# Entropy device harvests point-to-point randomness
 dmesg_enable="YES"	# Save dmesg(8) to /var/run/dmesg.boot
 watchdogd_enable="NO"	# Start the software watchdog daemon
+watchdogd_flags=""	# Flags to watchdogd (if enabled)
 devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules" # Files containing
 							    # devfs(8) rules.
 devfs_system_ruleset=""	# The name (NOT number) of a ruleset to apply to /dev

From 32ae24b7d7fc9ceab64037983feffd0a285cb1c7 Mon Sep 17 00:00:00 2001
From: Remko Lodder 
Date: Wed, 21 Oct 2009 10:15:26 +0000
Subject: [PATCH 251/646] The tunefs utility does not work on active
 filesystems.

PR:		docs/139705
Submitted by:	Warren Block 
Approved by:	imp (mentor, implicit)
---
 sbin/tunefs/tunefs.8 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sbin/tunefs/tunefs.8 b/sbin/tunefs/tunefs.8
index 06e47cae864..e2664e3edeb 100644
--- a/sbin/tunefs/tunefs.8
+++ b/sbin/tunefs/tunefs.8
@@ -28,7 +28,7 @@
 .\"     @(#)tunefs.8	8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd August 13, 2007
+.Dd October 21, 2009
 .Dt TUNEFS 8
 .Os
 .Sh NAME
@@ -165,7 +165,7 @@ The
 utility appeared in
 .Bx 4.2 .
 .Sh BUGS
-This utility should work on active file systems.
+This utility does not work on active file systems.
 To change the root file system, the system must be rebooted
 after the file system is tuned.
 .\" Take this out and a Unix Daemon will dog your steps from now until

From c8c45602aa34bf4d97252f33a835bbe11590d96e Mon Sep 17 00:00:00 2001
From: Rink Springer 
Date: Wed, 21 Oct 2009 11:10:34 +0000
Subject: [PATCH 252/646] Introduce 'netDev=ANY' support for scripted
 (install.cfg) installs, which results in the first ethernet interface with
 physical link being selected.

While here, fix a minor typo causing an 'if' to be missed.

Submitted by:	randi
---
 usr.sbin/sysinstall/tcpip.c | 85 ++++++++++++++++++++++++++++++++-----
 1 file changed, 74 insertions(+), 11 deletions(-)

diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c
index f505a0581c0..75a40e87512 100644
--- a/usr.sbin/sysinstall/tcpip.c
+++ b/usr.sbin/sysinstall/tcpip.c
@@ -40,10 +40,17 @@
 #include "sysinstall.h"
 #include 
 #include 
+#include 
 #include 
+#include 
+
 #include 
+#include 
+#include 
+
 #include 
 #include 
+#include 
 
 /* The help file for the TCP/IP setup screen */
 #define TCP_HELPFILE		"tcp"
@@ -636,6 +643,51 @@ netHook(dialogMenuItem *self)
     return devs ? DITEM_LEAVE_MENU : DITEM_FAILURE;
 }
 
+static char *
+tcpDeviceScan(void)
+{
+	int s;
+	struct ifmediareq ifmr;
+	struct ifaddrs *ifap, *ifa;
+	struct if_data *ifd;
+	char *network_dev;
+
+	if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
+		return (NULL);
+
+	if (getifaddrs(&ifap) < 0)
+		return (NULL);
+
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+		memset(&ifmr, 0, sizeof(ifmr));
+		strlcpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
+
+		if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+			continue;	/* some devices don't support this */ 
+
+		if ((ifmr.ifm_status & IFM_AVALID) == 0)
+			continue;	/* not active */
+
+		if (IFM_TYPE(ifmr.ifm_active) != IFM_ETHER)
+			continue;	/* not an ethernet device */
+
+		if (ifmr.ifm_status & IFM_ACTIVE) {
+			network_dev = strdup(ifa->ifa_name);
+			freeifaddrs(ifap);
+
+			if (!variable_get(VAR_NONINTERACTIVE)) 
+				msgConfirm("Using interface %s", network_dev);
+
+			msgDebug("tcpDeviceScan found %s", network_dev);
+			return (network_dev);
+		}
+	}
+
+	freeifaddrs(ifap);
+
+	return (NULL);
+}
+
 /* Get a network device */
 Device *
 tcpDeviceSelect(void)
@@ -647,27 +699,38 @@ tcpDeviceSelect(void)
 
     rval = NULL;
 
-    if (variable_get(VAR_NONINTERACTIVE) && variable_get(VAR_NETWORK_DEVICE)) {
+    if (variable_get(VAR_NETWORK_DEVICE)) {
 	network_dev = variable_get(VAR_NETWORK_DEVICE);
 
+	/* 
+	 * netDev can be set to several types of values.
+	 * If netDev is set to ANY, scan all network devices
+	 * looking for a valid link, and go with the first
+	 * device found. netDev can also be specified as a
+	 * comma delimited list, with each network device
+	 * tried in order. netDev can also be set to a single
+	 * network device.
+	 */
+	if (!strcmp(network_dev, "ANY")) 
+		network_dev = strdup(tcpDeviceScan()); 
+
 	while ((dev = strsep(&network_dev, ",")) != NULL) {
 	    devs = deviceFind(dev, DEVICE_TYPE_NETWORK);
 	    cnt = deviceCount(devs);
+
 	    if (cnt) {
-		if (DITEM_STATUS(tcpOpenDialog(devs[0]) == DITEM_SUCCESS))
-		    return(devs[0]);
+		if (DITEM_STATUS(tcpOpenDialog(devs[0])) == DITEM_SUCCESS) 
+		    return (devs[0]);
 	    }
 	}
+
+	if (!variable_get(VAR_NONINTERACTIVE))
+		msgConfirm("No network devices available!");
+
+	return (NULL);
     }
 
-    devs = deviceFind(variable_get(VAR_NETWORK_DEVICE), DEVICE_TYPE_NETWORK);
-    cnt = deviceCount(devs);
-
-    if (!cnt) {
-	msgConfirm("No network devices available!");
-	return NULL;
-    }
-    else if ((!RunningAsInit) && (variable_check("NETWORK_CONFIGURED=NO") != TRUE)) {
+    if ((!RunningAsInit) && (variable_check("NETWORK_CONFIGURED=NO") != TRUE)) {
 	if (!msgYesNo("Running multi-user, assume that the network is already configured?"))
 	    return devs[0];
     }

From 15eda8010b4f2ec9f6b1f56a71fc6fd8c38ab27f Mon Sep 17 00:00:00 2001
From: Stanislav Sedov 
Date: Wed, 21 Oct 2009 11:50:18 +0000
Subject: [PATCH 253/646] - On entrance to the rx_eof sync RX rings maps with
 POSTWRITE flag   instead of POSTREAD: the hardware do not touch this memory
 (CPU   updates it).  It is already synchronized as PREWRITE after the  
 processing is done.

- Synchronize RX return ring memory in rx_eof.  This is needed
  as the deviced updates this memory when receives packets.

- Decouple the synchronization of BGE status block in the interrupt
  service routine: perfrom PREREAD synchronization only all accesses
  to this block are finished.  This seems to be more natural.

Reviewed by:	yongari, marius
MFC after:	2 weeks
---
 sys/dev/bge/if_bge.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 865a0d68ea4..39990b00b72 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -3122,10 +3122,10 @@ bge_rxeof(struct bge_softc *sc)
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
 	    sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTREAD);
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
-	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTREAD);
+	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTWRITE);
 	if (BGE_IS_JUMBO_CAPABLE(sc))
 		bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
-		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD);
+		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTWRITE);
 
 	while (rx_cons != rx_prod) {
 		struct bge_rx_bd	*cur_rx;
@@ -3251,6 +3251,8 @@ bge_rxeof(struct bge_softc *sc)
 			return (rx_npkts);
 	}
 
+	bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
+	    sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_PREREAD);
 	if (stdcnt > 0)
 		bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
 		    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE);
@@ -3423,8 +3425,6 @@ bge_intr(void *xsc)
 	/* Make sure the descriptor ring indexes are coherent. */
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
 	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
-	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
 
 	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
 	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
@@ -3445,6 +3445,9 @@ bge_intr(void *xsc)
 	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		bge_start_locked(ifp);
 
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
+
 	BGE_UNLOCK(sc);
 }
 

From a1aa38dedf0bd4636a45f41e6ad5ca8d212f4771 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 12:42:25 +0000
Subject: [PATCH 254/646] MFp4: On error, freeze device queue, to allow periph
 driver to do proper recovery. Freeze SIM queue only in some cases, when it is
 needed to protect SIM.

Implement better command timeout detection logic for non-queued commands.
This fixes false positives when command with short timeout waiting for the
long one. For example, when hald tastes CD during burning process.

Read and clear SERR register on interrupt.
---
 sys/dev/ahci/ahci.c | 114 ++++++++++++++++++++++++++++++--------------
 sys/dev/ahci/ahci.h |   2 +-
 2 files changed, 79 insertions(+), 37 deletions(-)

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index f420629eaab..86c1f167b66 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -866,15 +866,11 @@ ahci_slotsfree(device_t dev)
 }
 
 static void
-ahci_phy_check_events(device_t dev)
+ahci_phy_check_events(device_t dev, u_int32_t serr)
 {
 	struct ahci_channel *ch = device_get_softc(dev);
-	u_int32_t error = ATA_INL(ch->r_mem, AHCI_P_SERR);
 
-	/* Clear error bits/interrupt */
-	ATA_OUTL(ch->r_mem, AHCI_P_SERR, error);
-	/* If we have a connection event, deal with it */
-	if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
+	if ((serr & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
 		u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
 		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
 		    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
@@ -944,7 +940,7 @@ ahci_ch_intr(void *data)
 {
 	device_t dev = (device_t)data;
 	struct ahci_channel *ch = device_get_softc(dev);
-	uint32_t istatus, sstatus, cstatus, sntf = 0, ok, err;
+	uint32_t istatus, sstatus, cstatus, serr = 0, sntf = 0, ok, err;
 	enum ahci_err_type et;
 	int i, ccs, ncq_err = 0;
 
@@ -959,14 +955,20 @@ ahci_ch_intr(void *data)
 	if ((istatus & AHCI_P_IX_SDB) && (ch->caps & AHCI_CAP_SSNTF))
 		sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF);
 	/* Process PHY events */
-	if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
-		ahci_phy_check_events(dev);
+	if (istatus & (AHCI_P_IX_PC | AHCI_P_IX_PRC | AHCI_P_IX_OF |
+	    AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
+		serr = ATA_INL(ch->r_mem, AHCI_P_SERR);
+		if (serr) {
+			ATA_OUTL(ch->r_mem, AHCI_P_SERR, serr);
+			ahci_phy_check_events(dev, serr);
+		}
+	}
 	/* Process command errors */
-	if (istatus & (AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF |
-		       AHCI_P_IX_TFE | AHCI_P_IX_OF)) {
+	if (istatus & (AHCI_P_IX_OF | AHCI_P_IX_IF |
+	    AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
 //device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
 //    __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
-//    ATA_INL(ch->r_mem, AHCI_P_SERR));
+//    serr);
 		ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
 		    >> AHCI_P_CMD_CCS_SHIFT;
 		err = ch->rslots & (cstatus | sstatus);
@@ -985,19 +987,26 @@ ahci_ch_intr(void *data)
 	}
 	/* On error, complete the rest of commands with error statuses. */
 	if (err) {
-		if (!ch->readlog)
-			xpt_freeze_simq(ch->sim, ch->numrslots);
 		if (ch->frozen) {
 			union ccb *fccb = ch->frozen;
 			ch->frozen = NULL;
 			fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+			if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+				xpt_freeze_devq(fccb->ccb_h.path, 1);
+				fccb->ccb_h.status |= CAM_DEV_QFRZN;
+			}
 			xpt_done(fccb);
 		}
 		for (i = 0; i < ch->numslots; i++) {
 			/* XXX: reqests in loading state. */
 			if (((err >> i) & 1) == 0)
 				continue;
-			if (istatus & AHCI_P_IX_TFE) {
+			if (istatus & AHCI_P_IX_IF) {
+				if (ch->numtslots == 0 && i != ccs)
+					et = AHCI_ERR_INNOCENT;
+				else
+					et = AHCI_ERR_SATA;
+			} else if (istatus & AHCI_P_IX_TFE) {
 				/* Task File Error */
 				if (ch->numtslots == 0) {
 					/* Untagged operation. */
@@ -1010,9 +1019,6 @@ ahci_ch_intr(void *data)
 					et = AHCI_ERR_NCQ;
 					ncq_err = 1;
 				}
-			} else if (istatus & AHCI_P_IX_IF) {
-				/* SATA error */
-				et = AHCI_ERR_SATA;
 			} else
 				et = AHCI_ERR_INVALID;
 			ahci_end_transaction(&ch->slot[i], et);
@@ -1121,8 +1127,6 @@ ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 
 	if (error) {
 		device_printf(slot->dev, "DMA load error\n");
-		if (!ch->readlog)
-			xpt_freeze_simq(ch->sim, 1);
 		ahci_end_transaction(slot, AHCI_ERR_INVALID);
 		return;
 	}
@@ -1161,8 +1165,6 @@ ahci_execute_transaction(struct ahci_slot *slot)
 	/* Setup the FIS for this request */
 	if (!(fis_size = ahci_setup_fis(ctp, ccb, slot->slot))) {
 		device_printf(ch->dev, "Setting up SATA FIS failed\n");
-		if (!ch->readlog)
-			xpt_freeze_simq(ch->sim, 1);
 		ahci_end_transaction(slot, AHCI_ERR_INVALID);
 		return;
 	}
@@ -1229,13 +1231,12 @@ ahci_execute_transaction(struct ahci_slot *slot)
 			/* Kick controller into sane state */
 			ahci_stop(ch->dev);
 			ahci_start(ch->dev);
-			xpt_freeze_simq(ch->sim, 1);
 		}
 		ahci_end_transaction(slot, et);
 		return;
 	}
 	/* Start command execution timeout */
-	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
+	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 2000,
 	    (timeout_t*)ahci_timeout, slot);
 	return;
 }
@@ -1246,24 +1247,47 @@ ahci_timeout(struct ahci_slot *slot)
 {
 	device_t dev = slot->dev;
 	struct ahci_channel *ch = device_get_softc(dev);
+	uint32_t sstatus;
+	int ccs;
 	int i;
 
 	/* Check for stale timeout. */
-	if (slot->state != AHCI_SLOT_RUNNING)
+	if (slot->state < AHCI_SLOT_RUNNING)
 		return;
 
+	/* Check if slot was not being executed last time we checked. */
+	if (slot->state < AHCI_SLOT_EXECUTING) {
+		/* Check if slot started executing. */
+		sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT);
+		ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
+		    >> AHCI_P_CMD_CCS_SHIFT;
+		if ((sstatus & (1 << slot->slot)) != 0 || ccs == slot->slot)
+			slot->state = AHCI_SLOT_EXECUTING;
+
+		callout_reset(&slot->timeout,
+		    (int)slot->ccb->ccb_h.timeout * hz / 2000,
+		    (timeout_t*)ahci_timeout, slot);
+		return;
+	}
+
 	device_printf(dev, "Timeout on slot %d\n", slot->slot);
+	device_printf(dev, "is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
+	    ATA_INL(ch->r_mem, AHCI_P_IS), ATA_INL(ch->r_mem, AHCI_P_CI),
+	    ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots,
+	    ATA_INL(ch->r_mem, AHCI_P_TFD), ATA_INL(ch->r_mem, AHCI_P_SERR));
 	/* Kick controller into sane state. */
 	ahci_stop(ch->dev);
 	ahci_start(ch->dev);
 
-	if (!ch->readlog)
-		xpt_freeze_simq(ch->sim, ch->numrslots);
 	/* Handle frozen command. */
 	if (ch->frozen) {
 		union ccb *fccb = ch->frozen;
 		ch->frozen = NULL;
 		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+			xpt_freeze_devq(fccb->ccb_h.path, 1);
+			fccb->ccb_h.status |= CAM_DEV_QFRZN;
+		}
 		xpt_done(fccb);
 	}
 	/* Handle command with timeout. */
@@ -1321,10 +1345,14 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
 		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 		bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map);
 	}
+	/* In case of error, freeze device for proper recovery. */
+	if ((et != AHCI_ERR_NONE) && (!ch->readlog) &&
+	    !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
+		xpt_freeze_devq(ccb->ccb_h.path, 1);
+		ccb->ccb_h.status |= CAM_DEV_QFRZN;
+	}
 	/* Set proper result status. */
 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
-	if (et != AHCI_ERR_NONE)
-		ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 	switch (et) {
 	case AHCI_ERR_NONE:
 		ccb->ccb_h.status |= CAM_REQ_CMP;
@@ -1338,6 +1366,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
 		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 		break;
 	case AHCI_ERR_TFE:
+	case AHCI_ERR_NCQ:
 		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
 			ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
@@ -1346,13 +1375,21 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
 		}
 		break;
 	case AHCI_ERR_SATA:
-			ccb->ccb_h.status |= CAM_UNCOR_PARITY;
+		if (!ch->readlog) {
+			xpt_freeze_simq(ch->sim, 1);
+			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
+		}
+		ccb->ccb_h.status |= CAM_UNCOR_PARITY;
 		break;
 	case AHCI_ERR_TIMEOUT:
+		if (!ch->readlog) {
+			xpt_freeze_simq(ch->sim, 1);
+			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
+		}
 		ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
 		break;
-	case AHCI_ERR_NCQ:
-		ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
 	default:
 		ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
 	}
@@ -1436,7 +1473,8 @@ ahci_issue_read_log(device_t dev)
 	ataio->cmd.lba_low = 0x10;
 	ataio->cmd.lba_mid = 0;
 	ataio->cmd.lba_mid_exp = 0;
-	
+	/* Freeze SIM while doing READ LOG EXT. */
+	xpt_freeze_simq(ch->sim, 1);
 	ahci_begin_transaction(dev, ccb);
 }
 
@@ -1491,6 +1529,7 @@ ahci_process_read_log(device_t dev, union ccb *ccb)
 	}
 	free(ccb->ataio.data_ptr, M_AHCI);
 	xpt_free_ccb(ccb);
+	xpt_release_simq(ch->sim, TRUE);
 }
 
 static void
@@ -1615,12 +1654,15 @@ ahci_reset(device_t dev)
 
 	if (bootverbose)
 		device_printf(dev, "AHCI reset...\n");
-	xpt_freeze_simq(ch->sim, ch->numrslots);
 	/* Requeue freezed command. */
 	if (ch->frozen) {
 		union ccb *fccb = ch->frozen;
 		ch->frozen = NULL;
 		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+			xpt_freeze_devq(fccb->ccb_h.path, 1);
+			fccb->ccb_h.status |= CAM_DEV_QFRZN;
+		}
 		xpt_done(fccb);
 	}
 	/* Kill the engine and requeue all running commands. */
@@ -1632,6 +1674,8 @@ ahci_reset(device_t dev)
 		/* XXX; Commands in loading state. */
 		ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT);
 	}
+	/* Tell the XPT about the event */
+	xpt_async(AC_BUS_RESET, ch->path, NULL);
 	/* Disable port interrupts */
 	ATA_OUTL(ch->r_mem, AHCI_P_IE, 0);
 	/* Reset and reconnect PHY, */
@@ -1661,8 +1705,6 @@ ahci_reset(device_t dev)
 	      AHCI_P_IX_DS | AHCI_P_IX_PS | (ctlr->ccc ? 0 : AHCI_P_IX_DHR)));
 	if (bootverbose)
 		device_printf(dev, "AHCI reset done: device found\n");
-	/* Tell the XPT about the event */
-	xpt_async(AC_BUS_RESET, ch->path, NULL);
 }
 
 static int
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index 9b5726ac805..df103ad658c 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -328,7 +328,7 @@ enum ahci_slot_states {
 	AHCI_SLOT_EMPTY,
 	AHCI_SLOT_LOADING,
 	AHCI_SLOT_RUNNING,
-	AHCI_SLOT_WAITING
+	AHCI_SLOT_EXECUTING
 };
 
 struct ahci_slot {

From a0d600845e653e8e474344aa51931d38f5d8240b Mon Sep 17 00:00:00 2001
From: Stanislav Sedov 
Date: Wed, 21 Oct 2009 12:47:09 +0000
Subject: [PATCH 255/646] - Introduce new option BCE_JUMBO_HDRSPLIT that allows
 user to enable header   splitting in bce(4) instead of (ab)using
 ZERO_COPY_SOCKETS that was not   propagated into if_bce.c anyway.  It is
 disabled by default.

Approved by:	davidch
MFC after:	3 days
---
 sys/conf/NOTES          |  6 ++++
 sys/conf/options        |  1 +
 sys/dev/bce/if_bce.c    | 74 ++++++++++++++++++++---------------------
 sys/dev/bce/if_bcereg.h | 20 +++++------
 4 files changed, 54 insertions(+), 47 deletions(-)

diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 1cba42f4643..deab220b445 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1985,6 +1985,12 @@ device		lmc
 # only works for Tigon II chips, and has no effect for Tigon I chips.
 options 	TI_JUMBO_HDRSPLIT
 
+#
+# Use header splitting feature on bce(4) adapters.
+# This may help to reduce the amount of jumbo-sized memory buffers used.
+#
+options		BCE_JUMBO_HDRSPLIT
+
 # These two options allow manipulating the mbuf cluster size and mbuf size,
 # respectively.  Be very careful with NIC driver modules when changing
 # these from their default values, because that can potentially cause a
diff --git a/sys/conf/options b/sys/conf/options
index 1df09d7d038..b1e62c33d09 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -511,6 +511,7 @@ DRM_DEBUG		opt_drm.h
 ZERO_COPY_SOCKETS	opt_zero.h
 TI_PRIVATE_JUMBOS	opt_ti.h
 TI_JUMBO_HDRSPLIT	opt_ti.h
+BCE_JUMBO_HDRSPLIT	opt_bce.h
 
 # XXX Conflict: # of devices vs network protocol (Native ATM).
 # This makes "atm.h" unusable.
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 431ed9f24f7..aa076c44d0c 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -293,12 +293,12 @@ static void bce_dump_enet           (struct bce_softc *, struct mbuf *);
 static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
 static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
 static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
 #endif
 static void bce_dump_txbd			(struct bce_softc *, int, struct tx_bd *);
 static void bce_dump_rxbd			(struct bce_softc *, int, struct rx_bd *);
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 static void bce_dump_pgbd			(struct bce_softc *, int, struct rx_bd *);
 #endif
 static void bce_dump_l2fhdr			(struct bce_softc *, int, struct l2_fhdr *);
@@ -306,7 +306,7 @@ static void bce_dump_ctx			(struct bce_softc *, u16);
 static void bce_dump_ftqs			(struct bce_softc *);
 static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
 static void bce_dump_rx_chain		(struct bce_softc *, u16, int);
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
 #endif
 static void bce_dump_status_block	(struct bce_softc *);
@@ -393,7 +393,7 @@ static int  bce_init_rx_chain		(struct bce_softc *);
 static void bce_fill_rx_chain		(struct bce_softc *);
 static void bce_free_rx_chain		(struct bce_softc *);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 static int  bce_get_pg_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *);
 static int  bce_init_pg_chain		(struct bce_softc *);
 static void bce_fill_pg_chain		(struct bce_softc *);
@@ -602,7 +602,7 @@ bce_print_adapter_info(struct bce_softc *sc)
 	/* Firmware version and device features. */
 	printf("B/C (%s); Flags (", sc->bce_bc_ver);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	printf("SPLT ");
     i++;
 #endif
@@ -1066,7 +1066,7 @@ bce_attach(device_t dev)
 	 * This may change later if the MTU size is set to
 	 * something other than 1500.
 	 */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	sc->rx_bd_mbuf_alloc_size = MHLEN;
 	/* Make sure offset is 16 byte aligned for hardware. */
 	sc->rx_bd_mbuf_align_pad  = roundup2((MSIZE - MHLEN), 16) -
@@ -2835,7 +2835,7 @@ bce_dma_free(struct bce_softc *sc)
 	}
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/* Free, unmap and destroy all page buffer descriptor chain pages. */
 	for (i = 0; i < PG_PAGES; i++ ) {
 		if (sc->pg_bd_chain[i] != NULL) {
@@ -2899,7 +2899,7 @@ bce_dma_free(struct bce_softc *sc)
 		sc->rx_mbuf_tag = NULL;
 	}
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/* Unload and destroy the page mbuf maps. */
 	for (i = 0; i < TOTAL_PG_BD; i++) {
 		if (sc->pg_mbuf_map[i] != NULL) {
@@ -3345,7 +3345,7 @@ bce_dma_alloc(device_t dev)
 	/*
 	 * Create a DMA tag for RX mbufs.
 	 */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
 		MCLBYTES : sc->rx_bd_mbuf_alloc_size);
 #else
@@ -3386,7 +3386,7 @@ bce_dma_alloc(device_t dev)
 		}
 	}
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/*
 	 * Create a DMA tag for the page buffer descriptor chain,
 	 * allocate and clear the memory, and fetch the physical
@@ -4473,7 +4473,7 @@ bce_stop(struct bce_softc *sc)
 	bce_disable_intr(sc);
 
 	/* Free RX buffers. */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	bce_free_pg_chain(sc);
 #endif
 	bce_free_rx_chain(sc);
@@ -4910,7 +4910,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
 			goto bce_get_rx_buf_exit);
 
 		/* This is a new mbuf allocation. */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 #else
 		if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
@@ -4991,7 +4991,7 @@ bce_get_rx_buf_exit:
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Encapsulate an mbuf cluster into the page chain.                        */
 /*                                                                          */
@@ -5100,7 +5100,7 @@ bce_get_pg_buf_exit:
 
 	return(rc);
 }
-#endif /* ZERO_COPY_SOCKETS */
+#endif /* BCE_JUMBO_HDRSPLIT */
 
 /****************************************************************************/
 /* Initialize the TX context memory.                                        */
@@ -5456,7 +5456,7 @@ bce_free_rx_chain(struct bce_softc *sc)
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Allocate memory and initialize the page data structures.                 */
 /* Assumes that bce_init_rx_chain() has not already been called.            */
@@ -5620,7 +5620,7 @@ bce_free_pg_chain(struct bce_softc *sc)
 
 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
 }
-#endif /* ZERO_COPY_SOCKETS */
+#endif /* BCE_JUMBO_HDRSPLIT */
 
 
 /****************************************************************************/
@@ -5793,7 +5793,7 @@ bce_rx_intr(struct bce_softc *sc)
 	unsigned int pkt_len;
 	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
 	u32 status;
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	unsigned int rem_len;
 	u16 sw_pg_cons, sw_pg_cons_idx;
 #endif
@@ -5809,7 +5809,7 @@ bce_rx_intr(struct bce_softc *sc)
 		bus_dmamap_sync(sc->rx_bd_chain_tag,
 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/* Prepare the page chain pages to be accessed by the host CPU. */
 	for (int i = 0; i < PG_PAGES; i++)
 		bus_dmamap_sync(sc->pg_bd_chain_tag,
@@ -5821,7 +5821,7 @@ bce_rx_intr(struct bce_softc *sc)
 
 	/* Get working copies of the driver's view of the consumer indices. */
 	sw_rx_cons = sc->rx_cons;
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	sw_pg_cons = sc->pg_cons;
 #endif
 
@@ -5882,7 +5882,7 @@ bce_rx_intr(struct bce_softc *sc)
 		 */
 		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 		/*
 		 * Check whether the received frame fits in a single
 		 * mbuf or not (i.e. packet data + FCS <=
@@ -6056,7 +6056,7 @@ bce_rx_int_next_rx:
 		if (m0) {
 			/* Make sure we don't lose our place when we release the lock. */
 			sc->rx_cons = sw_rx_cons;
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 			sc->pg_cons = sw_pg_cons;
 #endif
 
@@ -6066,7 +6066,7 @@ bce_rx_int_next_rx:
 
 			/* Recover our place. */
 			sw_rx_cons = sc->rx_cons;
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 			sw_pg_cons = sc->pg_cons;
 #endif
 		}
@@ -6077,7 +6077,7 @@ bce_rx_int_next_rx:
 	}
 
 	/* No new packets to process.  Refill the RX and page chains and exit. */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	sc->pg_cons = sw_pg_cons;
 	bce_fill_pg_chain(sc);
 #endif
@@ -6090,7 +6090,7 @@ bce_rx_int_next_rx:
 		bus_dmamap_sync(sc->rx_bd_chain_tag,
 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	for (int i = 0; i < PG_PAGES; i++)
 		bus_dmamap_sync(sc->pg_bd_chain_tag,
 		    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
@@ -6336,7 +6336,7 @@ bce_init_locked(struct bce_softc *sc)
 	 * Calculate and program the hardware Ethernet MTU
 	 * size. Be generous on the receive if we have room.
 	 */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size))
 		ether_mtu = sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size;
 #else
@@ -6368,7 +6368,7 @@ bce_init_locked(struct bce_softc *sc)
 	/* Program appropriate promiscuous/multicast filtering. */
 	bce_set_rx_mode(sc);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
 		__FUNCTION__, sc->pg_bd_mbuf_alloc_size);
 
@@ -6881,7 +6881,7 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 			BCE_LOCK(sc);
 			ifp->if_mtu = ifr->ifr_mtu;
 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 			/* No buffer allocation size changes are necessary. */
 #else
 			/* Recalculate our buffer allocation sizes. */
@@ -7584,7 +7584,7 @@ bce_tick(void *xsc)
 	bce_stats_update(sc);
 
 	/* Top off the receive and page chains. */
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	bce_fill_pg_chain(sc);
 #endif
 	bce_fill_rx_chain(sc);
@@ -7764,7 +7764,7 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Provides a sysctl interface to allow dumping the page chain.             */
 /*                                                                          */
@@ -8392,7 +8392,7 @@ bce_add_sysctls(struct bce_softc *sc)
 		(void *)sc, 0,
 		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 		"dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
 		(void *)sc, 0,
@@ -8687,7 +8687,7 @@ bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Prints out the mbufs in the mbuf page chain.                             */
 /*                                                                          */
@@ -8811,7 +8811,7 @@ bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Prints out a rx_bd structure in the page chain.                          */
 /*                                                                          */
@@ -9298,7 +9298,7 @@ bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
 }
 
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /****************************************************************************/
 /* Prints out the page chain.                                               */
 /*                                                                          */
@@ -9779,7 +9779,7 @@ bce_dump_driver_state(struct bce_softc *sc)
 		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
 		val_hi, val_lo);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
 	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
 	BCE_PRINTF(
@@ -9799,7 +9799,7 @@ bce_dump_driver_state(struct bce_softc *sc)
 		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
 		val_hi, val_lo);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
 	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
 	BCE_PRINTF(
@@ -9852,7 +9852,7 @@ bce_dump_driver_state(struct bce_softc *sc)
 	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
 		sc->free_rx_bd);
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer index\n",
 		sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
 
@@ -10358,7 +10358,7 @@ bce_breakpoint(struct bce_softc *sc)
 		bce_dump_tpat_state(sc, 0);
 		bce_dump_cp_state(sc, 0);
 		bce_dump_com_state(sc, 0);
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 		bce_dump_pgbd(sc, 0, NULL);
 		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
 		bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
index cd75f0c7cd7..3ee7b1d03d4 100644
--- a/sys/dev/bce/if_bcereg.h
+++ b/sys/dev/bce/if_bcereg.h
@@ -6216,7 +6216,7 @@ struct l2_fhdr {
 #define RX_PAGE(x) (((x) & ~USABLE_RX_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4))
 #define RX_IDX(x) ((x) & USABLE_RX_BD_PER_PAGE)
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 /*
  * To accomodate jumbo frames, the page chain should
  * be 4 times larger than the receive chain.
@@ -6238,7 +6238,7 @@ struct l2_fhdr {
 #define PG_PAGE(x) (((x) & ~USABLE_PG_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4))
 #define PG_IDX(x) ((x) & USABLE_PG_BD_PER_PAGE)
 
-#endif /* ZERO_COPY_SOCKETS */
+#endif /* BCE_JUMBO_HDRSPLIT */
 
 #define CTX_INIT_RETRY_COUNT        10
 
@@ -6517,7 +6517,7 @@ struct bce_softc
 	u16					tx_cons;
 	u32					tx_prod_bseq;	/* Counts the bytes used.  */
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	u16					pg_prod;
 	u16					pg_cons;
 #endif
@@ -6534,7 +6534,7 @@ struct bce_softc
 	int					rx_bd_mbuf_data_len;
 	int					rx_bd_mbuf_align_pad;
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	int					pg_bd_mbuf_alloc_size;
 #endif
 
@@ -6556,7 +6556,7 @@ struct bce_softc
 	struct rx_bd		*rx_bd_chain[RX_PAGES];
 	bus_addr_t			rx_bd_chain_paddr[RX_PAGES];
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/* H/W maintained page buffer descriptor chain structure. */
 	bus_dma_tag_t		pg_bd_chain_tag;
 	bus_dmamap_t		pg_bd_chain_map[PG_PAGES];
@@ -6593,7 +6593,7 @@ struct bce_softc
 	bus_dma_tag_t		rx_mbuf_tag;
 	bus_dma_tag_t		tx_mbuf_tag;
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	bus_dma_tag_t		pg_mbuf_tag;
 #endif
 
@@ -6605,7 +6605,7 @@ struct bce_softc
 	bus_dmamap_t		rx_mbuf_map[TOTAL_RX_BD];
 	struct mbuf			*rx_mbuf_ptr[TOTAL_RX_BD];
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	/* S/W maintained mbuf page chain structure. */
 	bus_dmamap_t		pg_mbuf_map[TOTAL_PG_BD];
 	struct mbuf			*pg_mbuf_ptr[TOTAL_PG_BD];
@@ -6617,7 +6617,7 @@ struct bce_softc
 	u16 used_tx_bd;
 	u16 max_tx_bd;
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	u16 free_pg_bd;
 	u16 max_pg_bd;
 #endif
@@ -6705,7 +6705,7 @@ struct bce_softc
 	int	debug_tx_mbuf_alloc;
 	int debug_rx_mbuf_alloc;
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	int debug_pg_mbuf_alloc;
 #endif
 
@@ -6722,7 +6722,7 @@ struct bce_softc
 	u32	rx_low_watermark;			/* Lowest number of rx_bd's free. */
 	u32 rx_empty_count;				/* Number of times the RX chain was empty. */
 
-#ifdef ZERO_COPY_SOCKETS
+#ifdef BCE_JUMBO_HDRSPLIT
 	u32	pg_low_watermark;			/* Lowest number of pages free. */
 	u32 pg_empty_count; 			/* Number of times the page chain was empty. */
 #endif

From e06db1922de2b896c96a4ff7e53e7f37defdb839 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 12:47:39 +0000
Subject: [PATCH 256/646] MFp4: Freeze device queue on error to permit periph
 driver to do proper recovery.

---
 sys/dev/siis/siis.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index c5577d945af..3344bc07b47 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -752,7 +752,12 @@ siis_ch_intr(void *data)
 		if (ch->frozen) {
 			union ccb *fccb = ch->frozen;
 			ch->frozen = NULL;
-			fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+			fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+			fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+			if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+				xpt_freeze_devq(fccb->ccb_h.path, 1);
+				fccb->ccb_h.status |= CAM_DEV_QFRZN;
+			}
 			xpt_done(fccb);
 		}
 		if (estatus == SIIS_P_CMDERR_DEV ||
@@ -986,7 +991,12 @@ device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n",
 	if (ch->frozen) {
 		union ccb *fccb = ch->frozen;
 		ch->frozen = NULL;
-		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+		fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+			xpt_freeze_devq(fccb->ccb_h.path, 1);
+			fccb->ccb_h.status |= CAM_DEV_QFRZN;
+		}
 		xpt_done(fccb);
 	}
 	/* Handle command with timeout. */
@@ -1044,11 +1054,17 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
 		bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map);
 	}
 	/* Set proper result status. */
-	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 	if (et != SIIS_ERR_NONE || ch->recovery) {
 		ch->eslots |= (1 << slot->slot);
 		ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 	}
+	/* In case of error, freeze device for proper recovery. */
+	if (et != SIIS_ERR_NONE &&
+	    !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
+		xpt_freeze_devq(ccb->ccb_h.path, 1);
+		ccb->ccb_h.status |= CAM_DEV_QFRZN;
+	}
+	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 	switch (et) {
 	case SIIS_ERR_NONE:
 		ccb->ccb_h.status |= CAM_REQ_CMP;
@@ -1062,6 +1078,7 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
 		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 		break;
 	case SIIS_ERR_TFE:
+	case SIIS_ERR_NCQ:
 		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
 			ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
@@ -1075,9 +1092,6 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
 	case SIIS_ERR_TIMEOUT:
 		ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
 		break;
-	case SIIS_ERR_NCQ:
-		ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
-		break;
 	default:
 		ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
 	}
@@ -1281,7 +1295,12 @@ siis_reset(device_t dev)
 	if (ch->frozen) {
 		union ccb *fccb = ch->frozen;
 		ch->frozen = NULL;
-		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+		fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+			xpt_freeze_devq(fccb->ccb_h.path, 1);
+			fccb->ccb_h.status |= CAM_DEV_QFRZN;
+		}
 		xpt_done(fccb);
 	}
 	/* Disable port interrupts */

From 8e7cccb3bd53d1b83fcb8365954db636e08305f4 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 13:00:01 +0000
Subject: [PATCH 257/646] MFp4: Report real max_target = 15. SIM doesn't need
 to know that target 15 is PMP. It is XPT business.

---
 sys/cam/ata/ata_xpt.c | 3 ++-
 sys/dev/ahci/ahci.c   | 2 +-
 sys/dev/siis/siis.c   | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 5acb9a35d0c..0d37b067874 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -1212,7 +1212,8 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 take_next:
 		/* Take next device. Wrap from 15 (PM) to 0. */
 		scan_info->counter = (scan_info->counter + 1 ) & 0x0f;
-		if (scan_info->counter >= scan_info->cpi->max_target+1) {
+		if (scan_info->counter > scan_info->cpi->max_target -
+		    ((scan_info->cpi->hba_inquiry & PI_SATAPM) ? 1 : 0)) {
 			xpt_free_ccb(work_ccb);
 			xpt_free_ccb((union ccb *)scan_info->cpi);
 			request_ccb = scan_info->request_ccb;
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 86c1f167b66..485ac3d5ce4 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -1967,7 +1967,7 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
 		cpi->hba_misc = PIM_SEQSCAN;
 		cpi->hba_eng_cnt = 0;
 		if (ch->caps & AHCI_CAP_SPM)
-			cpi->max_target = 14;
+			cpi->max_target = 15;
 		else
 			cpi->max_target = 0;
 		cpi->max_lun = 0;
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 3344bc07b47..207713722d0 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1584,7 +1584,7 @@ siisaction(struct cam_sim *sim, union ccb *ccb)
 		cpi->target_sprt = 0;
 		cpi->hba_misc = PIM_SEQSCAN;
 		cpi->hba_eng_cnt = 0;
-		cpi->max_target = 14;
+		cpi->max_target = 15;
 		cpi->max_lun = 0;
 		cpi->initiator_id = 0;
 		cpi->bus_id = cam_sim_bus(sim);

From 56d7cd7cf1a2de9a8f493fc56defdf429a488a5b Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 21 Oct 2009 14:09:06 +0000
Subject: [PATCH 258/646] Add a missing free() call.

PR:		138379
Submitted by:	Patroklos Argyroudis 
Reviewed by:	gibbs
MFC after:	1 week
---
 sys/dev/aic7xxx/aicasm/aicasm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/dev/aic7xxx/aicasm/aicasm.c b/sys/dev/aic7xxx/aicasm/aicasm.c
index 6ba57bcc29e..3c9109ce38d 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm.c
+++ b/sys/dev/aic7xxx/aicasm/aicasm.c
@@ -639,6 +639,8 @@ output_listing(char *ifilename)
 		}
 		instrptr++;
 	}
+	free(func_values);
+
 	/* Dump the remainder of the file */
 	while(fgets(buf, sizeof(buf), ifile) != NULL)
 		fprintf(listfile, "             %s", buf);

From 46f118fe3f73ae5890df2871ddcaca1507585d6a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 14:20:55 +0000
Subject: [PATCH 259/646] MFp4: Add support for PIO-only devices. Fix maxio
 values and 256 sectors transactions for 28bits commands. Implement periodic
 ordered commands insertion, sames as da driver does. Remove some SCSIsms.

---
 sys/cam/ata/ata_da.c | 196 ++++++++++++++++++++++++-------------------
 1 file changed, 111 insertions(+), 85 deletions(-)

diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 622b91b250a..01c7c13376f 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -63,37 +63,32 @@ __FBSDID("$FreeBSD$");
 #define ATA_MAX_28BIT_LBA               268435455UL
 
 typedef enum {
-	ADA_STATE_NORMAL
+	ADA_STATE_NORMAL,
+	ADA_STATE_SET_MULTI
 } ada_state;
 
 typedef enum {
 	ADA_FLAG_PACK_INVALID	= 0x001,
 	ADA_FLAG_CAN_48BIT	= 0x002,
 	ADA_FLAG_CAN_FLUSHCACHE	= 0x004,
-	ADA_FLAG_CAN_NCQ		= 0x008,
-	ADA_FLAG_TAGGED_QUEUING	= 0x010,
+	ADA_FLAG_CAN_NCQ	= 0x008,
+	ADA_FLAG_CAN_DMA	= 0x010,
 	ADA_FLAG_NEED_OTAG	= 0x020,
 	ADA_FLAG_WENT_IDLE	= 0x040,
-	ADA_FLAG_RETRY_UA	= 0x080,
 	ADA_FLAG_OPEN		= 0x100,
 	ADA_FLAG_SCTX_INIT	= 0x200
 } ada_flags;
 
 typedef enum {
-	ADA_Q_NONE		= 0x00,
-	ADA_Q_NO_SYNC_CACHE	= 0x01,
-	ADA_Q_NO_6_BYTE		= 0x02,
-	ADA_Q_NO_PREVENT		= 0x04
+	ADA_Q_NONE		= 0x00
 } ada_quirks;
 
 typedef enum {
-	ADA_CCB_PROBE		= 0x01,
-	ADA_CCB_PROBE2		= 0x02,
+	ADA_CCB_SET_MULTI	= 0x01,
 	ADA_CCB_BUFFER_IO	= 0x03,
 	ADA_CCB_WAITING		= 0x04,
 	ADA_CCB_DUMP		= 0x05,
 	ADA_CCB_TYPE_MASK	= 0x0F,
-	ADA_CCB_RETRY_UA		= 0x10
 } ada_ccb_state;
 
 /* Offsets into our private area for storing information */
@@ -117,6 +112,7 @@ struct ada_softc {
 	ada_quirks quirks;
 	int	 ordered_tag_count;
 	int	 outstanding_cmds;
+	int	 secsperint;
 	struct	 disk_params params;
 	struct	 disk *disk;
 	union	 ccb saved_ccb;
@@ -289,8 +285,7 @@ adaclose(struct disk *dp)
 		else
 			ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
 		cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
-		    /*sense_flags*/SF_RETRY_UA,
-		    softc->disk->d_devstat);
+		    /*sense_flags*/0, softc->disk->d_devstat);
 
 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
 			xpt_print(periph->path, "Synchronize cache failed\n");
@@ -331,19 +326,6 @@ adastrategy(struct bio *bp)
 
 	cam_periph_lock(periph);
 
-#if 0
-	/*
-	 * check it's not too big a transfer for our adapter
-	 */
-	scsi_minphys(bp,&sd_switch);
-#endif
-
-	/*
-	 * Mask interrupts so that the pack cannot be invalidated until
-	 * after we are in the queue.  Otherwise, we might not properly
-	 * clean up one of the buffers.
-	 */
-	
 	/*
 	 * If the device has been made invalid, error out
 	 */
@@ -551,11 +533,6 @@ adaasync(void *callback_arg, u_int32_t code,
 		if (cgd->protocol != PROTO_ATA)
 			break;
 
-//		if (SID_TYPE(&cgd->inq_data) != T_DIRECT
-//		    && SID_TYPE(&cgd->inq_data) != T_RBC
-//		    && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
-//			break;
-
 		/*
 		 * Allocate a peripheral instance for
 		 * this device and start the probe
@@ -576,18 +553,18 @@ adaasync(void *callback_arg, u_int32_t code,
 	case AC_SENT_BDR:
 	case AC_BUS_RESET:
 	{
-		struct ada_softc *softc;
-		struct ccb_hdr *ccbh;
+		struct ada_softc *softc = (struct ada_softc *)periph->softc;
 
-		softc = (struct ada_softc *)periph->softc;
+		cam_periph_async(periph, code, path, arg);
+		if (softc->state != ADA_STATE_NORMAL)
+			break;
 		/*
-		 * Don't fail on the expected unit attention
-		 * that will occur.
+		 * Restore device configuration.
 		 */
-		softc->flags |= ADA_FLAG_RETRY_UA;
-		LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
-			ccbh->ccb_state |= ADA_CCB_RETRY_UA;
-		/* FALLTHROUGH*/
+		softc->state = ADA_STATE_SET_MULTI;
+		cam_periph_acquire(periph);
+		xpt_schedule(periph, 0);
+		break;
 	}
 	default:
 		cam_periph_async(periph, code, path, arg);
@@ -651,14 +628,15 @@ adaregister(struct cam_periph *periph, void *arg)
 
 	if (softc == NULL) {
 		printf("adaregister: Unable to probe new device. "
-		       "Unable to allocate softc\n");				
+		    "Unable to allocate softc\n");
 		return(CAM_REQ_CMP_ERR);
 	}
 
 	LIST_INIT(&softc->pending_ccbs);
-	softc->state = ADA_STATE_NORMAL;
 	bioq_init(&softc->bio_queue);
 
+	if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA)
+		softc->flags |= ADA_FLAG_CAN_DMA;
 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
 		softc->flags |= ADA_FLAG_CAN_48BIT;
 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
@@ -666,8 +644,8 @@ adaregister(struct cam_periph *periph, void *arg)
 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
 	    cgd->ident_data.queue >= 31)
 		softc->flags |= ADA_FLAG_CAN_NCQ;
-//	if ((cgd->inq_data.flags & SID_CmdQue) != 0)
-//		softc->flags |= ADA_FLAG_TAGGED_QUEUING;
+	softc->secsperint = max(1, min(cgd->ident_data.sectors_intr, 16));
+	softc->state = ADA_STATE_SET_MULTI;
 
 	periph->softc = softc;
 
@@ -713,9 +691,9 @@ adaregister(struct cam_periph *periph, void *arg)
 	else if (maxio > MAXPHYS)
 		maxio = MAXPHYS;	/* for safety */
 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
-		maxio = min(maxio, 65535 * 512);
+		maxio = min(maxio, 65536 * 512);
 	else					/* 28bit ATA command limit */
-		maxio = min(maxio, 255 * 512);
+		maxio = min(maxio, 256 * 512);
 	softc->disk->d_maxsize = maxio;
 	softc->disk->d_unit = periph->unit_number;
 	softc->disk->d_flags = 0;
@@ -730,8 +708,6 @@ adaregister(struct cam_periph *periph, void *arg)
 	/* XXX: these are not actually "firmware" values, so they may be wrong */
 	softc->disk->d_fwsectors = softc->params.secs_per_track;
 	softc->disk->d_fwheads = softc->params.heads;
-//	softc->disk->d_devstat->block_size = softc->params.secsize;
-//	softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
 
 	disk_create(softc->disk, DISK_VERSION);
 	mtx_lock(periph->sim->mtx);
@@ -766,8 +742,8 @@ adaregister(struct cam_periph *periph, void *arg)
 	 * to finish the probe.  The reference will be dropped in adadone at
 	 * the end of probe.
 	 */
-//	(void)cam_periph_hold(periph, PRIBIO);
-//	xpt_schedule(periph, /*priority*/5);
+	cam_periph_acquire(periph);
+	xpt_schedule(periph, /*priority*/5);
 
 	/*
 	 * Schedule a periodic event to occasionally send an
@@ -784,9 +760,8 @@ adaregister(struct cam_periph *periph, void *arg)
 static void
 adastart(struct cam_periph *periph, union ccb *start_ccb)
 {
-	struct ada_softc *softc;
-
-	softc = (struct ada_softc *)periph->softc;
+	struct ada_softc *softc = (struct ada_softc *)periph->softc;
+	struct ccb_ataio *ataio = &start_ccb->ataio;
 
 	switch (softc->state) {
 	case ADA_STATE_NORMAL:
@@ -809,7 +784,6 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 		} else if (bp == NULL) {
 			xpt_release_ccb(start_ccb);
 		} else {
-			struct ccb_ataio *ataio = &start_ccb->ataio;
 			u_int8_t tag_code;
 
 			bioq_remove(&softc->bio_queue, bp);
@@ -817,9 +791,9 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 			if ((softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
 				softc->flags &= ~ADA_FLAG_NEED_OTAG;
 				softc->ordered_tag_count++;
-				tag_code = 0;//MSG_ORDERED_Q_TAG;
+				tag_code = 0;
 			} else {
-				tag_code = 0;//MSG_SIMPLE_Q_TAG;
+				tag_code = 1;
 			}
 			switch (bp->bio_cmd) {
 			case BIO_READ:
@@ -838,7 +812,7 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 				    bp->bio_bcount,
 				    ada_default_timeout*1000);
 
-				if (softc->flags & ADA_FLAG_CAN_NCQ) {
+				if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
 					if (bp->bio_cmd == BIO_READ) {
 						ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
 						    lba, count);
@@ -848,21 +822,43 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 					}
 				} else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
 				    (lba + count >= ATA_MAX_28BIT_LBA ||
-				    count >= 256)) {
-					if (bp->bio_cmd == BIO_READ) {
-						ata_48bit_cmd(ataio, ATA_READ_DMA48,
-						    0, lba, count);
+				    count > 256)) {
+					if (softc->flags & ADA_FLAG_CAN_DMA) {
+						if (bp->bio_cmd == BIO_READ) {
+							ata_48bit_cmd(ataio, ATA_READ_DMA48,
+							    0, lba, count);
+						} else {
+							ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
+							    0, lba, count);
+						}
 					} else {
-						ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
-						    0, lba, count);
+						if (bp->bio_cmd == BIO_READ) {
+							ata_48bit_cmd(ataio, ATA_READ_MUL48,
+							    0, lba, count);
+						} else {
+							ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
+							    0, lba, count);
+						}
 					}
 				} else {
-					if (bp->bio_cmd == BIO_READ) {
-						ata_28bit_cmd(ataio, ATA_READ_DMA,
-						    0, lba, count);
+					if (count == 256)
+						count = 0;
+					if (softc->flags & ADA_FLAG_CAN_DMA) {
+						if (bp->bio_cmd == BIO_READ) {
+							ata_28bit_cmd(ataio, ATA_READ_DMA,
+							    0, lba, count);
+						} else {
+							ata_28bit_cmd(ataio, ATA_WRITE_DMA,
+							    0, lba, count);
+						}
 					} else {
-						ata_28bit_cmd(ataio, ATA_WRITE_DMA,
-						    0, lba, count);
+						if (bp->bio_cmd == BIO_READ) {
+							ata_28bit_cmd(ataio, ATA_READ_MUL,
+							    0, lba, count);
+						} else {
+							ata_28bit_cmd(ataio, ATA_WRITE_MUL,
+							    0, lba, count);
+						}
 					}
 				}
 			}
@@ -872,7 +868,7 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 				    1,
 				    adadone,
 				    CAM_DIR_NONE,
-				    tag_code,
+				    0,
 				    NULL,
 				    0,
 				    ada_default_timeout*1000);
@@ -893,12 +889,6 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 					 &start_ccb->ccb_h, periph_links.le);
 			softc->outstanding_cmds++;
 
-			/* We expect a unit attention from this device */
-			if ((softc->flags & ADA_FLAG_RETRY_UA) != 0) {
-				start_ccb->ccb_h.ccb_state |= ADA_CCB_RETRY_UA;
-				softc->flags &= ~ADA_FLAG_RETRY_UA;
-			}
-
 			start_ccb->ccb_h.ccb_bp = bp;
 			bp = bioq_first(&softc->bio_queue);
 
@@ -911,6 +901,21 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 		}
 		break;
 	}
+	case ADA_STATE_SET_MULTI:
+	{
+		cam_fill_ataio(ataio,
+		    ada_retry_count,
+		    adadone,
+		    CAM_DIR_NONE,
+		    0,
+		    NULL,
+		    0,
+		    ada_default_timeout*1000);
+
+		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, softc->secsperint);
+		start_ccb->ccb_h.ccb_state = ADA_CCB_SET_MULTI;
+		xpt_action(start_ccb);
+	}
 	}
 }
 
@@ -931,16 +936,12 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 			int error;
 			
-			error = adaerror(done_ccb, CAM_RETRY_SELTO, 0);
+			error = adaerror(done_ccb, 0, 0);
 			if (error == ERESTART) {
-				/*
-				 * A retry was scheuled, so
-				 * just return.
-				 */
+				/* A retry was scheduled, so just return. */
 				return;
 			}
 			if (error != 0) {
-
 				if (error == ENXIO) {
 					/*
 					 * Catastrophic error.  Mark our pack as
@@ -1002,6 +1003,35 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 		wakeup(&done_ccb->ccb_h.cbfcnp);
 		return;
 	}
+	case ADA_CCB_SET_MULTI:
+	{
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+		} else {
+			int	error;
+
+			error = adaerror(done_ccb, 0, 0);
+			if (error == ERESTART) {
+				/* A retry was scheduled, so just return. */
+				return;
+			}
+		}
+		softc->state = ADA_STATE_NORMAL;
+		/*
+		 * Since our peripheral may be invalidated by an error
+		 * above or an external event, we must release our CCB
+		 * before releasing the probe lock on the peripheral.
+		 * The peripheral will only go away once the last lock
+		 * is removed, and we need it around for the CCB release
+		 * operation.
+		 */
+		xpt_release_ccb(done_ccb);
+		if (bioq_first(&softc->bio_queue) != NULL) {
+			/* Have more work to do, so ensure we stay scheduled */
+			xpt_schedule(periph, 1);
+		}
+		cam_periph_release_locked(periph);
+		return;
+	}
 	case ADA_CCB_DUMP:
 		/* No-op.  We're polling */
 		return;
@@ -1049,10 +1079,6 @@ adasetgeom(struct cam_periph *periph, struct ccb_getdev *cgd)
 	lbasize = (u_int32_t)cgd->ident_data.lba_size_1 |
 		  ((u_int32_t)cgd->ident_data.lba_size_2 << 16);
 
-    /* does this device need oldstyle CHS addressing */
-//    if (!ad_version(cgd->ident_data.version_major) || !lbasize)
-//	atadev->flags |= ATA_D_USE_CHS;
-
 	/* use the 28bit LBA size if valid or bigger than the CHS mapping */
 	if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
 		dp->sectors = lbasize;

From 022ad82222d2b33be4e9a6f38bff19f24e86ecc2 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 21 Oct 2009 15:04:50 +0000
Subject: [PATCH 260/646] Check pointer for NULL before dereferencing it, not
 after.

PR:		138384
Submitted by:	Patroklos Argyroudis 
MFC after:	1 week
---
 sys/dev/ips/ips_disk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/ips/ips_disk.c b/sys/dev/ips/ips_disk.c
index 9e2fd5c2535..12bdacd6311 100644
--- a/sys/dev/ips/ips_disk.c
+++ b/sys/dev/ips/ips_disk.c
@@ -192,10 +192,10 @@ ipsd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
 
 	dp = arg;
 	dsc = dp->d_drv1;
-	sc = dsc->sc;
 
 	if (dsc == NULL)
 		return (EINVAL);
+	sc = dsc->sc;
 
 	if (ips_get_free_cmd(sc, &command, 0) != 0) {
 		printf("ipsd: failed to get cmd for dump\n");

From 4b997c49c0d9862c314ec6f05bc26a7184506dc0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 15:27:48 +0000
Subject: [PATCH 261/646] MFp4: Separate CAM_DEV_IDENTIFY_DATA_VALID flag from
 CAM_DEV_INQUIRY_DATA_VALID. Add workaround for very old devices without
 support for mode setting. Add some PATA bus scanning support. Remove some
 SCSIsms.

---
 sys/cam/ata/ata_xpt.c      | 202 +++++--------------------------------
 sys/cam/cam_xpt_internal.h |   1 +
 2 files changed, 29 insertions(+), 174 deletions(-)

diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 0d37b067874..dc25299433e 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
 
 #include 
 #include 
-#include 
 #include 
 #include 	/* for xpt_print below */
 #include "opt_cam.h"
@@ -755,11 +754,8 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 				    strlen(path->device->serial_num);
 			}
 
-			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
-
-			scsi_find_quirk(path->device);
+			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
 			ata_device_transport(path);
-
 			PROBE_SET_ACTION(softc, PROBE_SETMODE);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
@@ -793,7 +789,7 @@ device_fail:
 	case PROBE_SETMODE:
 	{
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			if (path->device->protocol == PROTO_ATA) {
+modedone:		if (path->device->protocol == PROTO_ATA) {
 				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 				xpt_action(done_ccb);
@@ -815,6 +811,10 @@ device_fail:
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
+		/* Old PIO2 devices may not support mode setting. */
+		if (ata_max_pmode(ident_buf) <= ATA_PIO2 &&
+		    (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0)
+			goto modedone;
 		goto device_fail;
 	}
 	case PROBE_INQUIRY:
@@ -854,8 +854,7 @@ device_fail:
 				}
 
 				scsi_find_quirk(path->device);
-
-//				scsi_devise_transport(path);
+				ata_device_transport(path);
 				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 				xpt_action(done_ccb);
@@ -876,7 +875,7 @@ device_fail:
 	}
 	case PROBE_PM_PID:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0)
+			if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0)
 				bzero(ident_buf, sizeof(*ident_buf));
 			softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
 			    (done_ccb->ataio.res.lba_mid << 16) +
@@ -940,7 +939,7 @@ device_fail:
 				softc->pm_ports = 5;
 			printf("PM ports: %d\n", softc->pm_ports);
 			ident_buf->config = softc->pm_ports;
-			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
+			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
 			softc->pm_step = 0;
 			PROBE_SET_ACTION(softc, PROBE_PM_RESET);
 			xpt_release_ccb(done_ccb);
@@ -1170,7 +1169,10 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 		}
 		scan_info->request_ccb = request_ccb;
 		scan_info->cpi = &work_ccb->cpi;
-		scan_info->found = 0x8001;
+		if (scan_info->cpi->transport == XPORT_ATA)
+			scan_info->found = 0x0003;
+		else
+			scan_info->found = 0x8001;
 		scan_info->counter = 0;
 		/* If PM supported, probe it first. */
 		if (scan_info->cpi->hba_inquiry & PI_SATAPM)
@@ -1400,68 +1402,29 @@ static void
 ata_device_transport(struct cam_path *path)
 {
 	struct ccb_pathinq cpi;
-//	struct ccb_trans_settings cts;
-	struct scsi_inquiry_data *inq_buf;
+	struct ccb_trans_settings cts;
+	struct scsi_inquiry_data *inq_buf = NULL;
+	struct ata_params *ident_buf = NULL;
 
 	/* Get transport information from the SIM */
 	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
-	inq_buf = NULL;
-//	if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
-//		inq_buf = &path->device->inq_data;
-//	path->device->protocol = cpi.protocol;
-//	path->device->protocol_version =
-//	    inq_buf != NULL ? SID_ANSI_REV(inq_buf) : cpi.protocol_version;
 	path->device->transport = cpi.transport;
-	path->device->transport_version = cpi.transport_version;
-#if 0
-	/*
-	 * Any device not using SPI3 features should
-	 * be considered SPI2 or lower.
-	 */
-	if (inq_buf != NULL) {
-		if (path->device->transport == XPORT_SPI
-		 && (inq_buf->spi3data & SID_SPI_MASK) == 0
-		 && path->device->transport_version > 2)
-			path->device->transport_version = 2;
-	} else {
-		struct cam_ed* otherdev;
-
-		for (otherdev = TAILQ_FIRST(&path->target->ed_entries);
-		     otherdev != NULL;
-		     otherdev = TAILQ_NEXT(otherdev, links)) {
-			if (otherdev != path->device)
-				break;
-		}
-
-		if (otherdev != NULL) {
-			/*
-			 * Initially assume the same versioning as
-			 * prior luns for this target.
-			 */
-			path->device->protocol_version =
-			    otherdev->protocol_version;
-			path->device->transport_version =
-			    otherdev->transport_version;
-		} else {
-			/* Until we know better, opt for safty */
-			path->device->protocol_version = 2;
-			if (path->device->transport == XPORT_SPI)
-				path->device->transport_version = 2;
-			else
-				path->device->transport_version = 0;
-		}
+	if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
+		inq_buf = &path->device->inq_data;
+	if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) != 0)
+		ident_buf = &path->device->ident_data;
+	if (path->device->protocol == PROTO_ATA) {
+		path->device->protocol_version = ident_buf ?
+		    ata_version(ident_buf->version_major) : cpi.protocol_version;
+	} else if (path->device->protocol == PROTO_SCSI) {
+		path->device->protocol_version = inq_buf ?
+		    SID_ANSI_REV(inq_buf) : cpi.protocol_version;
 	}
-
-	/*
-	 * XXX
-	 * For a device compliant with SPC-2 we should be able
-	 * to determine the transport version supported by
-	 * scrutinizing the version descriptors in the
-	 * inquiry buffer.
-	 */
+	path->device->transport_version = ident_buf ?
+	    ata_version(ident_buf->version_major) : cpi.transport_version;
 
 	/* Tell the controller what we think */
 	xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
@@ -1474,7 +1437,6 @@ ata_device_transport(struct cam_path *path)
 	cts.proto_specific.valid = 0;
 	cts.xport_specific.valid = 0;
 	xpt_action((union ccb *)&cts);
-#endif
 }
 
 static void
@@ -1630,114 +1592,6 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 	}
 
-	/* SPI specific sanity checking */
-	if (cts->transport == XPORT_SPI && async_update == FALSE) {
-		u_int spi3caps;
-		struct ccb_trans_settings_spi *spi;
-		struct ccb_trans_settings_spi *cur_spi;
-
-		spi = &cts->xport_specific.spi;
-
-		cur_spi = &cur_cts.xport_specific.spi;
-
-		/* Fill in any gaps in what the user gave us */
-		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
-			spi->sync_period = cur_spi->sync_period;
-		if ((cur_spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
-			spi->sync_period = 0;
-		if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
-			spi->sync_offset = cur_spi->sync_offset;
-		if ((cur_spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
-			spi->sync_offset = 0;
-		if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
-			spi->ppr_options = cur_spi->ppr_options;
-		if ((cur_spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
-			spi->ppr_options = 0;
-		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
-			spi->bus_width = cur_spi->bus_width;
-		if ((cur_spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
-			spi->bus_width = 0;
-		if ((spi->valid & CTS_SPI_VALID_DISC) == 0) {
-			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
-			spi->flags |= cur_spi->flags & CTS_SPI_FLAGS_DISC_ENB;
-		}
-		if ((cur_spi->valid & CTS_SPI_VALID_DISC) == 0)
-			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
-		if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
-		  && (inq_data->flags & SID_Sync) == 0
-		  && cts->type == CTS_TYPE_CURRENT_SETTINGS)
-		 || ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0)) {
-			/* Force async */
-			spi->sync_period = 0;
-			spi->sync_offset = 0;
-		}
-
-		switch (spi->bus_width) {
-		case MSG_EXT_WDTR_BUS_32_BIT:
-			if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
-			  || (inq_data->flags & SID_WBus32) != 0
-			  || cts->type == CTS_TYPE_USER_SETTINGS)
-			 && (cpi.hba_inquiry & PI_WIDE_32) != 0)
-				break;
-			/* Fall Through to 16-bit */
-		case MSG_EXT_WDTR_BUS_16_BIT:
-			if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
-			  || (inq_data->flags & SID_WBus16) != 0
-			  || cts->type == CTS_TYPE_USER_SETTINGS)
-			 && (cpi.hba_inquiry & PI_WIDE_16) != 0) {
-				spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
-				break;
-			}
-			/* Fall Through to 8-bit */
-		default: /* New bus width?? */
-		case MSG_EXT_WDTR_BUS_8_BIT:
-			/* All targets can do this */
-			spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
-			break;
-		}
-
-		spi3caps = cpi.xport_specific.spi.ppr_options;
-		if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
-		 && cts->type == CTS_TYPE_CURRENT_SETTINGS)
-			spi3caps &= inq_data->spi3data;
-
-		if ((spi3caps & SID_SPI_CLOCK_DT) == 0)
-			spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-
-		if ((spi3caps & SID_SPI_IUS) == 0)
-			spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ;
-
-		if ((spi3caps & SID_SPI_QAS) == 0)
-			spi->ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
-
-		/* No SPI Transfer settings are allowed unless we are wide */
-		if (spi->bus_width == 0)
-			spi->ppr_options = 0;
-
-		if ((spi->valid & CTS_SPI_VALID_DISC)
-		 && ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) == 0)) {
-			/*
-			 * Can't tag queue without disconnection.
-			 */
-			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
-			scsi->valid |= CTS_SCSI_VALID_TQ;
-		}
-
-		/*
-		 * If we are currently performing tagged transactions to
-		 * this device and want to change its negotiation parameters,
-		 * go non-tagged for a bit to give the controller a chance to
-		 * negotiate unhampered by tag messages.
-		 */
-		if (cts->type == CTS_TYPE_CURRENT_SETTINGS
-		 && (device->inq_flags & SID_CmdQue) != 0
-		 && (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
-		 && (spi->flags & (CTS_SPI_VALID_SYNC_RATE|
-				   CTS_SPI_VALID_SYNC_OFFSET|
-				   CTS_SPI_VALID_BUS_WIDTH)) != 0)
-			scsi_toggle_tags(cts->ccb_h.path);
-	}
-
 	if (cts->type == CTS_TYPE_CURRENT_SETTINGS
 	 && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
 		int device_tagenb;
diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
index e40cde84b57..9e5e3f1e951 100644
--- a/sys/cam/cam_xpt_internal.h
+++ b/sys/cam/cam_xpt_internal.h
@@ -116,6 +116,7 @@ struct cam_ed {
 #define CAM_DEV_INQUIRY_DATA_VALID	0x40
 #define	CAM_DEV_IN_DV			0x80
 #define	CAM_DEV_DV_HIT_BOTTOM		0x100
+#define CAM_DEV_IDENTIFY_DATA_VALID	0x200
 	u_int32_t	 tag_delay_count;
 #define	CAM_TAG_DELAY_COUNT		5
 	u_int32_t	 tag_saved_openings;

From 41d7d5932ee7af78afa595bdd4cb502142293cd9 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 21 Oct 2009 15:54:45 +0000
Subject: [PATCH 262/646] Check pointer for NULL before dereferencing it, not
 after.

PR:		138383
Submitted by:	Patroklos Argyroudis 
Reviewed by:	rnoland
MFC after:	1 week
---
 sys/dev/drm/mach64_state.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/dev/drm/mach64_state.c b/sys/dev/drm/mach64_state.c
index d59d55e7dd6..16848c23ac1 100644
--- a/sys/dev/drm/mach64_state.c
+++ b/sys/dev/drm/mach64_state.c
@@ -826,7 +826,7 @@ int mach64_dma_vertex(struct drm_device *dev, void *data,
 		      struct drm_file *file_priv)
 {
 	drm_mach64_private_t *dev_priv = dev->dev_private;
-	drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	drm_mach64_sarea_t *sarea_priv;
 	drm_mach64_vertex_t *vertex = data;
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -835,6 +835,7 @@ int mach64_dma_vertex(struct drm_device *dev, void *data,
 		DRM_ERROR("called with no initialization\n");
 		return -EINVAL;
 	}
+	sarea_priv = dev_priv->sarea_priv;
 
 	DRM_DEBUG("pid=%d buf=%p used=%lu discard=%d\n",
 		  DRM_CURRENTPID,

From c0d232d988604b6200b6af1be08f9bb40823ca5d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Wed, 21 Oct 2009 15:57:16 +0000
Subject: [PATCH 263/646] MFp4: Do not search for bus when it is not needed,

---
 sys/cam/cam_xpt.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 39b25dfa97c..9afeafa3bf5 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4148,8 +4148,6 @@ xpt_release_simq(struct cam_sim *sim, int run_queue)
 
 		sendq->qfrozen_cnt--;
 		if (sendq->qfrozen_cnt == 0) {
-			struct cam_eb *bus;
-
 			/*
 			 * If there is a timeout scheduled to release this
 			 * sim queue, remove it.  The queue frozen count is
@@ -4159,15 +4157,17 @@ xpt_release_simq(struct cam_sim *sim, int run_queue)
 				callout_stop(&sim->callout);
 				sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING;
 			}
-			bus = xpt_find_bus(sim->path_id);
 
 			if (run_queue) {
+				struct cam_eb *bus;
+
 				/*
 				 * Now that we are unfrozen run the send queue.
 				 */
+				bus = xpt_find_bus(sim->path_id);
 				xpt_run_dev_sendq(bus);
+				xpt_release_bus(bus);
 			}
-			xpt_release_bus(bus);
 		}
 	}
 }

From 9448b439eca6fc6baa21d2f7352ca00641eb00ec Mon Sep 17 00:00:00 2001
From: Roman Divacky 
Date: Wed, 21 Oct 2009 17:07:46 +0000
Subject: [PATCH 264/646] Set CSTD in all cases except when CC=icc and NO_WARNS
 is set. This way we can set desired C standard even for cross tools etc.

Tested by:	make universe
Approved by:	ed (maintainer)
OK by:		das
---
 share/mk/bsd.sys.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk
index 34e04f8cf26..f0a40c968ef 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -11,7 +11,7 @@
 # the default is gnu99 for now
 CSTD		?= gnu99
 
-.if !defined(NO_WARNS) && ${CC} != "icc"
+.if !defined(NO_WARNS) || ${CC} != "icc"
 . if ${CSTD} == "k&r"
 CFLAGS		+= -traditional
 . elif ${CSTD} == "c89" || ${CSTD} == "c90"

From d79186defa34b97f6e276f6c47bcd03e8b256f31 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Wed, 21 Oct 2009 18:09:48 +0000
Subject: [PATCH 265/646] o   Align function on a 32-byte boundary so that the
 core's front-end     can deliver 2 bundles per cycle to the back-end. o  
 Mark syscall stubs with a special unwind ABI tag so that unwind     libraries
 know how to unwind.

---
 sys/ia64/include/asm.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/sys/ia64/include/asm.h b/sys/ia64/include/asm.h
index 0e50d47ae5e..016bc870f2f 100644
--- a/sys/ia64/include/asm.h
+++ b/sys/ia64/include/asm.h
@@ -61,7 +61,7 @@
  */
 #define	ENTRY(_name_, _n_args_)			\
 	.global	_name_;				\
-	.align	16;				\
+	.align	32;				\
 	.proc	_name_;				\
 _name_:;					\
 	.regstk	_n_args_, 0, 0, 0;		\
@@ -69,7 +69,7 @@ _name_:;					\
 
 #define	ENTRY_NOPROFILE(_name_, _n_args_)	\
 	.global	_name_;				\
-	.align	16;				\
+	.align	32;				\
 	.proc	_name_;				\
 _name_:;					\
 	.regstk	_n_args_, 0, 0, 0
@@ -79,7 +79,7 @@ _name_:;					\
  *	Declare a local leaf function.
  */
 #define STATIC_ENTRY(_name_, _n_args_)		\
-	.align	16;				\
+	.align	32;				\
 	.proc	_name_;				\
 _name_:;					\
 	.regstk	_n_args_, 0, 0, 0		\
@@ -161,6 +161,10 @@ label:	ASCIZ msg;				\
 #define	SYSCALLNUM(name)	SYS_ ## name
 
 #define	CALLSYS_NOERROR(name)					\
+	.prologue ;						\
+	.unwabi		@svr4, 'S' ;				\
+	.save		rp, r0 ;				\
+	.body ;							\
 {	.mmi ;							\
 	alloc		r9 = ar.pfs, 0, 0, 8, 0 ;		\
 	mov		r31 = ar.k5 ;				\

From c0d2581bcb70da8c4ca5b51a5f7fbf94d7dbd99e Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Wed, 21 Oct 2009 18:29:26 +0000
Subject: [PATCH 266/646] PR: 139751 Approved by: des Obtained from: Xavier
 Heiny  MFC after: 3 weeks

---
 lib/libfetch/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index d49336a90ce..c54804bcd8d 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -772,7 +772,7 @@ fetch_no_proxy_match(const char *host)
 				break;
 
 		d_len = q - p;
-		if (d_len > 0 && h_len > d_len &&
+		if (d_len > 0 && h_len >= d_len &&
 		    strncasecmp(host + h_len - d_len,
 			p, d_len) == 0) {
 			/* domain name matches */

From a7b5ad271ca6f0dca42accb1e6b16a630f74451d Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Wed, 21 Oct 2009 18:31:54 +0000
Subject: [PATCH 267/646] Make input parsing in Farhenheit actually work.

Don't clobber *p with '\0' when testing whether it has the value of 'F'.
Just use the semantics of strtof() properly. If it returns p, we know
that it parsed the string until it reached 'C' or 'F'.

The code has not changed since it has been imported (r161951, Sep 3,
2006).

Submitted by:	Alexandre Perrin 
MFC after:	1 week
---
 sbin/sysctl/sysctl.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 4140fb3a586..4810c6165b8 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -68,7 +68,7 @@ static int	sysctl_all(int *oid, int len);
 static int	name2oid(char *, int *);
 
 static void	set_T_dev_t(char *, void **, size_t *);
-static int	set_IK(char *, int *);
+static int	set_IK(const char *, int *);
 
 static void
 usage(void)
@@ -452,19 +452,19 @@ set_T_dev_t(char *path, void **val, size_t *size)
 }
 
 static int
-set_IK(char *str, int *val)
+set_IK(const char *str, int *val)
 {
 	float temp;
 	int len, kelv;
-	char *p, *endptr;
+	const char *p;
+	char *endptr;
 
 	if ((len = strlen(str)) == 0)
 		return (0);
 	p = &str[len - 1];
 	if (*p == 'C' || *p == 'F') {
-		*p = '\0';
 		temp = strtof(str, &endptr);
-		if (endptr == str || *endptr != '\0')
+		if (endptr == str || endptr != p)
 			return (0);
 		if (*p == 'F')
 			temp = (temp - 32) * 5 / 9;

From 1a4fcaebe30b3067a19baf8871a27942f4bb32cf Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Wed, 21 Oct 2009 18:38:02 +0000
Subject: [PATCH 268/646] o   Introduce vm_sync_icache() for making the I-cache
 coherent with     the memory or D-cache, depending on the semantics of the
 platform.     vm_sync_icache() is basically a wrapper around
 pmap_sync_icache(),     that translates the vm_map_t argumument to pmap_t. o 
  Introduce pmap_sync_icache() to all PMAP implementation. For powerpc     it
 replaces the pmap_page_executable() function, added to solve     the I-cache
 problem in uiomove_fromphys(). o   In proc_rwmem() call vm_sync_icache() when
 writing to a page that     has execute permissions. This assures that when
 breakpoints are     written, the I-cache will be coherent and the process
 will actually     hit the breakpoint. o   This also fixes the Book-E PMAP
 implementation that was missing     necessary locking while trying to deal
 with the I-cache coherency     in pmap_enter() (read:
 mmu_booke_enter_locked).

The key property of this change is that the I-cache is made coherent
*after* writes have been done. Doing it in the PMAP layer when adding
or changing a mapping means that the I-cache is made coherent *before*
any writes happen. The difference is key when the I-cache prefetches.
---
 sys/amd64/amd64/pmap.c              |  5 ++
 sys/arm/arm/pmap.c                  | 10 +++-
 sys/arm/mv/mv_machdep.c             |  2 +-
 sys/i386/i386/pmap.c                |  5 ++
 sys/i386/xen/pmap.c                 |  5 ++
 sys/ia64/ia64/pmap.c                | 27 +++++++++++
 sys/kern/sys_process.c              |  4 ++
 sys/mips/mips/pmap.c                |  5 ++
 sys/powerpc/aim/mmu_oea.c           | 34 ++++++++++----
 sys/powerpc/aim/mmu_oea64.c         | 50 +++++++++++++-------
 sys/powerpc/booke/pmap.c            | 72 ++++++++++++++++-------------
 sys/powerpc/include/pmap.h          |  1 -
 sys/powerpc/powerpc/mmu_if.m        | 18 +++++---
 sys/powerpc/powerpc/pmap_dispatch.c | 10 ++--
 sys/powerpc/powerpc/uio_machdep.c   |  3 --
 sys/sparc64/sparc64/pmap.c          |  5 ++
 sys/sun4v/sun4v/pmap.c              |  5 ++
 sys/vm/pmap.h                       |  1 +
 sys/vm/vm_extern.h                  |  1 +
 sys/vm/vm_glue.c                    |  7 +++
 20 files changed, 196 insertions(+), 74 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index dd81d6b174b..c928294cf6c 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -4810,6 +4810,11 @@ if (oldpmap)	/* XXX FIXME */
 	critical_exit();
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 5e55f8ee09a..3b70a41056f 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -2863,14 +2863,14 @@ pmap_kenter_internal(vm_offset_t va, vm_offset_t pa, int flags)
 	if (pvzone != NULL && (m = vm_phys_paddr_to_vm_page(pa))) {
 		vm_page_lock_queues();
 		if (!TAILQ_EMPTY(&m->md.pv_list) || m->md.pv_kva) {
-				/* release vm_page lock for pv_entry UMA */
+			/* release vm_page lock for pv_entry UMA */
 			vm_page_unlock_queues();
 			if ((pve = pmap_get_pv_entry()) == NULL)
 				panic("pmap_kenter_internal: no pv entries");	
 			vm_page_lock_queues();
 			PMAP_LOCK(pmap_kernel());
 			pmap_enter_pv(m, pve, pmap_kernel(), va,
-					 PVF_WRITE | PVF_UNMAN);
+			    PVF_WRITE | PVF_UNMAN);
 			pmap_fix_cache(m, pmap_kernel(), va);
 			PMAP_UNLOCK(pmap_kernel());
 		} else {
@@ -4567,6 +4567,12 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
 }
 
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index 2dc20ceb08e..c348e24b3ca 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -408,7 +408,7 @@ initarm(void *mdp, void *unused __unused)
 		availmem_regions_sz = i;
 	} else {
 		/* Fall back to hardcoded boothowto flags and metadata. */
-		boothowto = RB_VERBOSE | RB_SINGLE;
+		boothowto = 0; // RB_VERBOSE | RB_SINGLE;
 		lastaddr = fake_preload_metadata();
 
 		/*
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 7e3bc3701ce..74edbbc4994 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -4859,6 +4859,11 @@ pmap_activate(struct thread *td)
 	critical_exit();
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 1d9c9c1cd9c..5bf1331c145 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -4175,6 +4175,11 @@ pmap_activate(struct thread *td)
 	critical_exit();
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index a5a2bc3f989..a6fac1f57a8 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -2276,6 +2276,33 @@ out:
 	return (prevpm);
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+	pmap_t oldpm;
+	struct ia64_lpte *pte;
+	vm_offset_t lim;
+	vm_size_t len;
+
+	sz += va & 31;
+	va &= ~31;
+	sz = (sz + 31) & ~31;
+
+	PMAP_LOCK(pm);
+	oldpm = pmap_switch(pm);
+	while (sz > 0) {
+		lim = round_page(va);
+		len = MIN(lim - va, sz);
+		pte = pmap_find_vhpt(va);
+		if (pte != NULL && pmap_present(pte))
+			ia64_sync_icache(va, len);
+		va += len;
+		sz -= len;
+	}
+	pmap_switch(oldpm);
+	PMAP_UNLOCK(pm);
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index b8803af0c83..88a5b89f8a0 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -327,6 +327,10 @@ proc_rwmem(struct proc *p, struct uio *uio)
 		 */
 		error = uiomove_fromphys(&m, page_offset, len, uio);
 
+		/* Make the I-cache coherent for breakpoints. */
+		if (!error && writing && (out_prot & VM_PROT_EXECUTE))
+			vm_sync_icache(map, uva, len);
+
 		/*
 		 * Release the page.
 		 */
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index 7b106dc4a4a..25b0b3a7bbd 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -2903,6 +2903,11 @@ pmap_activate(struct thread *td)
 	critical_exit();
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index bbf2e04daae..1ca230c7015 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -330,7 +330,7 @@ void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t);
 vm_offset_t moea_kextract(mmu_t, vm_offset_t);
 void moea_kenter(mmu_t, vm_offset_t, vm_offset_t);
 boolean_t moea_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
-boolean_t moea_page_executable(mmu_t, vm_page_t);
+static void moea_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t);
 
 static mmu_method_t moea_methods[] = {
 	MMUMETHOD(mmu_change_wiring,	moea_change_wiring),
@@ -357,6 +357,7 @@ static mmu_method_t moea_methods[] = {
 	MMUMETHOD(mmu_remove,		moea_remove),
 	MMUMETHOD(mmu_remove_all,      	moea_remove_all),
 	MMUMETHOD(mmu_remove_write,	moea_remove_write),
+	MMUMETHOD(mmu_sync_icache,	moea_sync_icache),
 	MMUMETHOD(mmu_zero_page,       	moea_zero_page),
 	MMUMETHOD(mmu_zero_page_area,	moea_zero_page_area),
 	MMUMETHOD(mmu_zero_page_idle,	moea_zero_page_idle),
@@ -371,7 +372,6 @@ static mmu_method_t moea_methods[] = {
 	MMUMETHOD(mmu_kextract,		moea_kextract),
 	MMUMETHOD(mmu_kenter,		moea_kenter),
 	MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped),
-	MMUMETHOD(mmu_page_executable,	moea_page_executable),
 
 	{ 0, 0 }
 };
@@ -2359,12 +2359,6 @@ moea_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
 	return (EFAULT);
 }
 
-boolean_t
-moea_page_executable(mmu_t mmu, vm_page_t pg)
-{
-	return ((moea_attr_fetch(pg) & PTE_EXEC) == PTE_EXEC);
-}
-
 /*
  * Map a set of physical memory pages into the kernel virtual
  * address space. Return a pointer to where it is mapped. This
@@ -2424,3 +2418,27 @@ moea_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
 		kmem_free(kernel_map, base, size);
 	}
 }
+
+static void
+moea_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+	struct pvo_entry *pvo;
+	vm_offset_t lim;
+	vm_paddr_t pa;
+	vm_size_t len;
+
+	PMAP_LOCK(pm);
+	while (sz > 0) {
+		lim = round_page(va);
+		len = MIN(lim - va, sz);
+		pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
+		if (pvo != NULL) {
+			pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) |
+			    (va & ADDR_POFF);
+			moea_syncicache(pa, len);
+		}
+		va += len;
+		sz -= len;
+	}
+	PMAP_UNLOCK(pm);
+}
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 4dad3dc7561..67e457ca217 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -369,7 +369,7 @@ static boolean_t	moea64_query_bit(vm_page_t, u_int64_t);
 static u_int		moea64_clear_bit(vm_page_t, u_int64_t, u_int64_t *);
 static void		moea64_kremove(mmu_t, vm_offset_t);
 static void		moea64_syncicache(pmap_t pmap, vm_offset_t va, 
-			    vm_offset_t pa);
+			    vm_offset_t pa, vm_size_t sz);
 static void		tlbia(void);
 
 /*
@@ -410,7 +410,7 @@ void moea64_unmapdev(mmu_t, vm_offset_t, vm_size_t);
 vm_offset_t moea64_kextract(mmu_t, vm_offset_t);
 void moea64_kenter(mmu_t, vm_offset_t, vm_offset_t);
 boolean_t moea64_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
-boolean_t moea64_page_executable(mmu_t, vm_page_t);
+static void moea64_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t);
 
 static mmu_method_t moea64_bridge_methods[] = {
 	MMUMETHOD(mmu_change_wiring,	moea64_change_wiring),
@@ -437,6 +437,7 @@ static mmu_method_t moea64_bridge_methods[] = {
 	MMUMETHOD(mmu_remove,		moea64_remove),
 	MMUMETHOD(mmu_remove_all,      	moea64_remove_all),
 	MMUMETHOD(mmu_remove_write,	moea64_remove_write),
+	MMUMETHOD(mmu_sync_icache,	moea64_sync_icache),
 	MMUMETHOD(mmu_zero_page,       	moea64_zero_page),
 	MMUMETHOD(mmu_zero_page_area,	moea64_zero_page_area),
 	MMUMETHOD(mmu_zero_page_idle,	moea64_zero_page_idle),
@@ -451,7 +452,6 @@ static mmu_method_t moea64_bridge_methods[] = {
 	MMUMETHOD(mmu_kextract,		moea64_kextract),
 	MMUMETHOD(mmu_kenter,		moea64_kenter),
 	MMUMETHOD(mmu_dev_direct_mapped,moea64_dev_direct_mapped),
-	MMUMETHOD(mmu_page_executable,	moea64_page_executable),
 
 	{ 0, 0 }
 };
@@ -1264,12 +1264,12 @@ moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
 	 * mapped executable and cacheable.
 	 */
 	if ((pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
-		moea64_syncicache(pmap, va, VM_PAGE_TO_PHYS(m));
+		moea64_syncicache(pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE);
 	}
 }
 
 static void
-moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa)
+moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_size_t sz)
 {
 	/*
 	 * This is much trickier than on older systems because
@@ -1285,16 +1285,16 @@ moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa)
 		 * If PMAP is not bootstrapped, we are likely to be
 		 * in real mode.
 		 */
-		__syncicache((void *)pa,PAGE_SIZE);
+		__syncicache((void *)pa, sz);
 	} else if (pmap == kernel_pmap) {
-		__syncicache((void *)va,PAGE_SIZE);
+		__syncicache((void *)va, sz);
 	} else {
 		/* Use the scratch page to set up a temp mapping */
 
 		mtx_lock(&moea64_scratchpage_mtx);
 
 		moea64_set_scratchpage_pa(1,pa);
-		__syncicache((void *)moea64_scratchpage_va[1],PAGE_SIZE);
+		__syncicache((void *)moea64_scratchpage_va[1], sz);
 
 		mtx_unlock(&moea64_scratchpage_mtx);
 	}
@@ -1817,8 +1817,9 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
 			    pvo->pvo_pmap, pvo->pvo_vaddr);
 			if ((pvo->pvo_pte.lpte.pte_lo & 
 			    (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
-				moea64_syncicache(pm, sva, 
-				     pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
+				moea64_syncicache(pm, sva,
+				    pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN,
+				    PAGE_SIZE);
 			}
 		}
 		UNLOCK_TABLE();
@@ -2406,12 +2407,6 @@ moea64_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
 	return (EFAULT);
 }
 
-boolean_t
-moea64_page_executable(mmu_t mmu, vm_page_t pg)
-{
-	return (!moea64_query_bit(pg, LPTE_NOEXEC));
-}
-
 /*
  * Map a set of physical memory pages into the kernel virtual
  * address space. Return a pointer to where it is mapped. This
@@ -2454,3 +2449,26 @@ moea64_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
 	kmem_free(kernel_map, base, size);
 }
 
+static void
+moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+	struct pvo_entry *pvo;
+	vm_offset_t lim;
+	vm_paddr_t pa;
+	vm_size_t len;
+
+	PMAP_LOCK(pm);
+	while (sz > 0) {
+		lim = round_page(va);
+		len = MIN(lim - va, sz);
+		pvo = moea64_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
+		if (pvo != NULL) {
+			pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) |
+			    (va & ADDR_POFF);
+			moea64_syncicache(pm, va, pa, len);
+		}
+		va += len;
+		sz -= len;
+	}
+	PMAP_UNLOCK(pm);
+}
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 78a72507fa4..26302a556a9 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -319,7 +319,8 @@ static vm_offset_t	mmu_booke_kextract(mmu_t, vm_offset_t);
 static void		mmu_booke_kenter(mmu_t, vm_offset_t, vm_offset_t);
 static void		mmu_booke_kremove(mmu_t, vm_offset_t);
 static boolean_t	mmu_booke_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
-static boolean_t	mmu_booke_page_executable(mmu_t, vm_page_t);
+static void		mmu_booke_sync_icache(mmu_t, pmap_t, vm_offset_t,
+    vm_size_t);
 static vm_offset_t	mmu_booke_dumpsys_map(mmu_t, struct pmap_md *,
     vm_size_t, vm_size_t *);
 static void		mmu_booke_dumpsys_unmap(mmu_t, struct pmap_md *,
@@ -357,6 +358,7 @@ static mmu_method_t mmu_booke_methods[] = {
 	MMUMETHOD(mmu_remove,		mmu_booke_remove),
 	MMUMETHOD(mmu_remove_all,	mmu_booke_remove_all),
 	MMUMETHOD(mmu_remove_write,	mmu_booke_remove_write),
+	MMUMETHOD(mmu_sync_icache,	mmu_booke_sync_icache),
 	MMUMETHOD(mmu_zero_page,	mmu_booke_zero_page),
 	MMUMETHOD(mmu_zero_page_area,	mmu_booke_zero_page_area),
 	MMUMETHOD(mmu_zero_page_idle,	mmu_booke_zero_page_idle),
@@ -370,7 +372,6 @@ static mmu_method_t mmu_booke_methods[] = {
 	MMUMETHOD(mmu_kenter,		mmu_booke_kenter),
 	MMUMETHOD(mmu_kextract,		mmu_booke_kextract),
 /*	MMUMETHOD(mmu_kremove,		mmu_booke_kremove),	*/
-	MMUMETHOD(mmu_page_executable,	mmu_booke_page_executable),
 	MMUMETHOD(mmu_unmapdev,		mmu_booke_unmapdev),
 
 	/* dumpsys() support */
@@ -1682,21 +1683,6 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
 		__syncicache((void *)va, PAGE_SIZE);
 		sync = 0;
 	}
-
-	if (sync) {
-		/* Create a temporary mapping. */
-		pmap = PCPU_GET(curpmap);
-
-		va = 0;
-		pte = pte_find(mmu, pmap, va);
-		KASSERT(pte == NULL, ("%s:%d", __func__, __LINE__));
-
-		flags = PTE_SR | PTE_VALID | PTE_UR | PTE_M;
-		
-		pte_enter(mmu, pmap, m, va, flags);
-		__syncicache((void *)va, PAGE_SIZE);
-		pte_remove(mmu, pmap, va, PTBL_UNHOLD);
-	}
 }
 
 /*
@@ -1991,25 +1977,47 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m)
 	vm_page_flag_clear(m, PG_WRITEABLE);
 }
 
-static boolean_t
-mmu_booke_page_executable(mmu_t mmu, vm_page_t m)
+static void
+mmu_booke_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
 {
-	pv_entry_t pv;
 	pte_t *pte;
-	boolean_t executable;
+	pmap_t pmap;
+	vm_page_t m;
+	vm_offset_t addr;
+	vm_paddr_t pa;
+	int active, valid;
+ 
+	va = trunc_page(va);
+	sz = round_page(sz);
 
-	executable = FALSE;
-	TAILQ_FOREACH(pv, &m->md.pv_list, pv_link) {
-		PMAP_LOCK(pv->pv_pmap);
-		pte = pte_find(mmu, pv->pv_pmap, pv->pv_va);
-		if (pte != NULL && PTE_ISVALID(pte) && (pte->flags & PTE_UX))
-			executable = TRUE;
-		PMAP_UNLOCK(pv->pv_pmap);
-		if (executable)
-			break;
+	vm_page_lock_queues();
+	pmap = PCPU_GET(curpmap);
+	active = (pm == kernel_pmap || pm == pmap) ? 1 : 0;
+	while (sz > 0) {
+		PMAP_LOCK(pm);
+		pte = pte_find(mmu, pm, va);
+		valid = (pte != NULL && PTE_ISVALID(pte)) ? 1 : 0;
+		if (valid)
+			pa = PTE_PA(pte);
+		PMAP_UNLOCK(pm);
+		if (valid) {
+			if (!active) {
+				/* Create a mapping in the active pmap. */
+				addr = 0;
+				m = PHYS_TO_VM_PAGE(pa);
+				PMAP_LOCK(pmap);
+				pte_enter(mmu, pmap, m, addr,
+				    PTE_SR | PTE_VALID | PTE_UR);
+				__syncicache((void *)addr, PAGE_SIZE);
+				pte_remove(mmu, pmap, addr, PTBL_UNHOLD);
+				PMAP_UNLOCK(pmap);
+			} else
+				__syncicache((void *)va, PAGE_SIZE);
+		}
+		va += PAGE_SIZE;
+		sz -= PAGE_SIZE;
 	}
-
-	return (executable);
+	vm_page_unlock_queues();
 }
 
 /*
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index d4fce7fef91..a23052ea975 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -171,7 +171,6 @@ void		pmap_bootstrap(vm_offset_t, vm_offset_t);
 void		pmap_kenter(vm_offset_t va, vm_offset_t pa);
 void		pmap_kremove(vm_offset_t);
 void		*pmap_mapdev(vm_offset_t, vm_size_t);
-boolean_t	pmap_page_executable(vm_page_t);
 void		pmap_unmapdev(vm_offset_t, vm_size_t);
 void		pmap_deactivate(struct thread *);
 vm_offset_t	pmap_kextract(vm_offset_t);
diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m
index 4a5a37c456c..5b8ba14d689 100644
--- a/sys/powerpc/powerpc/mmu_if.m
+++ b/sys/powerpc/powerpc/mmu_if.m
@@ -789,15 +789,21 @@ METHOD boolean_t dev_direct_mapped {
 
 
 /**
- * @brief Evaluate if a physical page has an executable mapping
+ * @brief Enforce instruction cache coherency. Typically called after a
+ * region of memory has been modified and before execution of or within
+ * that region is attempted. Setting breakpoints in a process through
+ * ptrace(2) is one example of when the instruction cache needs to be
+ * made coherent.
  *
- * @param _pg		physical page
- *
- * @retval bool		TRUE if a physical mapping exists for the given page.
+ * @param _pm		the physical map of the virtual address
+ * @param _va		the virtual address of the modified region
+ * @param _sz		the size of the modified region
  */
-METHOD boolean_t page_executable {
+METHOD void sync_icache {
 	mmu_t		_mmu;
-	vm_page_t	_pg;
+	pmap_t		_pm;
+	vm_offset_t	_va;
+	vm_size_t	_sz;
 };
 
 
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index b34c7ebbb9f..2b45e17c6f3 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -457,12 +457,12 @@ pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
 	return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
 }
 
-boolean_t
-pmap_page_executable(vm_page_t pg)
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
 {
-
-	CTR2(KTR_PMAP, "%s(%p)", __func__, pg);
-	return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
+ 
+	CTR4(KTR_PMAP, "%s(%p, %#x, %#x)", __func__, pm, va, sz);
+	return (MMU_SYNC_ICACHE(mmu_obj, pm, va, sz));
 }
 
 vm_offset_t
diff --git a/sys/powerpc/powerpc/uio_machdep.c b/sys/powerpc/powerpc/uio_machdep.c
index 2a88fd247ae..6d171145f2c 100644
--- a/sys/powerpc/powerpc/uio_machdep.c
+++ b/sys/powerpc/powerpc/uio_machdep.c
@@ -107,9 +107,6 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
 					sf_buf_free(sf);
 					goto out;
 				}
-				if (uio->uio_rw == UIO_WRITE &&
-				    pmap_page_executable(m))
-					__syncicache(cp, cnt);
 				break;
 			case UIO_SYSSPACE:
 				if (uio->uio_rw == UIO_READ)
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index 664a856d6ad..5956818016c 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -2001,6 +2001,11 @@ pmap_activate(struct thread *td)
 	mtx_unlock_spin(&sched_lock);
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  * Increase the starting virtual address of the given mapping if a
  * different alignment might result in more superpage mappings.
diff --git a/sys/sun4v/sun4v/pmap.c b/sys/sun4v/sun4v/pmap.c
index a754ce943e5..d3b8c79467e 100644
--- a/sys/sun4v/sun4v/pmap.c
+++ b/sys/sun4v/sun4v/pmap.c
@@ -424,6 +424,11 @@ pmap_activate(struct thread *td)
 	critical_exit();
 }
 
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
 /*
  *	Increase the starting virtual address of the given mapping if a
  *	different alignment might result in more superpage mappings.
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h
index 22d61181b3c..02fda073aea 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -133,6 +133,7 @@ void		 pmap_remove(pmap_t, vm_offset_t, vm_offset_t);
 void		 pmap_remove_all(vm_page_t m);
 void		 pmap_remove_pages(pmap_t);
 void		 pmap_remove_write(vm_page_t m);
+void		 pmap_sync_icache(pmap_t, vm_offset_t, vm_size_t);
 void		 pmap_zero_page(vm_page_t);
 void		 pmap_zero_page_area(vm_page_t, int off, int size);
 void		 pmap_zero_page_idle(vm_page_t);
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index 65b6c8e8e4a..ff489839a36 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -63,6 +63,7 @@ int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace
 void vm_waitproc(struct proc *);
 int vm_mmap(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, objtype_t, void *, vm_ooffset_t);
 void vm_set_page_size(void);
+void vm_sync_icache(vm_map_t, vm_offset_t, vm_size_t);
 struct vmspace *vmspace_alloc(vm_offset_t, vm_offset_t);
 struct vmspace *vmspace_fork(struct vmspace *, vm_ooffset_t *);
 int vmspace_exec(struct proc *, vm_offset_t, vm_offset_t);
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 851c73361ee..8882565ef83 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -309,6 +309,13 @@ vm_imgact_unmap_page(struct sf_buf *sf)
 	vm_page_unlock_queues();
 }
 
+void
+vm_sync_icache(vm_map_t map, vm_offset_t va, vm_offset_t sz)
+{
+
+	pmap_sync_icache(map->pmap, va, sz);
+}
+
 struct kstack_cache_entry {
 	vm_object_t ksobj;
 	struct kstack_cache_entry *next_ks_entry;

From 191bb483f240ad05095a8f1d36f4fd6815044a43 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Wed, 21 Oct 2009 18:44:00 +0000
Subject: [PATCH 269/646] Review previous change. It has no relation to the
 I-cache coherency changes and thus unintentional.

Spotted by: rdivacky@
---
 sys/arm/mv/mv_machdep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index c348e24b3ca..2dc20ceb08e 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -408,7 +408,7 @@ initarm(void *mdp, void *unused __unused)
 		availmem_regions_sz = i;
 	} else {
 		/* Fall back to hardcoded boothowto flags and metadata. */
-		boothowto = 0; // RB_VERBOSE | RB_SINGLE;
+		boothowto = RB_VERBOSE | RB_SINGLE;
 		lastaddr = fake_preload_metadata();
 
 		/*

From fa630f3569bd2e305a9022d0b77701ec399b84cb Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Wed, 21 Oct 2009 18:46:36 +0000
Subject: [PATCH 270/646] Handle the case where there is only one PMC in the
 system.

Approved by: jkoshy (mentor)
MFC after: 3 days
---
 sys/dev/hwpmc/hwpmc_mod.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 0c1d35b7e3b..d2e581aeb53 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -790,7 +790,7 @@ pmc_link_target_process(struct pmc *pm, struct pmc_process *pp)
 	KASSERT(PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)),
 	    ("[pmc,%d] Attaching a non-process-virtual pmc=%p to pid=%d",
 		__LINE__, pm, pp->pp_proc->p_pid));
-	KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt < ((int) md->pmd_npmc - 1),
+	KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt <= ((int) md->pmd_npmc - 1),
 	    ("[pmc,%d] Illegal reference count %d for process record %p",
 		__LINE__, pp->pp_refcnt, (void *) pp));
 
@@ -843,7 +843,7 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
 	KASSERT(pm != NULL && pp != NULL,
 	    ("[pmc,%d] Null pm %p or pp %p", __LINE__, pm, pp));
 
-	KASSERT(pp->pp_refcnt >= 1 && pp->pp_refcnt < (int) md->pmd_npmc,
+	KASSERT(pp->pp_refcnt >= 1 && pp->pp_refcnt <= (int) md->pmd_npmc,
 	    ("[pmc,%d] Illegal ref count %d on process record %p",
 		__LINE__, pp->pp_refcnt, (void *) pp));
 
@@ -1110,7 +1110,7 @@ pmc_detach_one_process(struct proc *p, struct pmc *pm, int flags)
 	 * descriptor from the target hash table and unset the P_HWPMC
 	 * flag in the struct proc.
 	 */
-	KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt < (int) md->pmd_npmc,
+	KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt <= (int) md->pmd_npmc,
 	    ("[pmc,%d] Illegal refcnt %d for process struct %p",
 		__LINE__, pp->pp_refcnt, pp));
 
@@ -1785,7 +1785,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
 					pmc_detach_one_process(td->td_proc,
 					    pm, PMC_FLAG_NONE);
 
-		KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt < (int) md->pmd_npmc,
+		KASSERT(pp->pp_refcnt >= 0 && pp->pp_refcnt <= (int) md->pmd_npmc,
 		    ("[pmc,%d] Illegal ref count %d on pp %p", __LINE__,
 			pp->pp_refcnt, pp));
 

From 22239c9dc4cd9d5a4b9f82ff5bdcb2b229d4bc5f Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 21 Oct 2009 19:26:12 +0000
Subject: [PATCH 271/646] Change gcc to assume a default machine architecture
 of 486 instead of 386 on "i386".  Doing it in the compiler is deemed to be
 less fragile then attempting to provide a default -march setting via
 bsd.cpu.mk.  FreeBSD itself has not supported plain 386 CPUs since 5.x.

Suggested by:	kan
Requested by:	rdivacky
MFC after:	1 month
---
 contrib/gcc/config/i386/i386.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c
index feab422cc38..e737ba542d4 100644
--- a/contrib/gcc/config/i386/i386.c
+++ b/contrib/gcc/config/i386/i386.c
@@ -1614,7 +1614,7 @@ override_options (void)
 	     "-mtune=generic instead as appropriate.");
 
   if (!ix86_arch_string)
-    ix86_arch_string = TARGET_64BIT ? "x86-64" : "i386";
+    ix86_arch_string = TARGET_64BIT ? "x86-64" : "i486";
   if (!strcmp (ix86_arch_string, "generic"))
     error ("generic CPU can be used only for -mtune= switch");
   if (!strncmp (ix86_arch_string, "generic", 7))

From 357864c2dd051e398a5dd9ad6d4f5702475fd918 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Wed, 21 Oct 2009 19:31:23 +0000
Subject: [PATCH 272/646] Don't call the newstate callback as that's dangerous.
 Rely no ENETRESET to DTRT.

MFC after:	3 days
---
 sys/net80211/ieee80211_mesh.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 432ce231631..d6622695581 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -388,8 +388,6 @@ mesh_select_proto_path(struct ieee80211vap *vap, const char *name)
 	for (i = 0; i < N(mesh_proto_paths); i++) {
 		if (strcasecmp(mesh_proto_paths[i].mpp_descr, name) == 0) {
 			ms->ms_ppath = &mesh_proto_paths[i];
-			if (vap->iv_state == IEEE80211_S_RUN)
-				vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
 			return 0;
 		}
 	}
@@ -405,8 +403,6 @@ mesh_select_proto_metric(struct ieee80211vap *vap, const char *name)
 	for (i = 0; i < N(mesh_proto_metrics); i++) {
 		if (strcasecmp(mesh_proto_metrics[i].mpm_descr, name) == 0) {
 			ms->ms_pmetric = &mesh_proto_metrics[i];
-			if (vap->iv_state == IEEE80211_S_RUN)
-				vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
 			return 0;
 		}
 	}

From e5367da3b76544dbcf0fb40668dabe72af00f662 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Wed, 21 Oct 2009 19:39:34 +0000
Subject: [PATCH 273/646] Move sed(1) from cross-tools to bootstrap-tools.

---
 Makefile.inc1 | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 8c40eefd5ed..3dcba1edb00 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -929,6 +929,10 @@ _ar=		usr.bin/ar
 _mklocale=	usr.bin/mklocale
 .endif
 
+.if ${BOOTSTRAPPING} < 900002
+_sed=		usr.bin/sed
+.endif
+
 .if ${BOOTSTRAPPING} < 700018
 _gensnmptree=	usr.sbin/bsnmpd/gensnmptree
 .endif
@@ -954,6 +958,7 @@ bootstrap-tools:
     usr.bin/makewhatis \
     ${_mklocale} \
     usr.bin/rpcgen \
+    ${_sed} \
     usr.bin/xinstall \
     ${_gensnmptree} \
     usr.sbin/config \
@@ -1033,7 +1038,6 @@ cross-tools:
 .for _tool in \
     gnu/usr.bin/binutils \
     gnu/usr.bin/cc \
-    usr.bin/sed \
     usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \
     ${_btxld} \
     ${_crunchide} \

From b5f58d7778a3c857354845e5c7f933aedd4fb417 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Wed, 21 Oct 2009 20:55:04 +0000
Subject: [PATCH 274/646] - Add support for chrooted installs. - Add examples
 to the man-page.

MFC after:	1 week
---
 usr.sbin/tzsetup/tzsetup.8 |  33 ++++--
 usr.sbin/tzsetup/tzsetup.c | 200 ++++++++++++++++++++++++-------------
 2 files changed, 156 insertions(+), 77 deletions(-)

diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8
index 48ca8e83d1a..4d548fdb968 100644
--- a/usr.sbin/tzsetup/tzsetup.8
+++ b/usr.sbin/tzsetup/tzsetup.8
@@ -32,7 +32,8 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl nrs
-.Op Ar zoneinfo file
+.Op Fl C Ar chroot directory
+.Op Ar zoneinfo file | zoneinfo name
 .Sh DESCRIPTION
 The
 .Nm
@@ -49,6 +50,9 @@ the hardware clock does not keep
 .Pp
 The following option is available:
 .Bl -tag -offset indent -width Fl
+.It Fl C Ar chroot directory
+Open all files and directories relative to
+.Ar chroot directory .
 .It Fl n
 Do not create or copy files.
 .It Fl r
@@ -62,8 +66,10 @@ Skip the initial question about adjusting the clock if not set to
 It is possible to short-circuit the menu system by specifying the
 location of a
 .Ar zoneinfo file
+or the name of the
+.Ar zoneinfo name
 on the command line; this is intended mainly for pre-configured installation
-scripts.
+scripts or people who know which zoneinfo they want to install.
 .Sh TIMEZONE DATABASE
 The contents of the timezone database are indexed by
 .Pa /usr/share/zoneinfo/zone.tab .
@@ -97,21 +103,36 @@ historically minded.
 .Sh FILES
 .Bl -tag -width /usr/share/zoneinfo/zone.tab -compact
 .It Pa /etc/localtime
-current time zone file
+current time zone file.
 .It Pa /etc/wall_cmos_clock
 see
 .Xr adjkerntz 8 .
 .It Pa /usr/share/misc/iso3166
 mapping of
 .Tn ISO
-3166 territory codes to names
+3166 territory codes to names.
 .It Pa /usr/share/zoneinfo
-directory for zoneinfo files
+directory for zoneinfo files.
 .It Pa /usr/share/zoneinfo/zone.tab
-mapping of timezone file to country and location
+mapping of timezone file to country and location.
 .It Pa /var/db/zoneinfo
 saved name of the timezone file installed last.
 .El
+.Sh EXAMPLES
+Normal usage, to select the right zoneinfo file via the dialog-based
+user interface:
+.Dl # tzsetup
+Install the file
+.Pa /usr/share/zoneinfo/Australia/Sydney :
+.Dl # tzsetup /usr/share/zoneinfo/Australia/Sydney
+Install the zoneinfo file for Australia/Sydney, assumed to be located
+in
+.Pa /usr/share/zoneinfo :
+.Dl # tzsetup Australia/Sydney
+After a reinstall of the zoneinfo files, you can reinstall the
+latest installed zoneinfo file: (as specified in
+.Pa /var/db/zoneinfo )
+.Dl # tzsetup -r
 .Sh SEE ALSO
 .Xr date 1 ,
 .Xr adjtime 2 ,
diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c
index b9ca8faa447..0ab7a2b519e 100644
--- a/usr.sbin/tzsetup/tzsetup.c
+++ b/usr.sbin/tzsetup/tzsetup.c
@@ -56,8 +56,14 @@ __FBSDID("$FreeBSD$");
 #define	_PATH_DB		"/var/db/zoneinfo"
 #define	_PATH_WALL_CMOS_CLOCK	"/etc/wall_cmos_clock"
 
+static char	path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN],
+		path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN], 
+		path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN];
+
 static int reallydoit = 1;
 static int reinstall = 0;
+static int usedialog = 1;
+static char *chrootenv = NULL;
 
 static void	usage(void);
 static int	continent_country_menu(dialogMenuItem *);
@@ -196,15 +202,15 @@ read_iso3166_table(void)
 	char		*s, *t, *name;
 	int		lineno;
 
-	fp = fopen(_PATH_ISO3166, "r");
+	fp = fopen(path_iso3166, "r");
 	if (!fp)
-		err(1, _PATH_ISO3166);
+		err(1, path_iso3166);
 	lineno = 0;
 
 	while ((s = fgetln(fp, &len)) != 0) {
 		lineno++;
 		if (s[len - 1] != '\n')
-			errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+			errx(1, "%s:%d: invalid format", path_iso3166, lineno);
 		s[len - 1] = '\0';
 		if (s[0] == '#' || strspn(s, " \t") == len - 1)
 			continue;
@@ -212,26 +218,25 @@ read_iso3166_table(void)
 		/* Isolate the two-letter code. */
 		t = strsep(&s, "\t");
 		if (t == 0 || strlen(t) != 2)
-			errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+			errx(1, "%s:%d: invalid format", path_iso3166, lineno);
 		if (t[0] < 'A' || t[0] > 'Z' || t[1] < 'A' || t[1] > 'Z')
-			errx(1, _PATH_ISO3166 ":%d: invalid code `%s'",
+			errx(1, "%s:%d: invalid code `%s'", path_iso3166,
 			    lineno, t);
 
 		/* Now skip past the three-letter and numeric codes. */
 		name = strsep(&s, "\t");	/* 3-let */
 		if (name == 0 || strlen(name) != 3)
-			errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+			errx(1, "%s:%d: invalid format", path_iso3166, lineno);
 		name = strsep(&s, "\t");	/* numeric */
 		if (name == 0 || strlen(name) != 3)
-			errx(1, _PATH_ISO3166 ":%d: invalid format", lineno);
+			errx(1, "%s:%d: invalid format", path_iso3166, lineno);
 
 		name = s;
 
 		cp = &countries[CODE2INT(t)];
 		if (cp->name)
-			errx(1, _PATH_ISO3166
-			    ":%d: country code `%s' multiply defined: %s",
-			    lineno, t, cp->name);
+			errx(1, "%s:%d: country code `%s' multiply defined: %s",
+			    path_iso3166, lineno, t, cp->name);
 		cp->name = strdup(name);
 		if (cp->name == NULL)
 			errx(1, "malloc failed");
@@ -251,18 +256,18 @@ add_zone_to_country(int lineno, const char *tlc, const char *descr,
 	struct country	*cp;
 
 	if (tlc[0] < 'A' || tlc[0] > 'Z' || tlc[1] < 'A' || tlc[1] > 'Z')
-		errx(1, _PATH_ZONETAB ":%d: country code `%s' invalid",
+		errx(1, "%s:%d: country code `%s' invalid", path_zonetab,
 		    lineno, tlc);
 	
 	cp = &countries[CODE2INT(tlc)];
 	if (cp->name == 0)
-		errx(1, _PATH_ZONETAB ":%d: country code `%s' unknown",
+		errx(1, "%s:%d: country code `%s' unknown", path_zonetab,
 		    lineno, tlc);
 
 	if (descr) {
 		if (cp->nzones < 0)
-			errx(1, _PATH_ZONETAB
-			    ":%d: conflicting zone definition", lineno);
+			errx(1, "%s:%d: conflicting zone definition",
+			    path_zonetab, lineno);
 
 		zp = malloc(sizeof(*zp));
 		if (zp == 0)
@@ -282,11 +287,11 @@ add_zone_to_country(int lineno, const char *tlc, const char *descr,
 		cp->nzones++;
 	} else {
 		if (cp->nzones > 0)
-			errx(1, _PATH_ZONETAB
-			    ":%d: zone must have description", lineno);
+			errx(1, "%s:%d: zone must have description",
+			    path_zonetab, lineno);
 		if (cp->nzones < 0)
-			errx(1, _PATH_ZONETAB
-			    ":%d: zone multiply defined", lineno);
+			errx(1, "%s:%d: zone multiply defined",
+			    path_zonetab, lineno);
 		cp->nzones = -1;
 		cp->filename = strdup(file);
 		if (cp->filename == NULL)
@@ -336,34 +341,34 @@ read_zones(void)
 	char		*line, *tlc, *coord, *file, *descr, *p;
 	int		lineno;
 
-	fp = fopen(_PATH_ZONETAB, "r");
+	fp = fopen(path_zonetab, "r");
 	if (!fp)
-		err(1, _PATH_ZONETAB);
+		err(1, path_zonetab);
 	lineno = 0;
 
 	while ((line = fgetln(fp, &len)) != 0) {
 		lineno++;
 		if (line[len - 1] != '\n')
-			errx(1, _PATH_ZONETAB ":%d: invalid format", lineno);
+			errx(1, "%s:%d: invalid format", path_zonetab, lineno);
 		line[len - 1] = '\0';
 		if (line[0] == '#')
 			continue;
 
 		tlc = strsep(&line, "\t");
 		if (strlen(tlc) != 2)
-			errx(1, _PATH_ZONETAB ":%d: invalid country code `%s'",
-			    lineno, tlc);
+			errx(1, "%s:%d: invalid country code `%s'",
+			    path_zonetab, lineno, tlc);
 		coord = strsep(&line, "\t");
 		file = strsep(&line, "\t");
 		p = strchr(file, '/');
 		if (p == 0)
-			errx(1, _PATH_ZONETAB ":%d: invalid zone name `%s'",
+			errx(1, "%s:%d: invalid zone name `%s'", path_zonetab,
 			    lineno, file);
 		contbuf[0] = '\0';
 		strncat(contbuf, file, p - file);
 		cont = find_continent(contbuf);
 		if (!cont)
-			errx(1, _PATH_ZONETAB ":%d: invalid region `%s'",
+			errx(1, "%s:%d: invalid region `%s'", path_zonetab,
 			    lineno, contbuf);
 
 		descr = (line != NULL && *line != '\0') ? line : NULL;
@@ -498,16 +503,15 @@ set_zone_menu(dialogMenuItem *dmi)
 }
 
 static int
-install_zone_file(const char *filename, int usedialog)
+install_zoneinfo_file(const char *zoneinfo_file)
 {
 	char		buf[1024];
 	char		title[64], prompt[64];
 	struct stat	sb;
 	ssize_t		len;
 	int		fd1, fd2, copymode;
-	FILE		*f;
 
-	if (lstat(_PATH_LOCALTIME, &sb) < 0) {
+	if (lstat(path_localtime, &sb) < 0) {
 		/* Nothing there yet... */
 		copymode = 1;
 	} else if (S_ISLNK(sb.st_mode))
@@ -518,11 +522,11 @@ install_zone_file(const char *filename, int usedialog)
 #ifdef VERBOSE
 	if (copymode)
 		snprintf(prompt, sizeof(prompt),
-		    "Copying %s to " _PATH_LOCALTIME, filename);
+		    "Copying %s to %s", zoneinfo_file, path_localtime);
 	else
 		snprintf(prompt, sizeof(prompt),
-		    "Creating symbolic link " _PATH_LOCALTIME " to %s",
-		    filename);
+		    "Creating symbolic link %s to %s",
+		    path_localtime, zoneinfo_file);
 	if (usedialog)
 		dialog_notify(prompt);
 	else
@@ -531,11 +535,11 @@ install_zone_file(const char *filename, int usedialog)
 
 	if (reallydoit) {
 		if (copymode) {
-			fd1 = open(filename, O_RDONLY, 0);
+			fd1 = open(zoneinfo_file, O_RDONLY, 0);
 			if (fd1 < 0) {
 				snprintf(title, sizeof(title), "Error");
 				snprintf(prompt, sizeof(prompt),
-				    "Could not open %s: %s", filename,
+				    "Could not open %s: %s", zoneinfo_file,
 				    strerror(errno));
 				if (usedialog)
 					dialog_mesgbox(title, prompt, 8, 72);
@@ -544,14 +548,14 @@ install_zone_file(const char *filename, int usedialog)
 				return (DITEM_FAILURE | DITEM_RECREATE);
 			}
 
-			unlink(_PATH_LOCALTIME);
-			fd2 = open(_PATH_LOCALTIME, O_CREAT | O_EXCL | O_WRONLY,
+			unlink(path_localtime);
+			fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY,
 			    S_IRUSR | S_IRGRP | S_IROTH);
 			if (fd2 < 0) {
 				snprintf(title, sizeof(title), "Error");
 				snprintf(prompt, sizeof(prompt),
-				    "Could not open " _PATH_LOCALTIME ": %s",
-				    strerror(errno));
+				    "Could not open %s: %s",
+				    path_localtime, strerror(errno));
 				if (usedialog)
 					dialog_mesgbox(title, prompt, 8, 72);
 				else
@@ -565,23 +569,23 @@ install_zone_file(const char *filename, int usedialog)
 			if (len == -1) {
 				snprintf(title, sizeof(title), "Error");
 				snprintf(prompt, sizeof(prompt),
-				    "Error copying %s to " _PATH_LOCALTIME
-				    ": %s", filename, strerror(errno));
+				    "Error copying %s to %s %s", zoneinfo_file,
+				    path_localtime, strerror(errno));
 				if (usedialog)
 					dialog_mesgbox(title, prompt, 8, 72);
 				else
 					fprintf(stderr, "%s\n", prompt);
 				/* Better to leave none than a corrupt one. */
-				unlink(_PATH_LOCALTIME);
+				unlink(path_localtime);
 				return (DITEM_FAILURE | DITEM_RECREATE);
 			}
 			close(fd1);
 			close(fd2);
 		} else {
-			if (access(filename, R_OK) != 0) {
+			if (access(zoneinfo_file, R_OK) != 0) {
 				snprintf(title, sizeof(title), "Error");
 				snprintf(prompt, sizeof(prompt),
-				    "Cannot access %s: %s", filename,
+				    "Cannot access %s: %s", zoneinfo_file,
 				    strerror(errno));
 				if (usedialog)
 					dialog_mesgbox(title, prompt, 8, 72);
@@ -589,12 +593,12 @@ install_zone_file(const char *filename, int usedialog)
 					fprintf(stderr, "%s\n", prompt);
 				return (DITEM_FAILURE | DITEM_RECREATE);
 			}
-			unlink(_PATH_LOCALTIME);
-			if (symlink(filename, _PATH_LOCALTIME) < 0) {
+			unlink(path_localtime);
+			if (symlink(zoneinfo_file, path_localtime) < 0) {
 				snprintf(title, sizeof(title), "Error");
 				snprintf(prompt, sizeof(prompt),
-				    "Cannot create symbolic link "
-				    _PATH_LOCALTIME " to %s: %s", filename,
+				    "Cannot create symbolic link %s to %s: %s",
+				    path_localtime, zoneinfo_file,
 				    strerror(errno));
 				if (usedialog)
 					dialog_mesgbox(title, prompt, 8, 72);
@@ -609,24 +613,38 @@ install_zone_file(const char *filename, int usedialog)
 	snprintf(title, sizeof(title), "Done");
 	if (copymode)
 		snprintf(prompt, sizeof(prompt),
-		    "Copied timezone file from %s to " _PATH_LOCALTIME,
-		    filename);
+		    "Copied timezone file from %s to %s", zoneinfo_file,
+		    path_localtime);
 	else
-		snprintf(prompt, sizeof(prompt), "Created symbolic link from "
-		    _PATH_LOCALTIME " to %s", filename);
+		snprintf(prompt, sizeof(prompt),
+		    "Created symbolic link from %s to %s", zoneinfo_file,
+		    path_localtime);
 	if (usedialog)
 		dialog_mesgbox(title, prompt, 8, 72);
 	else
 		fprintf(stderr, "%s\n", prompt);
 #endif
 
+	return (DITEM_LEAVE_MENU);
+}
+
+static int
+install_zoneinfo(const char *zoneinfo)
+{
+	int		rv;
+	FILE		*f;
+	char		path_zoneinfo_file[MAXPATHLEN];
+
+	sprintf(path_zoneinfo_file, "%s/%s", path_zoneinfo, zoneinfo);
+	rv = install_zoneinfo_file(path_zoneinfo_file);
+
 	/* Save knowledge for later */
-	if ((f = fopen(_PATH_DB, "w")) != NULL) {
-		fprintf(f, "%s\n", filename + strlen(_PATH_ZONEINFO) + 1);
+	if ((f = fopen(path_db, "w")) != NULL) {
+		fprintf(f, "%s\n", zoneinfo);
 		fclose(f);
 	}
 
-	return (DITEM_LEAVE_MENU);
+	return (rv);
 }
 
 static int
@@ -652,15 +670,12 @@ static int
 set_zone_multi(dialogMenuItem *dmi)
 {
 	struct zone	*zp = dmi->data;
-	char		*fn;
 	int		rv;
 
 	if (!confirm_zone(zp->filename))
 		return (DITEM_FAILURE | DITEM_RECREATE);
 
-	asprintf(&fn, "%s/%s", _PATH_ZONEINFO, zp->filename);
-	rv = install_zone_file(fn, 1);
-	free(fn);
+	rv = install_zoneinfo(zp->filename);
 	return (rv);
 }
 
@@ -668,15 +683,12 @@ static int
 set_zone_whole_country(dialogMenuItem *dmi)
 {
 	struct country	*cp = dmi->data;
-	char		*fn;
 	int		rv;
 
 	if (!confirm_zone(cp->filename))
 		return (DITEM_FAILURE | DITEM_RECREATE);
 
-	asprintf(&fn, "%s/%s", _PATH_ZONEINFO, cp->filename);
-	rv = install_zone_file(fn, 1);
-	free(fn);
+	rv = install_zoneinfo(cp->filename);
 	return (rv);
 }
 
@@ -701,13 +713,17 @@ main(int argc, char **argv)
 	int		c, fd, rv, skiputc;
 
 	skiputc = 0;
-	while ((c = getopt(argc, argv, "nrs")) != -1) {
+	while ((c = getopt(argc, argv, "C:nrs")) != -1) {
 		switch(c) {
+		case 'C':
+			chrootenv = optarg;
+			break;
 		case 'n':
 			reallydoit = 0;
 			break;
 		case 'r':
 			reinstall = 1;
+			usedialog = 0;
 			break;
 		case 's':
 			skiputc = 1;
@@ -720,6 +736,24 @@ main(int argc, char **argv)
 	if (argc - optind > 1)
 		usage();
 
+	if (chrootenv == NULL) {
+		strcpy(path_zonetab, _PATH_ZONETAB);
+		strcpy(path_iso3166, _PATH_ISO3166);
+		strcpy(path_zoneinfo, _PATH_ZONEINFO);
+		strcpy(path_localtime, _PATH_LOCALTIME);
+		strcpy(path_db, _PATH_DB);
+		strcpy(path_wall_cmos_clock, _PATH_WALL_CMOS_CLOCK);
+	} else {
+		sprintf(path_zonetab, "%s/%s", chrootenv, _PATH_ZONETAB);
+		sprintf(path_iso3166, "%s/%s", chrootenv, _PATH_ISO3166);
+		sprintf(path_zoneinfo, "%s/%s", chrootenv, _PATH_ZONEINFO);
+		sprintf(path_localtime, "%s/%s", chrootenv, _PATH_LOCALTIME);
+		sprintf(path_db, "%s/%s", chrootenv, _PATH_DB);
+		sprintf(path_wall_cmos_clock, "%s/%s", chrootenv,
+		    _PATH_WALL_CMOS_CLOCK);
+	}
+
+
 	/* Override the user-supplied umask. */
 	(void)umask(S_IWGRP | S_IWOTH);
 
@@ -731,25 +765,49 @@ main(int argc, char **argv)
 	if (reinstall == 1) {
 		FILE *f;
 		char zonefile[MAXPATHLEN];
+		char path_db[MAXPATHLEN];
 
-		sprintf(zonefile, "%s/", _PATH_ZONEINFO);
-		if ((f = fopen(_PATH_DB, "r")) != NULL) {
-			if (fgets(zonefile + strlen(zonefile),
-			    sizeof(zonefile) - strlen(zonefile), f) != NULL) {
+		zonefile[0] = '\0';
+		path_db[0] = '\0';
+		if (chrootenv != NULL) {
+			sprintf(zonefile, "%s/", chrootenv);
+			sprintf(path_db, "%s/", chrootenv);
+		}
+		strcat(zonefile, _PATH_ZONEINFO);
+		strcat(zonefile, "/");
+		strcat(path_db, _PATH_DB);
+
+		if ((f = fopen(path_db, "r")) != NULL) {
+			if (fgets(zonefile, sizeof(zonefile), f) != NULL) {
 				zonefile[sizeof(zonefile) - 1] = 0;
 				if (strlen(zonefile) > 0) {
 					zonefile[strlen(zonefile) - 1] = 0;
-					rv = install_zone_file(zonefile, 0);
+					rv = install_zoneinfo(zonefile);
 					exit(rv & ~DITEM_LEAVE_MENU);
 				}
-				errx(1, "Error reading %s.\n", _PATH_DB);
+				errx(1, "Error reading %s.\n", path_db);
 			}
 			fclose(f);
 			errx(1,
 			    "Unable to determine earlier installed zoneinfo "
-			    "file. Check %s", _PATH_DB);
+			    "file. Check %s", path_db);
 		}
-		errx(1, "Cannot open %s for reading. Does it exist?", _PATH_DB);
+		errx(1, "Cannot open %s for reading. Does it exist?", path_db);
+	}
+
+	/*
+	 * If the arguments on the command-line do not specify a file,
+	 * then interpret it as a zoneinfo name
+	 */
+	if (optind == argc - 1) {
+		struct stat sb;
+
+		if (stat(argv[optind], &sb) != 0) {
+			usedialog = 0;
+			rv = install_zoneinfo(argv[optind]);
+			exit(rv & ~DITEM_LEAVE_MENU);
+		}
+		/* FALLTHROUGH */
 	}
 
 	init_dialog();
@@ -783,7 +841,7 @@ main(int argc, char **argv)
 		snprintf(prompt, sizeof(prompt),
 		    "\nUse the default `%s' zone?", argv[optind]);
 		if (!dialog_yesno(title, prompt, 7, 72)) {
-			rv = install_zone_file(argv[optind], 1);
+			rv = install_zoneinfo_file(argv[optind]);
 			dialog_clear();
 			end_dialog();
 			exit(rv & ~DITEM_LEAVE_MENU);

From 38a96a683893abb35ce15f26315b0c9656b8e76f Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Wed, 21 Oct 2009 20:59:12 +0000
Subject: [PATCH 275/646] After the installation of the /usr/share/zoneinfo,
 run tzsetup if /var/db/zoneinfo exists.

MFC after:	1 week
---
 share/zoneinfo/Makefile | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/share/zoneinfo/Makefile b/share/zoneinfo/Makefile
index e2542777979..6acd502715a 100644
--- a/share/zoneinfo/Makefile
+++ b/share/zoneinfo/Makefile
@@ -54,4 +54,24 @@ beforeinstall:
 	${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
 	    ${.CURDIR}/zone.tab ${DESTDIR}/usr/share/zoneinfo/
 
+afterinstall:
+	@#
+	@# If the file /var/db/zoneinfo exists, and it is owned by root:wheel,
+	@# and the contents of it exists in /usr/share/zoneinfo, then reinstall
+	@# it.
+	@#
+	@if [ -f ${DESTDIR}/var/db/zoneinfo -a -O ${DESTDIR}/var/db/zoneinfo \
+	    -a -G ${DESTDIR}/var/db/zoneinfo ]; then \
+		zf=$$(cat ${DESTDIR}/var/db/zoneinfo); \
+		if [ -f ${DESTDIR}/usr/share/zoneinfo/$${zf} ]; then \
+			if [ ! -z "${DESTDIR}" ]; then \
+				optC="-C ${DESTDIR}"; \
+			fi; \
+			echo "Updating /etc/localtime"; \
+			tzsetup ${optC} -r; \
+		fi; \
+	else \
+		echo "Run tzsetup(8) manually to update /etc/localtime."; \
+	fi
+
 .include 

From 9b683f8da6be8d2ae9a1a3a0949c3db4fda97a64 Mon Sep 17 00:00:00 2001
From: Philip Paeps 
Date: Wed, 21 Oct 2009 23:50:35 +0000
Subject: [PATCH 276/646] Make dhclient use bootpc (68) as the source port for
 unicast DHCPREQUEST packets instead of allowing the protocol stack to pick a
 random source port.

This fixes the behaviour where dhclient would never transition from RENEWING
to BOUND without going through REBINDING in networks which are paranoid about
DHCP spoofing, such as most mainstream cable-broadband ISP networks.

Reviewed by:	brooks
Obtained from:	OpenBSD (partly - I'm not convinced their solution can work)
MFC after:	1 week (pending re approval)
---
 sbin/dhclient/bpf.c    | 45 +++++++++++++++++++++++++-----------------
 sbin/dhclient/dhcpd.h  |  3 +++
 sbin/dhclient/packet.c | 11 +++++++++++
 3 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/sbin/dhclient/bpf.c b/sbin/dhclient/bpf.c
index 8a669e1befb..9f8e45fbfd2 100644
--- a/sbin/dhclient/bpf.c
+++ b/sbin/dhclient/bpf.c
@@ -90,11 +90,23 @@ if_register_bpf(struct interface_info *info)
 void
 if_register_send(struct interface_info *info)
 {
+	int sock, on = 1;
+
 	/*
 	 * If we're using the bpf API for sending and receiving, we
 	 * don't need to register this interface twice.
 	 */
 	info->wfdesc = info->rfdesc;
+
+	/*
+	 * Use raw socket for unicast send.
+	 */
+	if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
+		error("socket(SOCK_RAW): %m");
+	if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on,
+	    sizeof(on)) == -1)
+		error("setsockopt(IP_HDRINCL): %m");
+	info->ufdesc = sock;
 }
 
 /*
@@ -244,35 +256,32 @@ send_packet(struct interface_info *interface, struct dhcp_packet *raw,
 {
 	unsigned char buf[256];
 	struct iovec iov[2];
+	struct msghdr msg;
 	int result, bufp = 0;
-	int sock;
-
-	if (to->sin_addr.s_addr != INADDR_BROADCAST) {
-		note("SENDING DIRECT");
-		/* We know who the server is, send the packet via
-		   normal socket interface */
-
-		if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0) {
-			result = sendto (sock, (char *)raw, len, 0,
-					 (struct sockaddr *)to, sizeof *to);
-			close(sock);
-			if (result > 0)
-				return result;
-			}
-		}
 
 	/* Assemble the headers... */
-	assemble_hw_header(interface, buf, &bufp, hto);
+	if (to->sin_addr.s_addr == INADDR_BROADCAST)
+		assemble_hw_header(interface, buf, &bufp, hto);
 	assemble_udp_ip_header(buf, &bufp, from.s_addr,
 	    to->sin_addr.s_addr, to->sin_port, (unsigned char *)raw, len);
 
-	/* Fire it off */
 	iov[0].iov_base = (char *)buf;
 	iov[0].iov_len = bufp;
 	iov[1].iov_base = (char *)raw;
 	iov[1].iov_len = len;
 
-	result = writev(interface->wfdesc, iov, 2);
+	/* Fire it off */
+	if (to->sin_addr.s_addr == INADDR_BROADCAST)
+		result = writev(interface->wfdesc, iov, 2);
+	else {
+		memset(&msg, 0, sizeof(msg));
+		msg.msg_name = (struct sockaddr *)to;
+		msg.msg_namelen = sizeof(*to);
+		msg.msg_iov = iov;
+		msg.msg_iovlen = 2;
+		result = sendmsg(interface->ufdesc, &msg, 0);
+	}
+
 	if (result < 0)
 		warning("send_packet: %m");
 	return (result);
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index 8097f14b1de..bd4c9c0b5e1 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -37,6 +37,8 @@
  * Enterprises.  To learn more about the Internet Software Consortium,
  * see ``http://www.vix.com/isc''.  To learn more about Vixie
  * Enterprises, see ``http://www.vix.com''.
+ *
+ * $FreeBSD$
  */
 
 #include 
@@ -194,6 +196,7 @@ struct interface_info {
 	char			 name[IFNAMSIZ];
 	int			 rfdesc;
 	int			 wfdesc;
+	int			 ufdesc;
 	unsigned char		*rbuf;
 	size_t			 rbuf_max;
 	size_t			 rbuf_offset;
diff --git a/sbin/dhclient/packet.c b/sbin/dhclient/packet.c
index 484953ca2d9..2e90cc85a8d 100644
--- a/sbin/dhclient/packet.c
+++ b/sbin/dhclient/packet.c
@@ -135,6 +135,17 @@ assemble_udp_ip_header(unsigned char *buf, int *bufix, u_int32_t from,
 	ip.ip_dst.s_addr = to;
 
 	ip.ip_sum = wrapsum(checksum((unsigned char *)&ip, sizeof(ip), 0));
+
+	/*
+	 * While the BPF -- used for broadcasts -- expects a "true" IP header
+	 * with all the bytes in network byte order, the raw socket interface
+	 * which is used for unicasts expects the ip_len field to be in host
+	 * byte order.  In both cases, the checksum has to be correct, so this
+	 * is as good a place as any to turn the bytes around again.
+	 */
+	if (to != INADDR_BROADCAST)
+		ip.ip_len = ntohs(ip.ip_len);
+
 	memcpy(&buf[*bufix], &ip, sizeof(ip));
 	*bufix += sizeof(ip);
 

From fc02477e1c4ff69f56db3f902907e881d927e2d3 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Thu, 22 Oct 2009 00:32:01 +0000
Subject: [PATCH 277/646] Verify "smp_started" is true before calling
 sched_bind() and sched_unbind().

Reviewed by:	kmacy
MFC after:	3 days
---
 sys/net/flowtable.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index 31c2acc19a9..3ed0528dd28 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -963,15 +963,19 @@ flowtable_clean_vnet(void)
 				if (CPU_ABSENT(i))
 					continue;
 
-				thread_lock(curthread);
-				sched_bind(curthread, i);
-				thread_unlock(curthread);
+				if (smp_started == 1) {
+					thread_lock(curthread);
+					sched_bind(curthread, i);
+					thread_unlock(curthread);
+				}
 
 				flowtable_free_stale(ft, NULL);
 
-				thread_lock(curthread);
-				sched_unbind(curthread);
-				thread_unlock(curthread);
+				if (smp_started == 1) {
+					thread_lock(curthread);
+					sched_unbind(curthread);
+					thread_unlock(curthread);
+				}
 			}
 		} else {
 			flowtable_free_stale(ft, NULL);

From e6fa23b0da7ba06e2da3c316c0bcf28847b695bd Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 22 Oct 2009 06:13:07 +0000
Subject: [PATCH 278/646] Fix a memory leak in an error case.

PR:		138376
Submitted by:	Patroklos Argyroudis 
Reviewed by:	scottl
MFC after:	1 week
---
 sys/cam/scsi/scsi_low.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/cam/scsi/scsi_low.c b/sys/cam/scsi/scsi_low.c
index 57054a23e93..1cee43dca29 100644
--- a/sys/cam/scsi/scsi_low.c
+++ b/sys/cam/scsi/scsi_low.c
@@ -638,7 +638,10 @@ scsi_low_attach_xs(slp)
 		return ENOMEM;
 	splp = SCSI_LOW_MALLOC(sizeof(*splp));
 	if (splp == NULL)
+	{
+		SCSI_LOW_FREE(sap);
 		return ENOMEM;
+	}
 
 	SCSI_LOW_BZERO(sap, sizeof(*sap));
 	SCSI_LOW_BZERO(splp, sizeof(*splp));

From 4382b0681eaa3c319464d2669d45da46dde04637 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 22 Oct 2009 06:17:04 +0000
Subject: [PATCH 279/646] Check pointer for NULL before dereferencing it, not
 after.

PR:		138390
Submitted by:	Patroklos Argyroudis 
MFC after:	1 week
---
 sys/net/if_gif.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 6abc8071e02..22ef6abc8ee 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -507,7 +507,7 @@ gif_input(m, af, ifp)
 	struct ifnet *ifp;
 {
 	int isr, n;
-	struct gif_softc *sc = ifp->if_softc;
+	struct gif_softc *sc;
 	struct etherip_header *eip;
 	struct ether_header *eh;
 	struct ifnet *oldifp;
@@ -517,7 +517,7 @@ gif_input(m, af, ifp)
 		m_freem(m);
 		return;
 	}
-
+	sc = ifp->if_softc;
 	m->m_pkthdr.rcvif = ifp;
 
 #ifdef MAC

From ef1be3b04221c520aca0f6f839d1d4dc339912e1 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 22 Oct 2009 06:51:29 +0000
Subject: [PATCH 280/646] Check pointer for NULL before dereferencing it, not
 after.

PR:		138387, 138388
Submitted by:	Patroklos Argyroudis 
MFC after:	1 week
---
 sys/dev/ppbus/lpt.c      | 7 +++++--
 sys/dev/ppbus/pcfclock.c | 6 ++++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c
index 56b43788401..18d46ae39d5 100644
--- a/sys/dev/ppbus/lpt.c
+++ b/sys/dev/ppbus/lpt.c
@@ -486,12 +486,15 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
 {
 	int trys, err;
 	struct lpt_data *sc = dev->si_drv1;
-	device_t lptdev = sc->sc_dev;
-	device_t ppbus = device_get_parent(lptdev);
+	device_t lptdev;
+	device_t ppbus;
 
 	if (!sc)
 		return (ENXIO);
 
+	lptdev = sc->sc_dev;
+	ppbus = device_get_parent(lptdev);
+
 	ppb_lock(ppbus);
 	if (sc->sc_state) {
 		lprintf(("%s: still open %x\n", device_get_nameunit(lptdev),
diff --git a/sys/dev/ppbus/pcfclock.c b/sys/dev/ppbus/pcfclock.c
index e59a8919e03..65612a21de4 100644
--- a/sys/dev/ppbus/pcfclock.c
+++ b/sys/dev/ppbus/pcfclock.c
@@ -150,12 +150,14 @@ static int
 pcfclock_open(struct cdev *dev, int flag, int fms, struct thread *td)
 {
 	struct pcfclock_data *sc = dev->si_drv1;
-	device_t pcfclockdev = sc->dev;
-	device_t ppbus = device_get_parent(pcfclockdev);
+	device_t pcfclockdev;
+	device_t ppbus;
 	int res;
 
 	if (!sc)
 		return (ENXIO);
+	pcfclockdev = sc->dev;
+	ppbus = device_get_parent(pcfclockdev);
 
 	ppb_lock(ppbus);
 	res = ppb_request_bus(ppbus, pcfclockdev,

From fa3e572c935b4871cb3aa955436fb01fa45044fb Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Thu, 22 Oct 2009 08:38:27 +0000
Subject: [PATCH 281/646] Remove self-reference.

---
 share/man/man4/mac_mls.4 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/share/man/man4/mac_mls.4 b/share/man/man4/mac_mls.4
index 95e66be18c5..921781adf1e 100644
--- a/share/man/man4/mac_mls.4
+++ b/share/man/man4/mac_mls.4
@@ -212,7 +212,6 @@ allow the superuser to bypass MLS protections.
 .Xr mac_bsdextended 4 ,
 .Xr mac_ifoff 4 ,
 .Xr mac_lomac 4 ,
-.Xr mac_mls 4 ,
 .Xr mac_none 4 ,
 .Xr mac_partition 4 ,
 .Xr mac_portacl 4 ,

From 5d98bcc2ff10868da3abf362ffc6e0a902872f23 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 22 Oct 2009 11:35:12 +0000
Subject: [PATCH 282/646] List more dependencies for these drivers. While here,
 convert atapicam(4) to use our standard section 4 SYNOPSIS layout.

PR:		132525
Submitted by:	gcooper
MFC after:	3 days
---
 share/man/man4/atapicam.4 | 17 ++++++++++++++++-
 share/man/man4/umass.4    |  5 ++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/atapicam.4 b/share/man/man4/atapicam.4
index 830a4dd3e56..81442074cc6 100644
--- a/share/man/man4/atapicam.4
+++ b/share/man/man4/atapicam.4
@@ -27,14 +27,29 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 23, 2002
+.Dd October 22, 2009
 .Dt ATAPICAM 4
 .Os
 .Sh NAME
 .Nm atapicam
 .Nd CAM XPT (transport) module for ATAPI devices
 .Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device scbus"
+.Cd "device cam"
+.Cd "device ata"
 .Cd "device atapicam"
+.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
+atapicam_load="YES"
+.Ed
 .Sh DESCRIPTION
 The ATAPI/CAM module allows ATAPI devices (CD-ROM, CD-RW, DVD drives,
 floppy drives such as Iomega Zip, tape drives) to be accessed through
diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4
index e1949caf8e5..ffa1ac31073 100644
--- a/share/man/man4/umass.4
+++ b/share/man/man4/umass.4
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 22, 2006
+.Dd October 22, 2009
 .Dt UMASS 4
 .Os
 .Sh NAME
@@ -38,6 +38,9 @@ To compile this driver into the kernel,
 place the following line in your
 kernel configuration file:
 .Bd -ragged -offset indent
+.Cd "device scbus"
+.Cd "device cam"
+.Cd "device usb"
 .Cd "device umass"
 .Ed
 .Pp

From b48db8e12d07b8a1c49b85d2c02b91dc9b96d6ef Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Thu, 22 Oct 2009 11:45:35 +0000
Subject: [PATCH 283/646] Unbreak NO_WARNS, keeping CSTD effect on CFLAGS out
 of its control. Unbreak compiles with icc.

---
 share/mk/bsd.sys.mk | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk
index f0a40c968ef..9a189a6a876 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -11,7 +11,7 @@
 # the default is gnu99 for now
 CSTD		?= gnu99
 
-.if !defined(NO_WARNS) || ${CC} != "icc"
+.if ${CC} != "icc"
 . if ${CSTD} == "k&r"
 CFLAGS		+= -traditional
 . elif ${CSTD} == "c89" || ${CSTD} == "c90"
@@ -23,6 +23,8 @@ CFLAGS		+= -std=iso9899:1999
 . else
 CFLAGS		+= -std=${CSTD}
 . endif
+.endif
+.if !defined(NO_WARNS) && ${CC} != "icc"
 # -pedantic is problematic because it also imposes namespace restrictions
 #CFLAGS		+= -pedantic
 . if defined(WARNS)

From bcda02c3e48351b3a9ce733327cdd0b60a465103 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Thu, 22 Oct 2009 12:48:17 +0000
Subject: [PATCH 284/646] Don't use BUS_DMA_ALLOCNOW as that causes the
 attachment to fail on Cambria boards.

MFC after:	2 months
---
 sys/dev/mwl/if_mwl_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c
index 2fb09227d0b..33666d40f12 100644
--- a/sys/dev/mwl/if_mwl_pci.c
+++ b/sys/dev/mwl/if_mwl_pci.c
@@ -204,7 +204,7 @@ mwl_pci_attach(device_t dev)
 			       BUS_SPACE_MAXADDR,	/* maxsize */
 			       MWL_TXDESC,		/* nsegments */
 			       BUS_SPACE_MAXADDR,	/* maxsegsize */
-			       BUS_DMA_ALLOCNOW,	/* flags */
+			       0,			/* flags */
 			       NULL,			/* lockfunc */
 			       NULL,			/* lockarg */
 			       &sc->sc_dmat)) {

From 3eec6f034a8e137b9a6b74121c8fed2ac5ecfb67 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 22 Oct 2009 14:53:44 +0000
Subject: [PATCH 285/646] Set the devclass_t pointer specified in the
 DRIVER_MODULE() macro sooner so it is always valid when a driver's identify
 routine is called.  Previously, new-bus would attempt to create the devclass
 for a newly loaded driver in two separate places, once in
 devclass_add_driver(), and again after devclass_add_driver() returned in
 driver_module_handler().  Only the second lookup attempted to set a device
 class' parent and set the devclass_t pointer specified in the DRIVER_MODULE()
 macro.  However, by the time it was executed, the driver was already added to
 existing instances of the parent driver at which point in time the new
 driver's identify routine would have been invoked.  The fix is to merge the
 two attempts and only create the devclass once in devclass_add_driver()
 including setting the devclass_t pointer passed to DRIVER_MODULE() before the
 driver is added to any existing bus devices.

Reported by:	avg
Reviewed by:	imp
MFC after:	2 weeks
---
 sys/kern/subr_bus.c | 38 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index e4d1f9b5a0d..0c97aa3b78b 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1049,9 +1049,10 @@ devclass_driver_added(devclass_t dc, driver_t *driver)
  * @param driver	the driver to register
  */
 static int
-devclass_add_driver(devclass_t dc, driver_t *driver, int pass)
+devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp)
 {
 	driverlink_t dl;
+	const char *parentname;
 
 	PDEBUG(("%s", DRIVERNAME(driver)));
 
@@ -1072,9 +1073,17 @@ devclass_add_driver(devclass_t dc, driver_t *driver, int pass)
 	kobj_class_compile((kobj_class_t) driver);
 
 	/*
-	 * Make sure the devclass which the driver is implementing exists.
+	 * If the driver has any base classes, make the
+	 * devclass inherit from the devclass of the driver's
+	 * first base class. This will allow the system to
+	 * search for drivers in both devclasses for children
+	 * of a device using this driver.
 	 */
-	devclass_find_internal(driver->name, NULL, TRUE);
+	if (driver->baseclasses)
+		parentname = driver->baseclasses[0]->name;
+	else
+		parentname = NULL;
+	*dcp = devclass_find_internal(driver->name, parentname, TRUE);
 
 	dl->driver = driver;
 	TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
@@ -4157,27 +4166,8 @@ driver_module_handler(module_t mod, int what, void *arg)
 		driver = dmd->dmd_driver;
 		PDEBUG(("Loading module: driver %s on bus %s (pass %d)",
 		    DRIVERNAME(driver), dmd->dmd_busname, pass));
-		error = devclass_add_driver(bus_devclass, driver, pass);
-		if (error)
-			break;
-
-		/*
-		 * If the driver has any base classes, make the
-		 * devclass inherit from the devclass of the driver's
-		 * first base class. This will allow the system to
-		 * search for drivers in both devclasses for children
-		 * of a device using this driver.
-		 */
-		if (driver->baseclasses) {
-			const char *parentname;
-			parentname = driver->baseclasses[0]->name;
-			*dmd->dmd_devclass =
-				devclass_find_internal(driver->name,
-				    parentname, TRUE);
-		} else {
-			*dmd->dmd_devclass =
-				devclass_find_internal(driver->name, NULL, TRUE);
-		}
+		error = devclass_add_driver(bus_devclass, driver, pass,
+		    dmd->dmd_devclass);
 		break;
 
 	case MOD_UNLOAD:

From 038abe369ed33b35f458d00ae056d37ccb1094b4 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Thu, 22 Oct 2009 17:30:22 +0000
Subject: [PATCH 286/646] Initialize rann_flags properly.

MFC after:	2 days
---
 sys/net80211/ieee80211_hwmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 32ca163745c..ea06b0e3a9d 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -653,6 +653,7 @@ hwmp_rootmode_rann_cb(void *arg)
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss,
 	    "%s", "send broadcast RANN");
 
+	rann.rann_flags = 0;
 	if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL)
 		rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR;
 	rann.rann_hopcount = 0;

From ab593611be01418440cf828e3be863c32e2e48d3 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 22 Oct 2009 20:44:55 +0000
Subject: [PATCH 287/646] cam_ccbq_fini() declared for 11 years, but never
 implemented. Remove it.

---
 sys/cam/cam_queue.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index d2990ad26e9..f3295f31470 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -96,8 +96,6 @@ int		cam_ccbq_init(struct cam_ccbq *ccbq, int openings);
 
 void		cam_ccbq_free(struct cam_ccbq *ccbq);
 
-void		cam_ccbq_fini(struct cam_ccbq *ccbq);
-
 /*
  * Allocate and initialize a cam_queue structure.
  */

From 4ed0304c97f019d3327503e5a5fde76a2cdbd8a3 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 22 Oct 2009 20:54:01 +0000
Subject: [PATCH 288/646] Allow dumping the USB mouse reports via 'sysctl -b
 dev.ums.N.parseinfo', previously only available via bootverbose.

PR:		usb/137191
Submitted by:	Eygene Ryabinkin
---
 sys/dev/usb/input/ums.c | 72 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index 7872fe737c5..52c02dc358c 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -161,7 +162,9 @@ static usb_fifo_open_t ums_open;
 static usb_fifo_close_t ums_close;
 static usb_fifo_ioctl_t ums_ioctl;
 
-static void ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy, int32_t dz, int32_t dt, int32_t buttons);
+static void	ums_put_queue(struct ums_softc *, int32_t, int32_t,
+		    int32_t, int32_t, int32_t);
+static int	ums_sysctl_handler_parseinfo(SYSCTL_HANDLER_ARGS);
 
 static struct usb_fifo_methods ums_fifo_methods = {
 	.f_open = &ums_open,
@@ -643,6 +646,12 @@ ums_attach(device_t dev)
 	if (err) {
 		goto detach;
 	}
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "parseinfo", CTLTYPE_STRING|CTLFLAG_RD,
+	    sc, 0, ums_sysctl_handler_parseinfo,
+	    "", "Dump UMS report parsing information");
+
 	return (0);
 
 detach:
@@ -916,6 +925,67 @@ done:
 	return (error);
 }
 
+static int
+ums_sysctl_handler_parseinfo(SYSCTL_HANDLER_ARGS)
+{
+	struct ums_softc *sc = arg1;
+	struct ums_info *info;
+	struct sbuf *sb;
+	int i, j, err;
+
+	sb = sbuf_new_auto();
+	for (i = 0; i < UMS_INFO_MAX; i++) {
+		info = &sc->sc_info[i];
+
+		/* Don't emit empty info */
+		if ((info->sc_flags &
+		    (UMS_FLAG_X_AXIS | UMS_FLAG_Y_AXIS | UMS_FLAG_Z_AXIS |
+		     UMS_FLAG_T_AXIS | UMS_FLAG_W_AXIS)) == 0 &&
+		    info->sc_buttons == 0)
+			continue;
+
+		sbuf_printf(sb, "i%d:", i + 1);
+		if (info->sc_flags & UMS_FLAG_X_AXIS)
+			sbuf_printf(sb, " X:r%d, p%d, s%d;",
+			    (int)info->sc_iid_x,
+			    (int)info->sc_loc_x.pos,
+			    (int)info->sc_loc_x.size);
+		if (info->sc_flags & UMS_FLAG_Y_AXIS)
+			sbuf_printf(sb, " Y:r%d, p%d, s%d;",
+			    (int)info->sc_iid_y,
+			    (int)info->sc_loc_y.pos,
+			    (int)info->sc_loc_y.size);
+		if (info->sc_flags & UMS_FLAG_Z_AXIS)
+			sbuf_printf(sb, " Z:r%d, p%d, s%d;",
+			    (int)info->sc_iid_z,
+			    (int)info->sc_loc_z.pos,
+			    (int)info->sc_loc_z.size);
+		if (info->sc_flags & UMS_FLAG_T_AXIS)
+			sbuf_printf(sb, " T:r%d, p%d, s%d;",
+			    (int)info->sc_iid_t,
+			    (int)info->sc_loc_t.pos,
+			    (int)info->sc_loc_t.size);
+		if (info->sc_flags & UMS_FLAG_W_AXIS)
+			sbuf_printf(sb, " W:r%d, p%d, s%d;",
+			    (int)info->sc_iid_w,
+			    (int)info->sc_loc_w.pos,
+			    (int)info->sc_loc_w.size);
+
+		for (j = 0; j < info->sc_buttons; j++) {
+			sbuf_printf(sb, " B%d:r%d, p%d, s%d;", j + 1,
+			    (int)info->sc_iid_btn[j],
+			    (int)info->sc_loc_btn[j].pos,
+			    (int)info->sc_loc_btn[j].size);
+		}
+		sbuf_printf(sb, "\n");
+	}
+	sbuf_finish(sb);
+	err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+	sbuf_delete(sb);
+
+	return (err);
+}
+
 static devclass_t ums_devclass;
 
 static device_method_t ums_methods[] = {

From 97aa4d9845cbecf61909aca7b779251641bb1792 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 22 Oct 2009 20:57:17 +0000
Subject: [PATCH 289/646] Rename default to default_function, for compatibility
 with GNU awk. (For cross-compiling out-of-tree kernel modules, for example.)

---
 sys/tools/makeobjops.awk | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sys/tools/makeobjops.awk b/sys/tools/makeobjops.awk
index 61994f36e58..0406b855047 100644
--- a/sys/tools/makeobjops.awk
+++ b/sys/tools/makeobjops.awk
@@ -240,7 +240,7 @@ function handle_method (static, doc)
 		lineno++
 	}
 
-	default = "";
+	default_function = "";
 	if (!match(line, /\};?/)) {
 		warnsrc("Premature end of file");
 		error = 1;
@@ -248,9 +248,9 @@ function handle_method (static, doc)
 	}
 	extra = substr(line, RSTART + RLENGTH);
 	if (extra ~ /[	 ]*DEFAULT[ 	]*[a-zA-Z_][a-zA-Z_0-9]*[ 	]*;/) {
-		default = extra;
-		sub(/.*DEFAULT[	 ]*/, "", default);
-		sub(/[; 	]+.*$/, "", default);
+		default_function = extra;
+		sub(/.*DEFAULT[	 ]*/, "", default_function);
+		sub(/[; 	]+.*$/, "", default_function);
 	}
 	else if (extra && opt_d) {
 		#   Warn about garbage at end of line.
@@ -294,8 +294,8 @@ function handle_method (static, doc)
 
 	firstvar = varnames[1];
 
-	if (default == "")
-		default = "kobj_error_method";
+	if (default_function == "")
+		default_function = "kobj_error_method";
 
 	# the method description 
 	printh("/** @brief Unique descriptor for the " umname "() method */");
@@ -308,7 +308,7 @@ function handle_method (static, doc)
 
 	# Print out the method desc
 	printc("struct kobj_method " mname "_method_default = {");
-	printc("\t&" mname "_desc, (kobjop_t) " default);
+	printc("\t&" mname "_desc, (kobjop_t) " default_function);
 	printc("};\n");
 
 	printc("struct kobjop_desc " mname "_desc = {");

From 62d98575012da9e7021e0e690ec4d5deb677ee51 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Thu, 22 Oct 2009 20:59:51 +0000
Subject: [PATCH 290/646] Move comments to the beginning of the line to make it
 look better. Thank to ru@ for his noticing of it.

MFC after:	1 week
---
 share/zoneinfo/Makefile | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/share/zoneinfo/Makefile b/share/zoneinfo/Makefile
index 6acd502715a..326f3b488f2 100644
--- a/share/zoneinfo/Makefile
+++ b/share/zoneinfo/Makefile
@@ -55,11 +55,11 @@ beforeinstall:
 	    ${.CURDIR}/zone.tab ${DESTDIR}/usr/share/zoneinfo/
 
 afterinstall:
-	@#
-	@# If the file /var/db/zoneinfo exists, and it is owned by root:wheel,
-	@# and the contents of it exists in /usr/share/zoneinfo, then reinstall
-	@# it.
-	@#
+#
+# If the file /var/db/zoneinfo exists, and it is owned by root:wheel,
+# and the contents of it exists in /usr/share/zoneinfo, then reinstall
+# it.
+#
 	@if [ -f ${DESTDIR}/var/db/zoneinfo -a -O ${DESTDIR}/var/db/zoneinfo \
 	    -a -G ${DESTDIR}/var/db/zoneinfo ]; then \
 		zf=$$(cat ${DESTDIR}/var/db/zoneinfo); \

From 0c35eaad3fbd2cefd3ae24a03cef06f51d6ace53 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 22 Oct 2009 21:01:41 +0000
Subject: [PATCH 291/646] Prevent wraparound of the timeout variable.

Submitted by:	HPS
---
 lib/libusb/libusb20_ugen20.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
index 0dee7935b7a..f9f36891a03 100644
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -800,7 +800,11 @@ ugen20_tr_submit(struct libusb20_transfer *xfer)
 	if (xfer->flags & LIBUSB20_TRANSFER_DO_CLEAR_STALL) {
 		fsep->flags |= USB_FS_FLAG_CLEAR_STALL;
 	}
-	fsep->timeout = xfer->timeout;
+	/* NOTE: The "fsep->timeout" variable is 16-bit. */
+	if (xfer->timeout > 65535)
+		fsep->timeout = 65535;
+	else
+		fsep->timeout = xfer->timeout;
 
 	temp.ep_index = xfer->trIndex;
 

From 20a7933f537f94048723ebea9e768dacc948aa7c Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 22 Oct 2009 21:07:32 +0000
Subject: [PATCH 292/646] After thinking again, implement cam_ccbq_fini(). This
 is effectively NULL change, but makes this API a bit more consistent.

---
 sys/cam/cam_queue.c | 9 ++++++++-
 sys/cam/cam_queue.h | 2 ++
 sys/cam/cam_xpt.c   | 2 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index 1e756d2e89a..56586be3cf7 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -289,7 +289,7 @@ void
 cam_ccbq_free(struct cam_ccbq *ccbq)
 {
 	if (ccbq) {
-		camq_fini(&ccbq->queue);
+		cam_ccbq_fini(ccbq);
 		free(ccbq, M_CAMCCBQ);
 	}
 }
@@ -338,6 +338,13 @@ cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
 	return (0);
 }
 
+void
+cam_ccbq_fini(struct cam_ccbq *ccbq)
+{
+
+	camq_fini(&ccbq->queue);
+}
+
 /*
  * Heap routines for manipulating CAM queues.
  */
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index f3295f31470..d2990ad26e9 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -96,6 +96,8 @@ int		cam_ccbq_init(struct cam_ccbq *ccbq, int openings);
 
 void		cam_ccbq_free(struct cam_ccbq *ccbq);
 
+void		cam_ccbq_fini(struct cam_ccbq *ccbq);
+
 /*
  * Allocate and initialize a cam_queue structure.
  */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 9afeafa3bf5..5ca0584b5e0 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4447,7 +4447,7 @@ xpt_release_device(struct cam_eb *bus, struct cam_et *target,
 		devq = bus->sim->devq;
 		cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 		camq_fini(&device->drvq);
-		camq_fini(&device->ccbq.queue);
+		cam_ccbq_fini(&device->ccbq);
 		free(device, M_CAMXPT);
 		xpt_release_target(bus, target);
 	}

From 999987e51a2db77e5407c5a2cdb5d759b1317714 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Fri, 23 Oct 2009 03:17:02 +0000
Subject: [PATCH 293/646] Add SMP support on U3-based G5 systems. This does not
 yet work perfectly: at least on my Xserve, getting the decrementer and
 timebase on APs to tick requires setting up a clock chip over I2C, which is
 not yet done.

While here, correct the 64-bit tlbie function to set the CPU to 64-bit
mode correctly.

Hardware donated by:	grehan
---
 sys/powerpc/aim/mmu_oea64.c      |  81 +++++++++------
 sys/powerpc/aim/mp_cpudep.c      | 169 +++++++++++++++++++++++--------
 sys/powerpc/aim/platform_chrp.c  |   4 +-
 sys/powerpc/booke/mp_cpudep.c    |   7 +-
 sys/powerpc/include/pcpu.h       |   4 +-
 sys/powerpc/include/smp.h        |   3 +-
 sys/powerpc/include/spr.h        |   8 +-
 sys/powerpc/powerpc/cpu.c        |  23 ++---
 sys/powerpc/powerpc/mp_machdep.c |  10 +-
 9 files changed, 210 insertions(+), 99 deletions(-)

diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 67e457ca217..9a400363b68 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -182,35 +182,28 @@ va_to_vsid(pmap_t pm, vm_offset_t va)
  * Just to add to the fun, exceptions must be off as well
  * so that we can't trap in 64-bit mode. What a pain.
  */
+struct mtx	tlbie_mutex;
 
 static __inline void
 TLBIE(pmap_t pmap, vm_offset_t va) {
-	register_t msr;
-	register_t scratch;
-
 	uint64_t vpn;
 	register_t vpn_hi, vpn_lo;
-
-#if 1
-	/*
-	 * CPU documentation says that tlbie takes the VPN, not the
-	 * VA. I think the code below does this correctly. We will see.
-	 */
+	register_t msr;
+	register_t scratch;
 
 	vpn = (uint64_t)(va & ADDR_PIDX);
 	if (pmap != NULL)
 		vpn |= (va_to_vsid(pmap,va) << 28);
-#else
-	vpn = va;
-#endif
 
 	vpn_hi = (uint32_t)(vpn >> 32);
 	vpn_lo = (uint32_t)vpn;
 
+	mtx_lock_spin(&tlbie_mutex);
 	__asm __volatile("\
 	    mfmsr %0; \
 	    clrldi %1,%0,49; \
-	    insrdi %1,1,1,0; \
+	    mtmsr %1; \
+	    insrdi %1,%5,1,0; \
 	    mtmsrd %1; \
 	    ptesync; \
 	    \
@@ -222,7 +215,8 @@ TLBIE(pmap_t pmap, vm_offset_t va) {
 	    eieio; \
 	    tlbsync; \
 	    ptesync;" 
-	: "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32));
+	: "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32), "r"(1));
+	mtx_unlock_spin(&tlbie_mutex);
 }
 
 #define DISABLE_TRANS(msr)	msr = mfmsr(); mtmsr(msr & ~PSL_DR); isync()
@@ -352,7 +346,7 @@ static int		moea64_pte_insert(u_int, struct lpte *);
  * PVO calls.
  */
 static int	moea64_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
-		    vm_offset_t, vm_offset_t, uint64_t, int, int);
+		    vm_offset_t, vm_offset_t, uint64_t, int);
 static void	moea64_pvo_remove(struct pvo_entry *, int);
 static struct	pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t, int *);
 static struct	lpte *moea64_pvo_to_pte(const struct pvo_entry *, int);
@@ -824,6 +818,11 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
 	mtx_init(&moea64_table_mutex, "pmap table", NULL, MTX_DEF |
 	    MTX_RECURSE);
 
+	/*
+	 * Initialize the TLBIE lock. TLBIE can only be executed by one CPU.
+	 */
+	mtx_init(&tlbie_mutex, "tlbie mutex", NULL, MTX_SPIN);
+
 	/*
 	 * Initialise the unmanaged pvo pool.
 	 */
@@ -1254,7 +1253,7 @@ moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
 		pvo_flags |= PVO_FAKE;
 
 	error = moea64_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
-	    pte_lo, pvo_flags, 0);
+	    pte_lo, pvo_flags);
 
 	if (pmap == kernel_pmap)
 		TLBIE(pmap, va);
@@ -1427,16 +1426,15 @@ moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
 	if (pvo_allocator_start >= pvo_allocator_end)
 		panic("Ran out of PVO allocator buffer space!");
 
-	/* Now call pvo_enter in recursive mode */
 	moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
 	    &moea64_pvo_kunmanaged, va,  VM_PAGE_TO_PHYS(m), LPTE_M, 
-	    PVO_WIRED | PVO_BOOTSTRAP, 1);
+	    PVO_WIRED | PVO_BOOTSTRAP);
 
 	TLBIE(kernel_pmap, va);
-	
+
 	if (needed_lock)
 		PMAP_UNLOCK(kernel_pmap);
-
+	
 	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
                 bzero((void *)va, PAGE_SIZE);
 
@@ -1579,7 +1577,7 @@ moea64_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
 	PMAP_LOCK(kernel_pmap);
 	error = moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
 	    &moea64_pvo_kunmanaged, va, pa, pte_lo, 
-	    PVO_WIRED | VM_PROT_EXECUTE, 0);
+	    PVO_WIRED | VM_PROT_EXECUTE);
 
 	TLBIE(kernel_pmap, va);
 
@@ -1968,14 +1966,29 @@ static void
 tlbia(void)
 {
 	vm_offset_t i;
+	register_t msr, scratch;
 
-	for (i = 0; i < 0xFF000; i += 0x00001000) 
-		TLBIE(NULL,i);
+	for (i = 0; i < 0xFF000; i += 0x00001000) {
+		__asm __volatile("\
+		    mfmsr %0; \
+		    mr %1, %0; \
+		    insrdi %1,%3,1,0; \
+		    mtmsrd %1; \
+		    ptesync; \
+		    \
+		    tlbiel %2; \
+		    \
+		    mtmsrd %0; \
+		    eieio; \
+		    tlbsync; \
+		    ptesync;" 
+		: "=r"(msr), "=r"(scratch) : "r"(i), "r"(1));
+	}
 }
 
 static int
 moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
-    vm_offset_t va, vm_offset_t pa, uint64_t pte_lo, int flags, int recurse)
+    vm_offset_t va, vm_offset_t pa, uint64_t pte_lo, int flags)
 {
 	struct	 pvo_entry *pvo;
 	uint64_t vsid;
@@ -2011,16 +2024,14 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
 	 * Remove any existing mapping for this page.  Reuse the pvo entry if
 	 * there is a mapping.
 	 */
-	if (!recurse)
-		LOCK_TABLE();
+	LOCK_TABLE();
 
 	LIST_FOREACH(pvo, &moea64_pvo_table[ptegidx], pvo_olink) {
 		if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
 			if ((pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) == pa &&
 			    (pvo->pvo_pte.lpte.pte_lo & LPTE_PP) ==
 			    (pte_lo & LPTE_PP)) {
-				if (!recurse)
-					UNLOCK_TABLE();
+				UNLOCK_TABLE();
 				return (0);
 			}
 			moea64_pvo_remove(pvo, -1);
@@ -2041,12 +2052,19 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
 		moea64_bpvo_pool_index++;
 		bootstrap = 1;
 	} else {
+		/*
+		 * Note: drop the table around the UMA allocation in
+		 * case the UMA allocator needs to manipulate the page
+		 * table. The mapping we are working with is already
+		 * protected by the PMAP lock.
+		 */
+		UNLOCK_TABLE();
 		pvo = uma_zalloc(zone, M_NOWAIT);
+		LOCK_TABLE();
 	}
 
 	if (pvo == NULL) {
-		if (!recurse)
-			UNLOCK_TABLE();
+		UNLOCK_TABLE();
 		return (ENOMEM);
 	}
 
@@ -2093,8 +2111,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
 		moea64_pte_overflow++;
 	}
 
-	if (!recurse)
-		UNLOCK_TABLE();
+	UNLOCK_TABLE();
 
 	return (first ? ENOENT : 0);
 }
diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c
index 1dc9525c0ee..52f8542ac78 100644
--- a/sys/powerpc/aim/mp_cpudep.c
+++ b/sys/powerpc/aim/mp_cpudep.c
@@ -48,14 +48,34 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-extern void *rstcode;
-extern register_t l2cr_config;
-extern register_t l3cr_config;
-
 void *ap_pcpu;
 
+static register_t bsp_state[8];
+
+static void cpudep_save_config(void *dummy);
+SYSINIT(cpu_save_config, SI_SUB_CPU, SI_ORDER_ANY, cpudep_save_config, NULL);
+
+uintptr_t
+cpudep_ap_bootstrap(void)
+{
+	register_t msr, sp;
+
+	msr = PSL_KERNSET & ~PSL_EE;
+	mtmsr(msr);
+	isync();
+
+	__asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu));
+	powerpc_sync();
+
+	pcpup->pc_curthread = pcpup->pc_idlethread;
+	pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
+	sp = pcpup->pc_curpcb->pcb_sp;
+
+	return (sp);
+}
+
 static register_t
-l2_enable(void)
+mpc745x_l2_enable(register_t l2cr_config)
 {
 	register_t ccr;
 
@@ -77,7 +97,7 @@ l2_enable(void)
 }
 
 static register_t
-l3_enable(void)
+mpc745x_l3_enable(register_t l3cr_config)
 {
 	register_t ccr;
 
@@ -109,7 +129,7 @@ l3_enable(void)
 }
 
 static register_t
-l1d_enable(void)
+mpc745x_l1d_enable(void)
 {
 	register_t hid;
 
@@ -127,7 +147,7 @@ l1d_enable(void)
 }
 
 static register_t
-l1i_enable(void)
+mpc745x_l1i_enable(void)
 {
 	register_t hid;
 
@@ -144,43 +164,110 @@ l1i_enable(void)
 	return (hid);
 }
 
-uint32_t
-cpudep_ap_bootstrap(void)
+static void
+cpudep_save_config(void *dummy)
 {
-	uint32_t hid, msr, reg, sp;
+	uint16_t	vers;
 
-	// reg = mfspr(SPR_MSSCR0);
-	// mtspr(SPR_MSSCR0, reg | 0x3);
+	vers = mfpvr() >> 16;
 
-	__asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu));
-	powerpc_sync();
+	switch(vers) {
+	case IBM970:
+	case IBM970FX:
+	case IBM970MP:
+		__asm __volatile ("mfspr %0,%2; mr %1,%0; srdi %0,%0,32"
+		    : "=r" (bsp_state[0]),"=r" (bsp_state[1]) : "K" (SPR_HID0));
+		__asm __volatile ("mfspr %0,%2; mr %1,%0; srdi %0,%0,32"
+		    : "=r" (bsp_state[2]),"=r" (bsp_state[3]) : "K" (SPR_HID1));
+		__asm __volatile ("mfspr %0,%2; mr %1,%0; srdi %0,%0,32"
+		    : "=r" (bsp_state[4]),"=r" (bsp_state[5]) : "K" (SPR_HID4));
+		__asm __volatile ("mfspr %0,%2; mr %1,%0; srdi %0,%0,32"
+		    : "=r" (bsp_state[6]),"=r" (bsp_state[7]) : "K" (SPR_HID5));
 
-	__asm __volatile("mtspr 1023,%0" :: "r"(PCPU_GET(cpuid)));
-	__asm __volatile("mfspr %0,1023" : "=r"(pcpup->pc_pir));
+		break;
+	case MPC7450:
+	case MPC7455:
+	case MPC7457:
+		/* Only MPC745x CPUs have an L3 cache. */
+		bsp_state[3] = mfspr(SPR_L3CR);
 
-	msr = PSL_FP | PSL_IR | PSL_DR | PSL_ME | PSL_RI;
-	powerpc_sync();
-	isync();
-	mtmsr(msr);
-	isync();
-
-	if (l3cr_config != 0)
-		reg = l3_enable();
-	if (l2cr_config != 0)
-		reg = l2_enable();
-	reg = l1d_enable();
-	reg = l1i_enable();
-
-	hid = mfspr(SPR_HID0);
-	hid &= ~(HID0_DOZE | HID0_SLEEP);
-	hid |= HID0_NAP | HID0_DPM;
-	mtspr(SPR_HID0, hid);
-	isync();
-
-	pcpup->pc_curthread = pcpup->pc_idlethread;
-	pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
-	sp = pcpup->pc_curpcb->pcb_sp;
-
-	return (sp);
+		/* Fallthrough */
+	case MPC7400:
+	case MPC7410:
+	case MPC7447A:
+	case MPC7448:
+		bsp_state[2] = mfspr(SPR_L2CR);
+		bsp_state[1] = mfspr(SPR_HID1);
+		bsp_state[0] = mfspr(SPR_HID0);
+		break;
+	}
+}
+
+void
+cpudep_ap_setup()
+{ 
+	register_t	reg;
+	uint16_t	vers;
+
+	vers = mfpvr() >> 16;
+
+	switch(vers) {
+	case IBM970:
+	case IBM970FX:
+	case IBM970MP:
+		/* Set HIOR to 0 */
+		__asm __volatile("mtspr 311,%0" :: "r"(0));
+		powerpc_sync();
+
+		/*
+		 * The 970 has strange rules about how to update HID registers.
+		 * See Table 2-3, 970MP manual
+		 */
+
+		__asm __volatile(" \
+			ld	%0,0(%2);				\
+			mtspr	%1, %0;					\
+			mfspr	%0, %1;	mfspr	%0, %1;	mfspr	%0, %1;	\
+			mfspr	%0, %1;	mfspr	%0, %1;	mfspr	%0, %1;"
+		    : "=r"(reg) : "K"(SPR_HID0), "r"(bsp_state));
+		__asm __volatile("ld %0, 8(%2); mtspr %1, %0; mtspr %1, %0; \
+		    isync" : "=r"(reg) : "K"(SPR_HID1), "r"(bsp_state));
+		__asm __volatile("ld %0, 16(%2); sync; mtspr %1, %0; isync;"
+		    : "=r"(reg) : "K"(SPR_HID4), "r"(bsp_state));
+		__asm __volatile("ld %0, 24(%2); sync; mtspr %1, %0; isync;"
+		    : "=r"(reg) : "K"(SPR_HID5), "r"(bsp_state));
+
+		powerpc_sync();
+		break;
+	case MPC7450:
+	case MPC7455:
+	case MPC7457:
+		/* Only MPC745x CPUs have an L3 cache. */
+		reg = mpc745x_l3_enable(bsp_state[3]);
+		
+		/* Fallthrough */
+	case MPC7400:
+	case MPC7410:
+	case MPC7447A:
+	case MPC7448:
+		/* XXX: Program the CPU ID into PIR */
+		__asm __volatile("mtspr 1023,%0" :: "r"(PCPU_GET(cpuid)));
+
+		powerpc_sync();
+		isync();
+
+		mtspr(SPR_HID0, bsp_state[0]); isync();
+		mtspr(SPR_HID1, bsp_state[1]); isync();
+
+		reg = mpc745x_l2_enable(bsp_state[2]);
+		reg = mpc745x_l1d_enable();
+		reg = mpc745x_l1i_enable();
+
+		break;
+	default:
+		printf("WARNING: Unknown CPU type. Cache performace may be "
+		    "suboptimal.\n");
+		break;
+	}
 }
 
diff --git a/sys/powerpc/aim/platform_chrp.c b/sys/powerpc/aim/platform_chrp.c
index 03955ab49ea..2258c126e72 100644
--- a/sys/powerpc/aim/platform_chrp.c
+++ b/sys/powerpc/aim/platform_chrp.c
@@ -239,12 +239,14 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
 	rstvec = rstvec_virtbase + reset;
 
 	*rstvec = 4;
+	(void)(*rstvec);
 	powerpc_sync();
 	DELAY(1);
 	*rstvec = 0;
+	(void)(*rstvec);
 	powerpc_sync();
 
-	timeout = 1000;
+	timeout = 10000;
 	while (!pc->pc_awake && timeout--)
 		DELAY(100);
 
diff --git a/sys/powerpc/booke/mp_cpudep.c b/sys/powerpc/booke/mp_cpudep.c
index 59629814d61..55e33d8a3ba 100644
--- a/sys/powerpc/booke/mp_cpudep.c
+++ b/sys/powerpc/booke/mp_cpudep.c
@@ -47,7 +47,7 @@ extern void icache_inval(void);
 
 volatile void *ap_pcpu;
 
-uint32_t
+uintptr_t
 cpudep_ap_bootstrap()
 {
 	uint32_t msr, sp, csr;
@@ -78,3 +78,8 @@ cpudep_ap_bootstrap()
 
 	return (sp);
 }
+
+void
+cpudep_ap_setup()
+{
+}
diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h
index 51422daac70..1513922c634 100644
--- a/sys/powerpc/include/pcpu.h
+++ b/sys/powerpc/include/pcpu.h
@@ -43,8 +43,8 @@ struct pmap;
 	struct thread	*pc_vecthread;		/* current vec user */  \
 	uintptr_t	pc_hwref;					\
 	uint32_t	pc_pir;						\
-	int		pc_bsp:1;					\
-	int		pc_awake:1;					\
+	int		pc_bsp;						\
+	volatile int	pc_awake;					\
 	uint32_t	pc_ipimask;					\
 	register_t	pc_tempsave[CPUSAVE_LEN];			\
 	register_t	pc_disisave[CPUSAVE_LEN];			\
diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h
index 0e5ec16eb90..dfb3149217a 100644
--- a/sys/powerpc/include/smp.h
+++ b/sys/powerpc/include/smp.h
@@ -48,7 +48,8 @@ struct cpuref {
 };
 
 void	pmap_cpu_bootstrap(int);
-uint32_t cpudep_ap_bootstrap(void);
+uintptr_t cpudep_ap_bootstrap(void);
+void	cpudep_ap_setup(void);
 void	machdep_ap_bootstrap(void);
 
 #endif /* !LOCORE */
diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h
index 4e55326c4a3..586a57be9db 100644
--- a/sys/powerpc/include/spr.h
+++ b/sys/powerpc/include/spr.h
@@ -50,7 +50,7 @@
 #define mtspr64(reg,valhi,vallo,scratch)				\
 	__asm __volatile("						\
 		mfmsr %0; 						\
-		insrdi %0,1,1,0; 					\
+		insrdi %0,%5,1,0; 					\
 		mtmsrd %0; 						\
 		isync; 							\
 									\
@@ -62,13 +62,13 @@
 		clrldi %0,%0,1; 					\
 		mtmsrd %0; 						\
 		isync;"							\
-	: "=r"(scratch), "=r"(valhi) : "r"(vallo), "K"(reg), "r"(32))
+	: "=r"(scratch), "=r"(valhi) : "r"(vallo), "K"(reg), "r"(32), "r"(1))
 
 #define mfspr64upper(reg,scratch)					\
 	( { register_t val;						\
 	    __asm __volatile("						\
 		mfmsr %0; 						\
-		insrdi %0,1,1,0; 					\
+		insrdi %0,%4,1,0; 					\
 		mtmsrd %0; 						\
 		isync; 							\
 									\
@@ -78,7 +78,7 @@
 		clrldi %0,%0,1; 					\
 		mtmsrd %0; 						\
 		isync;" 						\
-	    : "=r"(scratch), "=r"(val) : "K"(reg), "r"(32)); 			\
+	    : "=r"(scratch), "=r"(val) : "K"(reg), "r"(32), "r"(1));	\
 	    val; } )
 
 #endif /* _LOCORE */
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index 77ebe95afd0..9f245e294ae 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -69,6 +69,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 int powerpc_pow_enabled;
@@ -112,9 +113,6 @@ static const struct cputab models[] = {
 static char model[64];
 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
 
-register_t	l2cr_config = 0;
-register_t	l3cr_config = 0;
-
 static void	cpu_print_speed(void);
 static void	cpu_print_cacheinfo(u_int, uint16_t);
 
@@ -258,11 +256,6 @@ cpu_setup(u_int cpuid)
 		case MPC7450:
 		case MPC7455:
 		case MPC7457:
-			/* Only MPC745x CPUs have an L3 cache. */
-
-			l3cr_config = mfspr(SPR_L3CR);
-
-			/* Fallthrough */
 		case MPC750:
 		case IBM750FX:
 		case MPC7400:
@@ -272,8 +265,6 @@ cpu_setup(u_int cpuid)
 			cpu_print_speed();
 			printf("\n");
 
-			l2cr_config = mfspr(SPR_L2CR);
-
 			if (bootverbose)
 				cpu_print_cacheinfo(cpuid, vers);
 			break;
@@ -366,15 +357,15 @@ cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
 	printf("L1 D-cache %sabled\n", (hid & HID0_DCE) ? "en" : "dis");
 
 	printf("cpu%u: ", cpuid);
-  	if (l2cr_config & L2CR_L2E) {
+  	if (mfspr(SPR_L2CR) & L2CR_L2E) {
 		switch (vers) {
 		case MPC7450:
 		case MPC7455:
 		case MPC7457:
 			printf("256KB L2 cache, ");
-			if (l3cr_config & L3CR_L3E)
+			if (mfspr(SPR_L3CR) & L3CR_L3E)
 				printf("%cMB L3 backside cache",
-				    l3cr_config & L3CR_L3SIZ ? '2' : '1');
+				    mfspr(SPR_L3CR) & L3CR_L3SIZ ? '2' : '1');
 			else
 				printf("L3 cache disabled");
 			printf("\n");
@@ -383,7 +374,7 @@ cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
 			printf("512KB L2 cache\n");
 			break; 
 		default:
-			switch (l2cr_config & L2CR_L2SIZ) {
+			switch (mfspr(SPR_L2CR) & L2CR_L2SIZ) {
 			case L2SIZ_256K:
 				printf("256KB ");
 				break;
@@ -394,9 +385,9 @@ cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
 				printf("1MB ");
 				break;
 			}
-			printf("write-%s", (l2cr_config & L2CR_L2WT)
+			printf("write-%s", (mfspr(SPR_L2CR) & L2CR_L2WT)
 			    ? "through" : "back");
-			if (l2cr_config & L2CR_L2PE)
+			if (mfspr(SPR_L2CR) & L2CR_L2PE)
 				printf(", with parity");
 			printf(" backside cache\n");
 			break;
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index 1ae7d6d6f7f..f3e16e898b8 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -64,7 +64,10 @@ static u_int ipi_msg_cnt[32];
 void
 machdep_ap_bootstrap(void)
 {
+	/* Set up important bits on the CPU (HID registers, etc.) */
+	cpudep_ap_setup();
 
+	/* Set PIR */
 	PCPU_SET(pir, mfspr(SPR_PIR));
 	PCPU_SET(awake, 1);
 	__asm __volatile("msync; isync");
@@ -78,7 +81,7 @@ machdep_ap_bootstrap(void)
 	__asm __volatile("mtdec %0" :: "r"(ap_decr));
 
 	atomic_add_int(&ap_awake, 1);
-	CTR1(KTR_SMP, "SMP: AP CPU%d launched", PCPU_GET(cpuid));
+	printf("SMP: AP CPU #%d launched\n", PCPU_GET(cpuid));
 
 	/* Initialize curthread */
 	PCPU_SET(curthread, PCPU_GET(idlethread));
@@ -86,6 +89,8 @@ machdep_ap_bootstrap(void)
 
 	/* Let the DEC and external interrupts go */
 	mtmsr(mfmsr() | PSL_EE);
+
+	/* Announce ourselves awake, and enter the scheduler */
 	sched_throw(NULL);
 }
 
@@ -247,6 +252,9 @@ cpu_mp_unleash(void *dummy)
 		    mp_ncpus, cpus, smp_cpus);
 	}
 
+	/* Let the APs get into the scheduler */
+	DELAY(10000);
+
 	smp_active = 1;
 	smp_started = 1;
 }

From ee649442196bee48525cd99809127ffbefcf7645 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 07:54:15 +0000
Subject: [PATCH 294/646] Remove some obsoleted comments.

---
 sys/cam/scsi/scsi_da.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index e3ad7e1abfa..12af78add23 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -813,19 +813,6 @@ dastrategy(struct bio *bp)
 
 	cam_periph_lock(periph);
 
-#if 0
-	/*
-	 * check it's not too big a transfer for our adapter
-	 */
-	scsi_minphys(bp,&sd_switch);
-#endif
-
-	/*
-	 * Mask interrupts so that the pack cannot be invalidated until
-	 * after we are in the queue.  Otherwise, we might not properly
-	 * clean up one of the buffers.
-	 */
-	
 	/*
 	 * If the device has been made invalid, error out
 	 */

From bbfa4aa1a69b818945d05dac04a8dc535e5db324 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 08:27:55 +0000
Subject: [PATCH 295/646] Replace most of priority numbers with defines. No
 logical changes.

---
 sys/cam/ata/ata_da.c        | 18 +++++++-------
 sys/cam/ata/ata_xpt.c       | 24 +++++++++----------
 sys/cam/cam.h               |  2 ++
 sys/cam/cam_periph.c        | 25 ++++++++++---------
 sys/cam/cam_xpt.c           | 20 ++++++++--------
 sys/cam/scsi/scsi_all.c     |  4 ++--
 sys/cam/scsi/scsi_cd.c      | 48 ++++++++++++++++++-------------------
 sys/cam/scsi/scsi_ch.c      | 14 +++++------
 sys/cam/scsi/scsi_da.c      | 22 ++++++++---------
 sys/cam/scsi/scsi_pt.c      |  4 ++--
 sys/cam/scsi/scsi_sa.c      |  4 ++--
 sys/cam/scsi/scsi_targ_bh.c | 16 ++++++-------
 sys/cam/scsi/scsi_target.c  | 10 ++++----
 sys/cam/scsi/scsi_xpt.c     | 22 ++++++++---------
 14 files changed, 117 insertions(+), 116 deletions(-)

diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 01c7c13376f..259d49d4252 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -270,7 +270,7 @@ adaclose(struct disk *dp)
 	/* We only sync the cache if the drive is capable of it. */
 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
 
-		ccb = cam_periph_getccb(periph, /*priority*/1);
+		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 		cam_fill_ataio(&ccb->ataio,
 				    1,
 				    adadone,
@@ -343,7 +343,7 @@ adastrategy(struct bio *bp)
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, /* XXX priority */1);
+	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 	cam_periph_unlock(periph);
 
 	return;
@@ -377,7 +377,7 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len
 
 	if (length > 0) {
 		periph->flags |= CAM_PERIPH_POLLED;
-		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
 		cam_fill_ataio(&ccb.ataio,
 		    0,
@@ -408,7 +408,7 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len
 	}
 
 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
-		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 
 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
 		cam_fill_ataio(&ccb.ataio,
@@ -563,7 +563,7 @@ adaasync(void *callback_arg, u_int32_t code,
 		 */
 		softc->state = ADA_STATE_SET_MULTI;
 		cam_periph_acquire(periph);
-		xpt_schedule(periph, 0);
+		xpt_schedule(periph, CAM_PRIORITY_DEV);
 		break;
 	}
 	default:
@@ -665,7 +665,7 @@ adaregister(struct cam_periph *periph, void *arg)
 
 	/* Check if the SIM does not want queued commands */
 	bzero(&cpi, sizeof(cpi));
-	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	if (cpi.ccb_h.status != CAM_REQ_CMP ||
@@ -897,7 +897,7 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 		
 		if (bp != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, /* XXX priority */1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 		break;
 	}
@@ -1027,7 +1027,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 		xpt_release_ccb(done_ccb);
 		if (bioq_first(&softc->bio_queue) != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, 1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 		cam_periph_release_locked(periph);
 		return;
@@ -1139,7 +1139,7 @@ adashutdown(void * arg, int howto)
 			continue;
 		}
 
-		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 
 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
 		cam_fill_ataio(&ccb.ataio,
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index dc25299433e..57882d21d1b 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -270,7 +270,7 @@ probeschedule(struct cam_periph *periph)
 	softc = (probe_softc *)periph->softc;
 	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 
-	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -506,7 +506,7 @@ proberequestdefaultnegotiation(struct cam_periph *periph)
 {
 	struct ccb_trans_settings cts;
 
-	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_USER_SETTINGS;
 	xpt_action((union ccb *)&cts);
@@ -528,7 +528,7 @@ proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
 	struct ccb_trans_settings_spi *spi;
 
 	memset(&cts, 0, sizeof (cts));
-	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_CURRENT_SETTINGS;
 	xpt_action((union ccb *)&cts);
@@ -655,7 +655,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 
 				/* Report SIM that PM is present. */
 				bzero(&cts, sizeof(cts));
-				xpt_setup_ccb(&cts.ccb_h, path, 1);
+				xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 				cts.type = CTS_TYPE_CURRENT_SETTINGS;
 				cts.xport_specific.sata.pm_present = 1;
@@ -1270,7 +1270,7 @@ ata_scan_lun(struct cam_periph *periph, struct cam_path *path,
 	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 		  ("xpt_scan_lun\n"));
 
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -1308,7 +1308,7 @@ ata_scan_lun(struct cam_periph *periph, struct cam_path *path,
 			free(new_path, M_CAMXPT);
 			return;
 		}
-		xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
+		xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_NORMAL);
 		request_ccb->ccb_h.cbfcnp = xptscandone;
 		request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 		request_ccb->crcn.flags = flags;
@@ -1407,7 +1407,7 @@ ata_device_transport(struct cam_path *path)
 	struct ata_params *ident_buf = NULL;
 
 	/* Get transport information from the SIM */
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -1427,7 +1427,7 @@ ata_device_transport(struct cam_path *path)
 	    ata_version(ident_buf->version_major) : cpi.transport_version;
 
 	/* Tell the controller what we think */
-	xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_CURRENT_SETTINGS;
 	cts.transport = path->device->transport;
@@ -1555,7 +1555,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 
 	inq_data = &device->inq_data;
 	scsi = &cts->proto_specific.scsi;
-	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -1576,7 +1576,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 		 * Perform sanity checking against what the
 		 * controller and device can do.
 		 */
-		xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, /*priority*/1);
+		xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
 		cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 		cur_cts.type = cts->type;
 		xpt_action((union ccb *)&cur_cts);
@@ -1636,7 +1636,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 				device->tag_delay_count = 0;
 
 				xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
-					      /*priority*/1);
+				    CAM_PRIORITY_NORMAL);
 				crs.ccb_h.func_code = XPT_REL_SIMQ;
 				crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 				crs.openings
@@ -1669,7 +1669,7 @@ scsi_toggle_tags(struct cam_path *path)
  	  && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
 		struct ccb_trans_settings cts;
 
-		xpt_setup_ccb(&cts.ccb_h, path, 1);
+		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 		cts.protocol = PROTO_SCSI;
 		cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
 		cts.transport = XPORT_UNSPECIFIED;
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index 36ad88a77cf..46a5e07eeeb 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -66,6 +66,8 @@ struct cam_periph;
  */
 typedef struct {
 	u_int32_t priority;
+#define CAM_PRIORITY_DEV	0
+#define CAM_PRIORITY_NORMAL	1
 #define CAM_PRIORITY_NONE	(u_int32_t)-1
 	u_int32_t generation;
 	int       index;
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 9137c55d106..1a67a0c4a2e 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -534,13 +534,13 @@ camperiphfree(struct cam_periph *periph)
 		switch (periph->deferred_ac) {
 		case AC_FOUND_DEVICE:
 			ccb.ccb_h.func_code = XPT_GDEV_TYPE;
-			xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
+			xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 			xpt_action(&ccb);
 			arg = &ccb;
 			break;
 		case AC_PATH_REGISTERED:
 			ccb.ccb_h.func_code = XPT_PATH_INQ;
-			xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
+			xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 			xpt_action(&ccb);
 			arg = &ccb;
 			break;
@@ -831,10 +831,10 @@ cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr,
 
 	switch(cmd){
 	case CAMGETPASSTHRU:
-		ccb = cam_periph_getccb(periph, /* priority */ 1);
+		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 		xpt_setup_ccb(&ccb->ccb_h,
 			      ccb->ccb_h.path,
-			      /*priority*/1);
+			      CAM_PRIORITY_NORMAL);
 		ccb->ccb_h.func_code = XPT_GDEVLIST;
 
 		/*
@@ -939,7 +939,7 @@ cam_freeze_devq(struct cam_path *path)
 {
 	struct ccb_hdr ccb_h;
 
-	xpt_setup_ccb(&ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&ccb_h, path, CAM_PRIORITY_NORMAL);
 	ccb_h.func_code = XPT_NOOP;
 	ccb_h.flags = CAM_DEV_QFREEZE;
 	xpt_action((union ccb *)&ccb_h);
@@ -952,8 +952,7 @@ cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
 {
 	struct ccb_relsim crs;
 
-	xpt_setup_ccb(&crs.ccb_h, path,
-		      /*priority*/1);
+	xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
 	crs.ccb_h.func_code = XPT_REL_SIMQ;
 	crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0;
 	crs.release_flags = relsim_flags;
@@ -1070,7 +1069,7 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
 			 * Grab the inquiry data for this device.
 			 */
 			xpt_setup_ccb(&cgd.ccb_h, done_ccb->ccb_h.path,
-				      /*priority*/ 1);
+			    CAM_PRIORITY_NORMAL);
 			cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action((union ccb *)&cgd);
 			err_action = scsi_error_action(&done_ccb->csio,
@@ -1212,7 +1211,7 @@ cam_periph_bus_settle(struct cam_periph *periph, u_int bus_settle)
 {
 	struct ccb_getdevstats cgds;
 
-	xpt_setup_ccb(&cgds.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cgds.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cgds.ccb_h.func_code = XPT_GDEV_STATS;
 	xpt_action((union ccb *)&cgds);
 	cam_periph_freeze_after_event(periph, &cgds.last_reset, bus_settle);
@@ -1280,7 +1279,7 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags,
 		 */
 		xpt_setup_ccb(&cgds.ccb_h,
 			      ccb->ccb_h.path,
-			      /*priority*/1);
+			      CAM_PRIORITY_NORMAL);
 		cgds.ccb_h.func_code = XPT_GDEV_STATS;
 		xpt_action((union ccb *)&cgds);
 
@@ -1403,7 +1402,7 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags,
 		/*
 		 * Grab the inquiry data for this device.
 		 */
-		xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path, /*priority*/ 1);
+		xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path, CAM_PRIORITY_NORMAL);
 		cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 		xpt_action((union ccb *)&cgd);
 
@@ -1543,14 +1542,14 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags,
 		
 		if ((err_action & SS_MASK) >= SS_START) {
 			/*
-			 * Drop the priority to 0 so that the recovery
+			 * Drop the priority, so that the recovery
 			 * CCB is the first to execute.  Freeze the queue
 			 * after this command is sent so that we can
 			 * restore the old csio and have it queued in
 			 * the proper order before we release normal 
 			 * transactions to the device.
 			 */
-			ccb->ccb_h.pinfo.priority = 0;
+			ccb->ccb_h.pinfo.priority = CAM_PRIORITY_DEV;
 			ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 			ccb->ccb_h.saved_ccb_ptr = save_ccb;
 			error = ERESTART;
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 5ca0584b5e0..e416ad79758 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -812,7 +812,7 @@ xpt_scanner_thread(void *dummy)
 			else
 				ccb->ccb_h.func_code = XPT_SCAN_LUN;
 			ccb->ccb_h.cbfcnp = xptdone;
-			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 1);
+			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_BUS);
 			cam_periph_runccb(ccb, NULL, 0, 0, NULL);
 			xpt_free_path(ccb->ccb_h.path);
 			xpt_free_ccb(ccb);
@@ -1059,7 +1059,7 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 		printf("%s%d: Serial Number %.60s\n", periph->periph_name,
 		       periph->unit_number, path->device->serial_num);
 	}
-	xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_CURRENT_SETTINGS;
 	xpt_action((union ccb*)&cts);
@@ -1068,7 +1068,7 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 	}
 
 	/* Ask the SIM for its base transfer speed */
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -2335,7 +2335,7 @@ xptsetasyncfunc(struct cam_ed *device, void *arg)
 			 device->target->bus->path_id,
 			 device->target->target_id,
 			 device->lun_id);
-	xpt_setup_ccb(&cgd.ccb_h, &path, /*priority*/1);
+	xpt_setup_ccb(&cgd.ccb_h, &path, CAM_PRIORITY_NORMAL);
 	cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 	xpt_action((union ccb *)&cgd);
 	cur_entry->callback(cur_entry->callback_arg,
@@ -2359,7 +2359,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, void *arg)
 			 bus->sim->path_id,
 			 CAM_TARGET_WILDCARD,
 			 CAM_LUN_WILDCARD);
-	xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	cur_entry->callback(cur_entry->callback_arg,
@@ -3799,7 +3799,7 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
 	if (status != CAM_REQ_CMP)
 		printf("xpt_compile_path returned %d\n", status);
 
-	xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -4544,7 +4544,7 @@ xpt_start_tags(struct cam_path *path)
 		newopenings = min(device->maxtags,
 				  sim->max_tagged_dev_openings);
 	xpt_dev_ccbq_resize(path, newopenings);
-	xpt_setup_ccb(&crs.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
 	crs.ccb_h.func_code = XPT_REL_SIMQ;
 	crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 	crs.openings
@@ -4571,7 +4571,7 @@ xptconfigbuscountfunc(struct cam_eb *bus, void *arg)
 		busses_to_config++;
 		xpt_compile_path(&path, NULL, bus->path_id,
 				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
-		xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
+		xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 		cpi.ccb_h.func_code = XPT_PATH_INQ;
 		xpt_action((union ccb *)&cpi);
 		can_negotiate = cpi.hba_inquiry;
@@ -4614,7 +4614,7 @@ xptconfigfunc(struct cam_eb *bus, void *arg)
 			xpt_finishconfig(xpt_periph, NULL);
 			return(0);
 		}
-		xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1);
+		xpt_setup_ccb(&work_ccb->ccb_h, path, CAM_PRIORITY_NORMAL);
 		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 		xpt_action(work_ccb);
 		if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
@@ -4629,7 +4629,7 @@ xptconfigfunc(struct cam_eb *bus, void *arg)
 		can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE);
 		if ((work_ccb->cpi.hba_misc & PIM_NOBUSRESET) == 0
 		 && (can_negotiate != 0)) {
-			xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1);
+			xpt_setup_ccb(&work_ccb->ccb_h, path, CAM_PRIORITY_NORMAL);
 			work_ccb->ccb_h.func_code = XPT_RESET_BUS;
 			work_ccb->ccb_h.cbfcnp = NULL;
 			CAM_DEBUG(path, CAM_DEBUG_SUBTRACE,
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index d4db50bee4c..e6f3a7c1005 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -3004,7 +3004,7 @@ scsi_command_string(struct cam_device *device, struct ccb_scsiio *csio,
 	 */
 	xpt_setup_ccb(&cgd.ccb_h,
 		      csio->ccb_h.path,
-		      /*priority*/ 1);
+		      CAM_PRIORITY_NORMAL);
 	cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 	xpt_action((union ccb *)&cgd);
 
@@ -3088,7 +3088,7 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio,
 	 */
 	xpt_setup_ccb(&cgd.ccb_h,
 		      csio->ccb_h.path,
-		      /*priority*/ 1);
+		      CAM_PRIORITY_NORMAL);
 	cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 	xpt_action((union ccb *)&cgd);
 
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 52f73113d64..f2a612b7734 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -673,7 +673,7 @@ cdregister(struct cam_periph *periph, void *arg)
 		softc->quirks = CD_Q_NONE;
 
 	/* Check if the SIM does not want 6 byte commands */
-	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
@@ -1105,7 +1105,7 @@ cdschedule(struct cam_periph *periph, int priority)
 		 * We don't do anything with the priority here.
 		 * This is strictly a fifo queue.
 		 */
-		softc->pinfo.priority = 1;
+		softc->pinfo.priority = CAM_PRIORITY_NORMAL;
 		softc->pinfo.generation = ++softc->changer->devq.generation;
 		camq_insert(&softc->changer->devq, (cam_pinfo *)softc);
 
@@ -1206,7 +1206,7 @@ cdrunchangerqueue(void *arg)
 
 	/* Just in case this device is waiting */
 	wakeup(&softc->changer);
-	xpt_schedule(softc->periph, /*priority*/ 1);
+	xpt_schedule(softc->periph, CAM_PRIORITY_NORMAL);
 
 	/*
 	 * Get rid of any pending timeouts, and set a flag to schedule new
@@ -1344,7 +1344,7 @@ cdgetccb(struct cam_periph *periph, u_int32_t priority)
 			 * If this changer isn't already queued, queue it up.
 			 */
 			if (softc->pinfo.index == CAM_UNQUEUED_INDEX) {
-				softc->pinfo.priority = 1;
+				softc->pinfo.priority = CAM_PRIORITY_NORMAL;
 				softc->pinfo.generation =
 					++softc->changer->devq.generation;
 				camq_insert(&softc->changer->devq,
@@ -1421,9 +1421,9 @@ cdstrategy(struct bio *bp)
 	 * differently for changers.
 	 */
 	if ((softc->flags & CD_FLAG_CHANGER) == 0)
-		xpt_schedule(periph, /* XXX priority */1);
+		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 	else
-		cdschedule(periph, /* priority */ 1);
+		cdschedule(periph, CAM_PRIORITY_NORMAL);
 
 	cam_periph_unlock(periph);
 	return;
@@ -1493,7 +1493,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb)
 		}
 		if (bp != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, /* XXX priority */1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 		break;
 	}
@@ -1668,7 +1668,7 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
 
 				xpt_setup_ccb(&cgd.ccb_h, 
 					      done_ccb->ccb_h.path,
-					      /* priority */ 1);
+					      CAM_PRIORITY_NORMAL);
 				cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 				xpt_action((union ccb *)&cgd);
 
@@ -2727,7 +2727,7 @@ cdprevent(struct cam_periph *periph, int action)
 		return;
 	}
 	    
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_prevent(&ccb->csio, 
 		     /*retries*/ 1,
@@ -2901,7 +2901,7 @@ cdsize(struct cam_periph *periph, u_int32_t *size)
 
 	softc = (struct cd_softc *)periph->softc;
              
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	/* XXX Should be M_WAITOK */
 	rcap_buf = malloc(sizeof(struct scsi_read_capacity_data), 
@@ -3153,7 +3153,7 @@ cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start,
 	ntoc = len;
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3200,7 +3200,7 @@ cdreadsubchannel(struct cam_periph *periph, u_int32_t mode,
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3252,7 +3252,7 @@ cdgetmode(struct cam_periph *periph, struct cd_mode_params *data,
 
 	softc = (struct cd_softc *)periph->softc;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3351,7 +3351,7 @@ cdsetmode(struct cam_periph *periph, struct cd_mode_params *data)
 
 	softc = (struct cd_softc *)periph->softc;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3443,7 +3443,7 @@ cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len)
 	u_int8_t cdb_len;
 
 	error = 0;
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 	csio = &ccb->csio;
 	/*
 	 * Use the smallest possible command to perform the operation.
@@ -3500,7 +3500,7 @@ cdplaymsf(struct cam_periph *periph, u_int32_t startm, u_int32_t starts,
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3546,7 +3546,7 @@ cdplaytracks(struct cam_periph *periph, u_int32_t strack, u_int32_t sindex,
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3588,7 +3588,7 @@ cdpause(struct cam_periph *periph, u_int32_t go)
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	csio = &ccb->csio;
 
@@ -3625,7 +3625,7 @@ cdstartunit(struct cam_periph *periph, int load)
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_start_stop(&ccb->csio,
 			/* retries */ 1,
@@ -3653,7 +3653,7 @@ cdstopunit(struct cam_periph *periph, u_int32_t eject)
 
 	error = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_start_stop(&ccb->csio,
 			/* retries */ 1,
@@ -3682,7 +3682,7 @@ cdsetspeed(struct cam_periph *periph, u_int32_t rdspeed, u_int32_t wrspeed)
 	int error;
 
 	error = 0;
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 	csio = &ccb->csio;
 
 	/* Preserve old behavior: units in multiples of CDROM speed */
@@ -3730,7 +3730,7 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
 	databuf = NULL;
 	lba = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	switch (authinfo->format) {
 	case DVD_REPORT_AGID:
@@ -3887,7 +3887,7 @@ cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
 	error = 0;
 	databuf = NULL;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	switch(authinfo->format) {
 	case DVD_SEND_CHALLENGE: {
@@ -3983,7 +3983,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
 	/* The address is reserved for many of the formats */
 	address = 0;
 
-	ccb = cdgetccb(periph, /* priority */ 1);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	switch(dvdstruct->format) {
 	case DVD_STRUCT_PHYSICAL:
diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c
index f8f39aba57c..781245a8df8 100644
--- a/sys/cam/scsi/scsi_ch.c
+++ b/sys/cam/scsi/scsi_ch.c
@@ -809,7 +809,7 @@ chmove(struct cam_periph *periph, struct changer_move *cm)
 	fromelem = softc->sc_firsts[cm->cm_fromtype] + cm->cm_fromunit;
 	toelem = softc->sc_firsts[cm->cm_totype] + cm->cm_tounit;
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_move_medium(&ccb->csio,
 			 /* retries */ 1,
@@ -868,7 +868,7 @@ chexchange(struct cam_periph *periph, struct changer_exchange *ce)
 	dst1 = softc->sc_firsts[ce->ce_fdsttype] + ce->ce_fdstunit;
 	dst2 = softc->sc_firsts[ce->ce_sdsttype] + ce->ce_sdstunit;
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_exchange_medium(&ccb->csio,
 			     /* retries */ 1,
@@ -918,7 +918,7 @@ chposition(struct cam_periph *periph, struct changer_position *cp)
 	 */
 	dst = softc->sc_firsts[cp->cp_type] + cp->cp_unit;
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_position_to_element(&ccb->csio,
 				 /* retries */ 1,
@@ -1075,7 +1075,7 @@ chgetelemstatus(struct cam_periph *periph,
 	data = (caddr_t)malloc(1024, M_DEVBUF, M_WAITOK);
 
 	cam_periph_lock(periph);
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_read_element_status(&ccb->csio,
 				 /* retries */ 1,
@@ -1201,7 +1201,7 @@ chielem(struct cam_periph *periph,
 	error = 0;
 	softc = (struct ch_softc *)periph->softc;
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_initialize_element_status(&ccb->csio,
 				      /* retries */ 1,
@@ -1285,7 +1285,7 @@ chsetvoltag(struct cam_periph *periph,
 	       min(strlen(csvr->csvr_voltag.cv_volid), sizeof(ssvtp.vitf)));
 	scsi_ulto2b(csvr->csvr_voltag.cv_serial, ssvtp.minvsn);
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_send_volume_tag(&ccb->csio,
 			     /* retries */ 1,
@@ -1323,7 +1323,7 @@ chgetparams(struct cam_periph *periph)
 
 	softc = (struct ch_softc *)periph->softc;
 
-	ccb = cam_periph_getccb(periph, /*priority*/ 1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	/*
 	 * The scsi_mode_sense_data structure is just a convenience
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 12af78add23..bb9299a4515 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -729,7 +729,7 @@ daclose(struct disk *dp)
 	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
 		union	ccb *ccb;
 
-		ccb = cam_periph_getccb(periph, /*priority*/1);
+		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 		scsi_synchronize_cache(&ccb->csio,
 				       /*retries*/1,
@@ -830,7 +830,7 @@ dastrategy(struct bio *bp)
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, /* XXX priority */1);
+	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 	cam_periph_unlock(periph);
 
 	return;
@@ -860,7 +860,7 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng
 
 	if (length > 0) {
 		periph->flags |= CAM_PERIPH_POLLED;
-		xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		csio.ccb_h.ccb_state = DA_CCB_DUMP;
 		scsi_read_write(&csio,
 				/*retries*/1,
@@ -897,7 +897,7 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng
 	 */
 	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
 
-		xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		csio.ccb_h.ccb_state = DA_CCB_DUMP;
 		scsi_synchronize_cache(&csio,
 				       /*retries*/1,
@@ -1194,7 +1194,7 @@ daregister(struct cam_periph *periph, void *arg)
 
 	/* Check if the SIM does not want 6 byte commands */
 	bzero(&cpi, sizeof(cpi));
-	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
@@ -1381,7 +1381,7 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
 		
 		if (bp != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, /* XXX priority */1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 		break;
 	}
@@ -1678,7 +1678,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
 
 				xpt_setup_ccb(&cgd.ccb_h, 
 					      done_ccb->ccb_h.path,
-					      /* priority */ 1);
+					      CAM_PRIORITY_NORMAL);
 				cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 				xpt_action((union ccb *)&cgd);
 
@@ -1832,7 +1832,7 @@ daprevent(struct cam_periph *periph, int action)
 		return;
 	}
 
-	ccb = cam_periph_getccb(periph, /*priority*/1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_prevent(&ccb->csio,
 		     /*retries*/1,
@@ -1882,7 +1882,7 @@ dagetcapacity(struct cam_periph *periph)
 	if (rcap == NULL)
 		return (ENOMEM);
 		
-	ccb = cam_periph_getccb(periph, /*priority*/1);
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 	scsi_read_capacity(&ccb->csio,
 			   /*retries*/4,
 			   /*cbfncp*/dadone,
@@ -1976,7 +1976,7 @@ dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector)
 	 * up with something that will make this a bootable
 	 * device.
 	 */
-	xpt_setup_ccb(&ccg.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&ccg.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
 	ccg.block_size = dp->secsize;
 	ccg.volume_size = dp->sectors;
@@ -2050,7 +2050,7 @@ dashutdown(void * arg, int howto)
 			continue;
 		}
 
-		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 
 		ccb.ccb_h.ccb_state = DA_CCB_DUMP;
 		scsi_synchronize_cache(&ccb.csio,
diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c
index 183293fc7c7..34217509ac6 100644
--- a/sys/cam/scsi/scsi_pt.c
+++ b/sys/cam/scsi/scsi_pt.c
@@ -224,7 +224,7 @@ ptstrategy(struct bio *bp)
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, /* XXX priority */1);
+	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 	cam_periph_unlock(periph);
 
 	return;
@@ -464,7 +464,7 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb)
 		
 		if (bp != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, /* XXX priority */1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 	}
 }
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c
index 254f2ba692f..13871b97d47 100644
--- a/sys/cam/scsi/scsi_sa.c
+++ b/sys/cam/scsi/scsi_sa.c
@@ -786,7 +786,7 @@ sastrategy(struct bio *bp)
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, 1);
+	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 	cam_periph_unlock(periph);
 
 	return;
@@ -1689,7 +1689,7 @@ again:
 		
 		if (bp != NULL) {
 			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, 1);
+			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 		}
 		break;
 	}
diff --git a/sys/cam/scsi/scsi_targ_bh.c b/sys/cam/scsi/scsi_targ_bh.c
index e8ec51f41d5..47b6e2b5957 100644
--- a/sys/cam/scsi/scsi_targ_bh.c
+++ b/sys/cam/scsi/scsi_targ_bh.c
@@ -240,7 +240,7 @@ targbhenlun(struct cam_periph *periph)
 	if ((softc->flags & TARGBH_FLAG_LUN_ENABLED) != 0)
 		return (CAM_REQ_CMP);
 
-	xpt_setup_ccb(&immed_ccb.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&immed_ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	immed_ccb.ccb_h.func_code = XPT_EN_LUN;
 
 	/* Don't need support for any vendor specific commands */
@@ -280,7 +280,7 @@ targbhenlun(struct cam_periph *periph)
 			break;
 		}
 
-		xpt_setup_ccb(&atio->ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&atio->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
 		atio->ccb_h.cbfcnp = targbhdone;
 		xpt_action((union ccb *)atio);
@@ -318,7 +318,7 @@ targbhenlun(struct cam_periph *periph)
 			break;
 		}
 
-		xpt_setup_ccb(&inot->ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&inot->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		inot->ccb_h.func_code = XPT_IMMED_NOTIFY;
 		inot->ccb_h.cbfcnp = targbhdone;
 		xpt_action((union ccb *)inot);
@@ -361,7 +361,7 @@ targbhdislun(struct cam_periph *periph)
 		
 		softc->accept_tio_list =
 		    ((struct targbh_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link;
-		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		ccb.cab.ccb_h.func_code = XPT_ABORT;
 		ccb.cab.abort_ccb = (union ccb *)atio;
 		xpt_action(&ccb);
@@ -369,7 +369,7 @@ targbhdislun(struct cam_periph *periph)
 
 	while ((ccb_h = SLIST_FIRST(&softc->immed_notify_slist)) != NULL) {
 		SLIST_REMOVE_HEAD(&softc->immed_notify_slist, periph_links.sle);
-		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1);
+		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 		ccb.cab.ccb_h.func_code = XPT_ABORT;
 		ccb.cab.abort_ccb = (union ccb *)ccb_h;
 		xpt_action(&ccb);
@@ -378,7 +378,7 @@ targbhdislun(struct cam_periph *periph)
 	/*
 	 * Dissable this lun.
 	 */
-	xpt_setup_ccb(&ccb.cel.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&ccb.cel.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	ccb.cel.ccb_h.func_code = XPT_EN_LUN;
 	ccb.cel.enable = 0;
 	xpt_action(&ccb);
@@ -528,7 +528,7 @@ targbhstart(struct cam_periph *periph, union ccb *start_ccb)
 		ccbh = TAILQ_FIRST(&softc->work_queue);
 	}
 	if (ccbh != NULL)
-		xpt_schedule(periph, /*priority*/1);
+		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
 }
 
 static void
@@ -647,7 +647,7 @@ targbhdone(struct cam_periph *periph, union ccb *done_ccb)
 		} else {
 			TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h,
 					  periph_links.tqe);
-			priority = 1;
+			priority = CAM_PRIORITY_NORMAL;
 		}
 		xpt_schedule(periph, priority);
 		break;
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 939e3f70189..de2ef7f177a 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -319,7 +319,7 @@ targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t
 		else
 			cdbg.flags = CAM_DEBUG_NONE;
 		cam_periph_lock(softc->periph);
-		xpt_setup_ccb(&cdbg.ccb_h, softc->path, /*priority*/0);
+		xpt_setup_ccb(&cdbg.ccb_h, softc->path, CAM_PRIORITY_NORMAL);
 		cdbg.ccb_h.func_code = XPT_DEBUG;
 		cdbg.ccb_h.cbfcnp = targdone;
 
@@ -410,7 +410,7 @@ targendislun(struct cam_path *path, int enable, int grp6_len, int grp7_len)
 	cam_status	  status;
 
 	/* Tell the lun to begin answering selects */
-	xpt_setup_ccb(&en_ccb.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&en_ccb.ccb_h, path, CAM_PRIORITY_NORMAL);
 	en_ccb.ccb_h.func_code = XPT_EN_LUN;
 	/* Don't need support for any vendor specific commands */
 	en_ccb.grp6_len = grp6_len;
@@ -438,7 +438,7 @@ targenable(struct targ_softc *softc, struct cam_path *path, int grp6_len,
 		return (CAM_LUN_ALRDY_ENA);
 
 	/* Make sure SIM supports target mode */
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	status = cpi.ccb_h.status & CAM_STATUS_MASK;
@@ -586,7 +586,7 @@ targwrite(struct cdev *dev, struct uio *uio, int ioflag)
 			break;
 		}
 		priority = fuword32(&user_ccb->ccb_h.pinfo.priority);
-		if (priority == -1) {
+		if (priority == CAM_PRIORITY_NONE) {
 			error = EINVAL;
 			break;
 		}
@@ -1100,7 +1100,7 @@ abort_all_pending(struct targ_softc *softc)
 	 * Then abort all pending CCBs.
 	 * targdone() will return the aborted CCB via user_ccb_queue
 	 */
-	xpt_setup_ccb(&cab.ccb_h, softc->path, /*priority*/0);
+	xpt_setup_ccb(&cab.ccb_h, softc->path, CAM_PRIORITY_NORMAL);
 	cab.ccb_h.func_code = XPT_ABORT;
 	cab.ccb_h.status = CAM_REQ_CMP_ERR;
 	TAILQ_FOREACH(ccb_h, &softc->pending_ccb_queue, periph_links.tqe) {
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index 5249d5fcd6b..35a5ac2a706 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -629,7 +629,7 @@ probeschedule(struct cam_periph *periph)
 	softc = (probe_softc *)periph->softc;
 	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 
-	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -880,7 +880,7 @@ proberequestdefaultnegotiation(struct cam_periph *periph)
 {
 	struct ccb_trans_settings cts;
 
-	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_USER_SETTINGS;
 	xpt_action((union ccb *)&cts);
@@ -902,7 +902,7 @@ proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
 	struct ccb_trans_settings_spi *spi;
 
 	memset(&cts, 0, sizeof (cts));
-	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_CURRENT_SETTINGS;
 	xpt_action((union ccb *)&cts);
@@ -1748,7 +1748,7 @@ scsi_scan_lun(struct cam_periph *periph, struct cam_path *path,
 	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 		  ("scsi_scan_lun\n"));
 
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -1798,7 +1798,7 @@ scsi_scan_lun(struct cam_periph *periph, struct cam_path *path,
 			free(new_path, M_CAMXPT);
 			return;
 		}
-		xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
+		xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_NORMAL);
 		request_ccb->ccb_h.cbfcnp = xptscandone;
 		request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 		request_ccb->crcn.flags = flags;
@@ -1896,7 +1896,7 @@ scsi_devise_transport(struct cam_path *path)
 	struct scsi_inquiry_data *inq_buf;
 
 	/* Get transport information from the SIM */
-	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -1956,7 +1956,7 @@ scsi_devise_transport(struct cam_path *path)
 	 */
 
 	/* Tell the controller what we think */
-	xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
+	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 	cts.type = CTS_TYPE_CURRENT_SETTINGS;
 	cts.transport = path->device->transport;
@@ -2084,7 +2084,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 
 	inq_data = &device->inq_data;
 	scsi = &cts->proto_specific.scsi;
-	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, /*priority*/1);
+	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
@@ -2105,7 +2105,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 		 * Perform sanity checking against what the
 		 * controller and device can do.
 		 */
-		xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, /*priority*/1);
+		xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
 		cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 		cur_cts.type = cts->type;
 		xpt_action((union ccb *)&cur_cts);
@@ -2273,7 +2273,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
 				device->tag_delay_count = 0;
 
 				xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
-					      /*priority*/1);
+				    CAM_PRIORITY_NORMAL);
 				crs.ccb_h.func_code = XPT_REL_SIMQ;
 				crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 				crs.openings
@@ -2306,7 +2306,7 @@ scsi_toggle_tags(struct cam_path *path)
  	  && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
 		struct ccb_trans_settings cts;
 
-		xpt_setup_ccb(&cts.ccb_h, path, 1);
+		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 		cts.protocol = PROTO_SCSI;
 		cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
 		cts.transport = XPORT_UNSPECIFIED;

From da5f0a6facddbaf62c9c782066bbb2f19a67ba2c Mon Sep 17 00:00:00 2001
From: Hiroki Sato 
Date: Fri, 23 Oct 2009 09:30:19 +0000
Subject: [PATCH 296/646] Use double-quotation marks to fix the unexpanded
 variable issue.

Spotted by:	swell.k
---
 etc/rc.d/netoptions | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/etc/rc.d/netoptions b/etc/rc.d/netoptions
index f2012c5f3e8..46313045679 100755
--- a/etc/rc.d/netoptions
+++ b/etc/rc.d/netoptions
@@ -53,7 +53,7 @@ netoptions_inet()
 		${SYSCTL_W} net.inet.tcp.rfc1323=1 >/dev/null
 	else
 		netoptions_init
-		echo -n ' rfc1323 extensions=${tcp_extensions}'
+		echo -n " rfc1323 extensions=${tcp_extensions}"
 		${SYSCTL_W} net.inet.tcp.rfc1323=0 >/dev/null
 	fi
 
@@ -61,13 +61,13 @@ netoptions_inet()
 		${SYSCTL_W} net.inet.tcp.always_keepalive=1 >/dev/null
 	else
 		netoptions_init
-		echo -n ' TCP keepalive=${tcp_keepalive}'
+		echo -n " TCP keepalive=${tcp_keepalive}"
 		${SYSCTL_W} net.inet.tcp.always_keepalive=0 >/dev/null
 	fi
 
 	if checkyesno tcp_drop_synfin; then
 		netoptions_init
-		echo -n ' drop SYN+FIN packets=${tcp_drop_synfin}'
+		echo -n " drop SYN+FIN packets=${tcp_drop_synfin}"
 		${SYSCTL_W} net.inet.tcp.drop_synfin=1 >/dev/null
 	else
 		${SYSCTL_W} net.inet.tcp.drop_synfin=0 >/dev/null

From d392e74276770747a6c2a765988dec7876dd0971 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Fri, 23 Oct 2009 11:13:08 +0000
Subject: [PATCH 297/646] The draft spec doesn't say beacon frames need to have
 a wildcard BSSID, so remove the mesh code necessary for that.

MFC after:	2 days
---
 sys/net80211/ieee80211_output.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index d2da01f6e96..9b532c32e21 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -2764,13 +2764,7 @@ ieee80211_beacon_alloc(struct ieee80211_node *ni,
 	*(uint16_t *)wh->i_dur = 0;
 	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 	IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
-#ifdef IEEE80211_SUPPORT_MESH
-	if (vap->iv_opmode == IEEE80211_M_MBSS) {
-		static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
-		IEEE80211_ADDR_COPY(wh->i_addr3, zerobssid);
-	} else
-#endif
-		IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
+	IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
 	*(uint16_t *)wh->i_seq = 0;
 
 	return m;

From 48f2bfe224b88b5c1499cb5a9a927c7b3508d309 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 11:26:58 +0000
Subject: [PATCH 298/646] Fix the build.

---
 sys/cam/cam_xpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index e416ad79758..479a6058c44 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -812,7 +812,7 @@ xpt_scanner_thread(void *dummy)
 			else
 				ccb->ccb_h.func_code = XPT_SCAN_LUN;
 			ccb->ccb_h.cbfcnp = xptdone;
-			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_BUS);
+			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_NORMAL);
 			cam_periph_runccb(ccb, NULL, 0, 0, NULL);
 			xpt_free_path(ccb->ccb_h.path);
 			xpt_free_ccb(ccb);

From 65d0fb03ad2580c999c3f590fa7e77f3ed8e1def Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 12:36:42 +0000
Subject: [PATCH 299/646] MFp4: Move Port Multiplier support code out of ATA
 XPT into pmp periph driver. This is convinient, as PMP itself is a bus target
 and has own state.

---
 sys/cam/ata/ata_pmp.c    | 735 +++++++++++++++++++++++++++++++++++++++
 sys/cam/ata/ata_xpt.c    | 277 ++-------------
 sys/conf/files           |   1 +
 sys/modules/cam/Makefile |   1 +
 4 files changed, 760 insertions(+), 254 deletions(-)
 create mode 100644 sys/cam/ata/ata_pmp.c

diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c
new file mode 100644
index 00000000000..76b3c0ad8b6
--- /dev/null
+++ b/sys/cam/ata/ata_pmp.c
@@ -0,0 +1,735 @@
+/*-
+ * Copyright (c) 2009 Alexander Motin 
+ * 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,
+ *    without modification, immediately at the beginning of the file.
+ * 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.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+
+#ifdef _KERNEL
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#endif /* _KERNEL */
+
+#ifndef _KERNEL
+#include 
+#include 
+#endif /* _KERNEL */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#ifdef _KERNEL
+
+typedef enum {
+	PMP_STATE_NORMAL,
+	PMP_STATE_PORTS,
+	PMP_STATE_CONFIG,
+	PMP_STATE_RESET,
+	PMP_STATE_CONNECT,
+	PMP_STATE_CHECK,
+	PMP_STATE_CLEAR,
+	PMP_STATE_SCAN
+} pmp_state;
+
+typedef enum {
+	PMP_FLAG_SCTX_INIT	= 0x200
+} pmp_flags;
+
+typedef enum {
+	PMP_CCB_PROBE		= 0x01,
+} pmp_ccb_state;
+
+/* Offsets into our private area for storing information */
+#define ccb_state	ppriv_field0
+#define ccb_bp		ppriv_ptr1
+
+struct pmp_softc {
+	SLIST_ENTRY(pmp_softc)	links;
+	pmp_state		state;
+	pmp_flags		flags;
+	uint32_t		pm_pid;
+	uint32_t		pm_prv;
+	int			pm_ports;
+	int			pm_step;
+	int			pm_try;
+	int			found;
+	int			frozen;
+	union			ccb saved_ccb;
+	struct task		sysctl_task;
+	struct sysctl_ctx_list	sysctl_ctx;
+	struct sysctl_oid	*sysctl_tree;
+};
+
+static	periph_init_t	pmpinit;
+static	void		pmpasync(void *callback_arg, u_int32_t code,
+				struct cam_path *path, void *arg);
+static	void		pmpsysctlinit(void *context, int pending);
+static	periph_ctor_t	pmpregister;
+static	periph_dtor_t	pmpcleanup;
+static	periph_start_t	pmpstart;
+static	periph_oninv_t	pmponinvalidate;
+static	void		pmpdone(struct cam_periph *periph,
+			       union ccb *done_ccb);
+
+#ifndef PMP_DEFAULT_TIMEOUT
+#define PMP_DEFAULT_TIMEOUT 30	/* Timeout in seconds */
+#endif
+
+#ifndef	PMP_DEFAULT_RETRY
+#define	PMP_DEFAULT_RETRY	1
+#endif
+
+static int pmp_retry_count = PMP_DEFAULT_RETRY;
+static int pmp_default_timeout = PMP_DEFAULT_TIMEOUT;
+
+SYSCTL_NODE(_kern_cam, OID_AUTO, pmp, CTLFLAG_RD, 0,
+            "CAM Direct Access Disk driver");
+SYSCTL_INT(_kern_cam_pmp, OID_AUTO, retry_count, CTLFLAG_RW,
+           &pmp_retry_count, 0, "Normal I/O retry count");
+TUNABLE_INT("kern.cam.pmp.retry_count", &pmp_retry_count);
+SYSCTL_INT(_kern_cam_pmp, OID_AUTO, default_timeout, CTLFLAG_RW,
+           &pmp_default_timeout, 0, "Normal I/O timeout (in seconds)");
+TUNABLE_INT("kern.cam.pmp.default_timeout", &pmp_default_timeout);
+
+static struct periph_driver pmpdriver =
+{
+	pmpinit, "pmp",
+	TAILQ_HEAD_INITIALIZER(pmpdriver.units), /* generation */ 0
+};
+
+PERIPHDRIVER_DECLARE(pmp, pmpdriver);
+
+MALLOC_DEFINE(M_ATPMP, "ata_pmp", "ata_pmp buffers");
+
+static void
+pmpinit(void)
+{
+	cam_status status;
+
+	/*
+	 * Install a global async callback.  This callback will
+	 * receive async callbacks like "new device found".
+	 */
+	status = xpt_register_async(AC_FOUND_DEVICE, pmpasync, NULL, NULL);
+
+	if (status != CAM_REQ_CMP) {
+		printf("pmp: Failed to attach master async callback "
+		       "due to status 0x%x!\n", status);
+	}
+}
+
+static void
+pmpfreeze(struct cam_periph *periph, int mask)
+{
+	struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
+	struct cam_path *dpath;
+	int i;
+
+	mask &= ~softc->frozen;
+	for (i = 0; i < 15; i++) {
+		if ((mask & (1 << i)) == 0)
+			continue;
+		if (xpt_create_path(&dpath, periph,
+		    xpt_path_path_id(periph->path),
+		    i, 0) == CAM_REQ_CMP) {
+printf("PMP freeze: %d\n", i);
+			softc->frozen |= (1 << i);
+			cam_freeze_devq(dpath);
+			xpt_free_path(dpath);
+		}
+	}
+}
+
+static void
+pmprelease(struct cam_periph *periph, int mask)
+{
+	struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
+	struct cam_path *dpath;
+	int i;
+
+	mask &= softc->frozen;
+	for (i = 0; i < 15; i++) {
+		if ((mask & (1 << i)) == 0)
+			continue;
+		if (xpt_create_path(&dpath, periph,
+		    xpt_path_path_id(periph->path),
+		    i, 0) == CAM_REQ_CMP) {
+printf("PMP release: %d\n", i);
+			softc->frozen &= ~(1 << i);
+			cam_release_devq(dpath, 0, 0, 0, FALSE);
+			xpt_free_path(dpath);
+		}
+	}
+}
+
+static void
+pmponinvalidate(struct cam_periph *periph)
+{
+	struct pmp_softc *softc;
+	struct cam_path *dpath;
+	int i;
+
+	softc = (struct pmp_softc *)periph->softc;
+
+	/*
+	 * De-register any async callbacks.
+	 */
+	xpt_register_async(0, pmpasync, periph, periph->path);
+
+	for (i = 0; i < 15; i++) {
+		if (xpt_create_path(&dpath, periph,
+		    xpt_path_path_id(periph->path),
+		    i, 0) == CAM_REQ_CMP) {
+			xpt_async(AC_LOST_DEVICE, dpath, NULL);
+			xpt_free_path(dpath);
+		}
+	}
+	xpt_print(periph->path, "lost device\n");
+}
+
+static void
+pmpcleanup(struct cam_periph *periph)
+{
+	struct pmp_softc *softc;
+
+	softc = (struct pmp_softc *)periph->softc;
+
+	xpt_print(periph->path, "removing device entry\n");
+	cam_periph_unlock(periph);
+
+	/*
+	 * If we can't free the sysctl tree, oh well...
+	 */
+	if ((softc->flags & PMP_FLAG_SCTX_INIT) != 0
+	    && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
+		xpt_print(periph->path, "can't remove sysctl context\n");
+	}
+
+	free(softc, M_DEVBUF);
+	cam_periph_lock(periph);
+}
+
+static void
+pmpasync(void *callback_arg, u_int32_t code,
+	struct cam_path *path, void *arg)
+{
+	struct cam_periph *periph;
+	struct pmp_softc *softc;
+
+	periph = (struct cam_periph *)callback_arg;
+	switch (code) {
+	case AC_FOUND_DEVICE:
+	{
+		struct ccb_getdev *cgd;
+		cam_status status;
+ 
+		cgd = (struct ccb_getdev *)arg;
+		if (cgd == NULL)
+			break;
+
+		if (cgd->protocol != PROTO_SATAPM)
+			break;
+
+		/*
+		 * Allocate a peripheral instance for
+		 * this device and start the probe
+		 * process.
+		 */
+		status = cam_periph_alloc(pmpregister, pmponinvalidate,
+					  pmpcleanup, pmpstart,
+					  "pmp", CAM_PERIPH_BIO,
+					  cgd->ccb_h.path, pmpasync,
+					  AC_FOUND_DEVICE, cgd);
+
+		if (status != CAM_REQ_CMP
+		 && status != CAM_REQ_INPROG)
+			printf("pmpasync: Unable to attach to new device "
+				"due to status 0x%x\n", status);
+		break;
+	}
+	case AC_SCSI_AEN:
+	case AC_SENT_BDR:
+	case AC_BUS_RESET:
+		softc = (struct pmp_softc *)periph->softc;
+		cam_periph_async(periph, code, path, arg);
+		if (softc->state != PMP_STATE_NORMAL)
+			break;
+		pmpfreeze(periph, softc->found);
+		if (code == AC_SENT_BDR || code == AC_BUS_RESET)
+			softc->found = 0; /* We have to reset everything. */
+		softc->state = PMP_STATE_PORTS;
+		cam_periph_acquire(periph);
+		xpt_schedule(periph, CAM_PRIORITY_DEV);
+		break;
+	default:
+		cam_periph_async(periph, code, path, arg);
+		break;
+	}
+}
+
+static void
+pmpsysctlinit(void *context, int pending)
+{
+	struct cam_periph *periph;
+	struct pmp_softc *softc;
+	char tmpstr[80], tmpstr2[80];
+
+	periph = (struct cam_periph *)context;
+	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+		return;
+
+	softc = (struct pmp_softc *)periph->softc;
+	snprintf(tmpstr, sizeof(tmpstr), "CAM PMP unit %d", periph->unit_number);
+	snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
+
+	sysctl_ctx_init(&softc->sysctl_ctx);
+	softc->flags |= PMP_FLAG_SCTX_INIT;
+	softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
+		SYSCTL_STATIC_CHILDREN(_kern_cam_pmp), OID_AUTO, tmpstr2,
+		CTLFLAG_RD, 0, tmpstr);
+	if (softc->sysctl_tree == NULL) {
+		printf("pmpsysctlinit: unable to allocate sysctl tree\n");
+		cam_periph_release(periph);
+		return;
+	}
+
+	cam_periph_release(periph);
+}
+
+static cam_status
+pmpregister(struct cam_periph *periph, void *arg)
+{
+	struct pmp_softc *softc;
+	struct ccb_pathinq cpi;
+	struct ccb_getdev *cgd;
+
+	cgd = (struct ccb_getdev *)arg;
+	if (periph == NULL) {
+		printf("pmpregister: periph was NULL!!\n");
+		return(CAM_REQ_CMP_ERR);
+	}
+
+	if (cgd == NULL) {
+		printf("pmpregister: no getdev CCB, can't register device\n");
+		return(CAM_REQ_CMP_ERR);
+	}
+
+	softc = (struct pmp_softc *)malloc(sizeof(*softc), M_DEVBUF,
+	    M_NOWAIT|M_ZERO);
+
+	if (softc == NULL) {
+		printf("pmpregister: Unable to probe new device. "
+		       "Unable to allocate softc\n");				
+		return(CAM_REQ_CMP_ERR);
+	}
+	periph->softc = softc;
+
+	softc->state = PMP_STATE_PORTS;
+	softc->pm_pid = ((uint32_t *)&cgd->ident_data)[0];
+	softc->pm_prv = ((uint32_t *)&cgd->ident_data)[1];
+
+	/* Check if the SIM does not want queued commands */
+	bzero(&cpi, sizeof(cpi));
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+	cpi.ccb_h.func_code = XPT_PATH_INQ;
+	xpt_action((union ccb *)&cpi);
+
+	TASK_INIT(&softc->sysctl_task, 0, pmpsysctlinit, periph);
+
+	xpt_announce_periph(periph, NULL);
+
+	/*
+	 * Add async callbacks for bus reset and
+	 * bus device reset calls.  I don't bother
+	 * checking if this fails as, in most cases,
+	 * the system will function just fine without
+	 * them and the only alternative would be to
+	 * not attach the device on failure.
+	 */
+	xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
+		AC_SCSI_AEN, pmpasync, periph, periph->path);
+
+	/*
+	 * Take an exclusive refcount on the periph while pmpstart is called
+	 * to finish the probe.  The reference will be dropped in pmpdone at
+	 * the end of probe.
+	 */
+	(void)cam_periph_acquire(periph);
+	xpt_schedule(periph, CAM_PRIORITY_DEV);
+
+	return(CAM_REQ_CMP);
+}
+
+static void
+pmpstart(struct cam_periph *periph, union ccb *start_ccb)
+{
+	struct ccb_ataio *ataio;
+	struct pmp_softc *softc;
+
+	softc = (struct pmp_softc *)periph->softc;
+	ataio = &start_ccb->ataio;
+
+	switch (softc->state) {
+	case PMP_STATE_PORTS:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_read_cmd(ataio, 2, 15);
+		break;
+	case PMP_STATE_CONFIG:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_write_cmd(ataio, 0x60, 15, 0xf);
+		break;
+	case PMP_STATE_RESET:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_write_cmd(ataio, 2, softc->pm_step,
+		    (softc->found & (1 << softc->pm_step)) ? 0 : 1);
+printf("PM RESET %d%s\n", softc->pm_step,
+    (softc->found & (1 << softc->pm_step)) ? " skipping" : "");
+		break;
+	case PMP_STATE_CONNECT:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_write_cmd(ataio, 2, softc->pm_step, 0);
+		break;
+	case PMP_STATE_CHECK:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_read_cmd(ataio, 0, softc->pm_step);
+		break;
+	case PMP_STATE_CLEAR:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
+		break;
+	default:
+		break;
+	}
+	xpt_action(start_ccb);
+}
+
+static void
+pmpdone(struct cam_periph *periph, union ccb *done_ccb)
+{
+	struct pmp_softc *softc;
+	struct ccb_ataio *ataio;
+	union ccb *work_ccb;
+	struct cam_path *path, *dpath;
+	u_int32_t  priority;
+
+	softc = (struct pmp_softc *)periph->softc;
+	ataio = &done_ccb->ataio;
+
+	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("pmpdone\n"));
+
+	path = done_ccb->ccb_h.path;
+	priority = done_ccb->ccb_h.pinfo.priority;
+
+	switch (softc->state) {
+	case PMP_STATE_PORTS:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
+			    (done_ccb->ataio.res.lba_mid << 16) +
+			    (done_ccb->ataio.res.lba_low << 8) +
+			    done_ccb->ataio.res.sector_count;
+			/* This PM declares 6 ports, while only 5 of them are real.
+			 * Port 5 is enclosure management bridge port, which has implementation
+			 * problems, causing probe faults. Hide it for now. */
+			if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
+				softc->pm_ports = 5;
+			/* This PM declares 7 ports, while only 5 of them are real.
+			 * Port 5 is some fake "Config  Disk" with 640 sectors size,
+			 * port 6 is enclosure management bridge port.
+			 * Both fake ports has implementation problems, causing
+			 * probe faults. Hide them for now. */
+			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
+				softc->pm_ports = 5;
+			printf("PM ports: %d\n", softc->pm_ports);
+			softc->state = PMP_STATE_CONFIG;
+			xpt_release_ccb(done_ccb);
+			xpt_schedule(periph, priority);
+			return;
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_CONFIG:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			softc->pm_step = 0;
+			softc->state = PMP_STATE_RESET;
+			xpt_release_ccb(done_ccb);
+			xpt_schedule(periph, priority);
+			return;
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_RESET:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			softc->pm_step++;
+			if (softc->pm_step < softc->pm_ports) {
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			} else {
+				softc->pm_step = 0;
+				DELAY(5000);
+				printf("PM reset done\n");
+				softc->state = PMP_STATE_CONNECT;
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			}
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_CONNECT:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			softc->pm_step++;
+			if (softc->pm_step < softc->pm_ports) {
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			} else {
+				softc->pm_step = 0;
+				softc->pm_try = 0;
+				printf("PM connect done\n");
+				softc->state = PMP_STATE_CHECK;
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			}
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_CHECK:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			int res = (done_ccb->ataio.res.lba_high << 24) +
+			    (done_ccb->ataio.res.lba_mid << 16) +
+			    (done_ccb->ataio.res.lba_low << 8) +
+			    done_ccb->ataio.res.sector_count;
+			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
+				printf("PM status: %d - %08x\n", softc->pm_step, res);
+				softc->found |= (1 << softc->pm_step);
+				softc->pm_step++;
+			} else {
+				if (softc->pm_try < 100) {
+					DELAY(10000);
+					softc->pm_try++;
+				} else {
+					printf("PM status: %d - %08x\n", softc->pm_step, res);
+					softc->found &= ~(1 << softc->pm_step);
+					if (xpt_create_path(&dpath, periph,
+					    done_ccb->ccb_h.path_id,
+					    softc->pm_step, 0) == CAM_REQ_CMP) {
+						xpt_async(AC_LOST_DEVICE, dpath, NULL);
+						xpt_free_path(dpath);
+					}
+					softc->pm_step++;
+				}
+			}
+			if (softc->pm_step < softc->pm_ports) {
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			} else {
+				softc->pm_step = 0;
+				softc->state = PMP_STATE_CLEAR;
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			}
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_CLEAR:
+		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			softc->pm_step++;
+			if (softc->pm_step < softc->pm_ports) {
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			} else if (softc->found) {
+				softc->pm_step = 0;
+				softc->state = PMP_STATE_SCAN;
+				work_ccb = xpt_alloc_ccb_nowait();
+				if (work_ccb != NULL)
+					goto do_scan;
+				xpt_release_ccb(done_ccb);
+			}
+			break;
+		} else if (cam_periph_error(done_ccb, 0, 0,
+					    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				cam_release_devq(done_ccb->ccb_h.path,
+						 /*relsim_flags*/0,
+						 /*reduction*/0,
+						 /*timeout*/0,
+						 /*getcount_only*/0);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PMP_STATE_SCAN:
+		work_ccb = done_ccb;
+		done_ccb = (union ccb*)work_ccb->ccb_h.ppriv_ptr0;
+		/* Free the current request path- we're done with it. */
+		xpt_free_path(work_ccb->ccb_h.path);
+		softc->pm_step++;
+do_scan:
+		while (softc->pm_step < softc->pm_ports &&
+		    (softc->found & (1 << softc->pm_step)) == 0) {
+			softc->pm_step++;
+		}
+		if (softc->pm_step >= softc->pm_ports) {
+			xpt_free_ccb(work_ccb);
+			xpt_release_ccb(done_ccb);
+			break;
+		}
+		if (xpt_create_path(&dpath, periph,
+		    done_ccb->ccb_h.path_id,
+		    softc->pm_step, 0) != CAM_REQ_CMP) {
+			printf("pmpdone: xpt_create_path failed"
+			    ", bus scan halted\n");
+			xpt_free_ccb(work_ccb);
+			xpt_release_ccb(done_ccb);
+			break;
+		}
+		xpt_setup_ccb(&work_ccb->ccb_h, dpath,
+		    done_ccb->ccb_h.pinfo.priority);
+		work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
+		work_ccb->ccb_h.cbfcnp = pmpdone;
+		work_ccb->ccb_h.ppriv_ptr0 = done_ccb;
+		work_ccb->crcn.flags = done_ccb->crcn.flags;
+		xpt_action(work_ccb);
+		pmprelease(periph, 1 << softc->pm_step);
+		return;
+	default:
+		break;
+	}
+	softc->state = PMP_STATE_NORMAL;
+	pmprelease(periph, -1);
+	cam_periph_release_locked(periph);
+}
+
+#endif /* _KERNEL */
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 57882d21d1b..a693e2cdc63 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -96,11 +96,6 @@ typedef enum {
 	PROBE_FULL_INQUIRY,
 	PROBE_PM_PID,
 	PROBE_PM_PRV,
-	PROBE_PM_PORTS,
-	PROBE_PM_RESET,
-	PROBE_PM_CONNECT,
-	PROBE_PM_CHECK,
-	PROBE_PM_CLEAR,
 	PROBE_INVALID
 } probe_action;
 
@@ -112,11 +107,6 @@ static char *probe_action_text[] = {
 	"PROBE_FULL_INQUIRY",
 	"PROBE_PM_PID",
 	"PROBE_PM_PRV",
-	"PROBE_PM_PORTS",
-	"PROBE_PM_RESET",
-	"PROBE_PM_CONNECT",
-	"PROBE_PM_CHECK",
-	"PROBE_PM_CLEAR",
 	"PROBE_INVALID"
 };
 
@@ -142,9 +132,6 @@ typedef struct {
 	u_int8_t	digest[16];
 	uint32_t	pm_pid;
 	uint32_t	pm_prv;
-	int		pm_ports;
-	int		pm_step;
-	int		pm_try;
 	struct cam_periph *periph;
 } probe_softc;
 
@@ -274,10 +261,9 @@ probeschedule(struct cam_periph *periph)
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 
-	if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
+	if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) ||
+	    periph->path->device->protocol == PROTO_SATAPM)
 		PROBE_SET_ACTION(softc, PROBE_RESET);
-	else if (periph->path->device->protocol == PROTO_SATAPM)
-		PROBE_SET_ACTION(softc, PROBE_PM_PID);
 	else
 		PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
 
@@ -295,7 +281,6 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 	/* Probe the device that our peripheral driver points to */
 	struct ccb_ataio *ataio;
 	struct ccb_scsiio *csio;
-	struct ccb_trans_settings cts;
 	probe_softc *softc;
 
 	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
@@ -306,21 +291,11 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 
 	switch (softc->action) {
 	case PROBE_RESET:
-		if (start_ccb->ccb_h.target_id == 15) {
-			/* Report SIM that we have no knowledge about PM presence. */
-			bzero(&cts, sizeof(cts));
-			xpt_setup_ccb(&cts.ccb_h, start_ccb->ccb_h.path, 1);
-			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
-			cts.type = CTS_TYPE_CURRENT_SETTINGS;
-			cts.xport_specific.sata.pm_present = 0;
-			cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
-			xpt_action((union ccb *)&cts);
-		}
 		cam_fill_ataio(ataio,
 		      0,
 		      probedone,
 		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
+		      0,
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      (start_ccb->ccb_h.target_id == 15 ? 3 : 15) * 1000);
@@ -351,7 +326,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		      1,
 		      probedone,
 		      /*flags*/CAM_DIR_IN,
-		      MSG_SIMPLE_Q_TAG,
+		      0,
 		      /*data_ptr*/(u_int8_t *)ident_buf,
 		      /*dxfer_len*/sizeof(struct ata_params),
 		      30 * 1000);
@@ -413,7 +388,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		      1,
 		      probedone,
 		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
+		      0,
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      10 * 1000);
@@ -424,74 +399,12 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		      1,
 		      probedone,
 		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
+		      0,
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      10 * 1000);
 		ata_pm_read_cmd(ataio, 1, 15);
 		break;
-	case PROBE_PM_PORTS:
-		cam_fill_ataio(ataio,
-		      1,
-		      probedone,
-		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
-		      /*data_ptr*/NULL,
-		      /*dxfer_len*/0,
-		      10 * 1000);
-		ata_pm_read_cmd(ataio, 2, 15);
-		break;
-	case PROBE_PM_RESET:
-	{
-		struct ata_params *ident_buf =
-		    &periph->path->device->ident_data;
-		cam_fill_ataio(ataio,
-		      1,
-		      probedone,
-		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
-		      /*data_ptr*/NULL,
-		      /*dxfer_len*/0,
-		      10 * 1000);
-		ata_pm_write_cmd(ataio, 2, softc->pm_step,
-		    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
-printf("PM RESET %d %04x %d\n", softc->pm_step, ident_buf->cylinders,
-    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
-		break;
-	}
-	case PROBE_PM_CONNECT:
-		cam_fill_ataio(ataio,
-		      1,
-		      probedone,
-		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
-		      /*data_ptr*/NULL,
-		      /*dxfer_len*/0,
-		      10 * 1000);
-		ata_pm_write_cmd(ataio, 2, softc->pm_step, 0);
-		break;
-	case PROBE_PM_CHECK:
-		cam_fill_ataio(ataio,
-		      1,
-		      probedone,
-		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
-		      /*data_ptr*/NULL,
-		      /*dxfer_len*/0,
-		      10 * 1000);
-		ata_pm_read_cmd(ataio, 0, softc->pm_step);
-		break;
-	case PROBE_PM_CLEAR:
-		cam_fill_ataio(ataio,
-		      1,
-		      probedone,
-		      /*flags*/CAM_DIR_NONE,
-		      MSG_SIMPLE_Q_TAG,
-		      /*data_ptr*/NULL,
-		      /*dxfer_len*/0,
-		      10 * 1000);
-		ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
-		break;
 	case PROBE_INVALID:
 		CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
 		    ("probestart: invalid action state\n"));
@@ -630,7 +543,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 	probe_softc *softc;
 	struct cam_path *path;
 	u_int32_t  priority;
-	int found = 0;
+	int found = 1;
 
 	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
 
@@ -672,8 +585,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 					xpt_print(path,
 					    "Unexpected signature 0x%04x\n", sign);
 				}
-				xpt_release_ccb(done_ccb);
-				break;
+				goto device_fail;
 			}
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
@@ -780,9 +692,8 @@ device_fail:
 		 * drivers that this device is no more.
 		 */
 		if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
-			/* Send the async notification. */
 			xpt_async(AC_LOST_DEVICE, path, NULL);
-
+		found = 0;
 		xpt_release_ccb(done_ccb);
 		break;
 	}
@@ -881,6 +792,7 @@ modedone:		if (path->device->protocol == PROTO_ATA) {
 			    (done_ccb->ataio.res.lba_mid << 16) +
 			    (done_ccb->ataio.res.lba_low << 8) +
 			    done_ccb->ataio.res.sector_count;
+			((uint32_t *)ident_buf)[0] = softc->pm_pid;
 			printf("PM Product ID: %08x\n", softc->pm_pid);
 			snprintf(ident_buf->model, sizeof(ident_buf->model),
 			    "Port Multiplier %08x", softc->pm_pid);
@@ -903,164 +815,24 @@ modedone:		if (path->device->protocol == PROTO_ATA) {
 			    (done_ccb->ataio.res.lba_mid << 16) +
 			    (done_ccb->ataio.res.lba_low << 8) +
 			    done_ccb->ataio.res.sector_count;
+			((uint32_t *)ident_buf)[1] = softc->pm_prv;
 			printf("PM Revision: %08x\n", softc->pm_prv);
 			snprintf(ident_buf->revision, sizeof(ident_buf->revision),
 			    "%04x", softc->pm_prv);
-			PROBE_SET_ACTION(softc, PROBE_PM_PORTS);
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	case PROBE_PM_PORTS:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			/* This PM declares 6 ports, while only 5 of them are real.
-			 * Port 5 is enclosure management bridge port, which has implementation
-			 * problems, causing probe faults. Hide it for now. */
-			if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
-				softc->pm_ports = 5;
-			/* This PM declares 7 ports, while only 5 of them are real.
-			 * Port 5 is some fake "Config  Disk" with 640 sectors size,
-			 * port 6 is enclosure management bridge port.
-			 * Both fake ports has implementation problems, causing
-			 * probe faults. Hide them for now. */
-			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
-				softc->pm_ports = 5;
-			printf("PM ports: %d\n", softc->pm_ports);
-			ident_buf->config = softc->pm_ports;
 			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
-			softc->pm_step = 0;
-			PROBE_SET_ACTION(softc, PROBE_PM_RESET);
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	case PROBE_PM_RESET:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				DELAY(5000);
-				printf("PM reset done\n");
-				PROBE_SET_ACTION(softc, PROBE_PM_CONNECT);
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	case PROBE_PM_CONNECT:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				softc->pm_try = 0;
-				printf("PM connect done\n");
-				PROBE_SET_ACTION(softc, PROBE_PM_CHECK);
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	case PROBE_PM_CHECK:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			int res = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
-				printf("PM status: %d - %08x\n", softc->pm_step, res);
-				ident_buf->cylinders |= (1 << softc->pm_step);
-				softc->pm_step++;
-			} else {
-				if (softc->pm_try < 100) {
-					DELAY(10000);
-					softc->pm_try++;
-				} else {
-					printf("PM status: %d - %08x\n", softc->pm_step, res);
-					ident_buf->cylinders &= ~(1 << softc->pm_step);
-					softc->pm_step++;
-				}
-			}
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				PROBE_SET_ACTION(softc, PROBE_PM_CLEAR);
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	case PROBE_PM_CLEAR:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-			found = ident_buf->cylinders | 0x8000;
-			if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+			if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
 				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 				xpt_action(done_ccb);
 				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 				    done_ccb);
-				xpt_release_ccb(done_ccb);
+			} else {
+				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+				xpt_action(done_ccb);
+				xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path,
+				    done_ccb);
 			}
+			xpt_release_ccb(done_ccb);
 			break;
 		} else if (cam_periph_error(done_ccb, 0, 0,
 					    &softc->saved_ccb) == ERESTART) {
@@ -1192,11 +964,11 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 		scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0;
 		/* Free the current request path- we're done with it. */
 		xpt_free_path(work_ccb->ccb_h.path);
-		/* If there is PM... */
+		/* If there is PMP... */
 		if (scan_info->counter == 15) {
 			if (work_ccb->ccb_h.ppriv_field1 != 0) {
-				/* Save PM probe result. */
-				scan_info->found = work_ccb->ccb_h.ppriv_field1;
+				/* everything else willbe probed by it */
+				scan_info->found = 0x8000;
 			} else {
 				struct ccb_trans_settings cts;
 
@@ -1225,6 +997,8 @@ take_next:
 			break;
 		}
 scan_next:
+		if ((scan_info->found & (1 << scan_info->counter)) == 0)
+			goto take_next;
 		status = xpt_create_path(&path, xpt_periph,
 		    scan_info->request_ccb->ccb_h.path_id,
 		    scan_info->counter, 0);
@@ -1240,11 +1014,6 @@ scan_next:
 			xpt_done(request_ccb);
 			break;
 		}
-		if ((scan_info->found & (1 << scan_info->counter)) == 0) {
-			xpt_async(AC_LOST_DEVICE, path, NULL);
-			xpt_free_path(path);
-			goto take_next;
-		}
 		xpt_setup_ccb(&work_ccb->ccb_h, path,
 		    scan_info->request_ccb->ccb_h.pinfo.priority);
 		work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
diff --git a/sys/conf/files b/sys/conf/files
index 033af70d769..9e99f2cd934 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -117,6 +117,7 @@ cam/scsi/scsi_all.c		optional scbus
 cam/scsi/scsi_cd.c		optional cd
 cam/scsi/scsi_ch.c		optional ch
 cam/ata/ata_da.c		optional da
+cam/ata/ata_pmp.c		optional da
 cam/scsi/scsi_da.c		optional da
 cam/scsi/scsi_low.c		optional ct | ncv | nsp | stg
 cam/scsi/scsi_low_pisa.c	optional ct | ncv | nsp | stg
diff --git a/sys/modules/cam/Makefile b/sys/modules/cam/Makefile
index ca5c56a7b1a..30f1f8936ba 100644
--- a/sys/modules/cam/Makefile
+++ b/sys/modules/cam/Makefile
@@ -28,6 +28,7 @@ SRCS+=	scsi_xpt.c
 SRCS+=	ata_all.c
 SRCS+=	ata_xpt.c
 SRCS+=	ata_da.c
+SRCS+=	ata_pmp.c
 
 EXPORT_SYMS=	YES	# XXX evaluate
 

From c269e21049464b2cb2058f10736ec6e5c0be1a7e Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 13:07:22 +0000
Subject: [PATCH 300/646] Revert interrupt reason check order back. ATAPI
 errors may set IF bit together with TFE.

---
 sys/dev/ahci/ahci.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 485ac3d5ce4..0a2472e7797 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -1001,12 +1001,7 @@ ahci_ch_intr(void *data)
 			/* XXX: reqests in loading state. */
 			if (((err >> i) & 1) == 0)
 				continue;
-			if (istatus & AHCI_P_IX_IF) {
-				if (ch->numtslots == 0 && i != ccs)
-					et = AHCI_ERR_INNOCENT;
-				else
-					et = AHCI_ERR_SATA;
-			} else if (istatus & AHCI_P_IX_TFE) {
+			if (istatus & AHCI_P_IX_TFE) {
 				/* Task File Error */
 				if (ch->numtslots == 0) {
 					/* Untagged operation. */
@@ -1019,6 +1014,11 @@ ahci_ch_intr(void *data)
 					et = AHCI_ERR_NCQ;
 					ncq_err = 1;
 				}
+			} else if (istatus & AHCI_P_IX_IF) {
+				if (ch->numtslots == 0 && i != ccs)
+					et = AHCI_ERR_INNOCENT;
+				else
+					et = AHCI_ERR_SATA;
 			} else
 				et = AHCI_ERR_INVALID;
 			ahci_end_transaction(&ch->slot[i], et);

From 62486e93c4058586e15f44395928cb32e24bac7d Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 23 Oct 2009 13:28:33 +0000
Subject: [PATCH 301/646] Properly sort the intr_event_describe_handler()
 prototype.

Submitted by:	bde
---
 sys/sys/interrupt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h
index 18f73d98968..028fa7f3098 100644
--- a/sys/sys/interrupt.h
+++ b/sys/sys/interrupt.h
@@ -168,12 +168,12 @@ int	intr_event_create(struct intr_event **event, void *source,
 	    void (*post_ithread)(void *), void (*post_filter)(void *),
 	    int (*assign_cpu)(void *, u_char), const char *fmt, ...)
 	    __printflike(9, 10);
+int	intr_event_describe_handler(struct intr_event *ie, void *cookie,
+	    const char *descr);
 int	intr_event_destroy(struct intr_event *ie);
 void	intr_event_execute_handlers(struct proc *p, struct intr_event *ie);
 int	intr_event_handle(struct intr_event *ie, struct trapframe *frame);
 int	intr_event_remove_handler(void *cookie);
-int	intr_event_describe_handler(struct intr_event *ie, void *cookie,
-	    const char *descr);
 int	intr_getaffinity(int irq, void *mask);
 void	*intr_handler_source(void *cookie);
 int	intr_setaffinity(int irq, void *mask);

From 0d3d0d74eab624acdba0c01c6957a08fb428ee80 Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Fri, 23 Oct 2009 13:35:00 +0000
Subject: [PATCH 302/646] Improve grammar in ip_input comment while attempting
 to maintain what might be its meaning.

MFC after:	3 days
---
 sys/netinet/ip_input.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index e96fa802576..5e87467fe25 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -530,8 +530,8 @@ tooshort:
 	}
 	if ((dchg = (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL)) != 0) {
 		/*
-		 * Directly ship on the packet.  This allows to forward
-		 * packets that were destined for us to some other directly
+		 * Directly ship the packet on.  This allows forwarding
+		 * packets originally destined to us to ome other directly
 		 * connected host.
 		 */
 		ip_forward(m, dchg);

From 0f3e2159540f538bdfeb664b8e58e9a2210bf54a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 13:39:30 +0000
Subject: [PATCH 303/646] Make "Retrying Command" to be printed before actual
 retrying. It should make debug/error log a bit more readable.

---
 sys/cam/cam_periph.c | 39 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 1a67a0c4a2e..14b655d54c2 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1767,16 +1767,27 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
 		break;
 	}
 
+	/*
+	 * If we have and error and are booting verbosely, whine
+	 * *unless* this was a non-retryable selection timeout.
+	 */
+	if (error != 0 && bootverbose &&
+	    !(status == CAM_SEL_TIMEOUT && (camflags & CAM_RETRY_SELTO) == 0)) {
+		if (error != ERESTART) {
+			if (action_string == NULL)
+				action_string = "Unretryable Error";
+			xpt_print(ccb->ccb_h.path, "error %d\n", error);
+			xpt_print(ccb->ccb_h.path, "%s\n", action_string);
+		} else
+			xpt_print(ccb->ccb_h.path, "Retrying Command\n");
+	}
+
 	/* Attempt a retry */
-	if (error == ERESTART || error == 0) {	
+	if (error == ERESTART || error == 0) {
 		if (frozen != 0)
 			ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
-
-		if (error == ERESTART) {
-			action_string = "Retrying Command";
+		if (error == ERESTART)
 			xpt_action(ccb);
-		}
-		
 		if (frozen != 0)
 			cam_release_devq(ccb->ccb_h.path,
 					 relsim_flags,
@@ -1785,21 +1796,5 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
 					 /*getcount_only*/0);
 	}
 
-	/*
-	 * If we have and error and are booting verbosely, whine
-	 * *unless* this was a non-retryable selection timeout.
-	 */
-	if (error != 0 && bootverbose &&
-	    !(status == CAM_SEL_TIMEOUT && (camflags & CAM_RETRY_SELTO) == 0)) {
-
-
-		if (action_string == NULL)
-			action_string = "Unretryable Error";
-		if (error != ERESTART) {
-			xpt_print(ccb->ccb_h.path, "error %d\n", error);
-		}
-		xpt_print(ccb->ccb_h.path, "%s\n", action_string);
-	}
-
 	return (error);
 }

From e2ee8728ee34a88f651ecc69b9dd89ae128cfee3 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Fri, 23 Oct 2009 14:27:40 +0000
Subject: [PATCH 304/646] Do not map the trap vectors into the kernel's address
 space. They are only used in real mode and keeping them mapped only serves to
 make NULL a valid address, which results in silent NULL pointer deferences.

Suggested by:   Patrick Kerharo
Obtained from:	projects/ppc64
---
 sys/powerpc/aim/mmu_oea64.c | 10 ++++++----
 sys/powerpc/aim/trap_subr.S |  9 +++++++--
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 9a400363b68..680a3915e1f 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -868,15 +868,17 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
 	ENABLE_TRANS(msr);
 
 	/*
-	 * Map certain important things, like ourselves and the exception
-	 * vectors
+	 * Map certain important things, like ourselves.
+	 *
+	 * NOTE: We do not map the exception vector space. That code is
+	 * used only in real mode, and leaving it unmapped allows us to
+	 * catch NULL pointer deferences, instead of making NULL a valid
+	 * address.
 	 */
 
 	DISABLE_TRANS(msr);
 	for (pa = kernelstart & ~PAGE_MASK; pa < kernelend; pa += PAGE_SIZE) 
 		moea64_kenter(mmup, pa, pa);
-	for (pa = EXC_RSVD; pa < EXC_LAST; pa += PAGE_SIZE) 
-		moea64_kenter(mmup, pa, pa);
 	ENABLE_TRANS(msr);
 
 	if (!ofw_real_mode) {
diff --git a/sys/powerpc/aim/trap_subr.S b/sys/powerpc/aim/trap_subr.S
index bcffb2930ff..5d9596b5184 100644
--- a/sys/powerpc/aim/trap_subr.S
+++ b/sys/powerpc/aim/trap_subr.S
@@ -275,10 +275,16 @@ CNAME(restorebridgesize) = .-CNAME(restorebridge)
 /*
  * Processor reset exception handler. These are typically
  * the first instructions the processor executes after a
- * software reset.
+ * software reset. We do this in two bits so that we are
+ * not still hanging around in the trap handling region
+ * once the MMU is turned on.
  */
 	.globl	CNAME(rstcode), CNAME(rstsize)
 CNAME(rstcode):
+	ba	cpu_reset
+CNAME(rstsize) = . - CNAME(rstcode)
+
+cpu_reset:
 	bl	1f
 
 	.space	124
@@ -296,7 +302,6 @@ CNAME(rstcode):
 	/* Should not be reached */
 9:
 	b	9b
-CNAME(rstsize) = . - CNAME(rstcode)
 #endif
 
 /*

From 364e9ccb9ced1d42b689af8c55b24c0d1792782f Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Fri, 23 Oct 2009 14:50:11 +0000
Subject: [PATCH 305/646] wordexp(3): fix some bugs with signals and long
 outputs * retry various system calls on EINTR * retry the rest after a short
 read (common if there is more than about 1K   of output) * block SIGCHLD like
 system(3) does (note that this does not and cannot   work fully in threaded
 programs, they will need to be careful with wait   functions)

PR:		90580
MFC after:	1 month
---
 lib/libc/gen/wordexp.c                       | 76 +++++++++++++++-----
 tools/regression/lib/libc/gen/test-wordexp.c | 42 +++++++++++
 2 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c
index a437543bca4..06abdc796ae 100644
--- a/lib/libc/gen/wordexp.c
+++ b/lib/libc/gen/wordexp.c
@@ -28,8 +28,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,24 @@ wordexp(const char * __restrict words, wordexp_t * __restrict we, int flags)
 	return (0);
 }
 
+static size_t
+we_read_fully(int fd, char *buffer, size_t len)
+{
+	size_t done;
+	ssize_t nread;
+
+	done = 0;
+	do {
+		nread = _read(fd, buffer + done, len - done);
+		if (nread == -1 && errno == EINTR)
+			continue;
+		if (nread <= 0)
+			break;
+		done += nread;
+	} while (done != len);
+	return done;
+}
+
 /*
  * we_askshell --
  *	Use the `wordexp' /bin/sh builtin function to do most of the work
@@ -90,20 +110,31 @@ we_askshell(const char *words, wordexp_t *we, int flags)
 	size_t sofs;			/* Offset into we->we_strings */
 	size_t vofs;			/* Offset into we->we_wordv */
 	pid_t pid;			/* Process ID of child */
+	pid_t wpid;			/* waitpid return value */
 	int status;			/* Child exit status */
+	int error;			/* Our return value */
+	int serrno;			/* errno to return */
 	char *ifs;			/* IFS env. var. */
 	char *np, *p;			/* Handy pointers */
 	char *nstrings;			/* Temporary for realloc() */
 	char **nwv;			/* Temporary for realloc() */
+	sigset_t newsigblock, oldsigblock;
 
+	serrno = errno;
 	if ((ifs = getenv("IFS")) == NULL)
 		ifs = " \t\n";
 
 	if (pipe(pdes) < 0)
 		return (WRDE_NOSPACE);	/* XXX */
+	(void)sigemptyset(&newsigblock);
+	(void)sigaddset(&newsigblock, SIGCHLD);
+	(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
 	if ((pid = fork()) < 0) {
+		serrno = errno;
 		_close(pdes[0]);
 		_close(pdes[1]);
+		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+		errno = serrno;
 		return (WRDE_NOSPACE);	/* XXX */
 	}
 	else if (pid == 0) {
@@ -114,6 +145,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
 		int devnull;
 		char *cmd;
 
+		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
 		_close(pdes[0]);
 		if (_dup2(pdes[1], STDOUT_FILENO) < 0)
 			_exit(1);
@@ -139,10 +171,11 @@ we_askshell(const char *words, wordexp_t *we, int flags)
 	 * the expanded words separated by nulls.
 	 */
 	_close(pdes[1]);
-	if (_read(pdes[0], wbuf, 8) != 8 || _read(pdes[0], bbuf, 8) != 8) {
-		_close(pdes[0]);
-		_waitpid(pid, &status, 0);
-		return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX);
+	if (we_read_fully(pdes[0], wbuf, 8) != 8 ||
+			we_read_fully(pdes[0], bbuf, 8) != 8) {
+		error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX;
+		serrno = errno;
+		goto cleanup;
 	}
 	wbuf[8] = bbuf[8] = '\0';
 	nwords = strtol(wbuf, NULL, 16);
@@ -162,33 +195,38 @@ we_askshell(const char *words, wordexp_t *we, int flags)
 	if ((nwv = realloc(we->we_wordv, (we->we_wordc + 1 +
 	    (flags & WRDE_DOOFFS ?  we->we_offs : 0)) *
 	    sizeof(char *))) == NULL) {
-		_close(pdes[0]);
-		_waitpid(pid, &status, 0);
-		return (WRDE_NOSPACE);
+		error = WRDE_NOSPACE;
+		goto cleanup;
 	}
 	we->we_wordv = nwv;
 	if ((nstrings = realloc(we->we_strings, we->we_nbytes)) == NULL) {
-		_close(pdes[0]);
-		_waitpid(pid, &status, 0);
-		return (WRDE_NOSPACE);
+		error = WRDE_NOSPACE;
+		goto cleanup;
 	}
 	for (i = 0; i < vofs; i++)
 		if (we->we_wordv[i] != NULL)
 			we->we_wordv[i] += nstrings - we->we_strings;
 	we->we_strings = nstrings;
 
-	if (_read(pdes[0], we->we_strings + sofs, nbytes) != nbytes) {
-		_close(pdes[0]);
-		_waitpid(pid, &status, 0);
-		return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX);
+	if (we_read_fully(pdes[0], we->we_strings + sofs, nbytes) != nbytes) {
+		error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX;
+		serrno = errno;
+		goto cleanup;
 	}
 
-	if (_waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) ||
-	    WEXITSTATUS(status) != 0) {
-		_close(pdes[0]);
-		return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX);
-	}
+	error = 0;
+cleanup:
 	_close(pdes[0]);
+	do
+		wpid = _waitpid(pid, &status, 0);
+	while (wpid < 0 && errno == EINTR);
+	(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+	if (error != 0) {
+		errno = serrno;
+		return (error);
+	}
+	if (wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX);
 
 	/*
 	 * Break the null-terminated expanded word strings out into
diff --git a/tools/regression/lib/libc/gen/test-wordexp.c b/tools/regression/lib/libc/gen/test-wordexp.c
index c78199ed929..df8f8856f62 100644
--- a/tools/regression/lib/libc/gen/test-wordexp.c
+++ b/tools/regression/lib/libc/gen/test-wordexp.c
@@ -32,17 +32,36 @@
 #include 
 __FBSDID("$FreeBSD$");
 
+#include 
+
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
+static void
+chld_handler(int x)
+{
+	int status, serrno;
+
+	(void)x;
+	serrno = errno;
+	while (waitpid(-1, &status, WNOHANG) > 0)
+		;
+	errno = serrno;
+}
+
 int
 main(int argc, char *argv[])
 {
+	struct sigaction sa;
 	wordexp_t we;
 	int r;
+	int i;
+	char longdata[6 * 10000 + 1];
 
 	/* Test that the macros are there. */
 	(void)(WRDE_APPEND + WRDE_DOOFFS + WRDE_NOCMD + WRDE_REUSE +
@@ -59,6 +78,15 @@ main(int argc, char *argv[])
 	assert(we.we_wordv[2] == NULL);
 	wordfree(&we);
 
+	/* Long output. */
+	for (i = 0; i < 10000; i++)
+		snprintf(longdata + 6 * i, 7, "%05d ", i);
+	r = wordexp(longdata, &we, 0);
+	assert(r == 0);
+	assert(we.we_wordc == 10000);
+	assert(we.we_wordv[10000] == NULL);
+	wordfree(&we);
+
 	/* WRDE_DOOFFS */
 	we.we_offs = 3;
 	r = wordexp("hello world", &we, WRDE_DOOFFS);
@@ -167,6 +195,20 @@ main(int argc, char *argv[])
 	r = wordexp("test } test", &we, 0);
 	assert(r == WRDE_BADCHAR);
 
+	/* With a SIGCHLD handler that reaps all zombies. */
+	sa.sa_flags = 0;
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = chld_handler;
+	r = sigaction(SIGCHLD, &sa, NULL);
+	assert(r == 0);
+	r = wordexp("hello world", &we, 0);
+	assert(r == 0);
+	assert(we.we_wordc == 2);
+	assert(strcmp(we.we_wordv[0], "hello") == 0);
+	assert(strcmp(we.we_wordv[1], "world") == 0);
+	assert(we.we_wordv[2] == NULL);
+	wordfree(&we);
+
 	printf("PASS wordexp()\n");
 	printf("PASS wordfree()\n");
 

From 90759b002169de371b4d75b72dba036f53640a54 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 14:56:29 +0000
Subject: [PATCH 306/646] MFp4: Do not differentiate 12/16 bytes ATAPI CCB
 formats when it is not needed.

---
 sys/dev/ata/ata-queue.c  | 6 +-----
 sys/dev/ata/atapi-cd.c   | 4 +---
 sys/dev/ata/atapi-fd.c   | 4 +---
 sys/dev/ata/atapi-tape.c | 5 +----
 4 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 87568844e58..88568842246 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -150,15 +150,11 @@ ata_atapicmd(device_t dev, u_int8_t *ccb, caddr_t data,
 	     int count, int flags, int timeout)
 {
     struct ata_request *request = ata_alloc_request();
-    struct ata_device *atadev = device_get_softc(dev);
     int error = ENOMEM;
 
     if (request) {
 	request->dev = dev;
-	if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12)
-	    bcopy(ccb, request->u.atapi.ccb, 12);
-	else
-	    bcopy(ccb, request->u.atapi.ccb, 16);
+	bcopy(ccb, request->u.atapi.ccb, 16);
 	request->data = data;
 	request->bytecount = count;
 	request->transfersize = min(request->bytecount, 65534);
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index aee837480a8..941c1018547 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -863,9 +863,7 @@ acd_strategy(struct bio *bp)
     }
     request->dev = dev;
     request->bio = bp;
-    bcopy(ccb, request->u.atapi.ccb,
-	  (atadev->param.config & ATA_PROTO_MASK) == 
-	  ATA_PROTO_ATAPI_12 ? 16 : 12);
+    bcopy(ccb, request->u.atapi.ccb, 16);
     request->data = bp->bio_data;
     request->bytecount = count * blocksize;
     request->transfersize = min(request->bytecount, 65534);
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index b8434b30433..5baeab9a7ee 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -240,9 +240,7 @@ afd_strategy(struct bio *bp)
     }
     request->dev = dev;
     request->bio = bp;
-    bcopy(ccb, request->u.atapi.ccb,
-	  (atadev->param.config & ATA_PROTO_MASK) == 
-	  ATA_PROTO_ATAPI_12 ? 16 : 12);
+    bcopy(ccb, request->u.atapi.ccb, 16);
     request->data = bp->bio_data;
     request->bytecount = count * fdp->sectorsize;
     request->transfersize = min(request->bytecount, 65534);
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index dd74461b72c..5b4da81dc1b 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -373,7 +373,6 @@ static void
 ast_strategy(struct bio *bp)
 {
     device_t dev = bp->bio_dev->si_drv1;
-    struct ata_device *atadev = device_get_softc(dev);
     struct ast_softc *stp = device_get_ivars(dev);
     struct ata_request *request;
     u_int32_t blkcount;
@@ -426,9 +425,7 @@ ast_strategy(struct bio *bp)
     }
     request->dev = dev;
     request->driver = bp;
-    bcopy(ccb, request->u.atapi.ccb,
-	  (atadev->param.config & ATA_PROTO_MASK) == 
-	  ATA_PROTO_ATAPI_12 ? 16 : 12);
+    bcopy(ccb, request->u.atapi.ccb, 16);
     request->data = bp->bio_data;
     request->bytecount = blkcount * stp->blksize;
     request->transfersize = min(request->bytecount, 65534);

From 4f9d48e478f0b7d6f05938be6227349dc6514d96 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 23 Oct 2009 15:09:51 +0000
Subject: [PATCH 307/646] Don't bother copying the name of a kproc or kthread
 out into a temporary array just to pass that array to printf().  kproc and
 kthread names are NUL-terminated and can be printed using printf() directly.

Reviewed by:	bde
---
 sys/kern/kern_shutdown.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 6534d5c5541..3d963213597 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -618,16 +618,14 @@ void
 kproc_shutdown(void *arg, int howto)
 {
 	struct proc *p;
-	char procname[MAXCOMLEN + 1];
 	int error;
 
 	if (panicstr)
 		return;
 
 	p = (struct proc *)arg;
-	strlcpy(procname, p->p_comm, sizeof(procname));
 	printf("Waiting (max %d seconds) for system process `%s' to stop...",
-	    kproc_shutdown_wait, procname);
+	    kproc_shutdown_wait, p->p_comm);
 	error = kproc_suspend(p, kproc_shutdown_wait * hz);
 
 	if (error == EWOULDBLOCK)
@@ -640,16 +638,14 @@ void
 kthread_shutdown(void *arg, int howto)
 {
 	struct thread *td;
-	char procname[MAXCOMLEN + 1];
 	int error;
 
 	if (panicstr)
 		return;
 
 	td = (struct thread *)arg;
-	strlcpy(procname, td->td_name, sizeof(procname));
 	printf("Waiting (max %d seconds) for system thread `%s' to stop...",
-	    kproc_shutdown_wait, procname);
+	    kproc_shutdown_wait, td->td_name);
 	error = kthread_suspend(td, kproc_shutdown_wait * hz);
 
 	if (error == EWOULDBLOCK)

From 0deb032554242223e39ecac0b3663fa557ffdf71 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 23 Oct 2009 15:10:41 +0000
Subject: [PATCH 308/646] Style fix.

---
 sys/sys/ktrace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 8aedac1c160..c48c900199e 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -52,7 +52,7 @@ struct ktr_header {
 	int	ktr_len;		/* length of buf */
 	short	ktr_type;		/* trace record type */
 	pid_t	ktr_pid;		/* process id */
-	char	ktr_comm[MAXCOMLEN+1];	/* command name */
+	char	ktr_comm[MAXCOMLEN + 1];/* command name */
 	struct	timeval ktr_time;	/* timestamp */
 	intptr_t	ktr_tid;	/* was ktr_buffer */
 };

From 5ca4819ddf209124a8ffaad0f44d58cf6c77ec37 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 23 Oct 2009 15:14:54 +0000
Subject: [PATCH 309/646] - Fix several off-by-one errors when using MAXCOMLEN.
  The p_comm[] and   td_name[] arrays are actually MAXCOMLEN + 1 in size and a
 few places that   created shadow copies of these arrays were just using
 MAXCOMLEN. - Prefer using sizeof() of an array type to explicit constants for
 the   array length in a few places. - Ensure that all of p_comm[] and
 td_name[] is always zero'd during   execve() to guard against any possible
 information leaks.  Previously   trailing garbage in p_comm[] could be leaked
 to userland in ktrace   record headers via td_name[].

Reviewed by:	bde
---
 sys/kern/kern_exec.c      | 20 +++++++-------------
 sys/kern/kern_ktrace.c    |  7 ++++++-
 sys/kern/subr_bus.c       |  2 +-
 sys/kern/subr_taskqueue.c |  4 ++--
 sys/sys/interrupt.h       |  6 +++---
 5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 033f64122fc..dce624d484b 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -326,7 +326,7 @@ do_execve(td, args, mac_p)
 	struct ucred *newcred = NULL, *oldcred;
 	struct uidinfo *euip;
 	register_t *stack_base;
-	int error, len = 0, i;
+	int error, i;
 	struct image_params image_params, *imgp;
 	struct vattr attr;
 	int (*img_first)(struct image_params *);
@@ -602,18 +602,12 @@ interpret:
 	execsigs(p);
 
 	/* name this process - nameiexec(p, ndp) */
-	if (args->fname) {
-		len = min(nd.ni_cnd.cn_namelen,MAXCOMLEN);
-		bcopy(nd.ni_cnd.cn_nameptr, p->p_comm, len);
-	} else {
-		if (vn_commname(binvp, p->p_comm, MAXCOMLEN + 1) == 0)
-			len = MAXCOMLEN;
-		else {
-			len = sizeof(fexecv_proc_title);
-			bcopy(fexecv_proc_title, p->p_comm, len);
-		}
-	}
-	p->p_comm[len] = 0;
+	bzero(p->p_comm, sizeof(p->p_comm));
+	if (args->fname)
+		bcopy(nd.ni_cnd.cn_nameptr, p->p_comm,
+		    min(nd.ni_cnd.cn_namelen, MAXCOMLEN));
+	else if (vn_commname(binvp, p->p_comm, sizeof(p->p_comm)) != 0)
+		bcopy(fexecv_proc_title, p->p_comm, sizeof(fexecv_proc_title));
 	bcopy(p->p_comm, td->td_name, sizeof(td->td_name));
 
 	/*
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 7506b6f6754..2182ff7857f 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -256,6 +256,10 @@ ktrace_resize_pool(u_int newsize)
 	return (ktr_requestpool);
 }
 
+/* ktr_getrequest() assumes that ktr_comm[] is the same size as td_name[]. */
+CTASSERT(sizeof(((struct ktr_header *)NULL)->ktr_comm) ==
+    (sizeof((struct thread *)NULL)->td_name));
+
 static struct ktr_request *
 ktr_getrequest(int type)
 {
@@ -283,7 +287,8 @@ ktr_getrequest(int type)
 		microtime(&req->ktr_header.ktr_time);
 		req->ktr_header.ktr_pid = p->p_pid;
 		req->ktr_header.ktr_tid = td->td_tid;
-		bcopy(td->td_name, req->ktr_header.ktr_comm, MAXCOMLEN + 1);
+		bcopy(td->td_name, req->ktr_header.ktr_comm,
+		    sizeof(req->ktr_header.ktr_comm));
 		req->ktr_buffer = NULL;
 		req->ktr_header.ktr_len = 0;
 	} else {
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 0c97aa3b78b..0e3ef80c690 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -3861,8 +3861,8 @@ int
 bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
     const char *fmt, ...)
 {
-	char descr[MAXCOMLEN];
 	va_list ap;
+	char descr[MAXCOMLEN + 1];
 
 	if (dev->parent == NULL)
 		return (EINVAL);
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index 22c1809a8a2..8405b3d642b 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -301,7 +301,7 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
 	struct thread *td;
 	struct taskqueue *tq;
 	int i, error;
-	char ktname[MAXCOMLEN];
+	char ktname[MAXCOMLEN + 1];
 
 	if (count <= 0)
 		return (EINVAL);
@@ -309,7 +309,7 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
 	tq = *tqp;
 
 	va_start(ap, name);
-	vsnprintf(ktname, MAXCOMLEN, name, ap);
+	vsnprintf(ktname, sizeof(ktname), name, ap);
 	va_end(ap);
 
 	tq->tq_threads = malloc(sizeof(struct thread *) * count, M_TASKQUEUE,
diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h
index 028fa7f3098..c1df1c764a7 100644
--- a/sys/sys/interrupt.h
+++ b/sys/sys/interrupt.h
@@ -47,7 +47,7 @@ struct intr_handler {
 	driver_intr_t	*ih_handler;	/* Threaded handler function. */
 	void		*ih_argument;	/* Argument to pass to handlers. */
 	int		 ih_flags;
-	char		 ih_name[MAXCOMLEN]; /* Name of handler. */
+	char		 ih_name[MAXCOMLEN + 1]; /* Name of handler. */
 	struct intr_event *ih_event;	/* Event we are connected to. */
 	int		 ih_need;	/* Needs service. */
 	TAILQ_ENTRY(intr_handler) ih_next; /* Next handler for this event. */
@@ -104,8 +104,8 @@ struct intr_handler {
 struct intr_event {
 	TAILQ_ENTRY(intr_event) ie_list;
 	TAILQ_HEAD(, intr_handler) ie_handlers; /* Interrupt handlers. */
-	char		ie_name[MAXCOMLEN]; /* Individual event name. */
-	char		ie_fullname[MAXCOMLEN];
+	char		ie_name[MAXCOMLEN + 1]; /* Individual event name. */
+	char		ie_fullname[MAXCOMLEN + 1];
 	struct mtx	ie_lock;
 	void		*ie_source;	/* Cookie used by MD code. */
 	struct intr_thread *ie_thread;	/* Thread we are connected to. */

From 974e99b008066de02a4a21572066d5b93ef1d3db Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Fri, 23 Oct 2009 17:26:29 +0000
Subject: [PATCH 310/646] Remove unneeded blank line from bpf_drvinit().

MFC after:	3 days
---
 sys/net/bpf.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 2b62f037e37..f6260c0a642 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -2038,7 +2038,6 @@ bpf_drvinit(void *unused)
 	dev = make_dev(&bpf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "bpf");
 	/* For compatibility */
 	make_dev_alias(dev, "bpf0");
-
 }
 
 /*

From 6cb2b4e7a806d3cca4a81ebe30740cc92002d8a7 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Fri, 23 Oct 2009 18:27:34 +0000
Subject: [PATCH 311/646] Use the correct option name in the preprocessor
 command to enable or disable diagnostic messages.

Reviewed by:	ru
MFC after:	3 days
---
 sys/netinet/if_ether.c | 2 +-
 sys/netinet/in.c       | 6 +++---
 sys/netinet6/in6.c     | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 4737b13ba94..4e26ebc2e33 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -180,7 +180,7 @@ arptimer(void *arg)
 		(void) llentry_free(lle);
 		ARPSTAT_INC(timeouts);
 	} 
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 	else {
 		struct sockaddr *l3addr = L3_ADDR(lle);
 		log(LOG_INFO, "arptimer issue: %p, IPv4 address: \"%s\"\n", lle,
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index c124513558c..09f2f449b19 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1327,7 +1327,7 @@ in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
 	/* XXX rtalloc1 should take a const param */
 	rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
 	if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 		log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
 		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
 #endif
@@ -1366,7 +1366,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
 			break;
 	}
 	if (lle == NULL) {
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 		if (flags & LLE_DELETE)
 			log(LOG_INFO, "interface address is missing from cache = %p  in delete\n", lle);	
 #endif
@@ -1401,7 +1401,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
 			lle->la_flags = LLE_DELETED;
 			EVENTHANDLER_INVOKE(arp_update_event, lle);
 			LLE_WUNLOCK(lle);
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 			log(LOG_INFO, "ifaddr cache = %p  is deleted\n", lle);	
 #endif
 		}
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index ccea27ad72b..7254c4d0eb0 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2437,7 +2437,7 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
 			LLE_WLOCK(lle);
 			lle->la_flags = LLE_DELETED;
 			LLE_WUNLOCK(lle);
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 			log(LOG_INFO, "ifaddr cache = %p  is deleted\n", lle);	
 #endif	
 		}

From a0ce33465fb1e46db31d2a66de7d0297b55013d6 Mon Sep 17 00:00:00 2001
From: Jung-uk Kim 
Date: Fri, 23 Oct 2009 18:41:00 +0000
Subject: [PATCH 312/646] - When we restore VESA state, try BIOS POST earlier. 
 VESA restore state function may not work properly if we don't.  Turn off
 hardware cursor as vesa_set_mode() does. - Add VBE 3.0 specific fields in
 VESA mode structure and pack it.  Note the padding is 190 bytes although VBE
 3.0 says 189 bytes.  It must be wrong because the size of structure becomes
 255 bytes and the specification says it must be 256 bytes in total.  In fact,
 an example code in the spec. does it right, though.  While we are at it, fix
 some i386-isms. - Remove state buffer size limitation.  It is no longer
 necessary since sys/compat/x86bios/x86bios.c r198251. - Move int 0x10 vector
 test into vesa_bios_post() as we always do it anyway.

---
 sys/dev/fb/vesa.c | 80 +++++++++++++++++++++++++++++++++--------------
 sys/dev/fb/vesa.h | 16 +++++++++-
 2 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 11b95985d7d..728230c37c8 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -74,8 +74,7 @@ typedef struct adp_state adp_state_t;
 
 /* VESA video adapter */
 static video_adapter_t *vesa_adp = NULL;
-static int vesa_state_buf_size = 0;
-#define VESA_BIOS_BUFSIZE	(3 * PAGE_SIZE)
+static ssize_t vesa_state_buf_size = -1;
 
 /* VESA functions */
 #if 0
@@ -188,7 +187,7 @@ static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g,
 #define STATE_REG	(1<<3)
 #define STATE_MOST	(STATE_HW | STATE_DATA | STATE_REG)
 #define STATE_ALL	(STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
-static int vesa_bios_state_buf_size(void);
+static ssize_t vesa_bios_state_buf_size(void);
 static int vesa_bios_save_restore(int code, void *p, size_t size);
 static int vesa_bios_get_line_length(void);
 static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines);
@@ -282,6 +281,10 @@ vesa_bios_post(void)
 	}
 	regs.R_DL = 0x80;
 	x86bios_call(®s, 0xc000, 0x0003);
+
+	if (x86bios_get_intr(0x10) == 0)
+		return (1);
+
 	return (0);
 }
 
@@ -532,7 +535,7 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
 }
 #endif
 
-static int
+static ssize_t
 vesa_bios_state_buf_size(void)
 {
 	x86regs_t regs;
@@ -557,9 +560,6 @@ vesa_bios_save_restore(int code, void *p, size_t size)
 	uint32_t offs;
 	void *buf;
 
-	if (size > VESA_BIOS_BUFSIZE)
-		return (1);
-
 	if (code != STATE_SAVE && code != STATE_LOAD)
 		return (1);
 
@@ -808,12 +808,11 @@ vesa_bios_init(void)
 	if (x86bios_get_intr(0x10) == 0) {
 		if (vesa_bios_post() != 0)
 			return (1);
-		offs = x86bios_get_intr(0x10);
-		if (offs == 0)
-			return (1);
-		if (bootverbose)
+		if (bootverbose) {
+			offs = x86bios_get_intr(0x10);
 			printf("VESA: interrupt vector installed (0x%x)\n",
 			    BIOS_SADDRTOLADDR(offs));
+		}
 	}
 
 	x86bios_init_regs(®s);
@@ -879,6 +878,22 @@ vesa_bios_init(void)
 		if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode))
 			continue;
 
+		vmode.v_modeattr = le16toh(vmode.v_modeattr);
+		vmode.v_wgran = le16toh(vmode.v_wgran);
+		vmode.v_wsize = le16toh(vmode.v_wsize);
+		vmode.v_waseg = le16toh(vmode.v_waseg);
+		vmode.v_wbseg = le16toh(vmode.v_wbseg);
+		vmode.v_posfunc = le32toh(vmode.v_posfunc);
+		vmode.v_bpscanline = le16toh(vmode.v_bpscanline);
+		vmode.v_width = le16toh(vmode.v_width);
+		vmode.v_height = le16toh(vmode.v_height);
+		vmode.v_lfb = le32toh(vmode.v_lfb);
+		vmode.v_offscreen = le32toh(vmode.v_offscreen);
+		vmode.v_offscreensize = le16toh(vmode.v_offscreensize);
+		vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock);
+		vmode.v_linbpscanline = le16toh(vmode.v_linbpscanline);
+		vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock);
+
 		/* reject unsupported modes */
 #if 0
 		if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO 
@@ -1417,11 +1432,14 @@ vesa_save_state(video_adapter_t *adp, void *p, size_t size)
 	if (adp != vesa_adp)
 		return ((*prevvidsw->save_state)(adp, p, size));
 
-	if (vesa_state_buf_size == 0)
+	if (vesa_state_buf_size == -1) {
 		vesa_state_buf_size = vesa_bios_state_buf_size();
+		if (vesa_state_buf_size == 0)
+			return (1);
+	}
 	if (size == 0)
-		return (sizeof(int) + vesa_state_buf_size);
-	else if (size < (sizeof(int) + vesa_state_buf_size))
+		return (offsetof(adp_state_t, regs) + vesa_state_buf_size);
+	else if (size < (offsetof(adp_state_t, regs) + vesa_state_buf_size))
 		return (1);
 
 	((adp_state_t *)p)->sig = V_STATE_SIG;
@@ -1438,22 +1456,36 @@ vesa_load_state(video_adapter_t *adp, void *p)
 	if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG))
 		return ((*prevvidsw->load_state)(adp, p));
 
+	if (vesa_state_buf_size <= 0)
+		return (1);
+
+	/*
+	 * If the current mode is not the same, probably it was powered down.
+	 * Try BIOS POST to restore a sane state.
+	 */
+	mode = vesa_bios_get_current_mode();
+	if (mode >= 0 && (mode & 0x1ff) != adp->va_mode &&
+	    VESA_MODE(adp->va_mode))
+		(void)vesa_bios_post();
+
 	ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs,
 	    vesa_state_buf_size);
 
 	/*
-	 * If the current mode is not restored properly, try BIOS POST and
-	 * force setting the mode.
+	 * If the desired mode is not restored, force setting the mode.
 	 */
-	flags = adp->va_info.vi_flags;
-	if (!(flags & V_INFO_GRAPHICS))
-		flags &= ~V_INFO_LINEAR;
-	mode = adp->va_mode | ((flags & V_INFO_LINEAR) ? 0x4000 : 0);
-	if (vesa_bios_get_current_mode() != mode && vesa_bios_post() == 0 &&
-	    x86bios_get_intr(0x10) != 0) {
-		int10_set_mode(adp->va_initial_bios_mode);
-		vesa_bios_set_mode(mode);
+	mode = vesa_bios_get_current_mode();
+	if (mode >= 0 && (mode & 0x1ff) != adp->va_mode &&
+	    VESA_MODE(adp->va_mode)) {
+		mode = adp->va_mode;
+		flags = adp->va_info.vi_flags;
+		if ((flags & V_INFO_GRAPHICS) != 0 &&
+		    (flags & V_INFO_LINEAR) != 0)
+			mode |= 0x4000;
+		(void)vesa_bios_set_mode(mode);
+		(void)(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
 	}
+
 	return (ret);
 }
 
diff --git a/sys/dev/fb/vesa.h b/sys/dev/fb/vesa.h
index bd9986b155c..25b9bd50f2d 100644
--- a/sys/dev/fb/vesa.h
+++ b/sys/dev/fb/vesa.h
@@ -108,7 +108,21 @@ struct vesa_mode
     u_int32_t		v_lfb;
     u_int32_t		v_offscreen;
     u_int16_t		v_offscreensize;
-};
+    /* 3.0 implementations */
+    u_int16_t		v_linbpscanline;
+    u_int8_t		v_bankipages;
+    u_int8_t		v_linipages;
+    u_int8_t		v_linredmasksize;
+    u_int8_t		v_linredfieldpos;
+    u_int8_t		v_lingreenmasksize;
+    u_int8_t		v_lingreenfieldpos;
+    u_int8_t		v_linbluemasksize;
+    u_int8_t		v_linbluefieldpos;
+    u_int8_t		v_linresmasksize;
+    u_int8_t		v_linresfieldpos;
+    u_int32_t		v_maxpixelclock;
+    u_int8_t		v_reserved1[190];
+} __packed;
 
 #ifdef _KERNEL
 

From 14c436e101db34985383616c8f813ab2be1eecb9 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 23 Oct 2009 18:44:53 +0000
Subject: [PATCH 313/646] Correct some issues with zfs boot.

 - Teach it to read gang blocks. (essentially untested)
   If you see "ZFS: gang block detected!", please let
   me know, so we can either remove the printf if it
   works, or fix it if it doesn't.

 - If multiple partitions exist on a disk, probe them all.
   We also need to reset dsk->start to 0 to read the right
   sector here.

 - With GPT, we can have 128 partitions.

 - If the bootfs property has ever been set on a pool
   it seems that it never goes away.  zpool won't allow
   you to add to the pool with the bootfs property set.
   However, if you clear the property back to default
   we end up getting 0 for the object number and read
   a bogus block pointer and fail to boot.

 - Fix some error printfs. The printf in the loader is
   only capable of c,s and u formats.

 - Teach printf how to display %llu

Reviewed by:	dfr, jhb
MFC after:	2 weeks
---
 sys/boot/i386/zfsboot/zfsboot.c | 23 +++++++++--
 sys/boot/zfs/zfs.c              |  4 +-
 sys/boot/zfs/zfsimpl.c          | 71 +++++++++++++++++++++++++--------
 sys/cddl/boot/zfs/zfsimpl.h     | 18 +++++++++
 4 files changed, 93 insertions(+), 23 deletions(-)

diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c
index a654393f184..c0dedd7cc86 100644
--- a/sys/boot/i386/zfsboot/zfsboot.c
+++ b/sys/boot/i386/zfsboot/zfsboot.c
@@ -474,6 +474,7 @@ probe_drive(struct dsk *dsk, spa_t **spap)
     slba = hdr.hdr_lba_table;
     elba = slba + hdr.hdr_entries / entries_per_sec;
     while (slba < elba) {
+	dsk->start = 0;
 	if (drvread(dsk, sec, slba, 1))
 	    return;
 	for (part = 0; part < entries_per_sec; part++) {
@@ -494,7 +495,6 @@ probe_drive(struct dsk *dsk, spa_t **spap)
 		     */
 		    dsk = copy_dsk(dsk);
 		}
-		break;
 	    }
 	}
 	slba++;
@@ -857,12 +857,13 @@ static void
 printf(const char *fmt,...)
 {
     va_list ap;
-    char buf[10];
+    char buf[20];
     char *s;
-    unsigned u;
+    unsigned long long u;
     int c;
     int minus;
     int prec;
+    int l;
     int len;
     int pad;
 
@@ -871,6 +872,7 @@ printf(const char *fmt,...)
 	if (c == '%') {
 	    minus = 0;
 	    prec = 0;
+	    l = 0;
 	nextfmt:
 	    c = *fmt++;
 	    switch (c) {
@@ -892,6 +894,9 @@ printf(const char *fmt,...)
 	    case 'c':
 		putchar(va_arg(ap, int));
 		continue;
+	    case 'l':
+		l++;
+		goto nextfmt;
 	    case 's':
 		s = va_arg(ap, char *);
 		if (prec) {
@@ -914,7 +919,17 @@ printf(const char *fmt,...)
 		}
 		continue;
 	    case 'u':
-		u = va_arg(ap, unsigned);
+		switch (l) {
+		case 2:
+		    u = va_arg(ap, unsigned long long);
+		    break;
+		case 1:
+		    u = va_arg(ap, unsigned long);
+		    break;
+		default:
+		    u = va_arg(ap, unsigned);
+		    break;
+		}
 		s = buf;
 		do
 		    *s++ = '0' + u % 10U;
diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c
index 9784ef97d50..52df7738ff3 100644
--- a/sys/boot/zfs/zfs.c
+++ b/sys/boot/zfs/zfs.c
@@ -100,7 +100,7 @@ zfs_open(const char *upath, struct open_file *f)
 	f->f_fsdata = (void *)fp;
 
 	if (spa->spa_root_objset.os_type != DMU_OST_ZFS) {
-		printf("Unexpected object set type %lld\n",
+		printf("Unexpected object set type %llu\n",
 		    spa->spa_root_objset.os_type);
 		rc = EIO;
 		goto out;
@@ -413,7 +413,7 @@ zfs_dev_init(void)
 		if (vdev_probe(vdev_read, (void*) (uintptr_t) fd, 0))
 			close(fd);
 
-		for (slice = 1; slice <= 4; slice++) {
+		for (slice = 1; slice <= 128; slice++) {
 			sprintf(devname, "disk%dp%d:", unit, slice);
 			fd = open(devname, O_RDONLY);
 			if (fd == -1) {
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index ff567a462ef..497fd7c94be 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -53,6 +53,8 @@ static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr;
 
 #define TEMP_SIZE	(1*SPA_MAXBLOCKSIZE)
 
+static int zio_read(spa_t *spa, const blkptr_t *bp, void *buf);
+
 static void
 zfs_init(void)
 {
@@ -896,6 +898,33 @@ ilog2(int n)
 	return -1;
 }
 
+static int
+zio_read_gang(spa_t *spa, const blkptr_t *bp, const dva_t *dva, void *buf)
+{
+	zio_gbh_phys_t zio_gb;
+	vdev_t *vdev;
+	int vdevid;
+	off_t offset;
+	int i;
+
+	vdevid = DVA_GET_VDEV(dva);
+	offset = DVA_GET_OFFSET(dva);
+	STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink)
+		if (vdev->v_id == vdevid)
+			break;
+	if (!vdev || !vdev->v_read)
+		return (EIO);
+	if (vdev->v_read(vdev, bp, &zio_gb, offset, SPA_GANGBLOCKSIZE))
+		return (EIO);
+
+	for (i = 0; i < SPA_GBH_NBLKPTRS; i++) {
+		if (zio_read(spa, &zio_gb.zg_blkptr[i], buf))
+			return (EIO);
+	}
+ 
+	return (0);
+}
+
 static int
 zio_read(spa_t *spa, const blkptr_t *bp, void *buf)
 {
@@ -920,20 +949,27 @@ zio_read(spa_t *spa, const blkptr_t *bp, void *buf)
 		if (!dva->dva_word[0] && !dva->dva_word[1])
 			continue;
 
-		vdevid = DVA_GET_VDEV(dva);
-		offset = DVA_GET_OFFSET(dva);
-		STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink)
-			if (vdev->v_id == vdevid)
-				break;
-		if (!vdev || !vdev->v_read)
-			continue;
-		if (vdev->v_read(vdev, bp, pbuf, offset, psize))
-			continue;
+		if (DVA_GET_GANG(dva)) {
+			printf("ZFS: gang block detected!\n");
+			if (zio_read_gang(spa, bp, dva, buf))
+				return (EIO); 
+		} else {
+			vdevid = DVA_GET_VDEV(dva);
+			offset = DVA_GET_OFFSET(dva);
+			STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink)
+				if (vdev->v_id == vdevid)
+					break;
+			if (!vdev || !vdev->v_read) {
+				continue;
+			}
+			if (vdev->v_read(vdev, bp, pbuf, offset, psize))
+				continue;
 
-		if (cpfunc != ZIO_COMPRESS_OFF) {
-			if (zio_decompress_data(cpfunc, pbuf, psize,
-				buf, lsize))
-				return (EIO);
+			if (cpfunc != ZIO_COMPRESS_OFF) {
+				if (zio_decompress_data(cpfunc, pbuf, psize,
+				    buf, lsize))
+					return (EIO);
+			}
 		}
 
 		return (0);
@@ -1331,13 +1367,13 @@ zfs_mount_dataset(spa_t *spa, uint64_t objnum, objset_phys_t *objset)
 	dsl_dataset_phys_t *ds;
 
 	if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
-		printf("ZFS: can't find dataset %lld\n", objnum);
+		printf("ZFS: can't find dataset %llu\n", objnum);
 		return (EIO);
 	}
 
 	ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
 	if (zio_read(spa, &ds->ds_bp, objset)) {
-		printf("ZFS: can't read object set for dataset %lld\n", objnum);
+		printf("ZFS: can't read object set for dataset %llu\n", objnum);
 		return (EIO);
 	}
 
@@ -1367,7 +1403,8 @@ zfs_mount_root(spa_t *spa, objset_phys_t *objset)
 	 */
 	if (zap_lookup(spa, &dir, DMU_POOL_PROPS, &props) == 0
 	     && objset_get_dnode(spa, &spa->spa_mos, props, &propdir) == 0
-	     && zap_lookup(spa, &propdir, "bootfs", &bootfs) == 0)
+	     && zap_lookup(spa, &propdir, "bootfs", &bootfs) == 0
+	     && bootfs != 0)
 		return zfs_mount_dataset(spa, bootfs, objset);
 
 	/*
@@ -1425,7 +1462,7 @@ zfs_lookup(spa_t *spa, const char *upath, dnode_phys_t *dnode)
 	int symlinks_followed = 0;
 
 	if (spa->spa_root_objset.os_type != DMU_OST_ZFS) {
-		printf("ZFS: unexpected object set type %lld\n",
+		printf("ZFS: unexpected object set type %llu\n",
 		       spa->spa_root_objset.os_type);
 		return (EIO);
 	}
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index a0b7b72c929..688bb5c6203 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -374,6 +374,24 @@ typedef struct vdev_label {
 #define	VDEV_LABEL_END_SIZE	(2 * sizeof (vdev_label_t))
 #define	VDEV_LABELS		4
 
+/*
+ * Gang block headers are self-checksumming and contain an array
+ * of block pointers.
+ */
+#define SPA_GANGBLOCKSIZE	SPA_MINBLOCKSIZE
+#define SPA_GBH_NBLKPTRS	((SPA_GANGBLOCKSIZE - \
+	sizeof (zio_block_tail_t)) / sizeof (blkptr_t))
+#define SPA_GBH_FILLER		((SPA_GANGBLOCKSIZE - \
+	sizeof (zio_block_tail_t) - \
+	(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
+	sizeof (uint64_t))
+
+typedef struct zio_gbh {
+	blkptr_t		zg_blkptr[SPA_GBH_NBLKPTRS];
+	uint64_t		zg_filler[SPA_GBH_FILLER];
+	zio_block_tail_t	zg_tail;
+} zio_gbh_phys_t;
+
 enum zio_checksum {
 	ZIO_CHECKSUM_INHERIT = 0,
 	ZIO_CHECKSUM_ON,

From 974f3534c04b35c7f32082a93199490ef18408f5 Mon Sep 17 00:00:00 2001
From: Jung-uk Kim 
Date: Fri, 23 Oct 2009 18:53:21 +0000
Subject: [PATCH 314/646] Search for default 800x600 graphics mode from
 supported VESA mode list. Many video controllers do not support 800x600x24
 mode any more.

---
 sys/dev/syscons/syscons.c | 64 ++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 18 deletions(-)

diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index d158f85332e..9ea8a6b9fe6 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -343,17 +343,46 @@ sc_alloc_tty(int index, int devnum)
 	return (tp);
 }
 
+#ifdef SC_PIXEL_MODE
+static int
+sc_initial_mode(video_adapter_t *adp, int unit)
+{
+	video_info_t info;
+	int depth, vmode;
+	int i;
+
+	vmode = 0;
+	(void)resource_int_value("sc", unit, "vesa_mode", &vmode);
+	if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX)
+	    vmode = 0;
+
+	/*
+	 * If the default mode is not supported, search for an available
+	 * 800x600 graphics mode with the highest color depth.
+	 */
+	if (vmode == 0 || vidd_get_info(adp, vmode, &info) != 0) {
+	    depth = vmode = 0;
+	    for (i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
+		if (vidd_get_info(adp, i, &info) == 0 &&
+		    (info.vi_flags & V_INFO_GRAPHICS) != 0 &&
+		    info.vi_width == 800 && info.vi_height == 600 &&
+		    info.vi_depth > depth) {
+			vmode = i;
+			depth = info.vi_depth;
+		}
+	}
+
+	return (vmode);
+}
+#endif
+
 int
 sc_attach_unit(int unit, int flags)
 {
     sc_softc_t *sc;
     scr_stat *scp;
-#ifdef SC_PIXEL_MODE
-    video_info_t info;
-#endif
     int vc;
     struct cdev *dev;
-    unsigned int vmode = 0;
 
     flags &= ~SC_KERNEL_CONSOLE;
 
@@ -374,25 +403,24 @@ sc_attach_unit(int unit, int flags)
     if (sc_console == NULL)	/* sc_console_unit < 0 */
 	sc_console = scp;
 
-    (void)resource_int_value("sc", unit, "vesa_mode", &vmode);
-    if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX)
-	vmode = M_VESA_FULL_800;
-
 #ifdef SC_PIXEL_MODE
-    if ((sc->config & SC_VESAMODE)
-	&& (vidd_get_info(sc->adp, vmode, &info) == 0)) {
+    if ((sc->config & SC_VESAMODE) != 0) {
+	int vmode;
+	vmode = sc_initial_mode(sc->adp, unit);
+	if (vmode >= M_VESA_BASE) {
 #ifdef DEV_SPLASH
-	if (sc->flags & SC_SPLASH_SCRN)
-	    splash_term(sc->adp);
+	    if (sc->flags & SC_SPLASH_SCRN)
+		splash_term(sc->adp);
 #endif
-	sc_set_graphics_mode(scp, NULL, vmode);
-	sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
-	sc->initial_mode = vmode;
+	    sc_set_graphics_mode(scp, NULL, vmode);
+	    sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
+	    sc->initial_mode = vmode;
 #ifdef DEV_SPLASH
-	/* put up the splash again! */
-	if (sc->flags & SC_SPLASH_SCRN)
-    	    splash_init(sc->adp, scsplash_callback, sc);
+	    /* put up the splash again! */
+	    if (sc->flags & SC_SPLASH_SCRN)
+		splash_init(sc->adp, scsplash_callback, sc);
 #endif
+	}
     }
 #endif /* SC_PIXEL_MODE */
 

From 1d9fd1477c4bc922565118cb9ab3210d74711972 Mon Sep 17 00:00:00 2001
From: Jung-uk Kim 
Date: Fri, 23 Oct 2009 18:57:52 +0000
Subject: [PATCH 315/646] Try hiding annoying text cursor after the video
 controller is reset.

---
 sys/amd64/acpica/acpi_wakecode.S | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sys/amd64/acpica/acpi_wakecode.S b/sys/amd64/acpica/acpi_wakecode.S
index 1372cc1a2d0..94a34f782de 100644
--- a/sys/amd64/acpica/acpi_wakecode.S
+++ b/sys/amd64/acpica/acpi_wakecode.S
@@ -88,6 +88,11 @@ wakeup_start:
 	movb	$0, reset_video - wakeup_start
 	lcall	$0xc000, $3
 
+	/* When we reach here, int 0x10 should be ready.  Hide cursor. */
+	movb	$0x01, %ah
+	movb	$0x20, %ch
+	int	$0x10
+
 	/* Re-start in case the previous BIOS call clobbers them. */
 	jmp	wakeup_start
 1:

From 9871fde43f6978379803dad64d70f0a8d919023b Mon Sep 17 00:00:00 2001
From: Jung-uk Kim 
Date: Fri, 23 Oct 2009 19:02:53 +0000
Subject: [PATCH 316/646] Remove a redundant byte swapping in the previous
 commit.

---
 sys/dev/fb/vesa.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 728230c37c8..22213012440 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -890,7 +890,6 @@ vesa_bios_init(void)
 		vmode.v_lfb = le32toh(vmode.v_lfb);
 		vmode.v_offscreen = le32toh(vmode.v_offscreen);
 		vmode.v_offscreensize = le16toh(vmode.v_offscreensize);
-		vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock);
 		vmode.v_linbpscanline = le16toh(vmode.v_linbpscanline);
 		vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock);
 

From 27acd6ea1f2174a29442b76a61167f898d533b81 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 23 Oct 2009 21:33:26 +0000
Subject: [PATCH 317/646] Reimplement device reset sequence in more
 controller-specific way.

---
 sys/dev/siis/siis.c | 72 +++++++++++++++++++++------------------------
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 207713722d0..0529f2a480c 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -80,7 +80,6 @@ static void siis_portinit(device_t dev);
 static int siis_wait_ready(device_t dev, int t);
 
 static int siis_sata_connect(struct siis_channel *ch);
-static int siis_sata_phy_reset(device_t dev);
 
 static void siis_issue_read_log(device_t dev);
 static void siis_process_read_log(device_t dev, union ccb *ccb);
@@ -1250,16 +1249,27 @@ siis_portinit(device_t dev)
 	siis_wait_ready(dev, 1000);
 }
 
-#if 0
-static void
+static int
 siis_devreset(device_t dev)
 {
 	struct siis_channel *ch = device_get_softc(dev);
+	int timeout = 0;
+	uint32_t val;
 
 	ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_DEV_RESET);
-	siis_wait_ready(dev, 1000);
+	while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) &
+	    SIIS_P_CTL_DEV_RESET) != 0) {
+		DELAY(1000);
+		if (timeout++ > 100) {
+			device_printf(dev, "device reset stuck (timeout %dms) "
+			    "status = %08x\n", timeout, val);
+			return (EBUSY);
+		}
+	}
+	if (bootverbose)
+		device_printf(dev, "device reset time=%dms\n", timeout);
+	return (0);
 }
-#endif
 
 static int
 siis_wait_ready(device_t dev, int t)
@@ -1287,6 +1297,7 @@ siis_reset(device_t dev)
 {
 	struct siis_channel *ch = device_get_softc(dev);
 	int i;
+	uint32_t val;
 
 	if (bootverbose)
 		device_printf(dev, "SIIS reset...\n");
@@ -1303,10 +1314,7 @@ siis_reset(device_t dev)
 		}
 		xpt_done(fccb);
 	}
-	/* Disable port interrupts */
-	ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF);
-	/* Kill the engine and requeue all running commands. */
-	siis_portinit(dev);
+	/* Requeue all running commands. */
 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
 		/* Do we have a running request on slot? */
 		if (ch->slot[i].state < SIIS_SLOT_RUNNING)
@@ -1314,8 +1322,23 @@ siis_reset(device_t dev)
 		/* XXX; Commands in loading state. */
 		siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT);
 	}
+	/* Disable port interrupts */
+	ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF);
+	/* Set speed limit. */
+	if (ch->sata_rev == 1)
+		val = ATA_SC_SPD_SPEED_GEN1;
+	else if (ch->sata_rev == 2)
+		val = ATA_SC_SPD_SPEED_GEN2;
+	else if (ch->sata_rev == 3)
+		val = ATA_SC_SPD_SPEED_GEN3;
+	else
+		val = 0;
+	ATA_OUTL(ch->r_mem, SIIS_P_SCTL,
+	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
+	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
+	siis_devreset(dev);
 	/* Reset and reconnect PHY, */
-	if (!siis_sata_phy_reset(dev)) {
+	if (!siis_sata_connect(ch)) {
 		ch->devices = 0;
 		/* Enable port interrupts */
 		ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED);
@@ -1327,9 +1350,8 @@ siis_reset(device_t dev)
 		return;
 	}
 	/* Wait for clearing busy status. */
-	if (siis_wait_ready(dev, 10000)) {
+	if (siis_wait_ready(dev, 10000))
 		device_printf(dev, "device ready timeout\n");
-	}
 	ch->devices = 1;
 	/* Enable port interrupts */
 	ATA_OUTL(ch->r_mem, SIIS_P_IS, 0xFFFFFFFF);
@@ -1420,32 +1442,6 @@ siis_sata_connect(struct siis_channel *ch)
 	return (1);
 }
 
-static int
-siis_sata_phy_reset(device_t dev)
-{
-	struct siis_channel *ch = device_get_softc(dev);
-	uint32_t val;
-
-	if (bootverbose)
-		device_printf(dev, "hardware reset ...\n");
-	ATA_OUTL(ch->r_mem, SIIS_P_SCTL, ATA_SC_IPM_DIS_PARTIAL |
-	    ATA_SC_IPM_DIS_SLUMBER | ATA_SC_DET_RESET);
-	DELAY(50000);
-	if (ch->sata_rev == 1)
-		val = ATA_SC_SPD_SPEED_GEN1;
-	else if (ch->sata_rev == 2)
-		val = ATA_SC_SPD_SPEED_GEN2;
-	else if (ch->sata_rev == 3)
-		val = ATA_SC_SPD_SPEED_GEN3;
-	else
-		val = 0;
-	ATA_OUTL(ch->r_mem, SIIS_P_SCTL,
-	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
-	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
-	DELAY(50000);
-	return (siis_sata_connect(ch));
-}
-
 static void
 siisaction(struct cam_sim *sim, union ccb *ccb)
 {

From dab90f68edd7c8d89e8dbcb395ca55e533fadc28 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Fri, 23 Oct 2009 21:36:33 +0000
Subject: [PATCH 318/646] Add some more paranoia to setting HID registers, and
 update the AIM clock routines to work better with SMP. This makes SMP work
 fully and stably on an Xserve G5.

Obtained from:	Book-E (clock bits)
---
 sys/powerpc/aim/clock.c     | 17 +++++++++++------
 sys/powerpc/aim/machdep.c   |  2 ++
 sys/powerpc/aim/mp_cpudep.c | 20 ++++++++++++++------
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c
index 0a5391f7424..a60878c83c5 100644
--- a/sys/powerpc/aim/clock.c
+++ b/sys/powerpc/aim/clock.c
@@ -95,8 +95,7 @@ static struct timecounter	decr_timecounter = {
 void
 decr_intr(struct trapframe *frame)
 {
-	long		tick;
-	int		nticks;
+	int32_t		tick, nticks;
 
 	/*
 	 * Check whether we are initialized.
@@ -112,13 +111,17 @@ decr_intr(struct trapframe *frame)
 	for (nticks = 0; tick < 0; nticks++)
 		tick += ticks_per_intr;
 	mtdec(tick);
+if (nticks > 5) printf("BIG NTICKS on CPU %d: %x\n",PCPU_GET(cpuid),nticks);
 
-	if (PCPU_GET(cpuid) == 0) {
-		while (nticks-- > 0)
+	while (nticks-- > 0) {
+		if (PCPU_GET(cpuid) == 0)
 			hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-	} else {
-		while (nticks-- > 0)
+		else
 			hardclock_cpu(TRAPF_USERMODE(frame));
+
+		statclock(TRAPF_USERMODE(frame));
+		if (profprocs != 0)
+			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	}
 }
 
@@ -145,6 +148,8 @@ decr_init(void)
 	ticks_per_intr = ticks_per_sec / hz;
 	mtdec(ticks_per_intr);
 
+	set_cputicker(mftb, ticks_per_sec, 0);
+
 	mtmsr(msr);
 }
 
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index 339e64abfd8..da73dfab3ff 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -885,6 +885,8 @@ cpu_initclocks(void)
 {
 
 	decr_tc_init();
+	stathz = hz;
+	profhz = hz;
 }
 
 /*
diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c
index 52f8542ac78..50f64d79441 100644
--- a/sys/powerpc/aim/mp_cpudep.c
+++ b/sys/powerpc/aim/mp_cpudep.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
 
 void *ap_pcpu;
 
-static register_t bsp_state[8];
+static register_t bsp_state[8] __aligned(8);
 
 static void cpudep_save_config(void *dummy);
 SYSINIT(cpu_save_config, SI_SUB_CPU, SI_ORDER_ANY, cpudep_save_config, NULL);
@@ -184,6 +184,8 @@ cpudep_save_config(void *dummy)
 		__asm __volatile ("mfspr %0,%2; mr %1,%0; srdi %0,%0,32"
 		    : "=r" (bsp_state[6]),"=r" (bsp_state[7]) : "K" (SPR_HID5));
 
+		powerpc_sync();
+
 		break;
 	case MPC7450:
 	case MPC7455:
@@ -224,17 +226,23 @@ cpudep_ap_setup()
 		 * See Table 2-3, 970MP manual
 		 */
 
+		__asm __volatile("mtasr %0; sync" :: "r"(0));
 		__asm __volatile(" \
 			ld	%0,0(%2);				\
+			sync; isync;					\
 			mtspr	%1, %0;					\
 			mfspr	%0, %1;	mfspr	%0, %1;	mfspr	%0, %1;	\
-			mfspr	%0, %1;	mfspr	%0, %1;	mfspr	%0, %1;"
+			mfspr	%0, %1;	mfspr	%0, %1;	mfspr	%0, %1; \
+			sync; isync" 
 		    : "=r"(reg) : "K"(SPR_HID0), "r"(bsp_state));
-		__asm __volatile("ld %0, 8(%2); mtspr %1, %0; mtspr %1, %0; \
-		    isync" : "=r"(reg) : "K"(SPR_HID1), "r"(bsp_state));
-		__asm __volatile("ld %0, 16(%2); sync; mtspr %1, %0; isync;"
+		__asm __volatile("ld %0, 8(%2); sync; isync;	\
+		    mtspr %1, %0; mtspr %1, %0; sync; isync"
+		    : "=r"(reg) : "K"(SPR_HID1), "r"(bsp_state));
+		__asm __volatile("ld %0, 16(%2); sync; isync;	\
+		    mtspr %1, %0; sync; isync;"
 		    : "=r"(reg) : "K"(SPR_HID4), "r"(bsp_state));
-		__asm __volatile("ld %0, 24(%2); sync; mtspr %1, %0; isync;"
+		__asm __volatile("ld %0, 24(%2); sync; isync;	\
+		    mtspr %1, %0; sync; isync;"
 		    : "=r"(reg) : "K"(SPR_HID5), "r"(bsp_state));
 
 		powerpc_sync();

From 4c1826ad5dfc145336e98ac83faef1dbdfe0694d Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Fri, 23 Oct 2009 21:44:46 +0000
Subject: [PATCH 319/646] Remove debugging printf that snuck in here.

Pointy hat to:	me
---
 sys/powerpc/aim/clock.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c
index a60878c83c5..b182b01f32d 100644
--- a/sys/powerpc/aim/clock.c
+++ b/sys/powerpc/aim/clock.c
@@ -111,7 +111,6 @@ decr_intr(struct trapframe *frame)
 	for (nticks = 0; tick < 0; nticks++)
 		tick += ticks_per_intr;
 	mtdec(tick);
-if (nticks > 5) printf("BIG NTICKS on CPU %d: %x\n",PCPU_GET(cpuid),nticks);
 
 	while (nticks-- > 0) {
 		if (PCPU_GET(cpuid) == 0)

From 8f30200753b6aa4b9a861e646c54ef4a0ca6f7cd Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Fri, 23 Oct 2009 22:04:18 +0000
Subject: [PATCH 320/646] Updated iwn(4) driver supporting the newer series,
 5000, 5150 and 5300.

Submitted by:	Bernhard Schmidt 
---
 sys/contrib/dev/iwn/LICENSE                   |   78 +-
 .../dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu    | 3336 +++++++++
 .../dev/iwn/iwlwifi-4965-4.44.17.fw.uu        | 3398 ---------
 .../dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu       | 6094 +++++++++++++++++
 .../dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu       | 5961 ++++++++++++++++
 sys/dev/iwn/if_iwn.c                          | 5822 +++++++++-------
 sys/dev/iwn/if_iwnreg.h                       | 1359 ++--
 sys/dev/iwn/if_iwnvar.h                       |  155 +-
 sys/modules/iwnfw/Makefile                    |   20 +-
 9 files changed, 20061 insertions(+), 6162 deletions(-)
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu
 delete mode 100644 sys/contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu

diff --git a/sys/contrib/dev/iwn/LICENSE b/sys/contrib/dev/iwn/LICENSE
index e86fd692257..74a3f7e5308 100644
--- a/sys/contrib/dev/iwn/LICENSE
+++ b/sys/contrib/dev/iwn/LICENSE
@@ -1,39 +1,39 @@
-Copyright (c) 2006, Intel Corporation.
-All rights reserved.
-
-Redistribution.  Redistribution and use in binary form, without 
-modification, are permitted provided that the following conditions are 
-met:
-
-* Redistributions must reproduce the above copyright notice and the 
-  following disclaimer in the documentation and/or other materials 
-  provided with the distribution. 
-* Neither the name of Intel Corporation nor the names of its suppliers 
-  may be used to endorse or promote products derived from this software 
-  without specific prior written permission. 
-* No reverse engineering, decompilation, or disassembly of this software 
-  is permitted.
-
-Limited patent license.  Intel Corporation grants a world-wide, 
-royalty-free, non-exclusive license under patents it now or hereafter 
-owns or controls to make, have made, use, import, offer to sell and 
-sell ("Utilize") this software, but solely to the extent that any 
-such patent is necessary to Utilize the software alone, or in 
-combination with an operating system licensed under an approved Open 
-Source license as listed by the Open Source Initiative at 
-http://opensource.org/licenses.  The patent license shall not apply to 
-any other combinations which include this software.  No hardware per 
-se is licensed hereunder.
-
-DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
-COPYRIGHT OWNER 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.
+Copyright (c) 2006-2009, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without 
+modification, are permitted provided that the following conditions are 
+met:
+
+* Redistributions must reproduce the above copyright notice and the 
+  following disclaimer in the documentation and/or other materials 
+  provided with the distribution. 
+* Neither the name of Intel Corporation nor the names of its suppliers 
+  may be used to endorse or promote products derived from this software 
+  without specific prior written permission. 
+* No reverse engineering, decompilation, or disassembly of this software 
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide, 
+royalty-free, non-exclusive license under patents it now or hereafter 
+owns or controls to make, have made, use, import, offer to sell and 
+sell ("Utilize") this software, but solely to the extent that any 
+such patent is necessary to Utilize the software alone, or in 
+combination with an operating system licensed under an approved Open 
+Source license as listed by the Open Source Initiative at 
+http://opensource.org/licenses.  The patent license shall not apply to 
+any other combinations which include this software.  No hardware per 
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
+COPYRIGHT OWNER 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.
diff --git a/sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu b/sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu
new file mode 100644
index 00000000000..f378d11753d
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu
@@ -0,0 +1,3336 @@
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without 
+modification, are permitted provided that the following conditions are 
+met:
+
+* Redistributions must reproduce the above copyright notice and the 
+  following disclaimer in the documentation and/or other materials 
+  provided with the distribution. 
+* Neither the name of Intel Corporation nor the names of its suppliers 
+  may be used to endorse or promote products derived from this software 
+  without specific prior written permission. 
+* No reverse engineering, decompilation, or disassembly of this software 
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide, 
+royalty-free, non-exclusive license under patents it now or hereafter 
+owns or controls to make, have made, use, import, offer to sell and 
+sell ("Utilize") this software, but solely to the extent that any 
+such patent is necessary to Utilize the software alone, or in 
+combination with an operating system licensed under an approved Open 
+Source license as listed by the Open Source Initiative at 
+http://opensource.org/licenses.  The patent license shall not apply to 
+any other combinations which include this software.  No hardware per 
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-4965-228.57.2.23.fw.uu
+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
+IADJcIohxADPcKQAHEA2oCDYz3GkAAxCDKEU2A2hOdnPcKUAUA0wGECAz3A/AALBEKXPcGAAAswQ
+pc9wAQACyxClz3AIAAKJEKXPcHcAApAQpc9wxwACixClz3BfAAIYEKXPcAUAAhkQpc9wAwACwBCl
+z3AgAAJeEKXPcGMAAmUQpc9wBgACZhClz3ABAALYEKXPcGAAAtIQpcYO7/8KcBkCz/Zs8eB4ANoN
+8FR4Y4giiM9wrADUAQHiT3o1eIsY2IDPcIAA0BUgiDBy4CDKB+7x4HjxwOHFCHXPcYAAyAMFiYDg
+BPQEiYDgD/Lv/wfaANjPcawA1AHYGYCAgOXKIKEC0BkAgM0Bz/bgePHA4cUIdSGQQJDPcKMA2P1V
+eIoYWAAglSnYErjwIEEAAZUwcArycghv94og0QOKINEDZghv9yCFjQHP9vHA4cUIdSGQQJDPcKgA
+1ANVeAsYWIAglRXYE7jwIEEAAZUwcAryNghv94og0QOKINEDKghv9yCFUQHP9vHA4cUIdSGQQJDP
+cKwA1AFVeIsYWIAglSvYErjwIEEAAZUwcAry+g8v94og0QOKINED7g8v9yCFFQHP9vHA4cUIdQCQ
+z3KgAOwnCLhPIEEAAZUQuCV4z3GgAMQnEKEAlQi4RSDAABChKoIBlTBwC/KuDy/3iiDRA4og0QOi
+Dy/3IIXNAM/24HjPcawA1AEA2IsZGICMGRiAB9iNGRiABtmRuc9woADEJzCgz3EYAAcCMKDPcoAA
+dHs0ioDhBfTPcRAABgIwoCCCgOFR8gbZlrkwoM9xeAAChTCgz3ECAAKBMKDPcVUAAoIwoM9xEAAC
+hjCgz3FBAAKHMKDPcQcAAtMwoM9xAQACijCgz3EAAAKlMKDPcQAAAqYwoM9xAAACpzCgz3EGAAKo
+MKDPcQYAAqkwoM9xBgACqjCgz3H/AAfFMKDPcf8AB9swoM9x/wAHJjCgz3H/AAcjMKDPcRgAAh8w
+oM9xzAACHlfwB9mWuTCgz3EBAAKHMKDPcQMAAsUwoM9xgAAC2zCgz3FwAAKFMKDPcXAAAoEwoM9x
+BgAC0zCgz3EhAAKKMKDPcQUAAqUwoM9xBQACpjCgz3EFAAKnMKDPcQwAAqgwoM9xDAACqTCgz3EM
+AAKqMKDPcUQAAiYwoM9xRAACIzCgz3EoAAIWMKDPcZkAAhUwoM9x/wAHgjCgz3H/AAeGMKDPcf8A
+Bx8woM9x/wAHHjCg4H7gePHAuHDPcIAAdHsAEAQATCQAgADYDvLPcoAAHEQC8AHgjuBV9xYiAQAg
+ibBx+fUX8M9ygACMRAPwAeCm4Ef3FiIBACCJsHH69QnwCtgKIcAP63KeDK/2idsA2NHA4H7geM9y
+gAB0ezSKgOEBggf0NYqA4cIgogDAIKEAxPHPcIAAdHtAgCKAz3CAABxEgOI2eAPy4H8HiOB/dxCA
+APHAFg6P9s91gAAhEQCNgOAcAAIAz3AAAJBlCiQAcOB4qCAAAeB44HgB2ACtBtiQuM91oADEJxCl
+z3CAAHR7QIAigM93oADsJ89wgAAcRIDiBfI2eAbZlrkF8HDgNngH2Za5MKXPdgQAB7zPcRAAB7jQ
+pTClz3EKAAe8MKXPcT8AAsEwpSKIELkFIYEPAAACsjClIYgQuQUhgQ8AAAKzMKUliBC5BSGBDwAA
+ArQwpSSIELkFIYEPAAACtTClI4gQuQUhgQ8AAAK2MKUGiBC4BSCADwAAArcQpc9wBAAGvBClz3AB
+AAaxEKXPcAMABq4Qpc9wAQAGvBClz3ADAAYAEKXPcAgABrwQpc9wEAAGuBClz3AAAKAoCiQAcOB4
+qCAAAeB44HjPcCAABrwQpc9wAAAoCgokAHDgeKggAAHgeOB4z3AAAAPwEKUKh4QgAQ9BKJEAz3Ag
+AAe8EKXPcAAAA+8QpSgXEBAKJQAEhCUBCIwlAYgM8hHYCiHAD+tyiiPEB9IKr/YKJAAETCGAoVMg
+ACFN94/gyiBhBMAgYgAQuAUggA8AAALbEKXQpc0Ej/bgePHAcgyv9oohBgTPdaAAsB8YhX4Lj/wI
+dgzwCNgKIcAP63LH20okAAB6Cq/2CiUAAc9yAAAD8M9xoADEJ89woADsJ1ChCoDnuAj0GIXSCi/8
+yXGC4O714/GFBI/28cDhxc91gAB0ewClIaVUraoN7/91rcIN7/8CpaoL7/8Dpc9wgADIAwWIgOAH
+8soNz//d/1oK7/8UjVEEj/bgePHAiiBSDhYLL/dz2c9wgACMNEAggQUuCG/3FtoB2c9wgACoNNHA
+4H81qOB48cCiC4/2guAIdYz3BdgKIcAP63JP20okAADCCa/2uHPPdoAAjDQLhs9xgAC8NBB1BPSo
+YYDgO/JGCO//AdgacIogEg6qCi/3qXFELb4VACZAHiCQz3KkABxAMqIhkADfz3OkALRFMaIikCUb
+WIAjkCYbWIAkkM9zpACYQDiiJZAgoyaQIaMnkDuiKJA8oimQOaIqkM9wpACQQSmgDgjv/wpwq6a+
+ZjAewhNdA4/24HjxwOHFpsGKIJINNgov94TZi3B+Di/3BtkAFAAxgOAW9EAkgDDPdYAAjDSpcToP
+L/cW2s9wgACoNAHZNKgLhYDgyiAhAAwPwf8AFAAxgeAa9Iog0g3qCS/3ldlAJIAwz3WAAIw0QCWB
+Ff4OL/cW2s9xgACoNAHYFakrhYHh1A7B/+4ND/fpAq/2psDgePHAZgqP9hUSATbguZ4AAQBEIAAO
+Q7hKIAAgz3GgAMgc6IFTIA0ARCCBADx5PWVEIAABQrgdZa99AtnPcKAAyB9JGFiACt4KJIBz4Hio
+IAAB4HjgeIDlDfYF2AohwA/rcoojhAiYczoIr/YKJQAEz3GqAKxSgeUoyMj2gLgoGhgwAdhdGRiA
+B/CguCgaGDBdGRiECiSAc+B4qCAAAeB44HjPcKAAyB9IGNiDIQKP9uB48cAC2M9xgADANBWpFolU
+iUUgQAIWqROJEHIF8jYP7/8UqdHA4H7gePHAAtjPcYAAwDQVqRaJVImjuKG4gLgWqRGJEHIE8g4P
+7/8UqdHA4H7xwGYJj/bPcKAAsB8YgADdz3aAAMA0z3GgALAfUyBQBQLYFa44gY4IL/eKIBAKz3Cg
+ALAfGIDPd4AAwFUohm4fGBDPcIAANFcTgG8fWBAB4HAfGBAajrSmtaagpnMfGBChpqKmo6bPcIAA
+uDWsoK2gAdoTjlauRCAADnKOQ7hEIwMOQ7twcAT0BdpWrhJx0/eBulaux//PcIAANFcUgAHgcR8Y
+EM9woACwHziAiiDQCgjwyv/PcKAAsB84gIogUAzyD8/2BQGP9vHAngiP9s91gADANBqNIYUJIRAA
+TCAAoATyTCAAos73BdgKIcAP63KKI4wDCiQABKYOb/ZKJQAAANgLpQylTCAAoA2l1/cIcQhyCHMI
+dhJpFHgfZfqHAeH+Zh9l+4e4YByA+2MveRJxGmJNpbH3bKXLpQDYDqUPpRClSiTAcADZqCAAAhUl
+QhALggHhL3kRonEAj/bxwA4Ir/aYcM91gADANDCNANpVJUMUSiTAcKgggAMRIYCACPTPcP8A//8V
+JYwQEaQB4k96MoVRhTByE4XR9hByy/YQccX2AtoA2AHZF/AB2gDYAtkT8AHaAtgA2Q/wEHHK9hBy
+xfYA2QLaAdgH8AHYAtkE8ALYAdkA2vAjjgDwI0UAAiWPA/AjAwD0pQDYDyCAAAIjQwF1pc9zgAAU
+NQSrDyBAAAWr0Qdv9gAcggDgePHAXg9v9gDYocFgwM9xoACwHziBkg7v9oogEA2o/4twzP/PcYAA
+2DXYic9ygAC8Ns91gADANIDmVSVDFAP0GI0Q8CDA/o3wIwYAAYUFKP4DDCZAjjX2AdgYrQDeNBqC
+g4DmzCBhgBD0IMbwI48DYYXejQUrvgM3d8b2AtgYrQHbNBrCgIHgHPKC4BDyg+Ah8gXYCiHAD+ty
+iiMPDIokww/yDG/2uHMq8AGFXY0FKj4AFIU3cAT3WRWBEB3wGYmA4Pv1WBWAEDNoJXgRrRbwAYVd
+jQUqPgBUhQAhQH4QcjD3VYVQcFkVgRCF90UhAQ4xrQTwE2kleBGtGY2B4BHyguAU8oPgFfIF2Aoh
+wA/rcooj0AOKJMMPfgxv9rhzHvBYFYAQM2gleBnwWRWBEBPwAYU9jQUpPgBUhQAhQH4QclkVgRAJ
+91WFUHCF90UhAQ4yrQTwE2kleBKtE41EIAAOQ7iH4Af0WRWAEEUgAA4TrYogEA02De/2MY0SjREV
+hRAzjQUgQAEleEQgAA4QFYQQQ7gLJACACfQF2AohwA/rcvYLb/aKI9AHMo0RFYUQE40FIUEBJXhE
+IAAOEBWEEEO4BiA+gQryBdgKIcAP63LGC2/2iiMQCPEFb/ahwOB48cAD2M9xgADANBWpANgWqRGJ
+VIkQcgXyAgvv/xSp0cDgfuB48cBaDU/2z3aAAMA0IYYajs93oACwHxBxAN1H9xuOIoYQcUQABQA0
+hs9wgAAcNTIgUAB0/7SmtaagpqGmoqajps92gAC4NaymraY4h1oM7/aKIFAK4v84hza5ACEABMm4
+D6ZJ8DaOQIYcjqG5EHI2rpL3zf44hzIM7/aKIJAKz3CAADRXFIDPcYAAwFUB4HEZGAAe8BiHSIbV
+uFBwUveBuTauwf7PcIAANFcUgM9xgADAVQHgcRkYADiHiiDQCgbww/44h4ogUAzeC8/2GIfPcYAA
+wFVuGRgACIbPcoAANFdvGRgAE4IB4HAZGAAajnMZGADNBE/24HjxwG4Nb/YP2Iog0AeiC+/28dnP
+coAAwDQVioDgEvKD4A/0z3CgALAfOIBNEgAGNrkieMm4jCDHj8QKzf8C8LP/0cDgfvHAGgxP9gh2
+wLiB4EohQCDCIUIkyXeEJwEcRL/JcIQgDgBCKNABRCaBEzx5z3WAAMA0BCaAHwAAAAxKuBitBCaA
+HwAAADBMuBmtBCaAHwAAAEBOuM9ygAC8NlMhvoA1GgKAMK0N9AXYCiHAD+tyiiPIDYokww/iCW/2
+SiUAAEwhAKAy8hCNBCABBBJxDfIF2AohwA/rcoojiQCKJMMPuglv9kolAAAEIMAjEHcN8gXYCiHA
+D+tyiiPJAIokww+aCW/2SiUAAIDnVvQF2AohwA/rcoojCQGKJMMPfglv9kolAABK8BmNg+AD9oDg
+DfYF2AohwA/rcoojiQKKJMMPWglv9kolAAAZjTiNEHED9oDhDfYF2AohwA/rcoojSQOKJMMPNglv
+9kolAAAQjXiNUyABAEQgggBEIAABXHpZYUK4GWEveXBxRPY4rShzWY1QcUP2Oa0ocoLhR/YA2c9w
+gAC8NjUYQoBQcxWNBvSA4ATyBNgVrVWNgeLMIiKAzCIigQb0MI0TaSV4Eq0RrYDnzCIigQXyE28F
+f/GtCiAAhMwiIoEG8kAowSAleBKtEI0zaCV4E60RjQYI7/8Urc9wgAD8NLkCb/bPsPHAXgpP9s92
+gADANBWOgOAN8lILb/YP2ADdta62rifMhv/PcIAA/DSvsIogkAx2Ce/2iiGQD5UCT/bgePHAGgpP
+9gh2FsjPdYAAwDQluFMgEABaFQAREHZT8oogkAlGCe/2yXEVjQHf9a0Xrclwc//gvgX0FY2E4Ar0
+z3ECAgICIgnv9oogkAze/1bwF42A4ADZMfT1rc9zgAC4NSyjLaM2rfqt+60K2BytBd7drVDYHq0A
+2I64CaVMEoIwCqWE4swiYoEIpQPaz3CAABQ1SKgE2kmoSqjLqMyozagG2k6oT6hQqFGoCNpSqAza
+U6gy2BCjz3CAALw2NBhCgP39FY2A4Bry0MqQ4Bb0TCAAoBTyEI3PcoAAuDUzaCV4Eq0Rrc9woACw
+HziAThUAFja5OGAPour+hQFP9vHAHglv9oDYocFgwGnMAhwEMM9wgABkEQCAgODE9O4LT/+A4MD0
+z3CAAEgxAIDkuLr0iiAKDzYI7/Y0EgE29gmAAM91gACYe6lw9g3v9oohCw8Flc92gAAkEUQggAMc
+eFMgvoAE9AOGhrgDps9wgACUfs4N7/YY2S6Vz3eAANB+eLm+De/26XDPcIAAkH9AEIWATCUAgOem
+CvIF2AohwA/rcqnbsg4v9ookgw8HhuGIz3CAAEARQCeQEEAngR9MIICoL3kkqM33BdgKIcAP63Kw
+24okgw+CDi/2CiUABAeGz3GAAECBrgzv9gpyDpXPcoAAlIMAtgDbKvAAFgFAFSLMABocWJAAFg5B
+z3GAAJR/FCHMAOgchBMAFo5Az3eAAJB/dX/sH4KT7R+CkwAWjkB1ee4fgpPvH4KTABYOQQHjlBmc
+AwAWAEGVGRwAA40Qc6oHxf8OCIABtghv9g7YXglv/QTYNMjPcYAA7IAUoc9wgABkESCAz3WAAGgR
+AIUYuRC4BXmIueYOr/aKIIsAAdnPcIAAZBEgoADYAKWuD+/2AMAa8M9xgAD8NQSBAeAEoc9woADU
+AxyQWg/P9gDAjg/v9gLZDgigAALYiiBKD54Or/YA2a0HL/ahwOB4z3CAACQRKIjPcIAA/H8B3PAg
+QADgfwYkABDgePHA+f/PcoAAJBEoigK5FHnPcIAAvIAwYNHACrjgfwyi8cAGDy/2iiALAaLBz3GA
+AGgRz3YAAMgUYH4ggc91gAAkESOFUCEMAFAkzJEI8i8oQQA6CKAATiDAB8bw57kX8gmFgeAA3wb0
+IgigAALY6aUDhae4A6WKIEsAYH4A2QqFgOCy8kB46qWu8M9wgABoEQCAgOCd9OC5iPTa//YKb/sM
+hRpwA9juCm/7C7gIcQpwygpv+wraz3GAAJheUYHPcYAAIF1UeTGJgOEB2cB5gODMISKAUPLPcIAA
+SIA6kM9wgAAcEQCQEHEA2h/0z3CAAJh7JYAVEgM2UyEPAFMjBQCwdxP0z3CAAJh7A4iB4MQhgQ8A
+BgAAxCOBDwAGAADMIcGAyiJhABbIT6XPdYAAZBHluM9wgABoESCAAIUQuRi4BXkT8oDiEfRMyoPg
+DfSJuWB+iiCLAALYAKUA2M9xgABoEQChQPCFIQwAYH6KIIsAA9j08YDgDvSLcIILr/uBwc9woACw
+HxiAAcGKIAsIH/CKIIsIYH6KIYUJz3GAAAQWF4EB4BehIPAyDmAAAdiGDi/2DtjODy/9BNiCDkAA
+z3CAAOyANICKIMoPQH4M8AXYCiHAD+tyiiMGAUokgACCCy/2uHMB2KUFL/aiwPHAPg0v9oogSwHP
+dYAAaBHPdgAAyBRgfiCFz3KAACQRA4IEIL6PAACCACCFFfKA4bwJAvjPd4AAZBFAhyCFGLpAKQAE
+RXiIuAV5YH6KIIsAAdgAp23wgOEn9APIz3eAAGQRBCCAD////8MDGhgwiiDLAGB+ANkAhyCFGLgQ
+uQV5hSFIAGB+iiCLAALYAKcB3sClz3MBAARTAdgG2eoKIAEE2slwRvCB4R/0A9j6CG/7C7gA2doI
+b/sK2oDgE/QyCQ/4z3eAAGQRIIcAhRi5ELgFeYi5YH6KIIsAAdgApwDYAKUB2CbwguEY9IK4A6LP
+cYAA/DUGgc93gABkEQHgBqEghxi5iLmRuWB+iiCLAAHYAKcA2AClDvAF2AohwA/rcoojxwFKJIAA
+Sgov9rhzANh1BA/28cD2Cy/2iiCLAc9xgABoEc92AADIFGB+IIHPdYAAJBEDhQQgvo8AAIIAHPLP
+dYAAZBEAhc9xgABoESCBGLgQuQV5hSEYAGB+iiCLAAbYAKUA2c9wgABoESCg/wEgAChwA9gSCG/7
+C7gA2fIPL/sK2s9xgABoEYDgIIEI9M91gABkEQCFGLjd8YDh2/Qojc9wgACEgM93gACYewQXEBE1
+eDoQEQE4EBIBCiBAhEokQCAMFxMQHvJScEz3BdgKIcAP63KKI4cOCiQABXYJL/a4cwogwIQO8jJw
+DPcF2AohwA/rcoojBw9KJEAAVgkv9rhzDCIApEz3BdgKIcAP63KKIwgASiRAADoJL/a4cwogwIQO
+8lJwDPcF2AohwA/rcoojiABKJEAAGgkv9rhzD4WA4CiNHvQLhYDgGvTPcKAAsB9YGAAFz3CgAMgf
+vBAAAA2lz3CAAHyA9CBBAGB+iiBLBoogSwZgfi2FLB0AFUWHBocWGhgwBZcVGpgwKI3Pc4AAfIAn
+GhwwUyIAAPQjQQDmDW/2ANsIjc9xgAB8fxV5Bgvv9gqHiiBLB893gABkEWB+IIfCDG/3AdjmDkAA
+KI3PcIAA/H/wIEAA4LgN8s9woACwH1gYAAXPcKAAyB+8EAAABKUAh89xgABoESCBGLgQuQV5irlg
+foogiwAE2ACnANnPcIAAaBEgoCiNz3CAAHyA9CBBAGB+iiALBM9xoADIH0cRAQZgfoogCwQPhYDg
+B/SOCiABANh+DQ//AdgN8AXYCiHAD+tyiiOJAUokgADyD+/1uHMA2PUBD/bgePHArgkv9oogywHP
+d4AAaBHPdgAAyBRgfiCHz3WAACQRSI3PcYAA/H8SavAhggDgujfyAdlGeTR4z3GAALyAEGEKuAyl
+Og4v+ySFgOAp8oogSwhgfoohiQgGDs/3z3CAAGQRAIAghxi4ELkFeYUhFABgfoogiwAF2c9wgABk
+ESCgANgApwHaz3GgAMgfz3CgALAfVqC8EQAALQIgAA6lA4UEIL6PAACCAAv0ANhqDS/7jLgA2UoN
+L/sK2oDgCPTPdYAAZBEAhRi4IIfn8M9wgACYewOAqg0v+y2FgOAghzvyD4WA4Df0z3CAAGQRAIAQ
+uRi4BXmFIRgAYH6KIIsAz3CAAGQRBtkgoADYz3GAAPw1AKcAgQHgAKEojc9wgAB8gPQgQQBgfoog
+ywWKIMsFYH4shc9xoACoIC+BYH6KIMsFiiDLBWB+JIWKIMsFYH4thbrwgOE+9M4KQAAojc9wgAD8
+f/AgQABAh89xgABkESCB4LgQukApAwZlehDygLgFpQDYBqUIuSV6RSKBAWB+iiCLAAbYAKeY8AHY
+z3OgALAfz3GgAMgfFqO8EQAABKW8EQAATyIBAoq5DqVgfoogiwAF2c9wgABkESCgANgAp1PwhuFP
+9CWF4Lke8gaFegtAAM9wgABkEUCAIIdAKgAGELkFeQi6RXmAuWB+iiCLAAHYAKfPcIAAjHvmCc/3
+iiBLBADZLfCA4QjyLylBAE4hgAcGpd7xz3CAAGQRAIAYuIUgFABPIEEEkrlgfoogiwDPcIAAZBEF
+2SCgANgApwHYz3KgALAfFqLPcaAAyB+8EQAADqVHEQEGiiBLBEB+A/CB4QP0Adgp8ILhG/QDhc9y
+gAD8NYS4A6UHgs91gABkEQHgB6IAhRi4ELkFeYUhGABgfoogiwAG2AClANgApw3wBdgKIcAP63KK
+I8sHSiSAACYN7/W4cwDYUQfP9eB48cDeDs/1z3aAACQRA4YEIL6PAACCAADfC/QA2C4LL/uMuOlx
+Dgsv+wragOAV9M9wgABkEQCAz3aAAGgRIIYYuM91AADIFBC5BXmFIRgAcQMgAIogiwDPcIAAmHsD
+gFYLL/sthoDggvIPhoDgfvQMhs91AADIFAgggA8AAAEUmSAKADILL/skhkiOz3GAAHyAgOD0IYEA
+MfJgfYogSwaKIMsEYH0shs9xoACoIC+BYH2KIMsEiiDLBGB9JIaKIMsEYH0thiYLQADPcIAAQBHl
+qAiOz3KAAPw1AeAsgg94AeEsos9xgACYeyOJMHBCACsACK7/AQAAz3KAAPw1AIIB4ACiYH2KIMsF
+iiDLBWB9LIbPcaAAqCAvgWB9iiDLBYogywVgfSSGiiDLBWB9LYbPcIAAZBEAgM92gABoESCGGLgQ
+uQV5dQIgAIUhGACFIQwA2gxv9oogiwAD2c9wgABkESCgqXbgprrwygxAAM91gABoEYDgIIUv8kiO
+z3CAAISAVXgckAHbCrgMps9woACwH3agz3CgAMgfvBAAAOamBKbPcIAA/H/wIIAAELmAuAWmz3aA
+AGQRAIYYuAV5hSGQAWoMb/aKIIsABNgApgbYAKWE8IDhmfQojs9wgAD8f/AgQAAB2QZ5z3CAAJh7
+A5CA4APygOES8s92gABkESCGGLmFIVQBz3IAAMgUYHqKIIsABdgApgCl3PDPcIAAmHsCkAq4kgkv
++y6GgODS8s9ygADAVTeCFoIieCKCQ4JCeRlhz3CAAJh7A5AwcKwABQDeC2/2iiCLBM9xoACoIC+B
+zgtv9oogiwTPcYAA/DUBgQHgeglgAAGhCI4B4AiuT/3PcIAAQBHlqM9wgACYewOIKI4QcV4ACgC2
+CC/7DIYacAPYqggv+wu4CHEKcIoIL/sK2s92gABkEUCFYIaA4EAqAQQYu2V5DPKFIQwARXleC2/2
+iiCLAAPYAKYA2HvwhSEYAEV5Sgtv9oogiwAG2PXx+gpAAPTxz3aAAGQRAIYghRi4ELkFeX7xheFl
+9AyGpggv+ySGgOBc8oogywQSC2/2LIbPcaAAqCAvgQILb/aKIMsEughAAM9wgABAEeWoCI4ghQHg
+CK7PcIAAZBEAgBC5GLgFeYUhFADWCm/2iiCLAAXZz3CAAGQRIKDPcIAAmHsDiCiOEHF6B+r/4KUQ
+/c4P7/oMhhpwA9jGD+/6C7gIcQpwog/v+graz3GAAGQRIIFAhYDgGLkQuqgF4v9FeYUhGACpds91
+AADIFIogiwBAfQbZz3CAAGQRoQXv/yCgAdh1A8/1BdgKIcAP63KKIw8ISiSAADYJ7/W4c3jx4Hjx
+wPYK7/WKIEsCz3WAAGgRz3YAAMgUYH4ghQCFgOA39ADZz3CgANAPNaCKIAsHz3GAAGQRYH4ggW4P
+j/fPd4AAAF5Ah1MiAACWDu/+KZcBh+W4ANgC8gmXUgvAAIogywNgfimXz3CAAGQRAIAghUAoAgYQ
+uUV5CLgFeYK5YH6KIIsABNgApQHYdvCE4Gj0Eg7P/kIO7/UC2EYKD/bGC+/+AdjPcIAAFF76C4/2
+sgwv9wHYggjP9893gABkEYogSwdgfiCHiiALBGB+LhIBNwCHQIVAKAEGCLgQukV5BXlgfoogiwAA
+2AClFsjluCCHE/LPcIAAJBEPgIDgDfRMyoPgCfQYuYUhHABgfoogiwAH2CLwNg3P/s9wgACYewSA
+QIcghYDgGLoQuUV5C/LPcIAAJBEDgAQgvo8AAIMAB/KIuWB+iiCLAAHYBvCLuWB+iiCLAAjYAKcA
+2AClDvAF2AohwA/rcooj0QNKJIAAvg+v9bhzANjpAc/18cB+Ce/1iiCLAs92gABoEc91AADIFGB9
+IIYAhoDgRPTPcoAAJBFjgs93gABkEQCHBCO+jwAAggBAKAEGHPRPgoDiGPQIuAV5gLlgfYogiwAB
+3+Cmz3MBAARTANgG2WoPoAAE2oogCwVgfQDZ6XBa8OC7BPKIuUXwz3KAAJh7RIKA4gryi7lgfYog
+iwAI2ACnANgI8Ai4BXlgfYogiwAA2ACmQPCB4Bj0z3CAACQRA4AEIL6PAACCAMogYQAy8nINj/fP
+d4AAZBEAhyCGGLgQuQV50vGC4Br0z3GAACQRA4HPd4AAZBGFuAOhz3GAAPw1CIEB4AihIIcYuYi5
+kblgfYogiwAB2MXxBdgKIcAP63KKIxIGSiSAAJoOr/W4cwDYxQDP9fHAWgjv9YogywLPdYAAaBHP
+dgAAyBRgfiCFiiDLAs93gACYe2B+JIcAhYDgPvQEh89xAQD8UAbaTggv+wrbz3GAACQRAaHPcoAA
+/DUqgowgw48B4SqiDvQF2AohwA/rcoojkg5KJIAAJg6v9UolAADyCO/1Dtg+Cu/8BNguC8/+z3CA
+AGQRAIAghUAoAgYQuUV5CLgleEUgwQBgfoogiwAD2AClAdgq8IPgHPTPcYAA/DULgc93gABkEQHg
+C6Eghxi5iLmQuZG5YH6KIIsAAdgApwDZIKXPcIAAJBEroA3wBdgKIcAP63KKI9MDSiSAAJ4Nr/W4
+cwDYyQeP9fHAwgnP9dHA4H8A2PHA4cWjwQh1iiCLA44OL/apcc9wgAAsESCIARxCM89wgAB6gPQg
+QABgwQHaz3GgAMgfAxwCMADYAhwCMM9woACwH1agwBEAAELAvBEAAAzZQcCLcO4PL/aE2nEHr/Wj
+wPHA9g6P9c91gABkESCFz3aAAGgRAIYYuRC4BXkeDi/2iiCLAADZIKUgps9wgAAsESCoz3CAADAR
+IKDPcIAAUBEgoP/Zz3CAACgRGQev9SCg8cDhxQh1pg+v9Q7Y7gjv/ATYqXDP/+f/2gnP/oogCwDK
+DS/2qXH1Bo/14HjxwHIOr/WB2KHBYMBpzM91AADIFAIcBDCKIIsHYH1a2c92gABkEYogiwdgfSCG
+iiCLB893gABoEWB9IIcAhoDgAtgP8s9xgAAwEQCBgbgAoc9xgAD8NQOBAeADoQHYGnAAwD4Ob/YK
+cUwggKA68s9wgAAoEQCAjCDDjx3yiiALAGB9ednPcIAAKBEAiDIP7/oK2f/Zz3CAACgRIKAghgCH
+GLkQuAV5YH2KIIsAANgApgCnAIaA4AX0AIeA4AXybgjP/YDgDvKKIAsAYH2B2c9wgAAwEQCALygB
+AE4gwAe+//UFr/WhwOB48cDPcIAAQIFBiM9xgADQfu4Jb/YC4s9wgAAkESCQz3CAAJh70cDgfy6w
+4HjPcYAAZBEggQDYgOHgfIHh4HyI4eB84H8B2OB48cBKDY/1KHXPcYAAZBFAgYDiBvSA5eIgQgNA
+8M9xgABMEaChz3OAADARIIOI4oe5IKPPc4AA/DUigwHhIqPPcYAASBEAoSr0z3CAAGgRAICD4CT0
+iiALADYML/aKIQgGz3aAACgRAIaMIMOPDfQF2AohwA/rcoojSAZKJIAA/gqv9UolAAAAjgYO7/oK
+2f/YAKYC2IT/wPEdBY/18cDPcIAAZBEAgIDgCfLPcYAA/DUJgQHgCaEC2Hv/0cDgfuB48cDPcYAA
+ZBGKIAsGwgsv9iCBYg2v9Q7YBg6v/ATY/9nPcIAAKBHRwOB/IKDxwFoMj/XPcQEA4FPPcoAAjHsi
+os9zgAAwNmCiz3GAAGSBIaIggxzdoKEggs9zgAC0e89ygACQf2GhWCLDD2OhGNtioWGBmHEhg4Dg
+jbkhowj0WSIDBs9wgABAEWCgPfDPcYAAQBEggUQovgghiS9wQCGFAM9xgADLewlhLyVHAQDfz3OA
+AEQRAuEveaCLDvAAJ44fgAC0e/tjFuYOZgHnW2PvfwQbgoMwdwIlQxCy9lgiwA8bY89wgABAEWCg
+z3CAAJh7TpDPcIAAmHsCIkIBUHpZYS6wFBzAAM9wgACYey6Q4QOv9RAcQADgePHAcguP9aXBz3WA
+ACwRAI3PdoAAfID0JgEQngov9oogCwPPcIAAmHsFgAHbwLgNHAIwAI0A2vQmABDPcaAAyB9jwM9w
+oACwH3agwBEAAA4cgjBBwLwRAAAPHIIwQMASgUTDFNlCwItw9gsv9oLacQOv9aXA8cD+Co/1pMHP
+doAALBEAjs91gAB8gPQlARAqCi/2iiBLA89wgACYewWAAdrAuAEcAjAAjs9xoADIH/QlABBgwADY
+AhwCMAMcAjDPcKAAsB9WoMARAABCwLwRAABBwM9wgADAVTuAB4A4YEPAi3AQ2XoLL/aD2vUCr/Wk
+wPHAfgqP9c91gABoEQCFgeAM8gXYCiHAD+tyiiMEA0okAACSCK/1uHPPdoAAZBEAhoLgzCDigQ7y
+BdgKIcAP63KKI0QDSiQAAGoIr/W4cwCGz3GAAKRjJYHPdwAAyBTguS7yguAN9CCFELmIuYm5mblg
+f4ogiwAD2ACmANgs8FINj/7PcIAAMBEAgCCF4LgAhhC5GLgFeQj0z3CAAJh7BICA4Aj0iLlgf4og
+iwAB2Obxi7lgf4ogiwAI2ODxQIVAKAEGCLgQukV5BXmBuWB/iiCLAALYEQKv9QCl4HjxwKYJr/UB
+2c9wgABFESCoz3WAAGQRAIXPdoAAaBGE4AT0IIaB4Q7yBdgKIcAP63KKIwUESiQAAJ4Pb/W4cwCF
+z3GAAGSBJYFAKAIG4Lkghgi4ELlFeQV5HPLPdYAAPBEAhQDaz3OAADgRDyICAACDRSGBAUZ4AKNy
+CC/2iiCLAAbYAKaKIEsEYggv9iCFCfCBuVoIL/aKIIsAAtgApnUBj/XgePHAAgmP9c9xgAAwEQCB
+z3WAAGQRgLgAoc9xgAD8NQWBz3aAAGgRAeAFoSCFAIYYuRC4BXmFIRgADggv9oogiwAG2AClANgp
+Aa/1AKbxwM9wgACYe0SQgOIg8s9wgABFEQCIgOAa9M9wgAAsESCIz3CAAPx/8CBAAOC4EPTPcYAA
+wFUbgSeBGWEwcgj3ug/v9YogywcB2APwANjRwOB+4HjxwF4Ij/XPdoAAZBEAFgUQTCVAgor3BdgK
+IcAP63JU23IOb/VKJIAAz3eAALxFAIahhgi4IoYFfTB1CfIQuaV5Zg/v9YogSwWipgCG8CcAEEB4
+gODt83EAj/XgeM9xgABINgKhz3CAAKRjAaHPcoAAfIEAgWCCAIBgoCCBBGoBoVYiAAIDoRjYAqFW
+IsACBaEBggShIYEBgY24kLjgfwGh8cC6DEAAz3CAAEg28glP99HA4H7xwEzKhOAH9OILwAC6DQAA
+BPCB4FQIAQDRwOB+8cCSD0/1z3WAAHyBABYBQAAWAEBWJQ4SAKUEbQoLL/YP2clwhgwv9iKVHpXP
+cYAAdBHYYAChA8gFIIAPAAAAfAMaGDA2C0/1tQdP9fHA7f+2Cg/2z3ABAKhWNg/P/5YOQACA4Av0
+z3IBAHRWANiSDmAABdlyDmAABdjRwOB+4HjxwOHFz3WgAMgfuBUAEM9xnwDY/9W4DqE6D8//FRUA
+ls9xoADQG464HKE+DmAAANhVB0/18cDhxQHaz3GgAMgfz3CgALAfVqC8EQAAqcFGwMARAADPdYAA
+pGNHwAWF4LgI8ue4BvR2Dw/7kg9v9RDYi3GpcAoLL/YY2otwJNmCD+/1kNoC2c9wnwDY/y6g5g1A
+AIDgC/TPcgEAdFYA2OINYAAF2cINYAAF2N0Gb/WpwPHAXg5v9TDaz3GfANj/TqEqGhgwz3OgANQH
+z3KgABQECqIfEwCGAdk0GhgwGRMNhgPYEKIkog8TDoYAFg9AABYPQAAWAEHPd6AAmAPep0DgEHix
+cBb3DxMAhlYgAAIOoh0TA4YOoq27baIDyAUggA8AAAB8AxoYMAPIrLgDGhgwbgsv9wkaWDA9Bm/1
+ANjgePHAyg1P9cx3ABeQEACPAI8Aj0wgAKjN9gXYCiHAD+tyTNtKJEAA3gtv9QolAAQA3c9wgABs
+NkwgAKBIAC4Aq6DAj89wgACASdZ4AIDpuA3yBdgKIcAP63Ja20okAACmC2/1CiUAAc9wgABsNguA
+z3GAAGw2AeUSdQ8ggAMLoaL3xggP9qkFT/XPcoAAbDYsggDYgOEI9C+CgOEG9CaCgeHKIGIA4H8P
+ePHA4cVqCSAACHXPcYAARGclkYDhYAAMAIDgLvLPcIAAnF8siADaz3OAAGw2DoMPIkIACyCAgCD0
+jCECgBzyhCUDH4wlApAO8owlApQH8oogzw4eDO/1ndkO8A+DRXgPow2DRXgNo89wgACASTZ4IICo
+uSCgKQVP9fHArgxv9QDZSiTAd+B4qCCABwHdz3KAAIBJNnoAgs9zgABsNui4yiUhEADeDyZOEIDl
+7oME9MZ/7qMH8AsngJMD9Ki4AKIB4c0ET/VKJMB3ANqoIEAGANnPc4AAbDYOgw8hgQALIECADPQN
+gwsgQIAI9M9wgACASVZ4IICIuSCgAeLgfvHA4cXPdYAAbDYoFQUQTCXAgIv3BdgKIcAP63JJ20IK
+b/VKJIAAKoXPcIAA4EXwIEAAQHhtBE/18cD2C0/1CHXPdoAAbDaKIE8KKgvv9SqGCoYQdUX3gOXK
+JQIQAvSqpoogjwoOC+/1qXExBE/14HjPcIAAbDbgfwqA4HjxwIogTwvyCu/1iiHEBaoMb/UC2ADY
+6v/RwOB+8cD2/wDZguDMIGKAyiBCAAL0AdjRwOB/D3jgePHAz3CgANAbE4DPcaAAyB/uuAzyANiO
+uBUZGICKIA8Mngrv9YohhACKIA8Mkgrv9YohRAHyDw/30cDgfvHAAdjPcYAAbDYDoc9woACoIA+A
+BKECgYHgrA/B/9HA4H7gePHAiiBPDFoK7/WC2RIMb/UC2NHA4H7gePHAAgtP9dD/geAM8gXYCiHA
+D+tylNuKJMMPGglv9bhzz3WAAGw2I4WB4QKFD/SB4ADZBfIUjYDgBfJuCSAAJqUM8COlAdgGpQjw
+gOAG9AHe8grv/8alwqXPcIAARGcFkIDg8A3J/wkDT/XgePHAkgpP9c91gABsNkuFgOLKIYEPgACI
+NjbyCIWB4Db0JBWAEADZDyEBACR6QiICgGyFyiJiACR7gOMB282FwHskfoDmAd7uhcB+5HmA4QHZ
+wHmA4swjIoDMJiKQzCEigAbyHK0A2ZoJIAAopSQVgBDPcYAAiDYB4A94CKkkFYAQoOAE9ADYCKlx
+Ak/18cDPcIAA7EXPcYAAbDZqDu/1QNpKCWAAANjRwOB+4HjxwOHFzHUAhc9wgAAAXgGA5bgM9AXY
+CiHAD+tyeNuKJMMP+g8v9bhzAIXPdYAAfIEApQRtSg3v9Q/ZViUAEsYO7/UilRoNz/XPcAEAKFya
+Cc//+ghAAIDgF/TPcIAARGcFkIDgiiCPC8f2xgjv9YnZPgsAAAbwugjv9Y7ZzgoAAL4IYAAN2NkB
+T/XgePHAWglP9c93gACkYwWH4LipwQny57gH9A4KD/sqCm/1ENiLcelwpg3v9Rjaz3GgAMgfz3Kg
+ALAfAdgWorwRAAAA3UbAwBEAAM92gABsNkfABoYk2UjAi3DyCe/1kNqht6WnoaejpgYN7/8C2M9w
+gABEZwWQgODF9qymr6YF8KlwagsgAKlxBoaB4AHayiIiAM91gACAESCFgOBZYSClAdjKICIAQYVY
+YAGl+g+v9Yogjw2KII8N7g+v9SGFBQFv9anA4HjxwJYIb/UA2Qh3GNjPdoAAbGMAtiHIosEBpvCu
+z3KAAIhjN6qKIP8PCqYG2BWqFqogyDGuMrY7tgOmOrZAJgATTg0v9+lxkNjPdYAATGMAtYtxgcJO
+Di/46XCB4AvyBdgKIcAP63Jx20okQABeDi/1uHcAwOC4AdjKICEAgOAK8oogTw5aD6/1ddkBhqO4
+AaaLcCRtcgzv9Qbaz3CAAKw2NgoP989wgABsNvyoUQBv9aLA4HjxwOIPL/WKIE8Oz3UAAMgUYH2M
+2QHYz3aAAGw2CKbPd4AApGOKIE8OYH0lh3yOANguhg8gwAALIQCAJPQshuWHz3KAAIBJdnoFeSym
+4L8thmCCDPLnvwr0JXgNpqi7YKKKIA8OndkJ8AZ5LaaIu2CiiiAPDqTZQH2KIA8OYH0thskHD/Xx
+wF4PL/UA2s9wgABsNgCAAN2Wvc9xAQAcYR1lqXDPdgAA/KtgfgXbANiWuM93gABEZyWHHWUFl7lh
+ANoKuA4gQADPcQEAEGBgfgzbz3EBAOBhqXAC2mB+DdvPcIAAbDagoADYlri4YKWHz3EBABBgHWUF
+lwDaCrgOIEADYH4M20UHD/XxwNoOL/UA2s92gABsNqCGAN+Wv89xAQAcYf1lqXA6DW/6Bdv9Zc9x
+AQDgYalwAtomDW/6DdsNBy/1oKbxwJ4OL/UA2s9woACwH7iAAN+Wv89xAQAcYQQljR/A/wAA/WUU
+5QAljh+AAAAAqXDqDG/6Bdv4Zc9xAQAcYQDa2gxv+gXbz3WAAGw2wKXPcQEA4GHJcALawgxv+g3b
+qQYv9cCl8cA2Di/1ANrPcKAAsB8YgADflr/PcQEAHGEEIIAPwP8AAB9nEOcAJ5AfgAAAAOlwz3UA
+APyrYH0F2wDYlrjPdoAARGclhh9nBZb5YQDaCrgOIEAAz3EBABBgYH0M2+lwz3EBABxhANpgfQXb
+ANiWuB9nBYbPcQEAEGAfZwWWANoKuA4gwANgfQzbz3EBAOBhCnAC2mB9DdvPcYAAbDYAGQAEANmW
+uQAgQCAlhgDaGWEFlgq4DiBAAM9xAQAQYGB9DNvZBQ/14HjxwHINL/WKIE8Nz3UAAMgUYH2iwc92
+gABsNgGGgeAQ9IogTw1gfYohxgoA3aGmTg4v9QLYTgnv/6lwZvB+Cc//geAB2MB4LycHkBDyiiAP
+DWB9iiGGDqoJz/8B2L4L7/8GpiIJ7/8C2FIJz/+C4A3yBdgKIcAP63KKI4cBiiTDDyYLL/W4cwPI
+BSCADwAAAHwDGhgwyggP9eoI7/8A2N4NL/UC2M9wgABEZwWQgOBYAAwADIZBwA2Gdg+v/0DAgOAG
+8oDnBPQGDy/8QNiLcAjZkg2v9ZTaiiCPDmB9iiHHCIogjw5gfS2GiiCPDmB9LIaA5wj0HgjP/wYJ
+z/8B2AimANgNptUEL/WiwOB48cBqDC/1iiAPCqYLr/WKIcUGCghP/s91gABsNoDgF/SKIM8Oiguv
+9YohRQgB2AGlz3CAAERnBZCA4MX2fg+P/0DwANgA2az/PPADyAQggA////+DAxoYMAPIh7gDGhgw
+A8iOuAMaGDDqD+/0AN62D8/54gwv9QLYJIXPcKAAqCAPgJYhCgAieNdwAIAAAEn3iiAPChoLr/WK
+IUUPw6USCO//wqWA4MogYQDMD4H/z3CAAERnBZCA4MT2Rg0v/EDYFQQP9fHApgsP9Qh2KHXiCq/1
+iiAPC89wgABEZwWQgODD9gr/AvAq/8lwqXHF/+kDD/XgePHAagsP9c9woADIH/KA5BAQAFMnQBUA
+IA0EOnDPcIAARGcFgBB12veKIM8Oz3YAAMgUYH6KIcgMiiDPDmB+6XGKIM8OYH4KcYogzw5gfipx
+iiDPDmB+qXHPcIAARGcFgBB1ANjKIG4AYQMP9fHAAgsP9c9wgACYXjGAz3CAACBdNHgRiIDgOfIK
+EgM2AYPtuDPyMxIPNjQSEDbPdqAAFAQqEg02z3KgANQHKqbPcIAAxD+0GwAAgdiQuJwbAAAB2AOm
+DhIAhioaWDAzGhgwHxIAhjQaGDDmDu/5ANgqGlgzqqYzGtgzz3GAAAQWGIE0Ghg0AeAYod0CD/Xg
+ePHAbgoP9TpwSHAacxjaz3aAAGxjQLYhEgI2iHfPdYAAiGMatkGmANpQrletUa6KI/8PaqY1rTat
+W7ZAJgATEgzv9UhxA4bpuA30DI7PcYAANDrDuBx4CWHPcIAANA8oYAyuz3EAAEgRz3CAAExjILBM
+IUCgBPKKIQUCILCA5wbyz3KAAOg24qLPcoAAmF5AguC6DvIa2kC2h7lMIACgILAG8s9wgABIMQSA
+F62x/89wgADoNgIMz/YVAg/18cC2CQ/1CHYacUh3pgmv+2h1gODMJiKQCfLPcIAA/GiwoIYKL/UD
+2AfwyXAKcelyANuYdcT/5QEP9eB48cDhxc9wgACkYwHZJaDPdYAA/GgQhUB4ANgQpWoKL/UD2NUB
+D/XgePHAVgkP9Yh1EN7Pc4AAbGPAs6Tfz3aAAExjgeDgtgX0pNiMuAC2KczPd4AAiGOOuI+4AbYh
+yADe0KvRq5m4AaPXr4og/w8KozWvNq/bs1qzQCMAA/oN7/bJcc92gADoNoDlA/Kipnv/Lgvv9slw
+UQEP9eB4z3CAAKRjJYDPcJ8A2P8uoAjYAB8AQAPbz3CgANQHFRjYgDTIANoAHwBAz3CgANAPDhiY
+gOB+4HjPcYAAiBHgfwCh4HjPcIAAiBHgfwCA4HjxwOHFKHNIcc9yoACwH1iCBCKCD8D/AAAAIo0P
+QAAAAM9ynwDY/66iz3KAAERnRYJwurpiWGDaDi/6AtrNAA/18cDhxc91gAD0Nqlw3guv9QPZAY2D
+4MT2Y7gBra4Lj/WpAA/18cAuCA/1Ad7PdaAAsB/Pc6AAyB/WpbwTAgDXcQAAAIB+Ew+GBPThvwTy
+DPDhvwry1qW8Ew8AQn/xcHH3ANgD8AHYVQAP9eB48cDmD+/0mHAB3Y+9z3egAMAdIIfPdqAAyB/h
+uTLYBvQN8M69CNgL8AHdCfAB2H4eGJC7fbB9j70I2C8mR/MV8u+9FfIA2Y+53P+A4Ov1AIfPcaqq
+qqqEIIMPfh4YkIogkwHODk/16QfP9M9xAAD/f9L/gOAG8gslAJHa9QDY2fEAh89xu7u7u4Qggw9+
+HhiQiiCTAefx4HjxwE4Pz/QIdYogEwGKDm/1qXHPcIAAIBEAiAHegODAfoogUwECvnIOb/XJcY7l
+BPaA5QP2AN1MyoPgzCAigST0z3GAAPQ2AInguB7yCpEQdQT0C5EQdhjyANrPd6AAyB8M2H4fGJCq
+scuxgOXKJoEQFG6leA3Zfh9YkMa4u/8M2H4fGJAxB8/0z3CAAIwRIojguQvyz3CgAKwvGYDPcqAA
+wC+KuBSi4bngfM9woACsLxmAz3GgAMAvjrgUoeB+4HjxwOHFz3WAABReqXAA2R4Pb/WE2iYI7/Wp
+cO0Gz/TgePHAcg7P9IHgKHYW9I7mzPYF2AohwA/rcoojSgCYc4YM7/S4djDZLH4CIUBwx3CAADQE
+GPDPcIAAsDjNYIwlw58L9AXYCiHAD+tyiiOKAZhzUgzv9Lh2FG0UeMdwgADUBn0Gz/TxwAoOz/TP
+dYAAHhEAjc93gAAcESCP4v9BiM92gACcEeS6IJcv8s9zgAAAXgmTEHEp9ACV8IvxcCX0z3CAACAR
+AIhuixBzH/QWyOW4G/JBhoDiANsN8s9woAAsIB2AQnjXcDEBAC1F9wHYAK4D8GCuANgQuAV5z3IA
+AMgUiiBHAwrw47rPcgAAyBQK8gHYAK6KIMcDQHrdBe/0AI4BjoDgBvIB2ACuiiAHA/bxANgAroog
+BwTw8eB48cBCDc/0GnB6cQomgJAKIQAhzCMigAbyQiMTIS8jxyQKcGpxsP8Idc93gACcEYDmB6cm
+8gaNBLgUeEAg0gADjeC4wo0M9AXYCiHAD+tyiiPQD5hzMgvv9AolwAQyIkAj4bgP9AXYCiHAD+ty
+iiORAJhzFgvv9AolwAQD8MGN4L4M9AXYCiHAD+tyiiNRA5hz9grv9AolwARRIUCg0SYikQzyBdgK
+IcAP63KKI9EEmHPWCu/0CiXABFEhAKAO8uO+DPQF2AohwA/rcoojUQaYc7YK7/QKJcAEB4cLgIDg
+DfIF2AohwA/rcooj0QeYc5oK7/QKJcAEz3GAADBGTCBAoAr0ViEABAinz3CAAOg3CacG2A3wKHAI
+p89wgAAQNwmnTCPAqgjYyiBsAhwXEhAMFxAQOnAA3gLdQCIAKvUggQNhvQIhAAQYYCYJL/oqcRUn
+jBMKpAHmgOXPfjD3PQTP9PHA7gvP9Bpwz3GAAABeSZHPdYAAHBEAlc92gACcERByEfTPcIAAHhEA
+kFCJEHIL9M9wgAAgEQCILokQcQP0Ao4C8ADYAa5p/89wgAAgEUCIz3GAAB4RAIkgjYDiAdrAegpz
+SiQAAI//B4YA3wGI5LgglQfyAdgDroogRwME8OOuiiCHA7YKT/XJA8/0z3GAAABez3CAABwRAJBJ
+kRBy4H3PcIAAHhEAkFCJEHLgfc9wgAAgEQCILokQceB9z3GAAJwRAYngfwKpFsjluBjyz3KAAABe
+LswpkhBxEvQVyDCKUyADADBzDPQEIIAPAAYAAIDgAdkOisB5EHHgfADYz3GAAJwRAqkBoeB/AKmA
+4PHAD/QA2Bz/z3GgACwgPYHHcUlrANIroBYKb/WKIIcF0cDgfuB48cDhxYDgKHUK9ADYEf8A2Sug
+iiDHBfIJb/WpcRkDz/TxwOHFz3WAAJwRiiBHBtoJb/UpjQTYKg3v/QHZCI0pjeb//9jxAu/0Cq3g
+ePHA4cXPdYAAnBGKIMcGrglv9SmNCo2MIMOPB/KeCy/6Btn/2AqtxQLP9OB44cVTIA0AoKkEIIEP
+AAYAAEIhAYAEIIAPQAAAAMohYgAgqtdwQAAAAAHYwHgAq+B/wcXgePHAAgrP9BpwenGIdahwCiKA
+IQohwCHPdoAAnBGg4ADfBPQHhgWIKfBEIAEGwriH4C4ALQBDuUeGMyYAcIAAMEdAJ4xzWWEUfFRt
+IHxZYQiJE/AMiRHwEIkP8BSJDfAF2AohwA/rcooj0gqYc9oPr/RKJQAA6XAVJk0T6oUfZ4Dnyicr
+EEwgAKAF8uPnhvZi3wTw7OeC9mvfCYZIhvR4IIgBiPQiQQAseAASgSAvcPQiQwAAEYIgbHo3cADY
+WPdAKwAmQC8DFGV4CLkFeUV5jghv9YoghwAJhvR4IIgAGkIgCYb0eCGIAdgAGUIgbQHP9PHACgnP
+9KHBmnA6cRpyaHUA389woAC0D3AQEwCKIMcASghv9Ypxz3CgANAP9aCLcUAkQjBAJIMwKnCp/4Dl
+BPSYdwrwz3CAAEhuAYiA4Pr1SiSAACDAARSCMIpxAhSDMNz+AN5KIUAoFSCNIwDZAthacAJtACBH
+ACDAARSCMLpxAhSDMAAlRhAvJYcDinEKJEAFoP+A4AbyUyYAEQ8nDxBAJUEgQiJAIIDgL3ki9wHm
+QiFAIIDgtAft/zpwz3GAAJwRA4EEoc9xoADQD1QZwATpcIkA7/ShwPHATgjP9Ch2SHUEIL6PAAAA
+GAHZyiEhAOi4IK4J8g95AK0AjoDgMPKEuSCtLPDpuATyINgArSjwD3hhuI7gKAANADMmAHCAADhH
+QCeMchR8AHwE2ACtE/AF2ACtD/AG2ACtDfAF2AohwA/rcoojCwyYcw4Or/RKJQAAAI6A4ATyII3U
+8TUAz/TxwKoPj/ShwQDez3CgALQPcBATAM9woADQD9Wgz3WAAJh7AxWUEIogBwHiDi/1inEElYDg
+yiWCI8oloSAFhYtxQCSDMEAkTjDJck3/CoVAJMIwyXHJ/0oiACBMJACghgAuAEp2z3WAAHx/FSWN
+FIAVABDguAHayiIhAM9wgABsgAUiQgUUIJEELySHACDAEBGBIAEUgjACFIMwdv4A2ALfGnAAJQYQ
+Am0AIAcEAxSFMCDAEBGBIAEUgjACFIMwCiQABDz/gODPJoIUQCBAIGG/gOcPeCb3QCJAIJJwiAfl
+/1pwz3GgANAPVBnABMlwDQev9KHA8cC6Do/0ocE6cADdz3CgALQPcBATAM9woADQD7WgiiBHAfYN
+L/UqcYQpBikAIZB/gADoblp1BPBAIlIgGBABIUpwMHCEAAYAFiAOICEWgBAEIL6PAABgAPDzCnAE
+gItxQCSDMEAkTzDpcgj/CnCoEAAAQCTCMOlxg/8gwCAWgRABFIIwAhSDMEokwAA8/gDYAt+acAMU
+hTAgwEAmhhggFoEQARSCMEAmxxgCFIMwCiQABQP/gODPJYIUQCRAIGG/gOcPeCf3uvHPcYAAnBFD
+gRUhQQSpcEWhz3GgANAPVBnABC0Gr/ShwPHA6g2P9BXIAN4EIL6PAAYAAMomYhDPcIAAvBCggPe9
+yiBBAwXyBSWAHwD/AADPcYAAyA7PcoAAuA7wIoID8CGBA0J5z3KAAMAO8CKCA0J4hCjEAK4K7/kv
+cIQoQQgCIYB/AABxZ54K7/lk2c9xgACcEQOhQC0BFA++xXkFebIML/WKIIcB0QWP9OB48cBaDa/0
+iiAHBgDflgwv9elxFd3PdoAAnBEMhjRoAeA0ecdxgADUBgymC4GA4BHyz3KgACwgXYJCeNdwSWsA
+0sf366GKIMcFWgwv9SCJDIaq4IP37KZhvYDlwgfN/2UFj/TgePHA9gyP9MP/5f/PcIAAHBEAkIDg
+2A6C/893gACcEQSHz3Hw8PDwMHAa8iOHZbgwcNb3z3GAAABeEolAIQ0FIIGpcgDb5P5SD8/+gOAI
+9F4Pj/yA4EwOYfXKIEEDAN4C3c9wgACIcIQuBhkyIEAOgOAQ8hUngBMFgM9x8PDw8DBwCPIjh2W4
+EHGgDeX/yiCFAwHmYb2A5c9+JPfFBI/04HjxwFYMj/ShwQh2KHeLcUAkQjBAJIMw6XB+/gEUgDCA
+4AfyAhSAMIDgA/Jkvs9+IMDJcW79ARSBMIDhBPKiiAPwoYiKIMcBWgsv9elxQC4AFkAtARQFeQEU
+gDAIuCV4AhSBMAV5Ogsv9YogxwHhvdEl4pAE8uS9DPIF2AohwA/rcoojWAqYcwYKr/S4djEEr/Sh
+wOB48cDGC4/0FchcEo0wUyAOAIogBwL2Ci/1qXHJcKlxTv0BiOS4C/IF2AohwA/rcoojGQCYc8IJ
+r/S4dfkDj/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlAEAAAEBAQEAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
+AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAA+G2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
+AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP8A8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAGAYAABgGAAAYBgAAFggAABgGAAAYBgAADAgAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAGAYAAD0EQAAABIAAGAYAACgEgAAyBMAAEgTAABgGAAAYBgAAJQkAABAJwAA
+6CcAAGAYAABgGAAAYBgAAMgjAABgGAAAJCkAAGQqAABgGAAAYBgAAGAYAABcIAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAY
+AABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAKAgAABgGAAAYBgAAGAYAABgGAAAYBgAAHQhAABgGAAAYBgAAGAYAABgGAAA
+YBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAY
+AABgGAAAZAABAGADAQBgGAAAxAUBAGAYAABwBwEADM8AAAzQAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYDwBAAxPAQBgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA
+YBgAAGAYAABgGAAAYBgAAGAYAADYVQEAYBgAALRXAQBgGAAAYBgAAGAYAABUFAAAoBsBAGAYAABg
+GAAAMGUBACwwAABgGAAAYBgAAGAYAAAw1AAAYBgAAGAYAACkwwAAeCIBAGAYAABgGAAAYBgAAIwy
+AQDk1AAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAHCgBAGAYAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAfDAAAGAYAABgGAAA
+YBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAY
+AABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA8CIAAPQiAABgGAAA
+YBgAAGAYAAAYAA38DnMPcB0gH0AgQCFAIjElZiYPJ2YoDysdLEQtHS5EMRAyCTMQNAlvWnAAcQBy
+AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5AcA
+AOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA
+5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADk
+BwAA5AcAAMwIAAAAAAAAbMYAAOQHAADgBgAA5AcAAPgaAQAUBwAA6LEAAOQHAADkBwAA5AcAAOQH
+AADkBwAA5AcAAJwHAAA4BwAAOAcAADgHAAA4BwAAtAgAAOQHAADkBwAA5AcAALAHAADkBwAA5AcA
+AOQHAADkBwAA5AcAANAIAADkBwAA5AcAANAGAAADAAAABGQBAAQAAABg3gAADgAAACRVAQAIAAAA
+OB0BAAIAAABYWQEACgAAABgeAQALAAAAxAkBAAwAAAD4CQEAEQAAABDGAAAJAAAATAEBABAAAAAo
+MAAADQAAANjCAAABAAAAxNMAAA8AAAAcOQEAEgAAAMwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAAQACAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADjIAAAMyQAAIMwAAFTKAABUyQAA7MwAAHDN
+AACozQAA7M0AAAAAAAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAAAAAAAwAA
+AAIAAAADAAAAAwAAAAMAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKwNAAAA
+AAAAAAAAAAAAAAAA/wD/AP8A////AP8A/wAAAQAAAAAAAAAFAAAAAAAAAAAAAAAQAAAAAIAAAAAA
+oAAQJwAA6AMAAOgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+/AwBABgOAQCcEAEAiBIBAPgUAQAoGAEAeA8BAJQPgABsY4AAGAAAAExjgAAAAAAAAAAAAGQygACk
+Y4AAMBoBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgIDBAQFBgYHCAgJCgoL
+DAwNDg4PZmZnaGhpamprbGxtbm5vcHBxcnJzdHR1dnZ3eHh5enp7fHx9fn4VPwAAAAAAAAAAAAAA
+AAABAgIDBAQFBgYHCAgJCgoLDAwNKCgpKiorLCwtR0hJSUpLS0xNTU5PT1BRUVJtbW5vb3BxcXJz
+c3R1dXZ3d3h5eXp7fH0MPzQsAQBQcAAANCwBAFFwAADoLAEARQAAAOgsAQBEAAAA6CwBAEkAAADo
+LAEASAAAADQsAQBScAAANCwBAFNwAADoLAEATgAAAOgsAQBNAAAA6CwBAFIAAADoLAEAUQAAADQs
+AQBA0gAANCwBAEHSAADoLAEAVwAAAOgsAQBWAAAA6CwBAFsAAADoLAEAWgAAADQsAQAI0gAANCwB
+AAnSAABwLAEAAIIAAHAsAQABggAANCwBAEXSAAA0LAEARtIAAHAsAQAAggAAcCwBAAGCAAA0LAEA
+BtIAADQsAQA+kAAANCwBAEPSAAA0LAEARNIAADQsAQBQ0gAANCwBAFHSAAA0LAEAUtIAADQsAQBT
+0gAANCwBAD+QAAA0LAEAE9IAADQsAQBAkAAANCwBABXSAAA0LAEAP9IAADQsAQA+0gAANCwBAD+Q
+AAA0LAEAE9IAAGQAZABpANwAyABaAKoAvgCGAX0APgBkAGQAaQDcAMgAWgCqAL4AhgF9AD4AAAAA
+AAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJQPgABsY4AAGAAAAExjgAAAAAAAAAAAAFQ2
+gACkY4AAAAAAAJQPgABsY4AAGAAAAExjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4NoAApGOAAKBdAQCUD4AA
+bGOAABgAAABMY4AAAAAAAAAAAACUD4AAbGOAABgAAABMY4AAAAAAAAAAAADQNoAApGOAAKBkAQAA
+FAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAP3s/dT9uP2g/Yj5uPmg+Yj1uPWg9YjxuPGg8Yjtu
+O2g7YjpuOmg6YjluOWg5YjhuOGg4YjduN2g3YjZuNmg2YjVuNWg1YjRuNGg0YjNuM2gzYjJuMmgy
+YjFuMWgxYjBuMGgwYiVuJWglYiRuJGgkYiNuI2gjYiJuGGgYYhduF2gXYhZuFmgWYhVuFWgVYhRu
+FGgUYhNuE2gTYhJuCGgIYgduB2gHYgZuBmgGYgVuBWgFYgRuBGgEYgNuA2gDYgJuAmgCYgFuAWgB
+YgBuAGgAYgBdAFgAUwBOP24/aD9iPm4+aD5iPW49aD1iPG48aDxiO247aDtiOm46aDpiOW45aDli
+OG44aDhiN243aDdiNm42aDZiNW41aDViNG40aDRiM24zaDNiMm4yaDJiMW4xaDFiMG4waDBiBm4G
+aAZiBW4FaAViBG4EaARiA24DaANiAm4CaAJiAW4BaAFiAG4AaABiAGEAYABfAF4AXQBcAFsAWgBZ
+AFgAVwBWAFUAVABTAFIAUQBQAE8ATgBNAEwASwBKAEkASABHAEYARQBEAAD/////////AAH//wID
+////BP//////////////////////Bf8G/wf/CP8J/wr/C/8M////Df///w7///8P////EP//////
+////////////////////////////////////////Ef///xL///8T////FP///xX///8W////F///
+/xj///8Z////Gv///xv/////HP///x3///8e////H////yD///8h//////////////////////8i
+IyT/JSYn//8o////Kf//////////////////////////////////////////////////////////
+////////////////////AAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEA
+AAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAABAAAAOeQBpQAtKickIR4bGBUSDwwJBgMADAgEADw4
+NDAsKCQgHBgUEAwIBH//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX6KKLLg0PBQcJCwED
+ChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8PBwYHAgMEBQABCAkLCigAKAAw
+ACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA9ACwACwALAA8ADQAMAAsAFQA
+RABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZAOgACgG6AHkAiACKBSoDOQGo
+AYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUAQQKsAJAAhACAAHgAeAB4AHQA
+Zg4AAImd2AnETuwEgzRIA2IndgJBGqQBsRM7AYERGAHAD/wAL6G9BJfQXgIPi5QBS2gvAYdFygAl
+tJcABdmGAOtceQCqqqoKAA0AAAAaAAAAJwAAADQAAABOAAAAaAAAAHUAAACCAAAAGwAAADYAAABR
+AAAAbAAAAKIAAADYAAAA8wAAAA4BAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzE
+Tid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUF
+BVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN
+0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4
+gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiA
+CgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEAAAAAAAAAAAYIBQU
+Dg4UFAUGAQIDBAAAAAAAAAAHCAgAAAAHCg0QEQAAAAcLDhARAAcLDhUbHyIAAAAABwoLDQAABwoP
+FRcaAAAICxAVGBsACxAWISwxNgAAAAcLDxASAAcLDxYdISQACAwPFx4iJQgPFx4tPERLAAgLDxYd
+ISUIDxYdLDpCSQgQFx8uPURMEB8uPVt5iJcABwcPBw8PDwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIA
+AEAAAAAABAAAQAAAAEAAAAAzEwAAAAUKDwEBAAECAQEBpcaE+JnujfYN/73Wsd5UkVBgAwKpzn1W
+GediteZNmuxFj50fQImH+hXv67LJjgv77EFns/1f6kW/I/dTluRbm8J1HOGuPWpMWmxBfgL1T4Nc
+aPRRNNEI+ZPic6tTYj8qDAhSlWVGXp0oMKE3Dwq1LwkONiSbGz3fJs1pTs1/n+obEp4ddFguNC02
+stzutPtb9qRNdmG3zn17Uj7dcV6XE/WmaLkAACzBYEAf48h57ba+1EaN2WdLct6U1JjosEqFa7sq
+xeVPFu3FhteaVWaUEc+KEOkGBIH+8KBEeLol40vzov5dwICKBa0/vCFIcATx32PBd3WvY0IwIBrl
+Dv1tv0yBFBg1Ji/D4b6iNcyIOS5Xk/JVgvxHeqzI57orMpXmoMCYGdGef6NmRH5UqzuDC8qMKcfT
+azwoeafivB0Wdq0721ZkTnQeFNuSCgxsSOS4XZ9uve9DpsSoOaQxN9OL8jLVQ4tZbrfajAFksdKc
+4Em02PqsB/Mlz6/KjvTpRxgQ1W+I8G9KclwkOPFXx3NRlyPLfKGc6CE+3ZbcYYYNhQ+Q4EJ8xHGq
+zNiQBQYB9xIco8Jfavmu0GmRF1iZJzq5JzjZE+uzKzMiu9JwqYkHpzO2LSI8khUgyUmH/6p4UHql
+jwP4WYAJFxraZTHXxoS40MOCsCl3WhEey3v8qNZtOixYnwAA9JsAAOieAACknAAA2EAAANhBAABU
+QAAAGEIAAAAAwABwRKAAbAAAgAAAsAAECKAAAAAAAAQAsAAYCKAAAQAAAAAAsAAcCKAAAwAAAAAA
+sADsHKAAMAAAAAAAsABQFKAAAwAAAAAAsAAEGKAAAwAAAAAAsABARKAAAAAAAAAAsAAYCKAAAAAA
+AAAAAAAEKKAAAgEAAAAAAABcSKcAAAAAAAAAAAAEKKAAAmkAAAKQ8QAEKKAAAQAAAACAAQAYKKAA
+AAAAAAAAAADwHKAAAgAAAAAAAADsHKAAAQAAAACgAQAIAKwAAAAAAAAQAgAwQKQAAAAAAAAAAAAQ
+HKAAAABwAAAAAADgHKAAAAAAAAAAAIAkEKAAAQAAAAAAMAAkEKAAAAAAAAAAAAA4HKAAAIAAAAAA
+gAI4HKAAAAABAABQQAAEKKAAAgMAAABgUAAEKKAAAgQAAAQgAAAEKKAAAQAAAABAAAAIAKwAAAAA
+AAAAoADsHKAAAgAAAAAAkABwRKAAJAAAgACwAgAACKoAAAAAAADAAgAECKoAAAAAAAUAEAFwRKAA
+hAAAgAAwAAAYKKAAAAAAAAAAAAA4HKAAAAABAACAAADgHKAAAAAAAABwoAAICKoAAAAAAACQoAAE
+AKoAAAAAAABwkAAoSKcAAAAAAACQkAAAAKYAAAAAAAMAAAAECKAAAwAAAAAAAACkIKAAAAAAAAAA
+AIAAIKAAAABgAAAAAIA4HKAAAAABAACgAYAIAKwAAAAAAASQAQAEKKAAAQAAAACQAQAEKKAAAQAA
+AACgAYAIAKwAAAAAAAAAAABcSKcAAQAAAAAgAgAIAKwAAAAAAAAAAAAwSacAAgAAAAAAAAAEKKAA
+AgFAAAAAAAAISKcA/wAAAAAAAAAEKKAAAmkhAAAAAABkQKYAAAgAAAAAAAAsSacAAAAAAAAAAIAA
+SKcAAQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQAAAAFBwEDBAAAQCNAJSEhISFAQEBAQAUEBAEB
+QEBAQAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUB
+AUAFBQVABUAFBQUFBQQAAAAcEQAAHDIAABwzAAAEAAAAHBUAAAAAAAAAAAAAZAAAAACQAQAKAAAA
+AAQEBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQJAAAAAAAAAAAAAAAAAAABAAAABQAAAAAA
+AAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAEAAAAQAAAAAAAAAAEAAAABAAAAAAAA
+AP8AAAD/AAAAAAAAAAAAAAAMYwEAjAIBAJACAQCUAgEA8AIBAPgCAQAAAwEAAAQLCRUlLwAABBEJ
+HCcyAAGAABGAABYEAiAAEoAAFgQDQAAQgAAXBATgABCAABcEBYAAEYAAFwQGIAASgAAXBAdAABCA
+ABgECOAAEIAAGAQJgAARgAAYBAogABKAABgEC0AAEIAAGQQM4AAQgAAZBA2AABGAABkEDoAAEIAA
+GgQigAAYAAAWACQAABkAABYBJgAAIgAAFgEoAAAaAAAWASqAABoAABYBLAAAIAAAFwEugAAYAAAX
+ATAAABkAABcBNAAAGgAAFwE2gAAaAAAXATgAACAAABgBPAAAGQAAGAE+AAAiAAAYAUAAABoAABgB
+ZAAAGgAAGwJmgAAaAAAbAmgAACAAABwCbAAAGQAAHAJuAAAiAAAcAnAAABoAABwCdAAAIAAAHQJ2
+gAAYAAAdAngAABkAAB0CfAAAGgAAHQJ+gAAaAAAdAoAAACAAAB4ChAAAGQAAHgKGAAAiAAAeAogA
+ABoAAB4CjAAAIAAAHwKRQAAZAAAfA5UAACMAAB8Dl8AAGgAAHwOZQAAYAAAgA51AABkAACADn8AA
+GQAAIAOhAAAjAAAgA6VAABgAACEDJE4BAHg+AQBEQAEAeEEBANRDAQCgRgEAjEoBAARMAQAoTQEA
+bFoBAIRaAQDwWgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANABAAEwAWABoAIAAmAC0ANQBAAEwAWgBrAIAAmAC0ACYA
+LQA1AEAATABaAGsAgACYALQA1gAAATABaQGtAQACawCAAJgAtADWAAABMAFpAa0BAAJgAtMCXQMA
+BMEEpgUwAWkBrQEAAmAC0wJdAwAEwQSmBbcGAAiCCUwLbg0AEFAAXwBxAIcAoQC/AOMADwFCAX8B
+xwEeAoQC/gKOAzwE////////////////////////////////////////////////////////////
+/////////////////////////zABaQGtAQACYALTAl0DAATBBKYFtwYACIIJTAtuDQAQAAAAAAAC
+BAYDCQYJAAkACQAJAAkACQAAAAAAAAAAAAAAAAAAAAAAAP////8AAAAAYAAAAAUFBQUFBQUFAAAA
+AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAA4AAAAOAAAABAAAgAAAAIAAAAAAAwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABAAGkgAABp
+IEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAAAYAWkgAABpIEAAaSAAAEog
+AABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYA
+EEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4AAAKBBLJww
+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
+87gE8m8hPwAU2IYJ7/+NuOkDj/9vIT8AkwfP//HAz3GAAGw5IIGA4QDZD/LPc4AATDED8AHhjuFU
+9xYjQgBAilBw+vUW8M9zgAC8MQLwAeGm4Uj3FiNCAECKUHD59Qrwz3AAAAcwKgnP/28hPwAA2dHA
+4H8ocOB4z3CAAGw5AYDO8eB4z3CAAGw5QIAigM9wgABMMYDiNngD8uB/B4jgf3cQgADPcawA1AEA
+2IsZGICMGRiAB9iNGRiABtmRuc9woADEJzCgz3EYAAcCMKDPcoAAbDk0ioDhBfTPcRAABgIwoCCC
+gOFR8gbZlrkwoM9xeAAChTCgz3ECAAKBMKDPcVUAAoIwoM9xEAAChjCgz3FBAAKHMKDPcQcAAtMw
+oM9xAQACijCgz3EAAAKlMKDPcQAAAqYwoM9xAAACpzCgz3EGAAKoMKDPcQYAAqkwoM9xBgACqjCg
+z3H/AAfFMKDPcf8AB9swoM9x/wAHJjCgz3H/AAcjMKDPcRgAAh8woM9xzAACHlfwB9mWuTCgz3EB
+AAKHMKDPcQMAAsUwoM9xgAAC2zCgz3FwAAKFMKDPcXAAAoEwoM9xBgAC0zCgz3EhAAKKMKDPcQUA
+AqUwoM9xBQACpjCgz3EFAAKnMKDPcQwAAqgwoM9xDAACqTCgz3EMAAKqMKDPcUQAAiYwoM9xRAAC
+IzCgz3EoAAIWMKDPcZkAAhUwoM9x/wAHgjCgz3H/AAeGMKDPcf8ABx8woM9x/wAHHjCg4H7gePHA
+UgmP/891gAAUDwCNgOAcAAIAz3AAAJBlCiQAcOB4qCAAAeB44HgB2ACtBtiQuM91oADEJxClz3CA
+AGw5QIAigM92oADsJ89wgABMMYDiBfI2eAbZlrkF8HDgNngH2Za5MKXPcQQAB7wwpc9xEAAHuDCl
+z3EKAAe8MKXPcT8AAsEwpSKIELkFIYEPAAACsjClIYgQuQUhgQ8AAAKzMKUliBC5BSGBDwAAArQw
+pSSIELkFIYEPAAACtTClI4gQuQUhgQ8AAAK2MKUGiBC4BSCADwAAArcQpc9wBAAGvBClz3ABAAax
+EKXPcAMABq4Qpc9wAQAGvBClz3ADAAYAEKXPcAgABrwQpc9wEAAGuBClz3AAAKAoCiQAcOB4qCAA
+AeB44HjPcCAABrwQpc9wAAAoCgokAHDgeKggAAHgeOB4z3AAAAPwEKXqhs9wIAAHvBClz3AAAAPv
+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
+QbME8CKzQ7PpAs/+8cCKCs/+GnAodkh3z3WAALgwfg3v/qlwz3GgAMQngOYJ8s9wNQACAxChz3A1
+AAIECPDPcDIAAgMQoc9wMgACBBChCnDJcelytv+CDe/+qXCdAs/+AAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA8AAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAX6
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAACg8RFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAC0v8AAAACABmQ
+QB8AAAIAAdIDAAAAAgAE0gAAAAACAAXSAAAAAIIACtJubgAAggAY0gEAAACCADzSAAAAAIIATdIA
+AAAAggBL0gMAAACCABfSAQAAAIIAPdIAAAAAggBO0gAAAACCAE/SAAAAAIIATNIAAAAAhAACAB8A
+AACFAAAACwAAAIUABgBAAAAAhQAIAAkAAACFAAkACQAAAIUACgAJAAAAhQB/AAwAAAAAAAAAAAAA
+AAAAAAAAAAAAAgAC0v8AAAACABmQQB8AAIUABwAPAAAAhAAAAAAAAACEAAEAAAAAAAIAF9IAAAAA
+AgBQcAAAAAACAFFwAAAAAAIAUnAAAAAAAgBTcAAAAAACAEDSAAAAAAIAQdIAAAAAggAEQ/8DAACE
+AAIABwAAAAUAQwDBAAAABQBMAMEAAAAFAFUAwQAAAIUABgBAAAAAAAAAAAAAAAAAAAAAAAAAAAMU
+IzRDVAAAAAAAAAAAY3RQcFFwRUn///////////////9ESAgAAABScFNwTlL///////////////9N
+UQkAAABA0kHSV1v///////////////9WWgoAAAAiAAAAQAAAAGQAAACRAAAABwAAAAAAAAAAAAAA
+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
+gAAYBAjgABCAABgECYAAEYAAGAQKIAASgAAYBAtAABCAABkEDOAAEIAAGQQNgAARgAAZBA6AABCA
+ABoEIoAAGAAAFgAkAAAZAAAWASYAACIAABYBKAAAGgAAFgEqgAAaAAAWASwAACAAABcBLoAAGAAA
+FwEwAAAZAAAXATQAABoAABcBNoAAGgAAFwE4AAAgAAAYATwAABkAABgBPgAAIgAAGAFAAAAaAAAY
+AWQAABoAABsCZoAAGgAAGwJoAAAgAAAcAmwAABkAABwCbgAAIgAAHAJwAAAaAAAcAnQAACAAAB0C
+doAAGAAAHQJ4AAAZAAAdAnwAABoAAB0CfoAAGgAAHQKAAAAgAAAeAoQAABkAAB4ChgAAIgAAHgKI
+AAAaAAAeAowAACAAAB8CkUAAGQAAHwOVAAAjAAAfA5fAABoAAB8DmUAAGAAAIAOdQAAZAAAgA5/A
+ABkAACADoQAAIwAAIAOlQAAYAAAhAwADCQADAwkACQADCQ4AAAAqAAAABwAAAAsAAAAAAgQGAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8AAOgAaSAAAGkgQABp
+IAAAaSBAACAggA8AAGABaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEokAABKJQAASiYAAEon
+AABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIAIEojACBKJAAgSiUA
+IEomACBKJwAgSiAAMEohADAKJIA/gAAAoEEsnDBALJwwQiQcNAoigD+AAAgPCiMAN5oIAABKJgBw
+aSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgAAED0B4ICBAhwAAAAAAAAAAAADhxZhwKHUEuM9xnwDY
+/xKhBCSADwDwAABFeBOhtqGA4wXyz3AAbQAQEaHgf8HF4HjPcp8A2P8SojOiadgYuBGi4H7geM9x
+nwDY/89ynwC4/xKhatgYuBGhHILgfuB+4HjgfuB48cD6CCAAANnPdqAAwC8Uhs9yoACsL891oACE
+NIu4GaJlhRgVBBAMFQUQEBUGEBSG47j/9YogCAAWos91oADIH893oADQGw4dWJAPHViQEB1YkBEd
+WJA82OL/TyBBADzY2/9ocADZl7mIcgHbzP8Rh/24//MA352/z3GAAOwDAdgTHdiTAKE3hs9wgAAE
+BMhyIKA6hs9wgAAIBCCgqHAA2Shzv/8PHdiTz3CAANgDABAaAM9xAG0AEM9wnwDY/zGgaSCAAG8h
+PwCZAAAA/ByItvwcSLb8HAi2/BzItfwciLX8HEi1/BwItfwcyLT8HIi0/BxItPwcCLT8HMiz/ByI
+s/wcSLPgfuB4BNw43TXw4HgE3DTdM/DgeATcMN0x8OB4BNws3S/w4HgE3CjdLfDgeATcJN0r8OB4
+BNwg3Snw4HgE3BzdJ/DgeATcGN0l8OB4BNwU3SPw4HgE3BDdIfDgeATcDN0f8OB4BNwI3Rzw4HgE
+3ATdGfA0FBowMBQZMCwUGDAoFBcwJBQWMCAUFTAcFBQwGBQTMBQUEjAQFBEwDBQQMALHAcawJE0z
+sCQfM+B+
+====
diff --git a/sys/contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu b/sys/contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu
deleted file mode 100644
index a4e3587f0e5..00000000000
--- a/sys/contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu
+++ /dev/null
@@ -1,3398 +0,0 @@
-Copyright (c) 2006, Intel Corporation.
-All rights reserved.
-
-Redistribution.  Redistribution and use in binary form, without 
-modification, are permitted provided that the following conditions are 
-met:
-
-* Redistributions must reproduce the above copyright notice and the 
-  following disclaimer in the documentation and/or other materials 
-  provided with the distribution. 
-* Neither the name of Intel Corporation nor the names of its suppliers 
-  may be used to endorse or promote products derived from this software 
-  without specific prior written permission. 
-* No reverse engineering, decompilation, or disassembly of this software 
-  is permitted.
-
-Limited patent license.  Intel Corporation grants a world-wide, 
-royalty-free, non-exclusive license under patents it now or hereafter 
-owns or controls to make, have made, use, import, offer to sell and 
-sell ("Utilize") this software, but solely to the extent that any 
-such patent is necessary to Utilize the software alone, or in 
-combination with an operating system licensed under an approved Open 
-Source license as listed by the Open Source Initiative at 
-http://opensource.org/licenses.  The patent license shall not apply to 
-any other combinations which include this software.  No hardware per 
-se is licensed hereunder.
-
-DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
-COPYRIGHT OWNER 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.
-begin-base64 644 iwlwifi-4965-4.44.17.fw.uu
-EQAsBPB/AQAAoAAASCgAAACgAAAUAwAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABp
-IAAAaSBAAGkgAABpIEAAICCADwAACARpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEol
-AABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMA
-IEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAACgQSycMEAsnDBCJBw0CiKAP4AAQDsKIwA3
-UgwAAEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAAgPQHggIECHAAAAAAAAAAAAAPHA4cXP
-caAA0BtUgc9wgADoUUCgUIHPdaAAyB9BoFGBQqBSgUOgU4FEoM9ynwDY/w6iEYH9uA/yz3CAAOwD
-AICB4An0z3CAACQPAIiC4CANAQaKIP8PEh0YkBMdGJAUHRiQFR0YkJUEAADgeADIz3KgAMgfDhoY
-gAHIDxoYgALIEBoYgAMSATYEyCR4ERoYgOB+4HjxwOHFz3WgANAbEYXPcqAAyB/9uADbEfLPcYAA
-7AMAgYLgC/QA2J24ExoYgGChICCADwAAAAAUhc9xgAAEDwQggI8DVwTxAKEK8i8pAQDPcIAA7Bbw
-IEAAQHjg/wkEAAAAyIS4ABoYMAHIm7gBGhgwAsgCGhgwA8iHuAMaGDDgfvHAAMiVuAAaGDAByIq4
-m7gBGhgwA8gFIIAPAAAAfAMaGDBwyoHgDPQDyM9xAAAQCKy4AxoYMPILIAAL2GfYcgqgAIohxQbR
-wOB+4HjPcQMAQA3PcKAAyB9DGFgAz3KAABwPIIIBaQCiOQSgAEjY4HjxwOHFANjPdQAAYAIIcfT/
-iiAHDalxCNqeCWAFGNtZAwAA4HjxwNoKAADPc4AABA+A4AbygeAG9AHYA/AA2AqrgOEG8oHhBvQB
-2APwANgLqwDYz3WgANAbFqUKiwDez3GgALAfgOCdvg/yCIuA4A3yz3cDAEANz3CgAKgg66DUoQLY
-FqUC8NWhC4uA4A/yCYuA4A3yz3AB4ACAFaXPcKAAyB8YEACGgrgWpYDiFvIA2ZS5z3CAABgPIKDP
-cAAATBzPcRCAAABuC4AAz3CgAMgfGBAAhoO4FqWNAgAAz3CgAMgfGBAAhs9xoADQG6G4FqEA2J24
-z3GgALAfFaHgfuB4z3Gqqru7z3CfANj/LqAuoC6gLqDPcKAAyDsOgM9xoAC4P4i4EhkYgGkgQAD+
-8eB48cDhxaHBCiYAAQonQAFTJ801UyXENVMmxTXXukDDVgmgAKlzz3CgANAPAN21oM9xoADIOy6B
-2gigAH3YOgugAKlwCNgA2b4KoACZueH/+QEgAKHA4cT8HMi+/BxIvuHA4cHhwuHD/BwIsfwcSLH8
-HIix/BzIsfwcCLL8HEiy/ByIsvwcyLLhxeHG4cf8HAi0/BwIv2okgBDhxGokwBDhxPHA63fPdqAA
-0BtcFhAQz3AAAEQcAg+gAAolwB+4cM9wgACEJAOAgOAE8heG4rgh9M9wgAAYDwCACyBAgcogIgMR
-9EwgQKAK8kwggKAI8kwgAKEI8g/YB/AN2AXwBNgD8A7YqXHpctDbCiQABL3/0cDBxGskwBDBxGsk
-gBDBxJ90BBQQNMHHwcbBxQQUCzQEFAo0BBQJNAQUCDQEFAc0BBQGNAQUBTQEFAQ0wcPBwsHBwcDB
-xEUsfhAKJkB+wcRrJIAUwcQgIICH8cDyD0AAddieD2AAiiHIDmYLAAC6CwABMP+eCQAABtgKIcAP
-63KKIwkDSiQAAAolAAGa/9HA4H78HIi2/BxItvwcCLb8HMi1/ByItfwcSLX8HAi1/BzItPwciLT8
-HEi0/BwItPwcyLP8HIiz/BxIs+B+4HgE3DjdNfDgeATcNN0z8OB4BNww3THw4HgE3CzdL/DgeATc
-KN0t8OB4BNwk3Svw4HgE3CDdKfDgeATcHN0n8OB4BNwY3SXw4HgE3BTdI/DgeATcEN0h8OB4BNwM
-3R/w4HgE3AjdHPDgeATcBN0Z8DQUGjAwFBkwLBQYMCgUFzAkFBYwIBQVMBwUFDAYFBMwFBQSMBAU
-ETAMFBAwAscBxrAkTTOwJB8z4H7xwE4Pz/8KJkCQCHUD8qDli/YF2AohwA/rcujbSiRAAF4N7/+4
-c89wgADsFrV4jQfv/8CgANmeuRl5z3CAAOQWAYDPcoAAaBYleOB/gBoAAADZnrkZec9wgADkFgGA
-z3KAAGgWJnjgf4AaAAAA2Z65GXnPcIAA5BYBgCR4QiAAgMogYgDgfuB4z3CAAOQWAYDgfy8oAQDg
-ePHAngrP/2kggAFvIT8A//HxwGrY3g1gAIohxAEA2I24jgygAQkaGDASzEQgPoUJ8s9wgACEEQCI
-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
-QIDPcD8AAsEQpc9wYAACzBClz3ABAALLEKXPcAgAAokQpc9wdwACkBClz3DHAAKLEKXPcF8AAhgQ
-pc9wBQACGRClz3ADAALAEKXPcCAAAl4Qpc9wYwACZRClz3AGAAJmEKXPcAEAAtgQpc9wYAAC0hCl
-xg7v/wpwQQLP9mzx4HgA2g3wVHhjiCKIz3CsANQBAeJPejV4ixjYgM9wgADIFSCIMHLgIMoH7vHg
-ePHA4cUIdc9xgADIAwWJgOAE9ASJgOAP8u//B9oA2M9xrADUAdgZgICA5cogoQLQGQCA9QHP9uB4
-8cDhxQh1IZBAkM9wowDY/VV4ihhYACCVKdgSuPAgQQABlTBwCvKSCG/3iiDRA4og0QOGCG/3IIW1
-Ac/28cDhxQh1IZBAkM9wqADUA1V4CxhYgCCVFdgTuPAgQQABlTBwCvJWCG/3iiDRA4og0QNKCG/3
-IIV5Ac/28cDhxQh1IZBAkM9wrADUAVV4ixhYgCCVK9gSuPAgQQABlTBwCvIaCG/3iiDRA4og0QMO
-CG/3IIU9Ac/28cDhxQh1AJDPcqAA7CcIuE8gQQABlRC4JXjPcaAAxCcQoQCVCLhFIMAAEKEqggGV
-MHAL8s4PL/eKINEDiiDRA8IPL/cghfUAz/bgeM9xrADUAQDYixkYgIwZGIAH2I0ZGIAG2ZG5z3Cg
-AMQnMKDPcRgABwIwoM9ygAB0bzSKgOEF9M9xEAAGAjCgIIKA4VHyBtmWuTCgz3F4AAKFMKDPcQIA
-AoEwoM9xVQACgjCgz3EQAAKGMKDPcUEAAocwoM9xBwAC0zCgz3EBAAKKMKDPcQAAAqUwoM9xAAAC
-pjCgz3EAAAKnMKDPcQYAAqgwoM9xBgACqTCgz3EGAAKqMKDPcf8AB8UwoM9x/wAH2zCgz3H/AAcm
-MKDPcf8AByMwoM9xGAACHzCgz3HMAAIeV/AH2Za5MKDPcQEAAocwoM9xAwACxTCgz3GAAALbMKDP
-cXAAAoUwoM9xcAACgTCgz3EGAALTMKDPcSEAAoowoM9xBQACpTCgz3EFAAKmMKDPcQUAAqcwoM9x
-DAACqDCgz3EMAAKpMKDPcQwAAqowoM9xRAACJjCgz3FEAAIjMKDPcSgAAhYwoM9xmQACFTCgz3H/
-AAeCMKDPcf8AB4YwoM9x/wAHHzCgz3H/AAceMKDgfuB48cC4cM9wgAB0bwAQBABMJACAANgO8s9y
-gAAUOALwAeCO4FX3FiIBACCJsHH59Rfwz3KAAIQ4A/AB4KbgR/cWIgEAIImwcfr1CfAK2AohwA/r
-csYMr/aJ2wDY0cDgfuB4z3KAAHRvNIqA4QGCB/Q1ioDhwiCiAMAgoQDE8c9wgAB0b0CAIoDPcIAA
-FDiA4jZ4A/LgfweI4H93EIAA8cA+Do/2z3WAABURAI2A4BwAAgDPcAAAkGUKJABw4HioIAAB4Hjg
-eAHYAK0G2JC4z3WgAMQnEKXPcIAAdG9AgCKAz3egAOwnz3CAABQ4gOIF8jZ4BtmWuQXwcOA2eAfZ
-lrkwpc92BAAHvM9xEAAHuNClMKXPcQoAB7wwpc9xPwACwTClIogQuQUhgQ8AAAKyMKUhiBC5BSGB
-DwAAArMwpSWIELkFIYEPAAACtDClJIgQuQUhgQ8AAAK1MKUjiBC5BSGBDwAAArYwpQaIELgFIIAP
-AAACtxClz3AEAAa8EKXPcAEABrEQpc9wAwAGrhClz3ABAAa8EKXPcAMABgAQpc9wCAAGvBClz3AQ
-AAa4EKXPcAAAoCgKJABw4HioIAAB4HjgeM9wIAAGvBClz3AAACgKCiQAcOB4qCAAAeB44HjPcAAA
-A/AQpQqHhCABD0EokQDPcCAAB7wQpc9wAAAD7xClKBcQEAolAASEJQEIjCUBiAzyEdgKIcAP63KK
-I8QH+gqv9gokAARMIYChUyAAIU33j+DKIGEEwCBiABC4BSCADwAAAtsQpdCl9QSP9uB48cCaDK/2
-iiEGBM91oACwHxiFvguP/Ah2DPAI2AohwA/rcsfbSiQAAKIKr/YKJQABz3IAAAPwz3GgAMQnz3Cg
-AOwnUKEKgOe4CPQYhTYLL/zJcYLg7vXj8a0Ej/bxwOHFz3WAAHRvAKUhpVStqg3v/3Wtwg3v/wKl
-qgvv/wOlz3CAAMgDBYiA4Afyyg3P/93/Wgrv/xSNeQSP9uB48cCKIFIONgsv93PZz3CAAIQoQCCB
-BU4Ib/cW2gHZz3CAAKAo0cDgfzWo4HjxwMoLj/aC4Ah1jPcF2AohwA/rck/bSiQAAOoJr/a4c892
-gACEKAuGz3GAALQoEHUE9KhhgOA78kYI7/8B2BpwiiASDsoKL/epcUQtvhUAJkAeIJDPcqQAHEAy
-oiGQAN/Pc6QAtEUxoiKQJRtYgCOQJhtYgCSQz3OkAJhAOKIlkCCjJpAhoyeQO6IokDyiKZA5oiqQ
-z3CkAJBBKaAOCO//CnCrpr5mMB7CE4UDj/bgePHA4cWmwYogkg1WCi/3hNmLcJ4OL/cG2QAUADGA
-4Bb0QCSAMM91gACEKKlxWg8v9xbaz3CAAKAoAdk0qAuFgODKICEADA/B/wAUADGB4Br0iiDSDQoK
-L/eV2UAkgDDPdYAAhChAJYEVHg8v9xbaz3GAAKAoAdgVqSuFgeHUDsH/Dg4P9xEDr/amwOB48cCO
-Co/2HhIBNuC5ngABAEQgAA5DuEogACDPcaAAyBzogVMgDQBEIIEAPHk9ZUQgAAFCuB1lr30C2c9w
-oADIH0kYWIAK3gokgHPgeKggAAHgeOB4gOUN9gXYCiHAD+tyiiOECJhzYgiv9golAATPcaoArFKB
-5THIyPaAuDEaGDAB2F0ZGIAH8KC4MRoYMF0ZGIQKJIBz4HioIAAB4HjgeM9woADIH0gY2INJAo/2
-4HjxwALYz3GAALgoFakWiVSJRSBAAhapE4kQcgXyNg/v/xSp0cDgfuB48cAC2M9xgAC4KBWpFolU
-iaO4obiAuBapEYkQcgTyDg/v/xSp0cDgfvHAkgmv9gDbz3CgALAfOIAC2s92gAC4KFWuGIDPdYAA
-wElIhm4dGBDPcIAANEsTgG8dmBAB4HAdGBAajtW5dKZ1pnMdGBBgpmGmYqZjps9wgACwKWygbaAB
-2HOOFq5EIwMO8o5Du0QnDx5Dv/FzBPQF2BauUHFN94G4Fq7N/89wgAA0SxSAAeBxHRgQAvDT/2kB
-j/bxwPoIj/bPdYAAuCgajSGFCSEQAEwgAKAE8kwgAKLO9wXYCiHAD+tyiiOMAwokAAQCD2/2SiUA
-AADYC6UMpUwgAKANpdf3CHEIcghzCHYSaRR4H2X6hwHh/mYfZfuHuGAcgPtjL3kScRpiTaWx92yl
-y6UA2A6lD6UQpUokwHAA2aggAAIVJUIQC4IB4S95EaLNAI/28cBqCK/2mHDPdYAAuCgwjQDaVSVD
-FEokwHCoIIADESGAgAj0z3D/AP//FSWMEBGkAeJPejKFUYUwchOF0fYQcsv2EHHF9gLaANgB2Rfw
-AdoA2ALZE/AB2gLYANkP8BBxyvYQcsX2ANkC2gHYB/AB2ALZBPAC2AHZANrwI44A8CNFAAIljwPw
-IwMA9KUA2A8ggAACI0MBdaXPc4AADCkEqw8gQAAFqy0Ar/YAHIIA4HjxwLoPb/YA2KHBYMCs/4tw
-0P/Pc4AA0Ck4i892gAC0Ks91gAC4KIDhVSVCFAP0GI0Q8CDA/o3wIgYAAYUFKP4DDCZAjjX2AdgY
-rQDZNB5CkIDhzCBhgBD0IMHwIk8AIYVejQUpvgA3d8b2AtgYrQHZNB5CkIHgHPKC4BDyg+Ah8gXY
-CiHAD+tyiiMPDIokww9eDW/2uHMq8AGFPY0FKT4AFIU3cAT3WRWBEB3wGYuA4Pv1WBWAEDNoJXgR
-rRbwAYU9jQUpPgA0hQAhQH4QcTD3VYVQcFkVgRCF90UhAQ4xrQTwE2kleBGtGY2B4BHyguAU8oPg
-FfIF2AohwA/rcooj0AOKJMMP6gxv9rhzHvBYFYAQM2gleBnwWRWBEBPwAYU9jQUpPgBUhQAhQH4Q
-clkVgRAJ91WFUHCF90UhAQ4yrQTwE2kleBKtE41EIAEOQ7mH4Qf0WRWAEEUgAA4TrTKNERWFEAUh
-QQEleEQgAA4QFYQQQ7gLJACACfQF2AohwA/rcm4Mb/aKI9AHMo0RFYUQE40FIUEBJXhEIAAOEBWE
-EEO4BiA+gQryBdgKIcAP63I+DG/2iiMQCGkGb/ahwOB48cAD2M9xgAC4KBWpANgWqRGJVIkQcgXy
-Ugvv/xSp0cDgfuB48cDaDU/2z3WAALgoGo0hhRBxR/cbjSKFEHE+AAUANIXPcIAAFCkuYH3/ANgU
-pRWlAKUBpQKlA6XPdYAAsCkMpQ2l5//PcKAAsB8YgDa42GDJuA+lNvAWjUCFPI2huDByFq2O9+T+
-z3CAADRLFIDPcYAAwEkB4HEZGAAO8M9xoACwHziBSIXVuVBxRfeBuBat6vHj/s9woACwHxiAz3GA
-AMBJbhkYAAiFz3KAADRLbxkYABOCAeBwGRgAGo1zGRgAhQVP9vHAGg5v9g/Yz3KAALgoFYqA4BPy
-g+AQ9M9woACwHziATRIABja5InjJuIwgx49UC83/A/DC/9HA4H7gePHAzgxP9gh2wLiB4EohQCDC
-IUIkyXeEJwEcRL/JcIQgDgBCKNABRCaBEzx5z3WAALgoBCaAHwAAAAxKuBitBCaAHwAAADBMuBmt
-BCaAHwAAAEBOuM9ygAC0KlMhvoA1GgKAMK0N9AXYCiHAD+tyiiPIDYokww+WCm/2SiUAAEwhAKAy
-8hCNBCABBBJxDfIF2AohwA/rcoojiQCKJMMPbgpv9kolAAAEIMAjEHcN8gXYCiHAD+tyiiPJAIok
-ww9OCm/2SiUAAIDnVvQF2AohwA/rcoojCQGKJMMPMgpv9kolAABK8BmNg+AD9oDgDfYF2AohwA/r
-coojiQKKJMMPDgpv9kolAAAZjTiNEHED9oDhDfYF2AohwA/rcoojSQOKJMMP6glv9kolAAAQjXiN
-UyABAEQgggBEIAABXHpZYUK4GWEveXBxRPY4rShzWY1QcUP2Oa0ocoLhR/YA2c9wgAC0KjUYQoBQ
-cxWNBvSA4ATyBNgVrVWNgeLMIiKAzCIigQb0MI0TaSV4Eq0RrYDnzCIigQXyE28Ff/GtCiAAhMwi
-IoEG8kAowSAleBKtEI0zaCV4E60RjZII7/8Urc9wgAD0KG0Db/bPsPHAEgtP9s92gAC4KBWOgOAN
-8gYMb/YP2ADdta62rjnMhv/PcIAA9CivsFUDT/bgePHA2gpP9gh3H8jPdYAAuCgluFoVARFTIBAA
-MHcVjUfyF60B3tWt6XB4/+C/BPQVjYTgBPTn/1bwF42A4ADaMfTVrc9wgACwKUygTaBWrdqt260K
-2TytBd7drVDZPq0A2Y65KaVwEoMwKqWE48wjYoEopQPZz3OAAAwpKKsE2SmrKqvLq8yrzasG2S6r
-L6swqzGrCNkyqwzZM6sy2TCgz3CAALQqNBiCgCn+FY2A4Bry0MqQ4Bb0TCAAoBTyEI3PcoAAsCkz
-aCV4Eq0Rrc9woACwHziAThUAFja5OGAPogL/XQJP9vHA9glv9oDYocFgwGnMAhwEMM9wgABUEQCA
-gOC/9J4MT/+A4Lv0z3CAAEAlAIDkuLX0iiAKDwYJ7/Y0EgE2GgmAAM92gACYb8lwxg7v9tzZBZbP
-d4AAGBFEIIADHHhTIL6ABfQDh4a4A6dVJsAdog7v9hjZLpbPdYAAlHFYJUAeeLmODu/2GnAcFYWQ
-TCUAgBwfABQK8gXYCiHAD+tyqNuODy/2iiSDDweHz3GAADQRAYhAIJAAQCCCD0wggKhPekSpzfcF
-2AohwA/rcq/biiSDD14PL/YKJQAEB4fPcYAAoHKCDe/2CnIOlgC3ANor8AAWg0AAIoEPgADIcXSp
-ABaDQAAigQ+AAORxeKkAFoFAFSWDEMgbQoDJG0KAABaBQMobQoDLG0KAABYDQc9xgACUc1V5RBnc
-gAAWAEEB4kUZHIADjhByrAfF/9oOwAGaCW/2DtgKCm/9BNg0yM9xgACAcgehz3CAAFQRIIDPdYAA
-WBEAhRi5ELgFeYi5vg+v9oogiwAB2c9wgABUESCgANgApZ4JL/cAwBnwz3GAAPQpBIEB4AShz3Cg
-ANQDHJBaCQ/3AMB6CS/3Atk+D2AAAtiKIEoPdg+v9gDZkQBv9qHAz3CAABgRKIjPcIAA3HEpYAHY
-4H8meOB48cD6/89ygAAYESiKArkUec9wgAAccjBg0cAKuOB/DKLxwO4PL/aKIAsBosHPcYAAWBHP
-dgAAwBRgfiCBz3WAABgRI4VQIQwAUCTMkQjyLyhBAG4PYABOIMAHxvDnuRfyCYWB4ADfBvRWD2AA
-AtjppQOFp7gDpYogSwBgfgDZCoWA4LLyQHjqpa7wz3CAAFgRAICA4J304LmI9Nr/Ggxv+wyFGnAD
-2BIMb/sLuAhxCnDuC2/7CtrPcYAAmFJRgc9xgAAgUVR5MYmA4QHZwHmA4MwhIoBQ8s9wgADkcTiI
-z3CAABARAJAQcQDaH/TPcIAAmG8lgB4SAzZTIQ8AUyMFALB3E/TPcIAAmG8DiIHgxCGBDwAGAADE
-I4EPAAYAAMwhwYDKImEAH8hOpc91gABUEeW4z3CAAFgRIIAAhRC5GLgFeRPygOIR9HDKg+AN9Im5
-YH6KIIsAAtgApQDYz3GAAFgRAKFA8IUhDABgfoogiwAD2PTxgOAO9Itwpgyv+4HBz3CgALAfGIAB
-wYogCwgf8IogiwhgfoohBQjPcYAA/BUXgQHgF6Eg8GYNYAAB2G4PL/YO2IIIb/0E2LYNQADPcIAA
-gHIngIogyg9AfgzwBdgKIcAP63KKI4UPSiSAAGoML/a4cwHYjQYv9qLA8cAmDi/2iiBLAc91gABY
-Ec92AADAFGB+IIXPcoAAGBEDggQgvo8AAIIAIIUV8oDhEAsC+M93gABUEUCHIIUYukApAARFeIi4
-BXlgfoogiwAB2ACnbfCA4Sf0A8jPd4AAVBEEIIAP////wwMaGDCKIMsAYH4A2QCHIIUYuBC5BXmF
-IUgAYH6KIIsAAtgApwHewKXPcwEAKFEB2AbZ1gkgAQTayXBG8IHhH/QD2B4Kb/sLuADZ/glv+wra
-gOAT9IYKD/jPd4AAVBEghwCFGLkQuAV5iLlgfoogiwAB2ACnANgApQHYJvCC4Rj0grgDos9xgAD0
-KQaBz3eAAFQRAeAGoSCHGLmIuZG5YH6KIIsAAdgApwDYAKUO8AXYCiHAD+tyiiNHAEokgAAyCy/2
-uHMA2F0FD/bxwN4ML/aKIIsBz3GAAFgRz3UAAMAUYH0ggc92gAAYEQOGBCC+jwAAggAb8s92gABU
-EQCGz3GAAFgRIIEYuBC5BXmFIRgAYH2KIIsABtgApgDZz3CAAFgRIKAocOXwA9g2CW/7C7gA2RYJ
-b/sK2s9xgABYEYDgIIEH9M92gABUEQCGGLjd8YDhw/Qojs9wgADwcTV4N5AsEBEBz3eAAJhvBBcQ
-EQwXExAKIkCgSiRAIB7yMnFM9wXYCiHAD+tyiiMHDQokAAViCi/2uHMKIMCEDvJScAz3BdgKIcAP
-63KKI4cNSiRAAEIKL/a4cwwhAKRM9wXYCiHAD+tyiiOHDkokQAAmCi/2uHMKIMCEDvIycAz3BdgK
-IcAP63KKIwcPSiRAAAYKL/a4cw6GgOAojh30C4aA4Bn0z3CgALAfWBgABc9woADIH7wQAAANps9w
-gAD8cSlgYH2KIEsGiiBLBmB9LYYsHgAVRYcGhx8aGDAFlx4amDBojs9xgAD8cTkaHDBTIgAAaWGq
-Dm/2ANsIjs9xgABccRV5Ag3v9gqHiiBLB893gABUEWB9IIeSDm/3AdgCDkAAAIfPcYAAWBEggRi4
-ELkFeYq5YH2KIIsABNgApwDZz3CAAFgRIKAojs9wgAD8cSlgYH2KIAsEz3GgAMgfRxEBBmB9iiAL
-BA6GgOAH9KoJIAEA2G4OD/8B2A3wBdgKIcAP63KKI0gOSiSAAAoJL/a4cwDYDQMP9uB48cDGCi/2
-iiDLAc93gABYEc91AADAFGB9IIfPdoAAGBEDhgQgvo8AAIIADPQA2D4PL/uMuADZHg8v+wragOAJ
-9M92gABUEQCGGLggh+Twz3CAAJhvA4B+Dy/7LYaA4CCHOfIOhoDgN/TPcIAAVBEAgBC5GLgFeYUh
-GABgfYogiwDPcIAAVBEG2SCgANjPcYAA9CkApwCBAeAAoSiOz3CAAPxxKWBgfYogywWKIMsFYH0s
-hs9xoACoIC+BYH2KIMsFiiDLBWB9JIaKIMsFYH0thrnwgOE69KYKQAAojs9wgADccShgQIfPcYAA
-VBEggeC4ELpAKQMGZXoP8oC4BaYA2AamCLklekUigQFgfYogiwAG2ACnl/AB2M9zoACwH89xoADI
-HxajvBEAAE8iAQKKuQSmYH2KIIsABdnPcIAAVBEgoADYAKdW8IbhUvQlhuC5HvIGhloLQADPcIAA
-VBFAgCCHQCoABhC5BXkIukV5gLlgfYogiwAB2ACnz3CAAIxv8gvP94ogSwQA2TDwgOEI8i8pQQBO
-IYAHBqbe8QHYz3GgALAfFqHPcKAAyB+8EAAABKbPcIAAVBEAgBi4hSAUAE8gQQSSuWB9iiCLAM9w
-gABUEQXZIKAA2ACnz3CgAMgfRxABBoogSwRAfQTwgeEE9AHYKvCC4Rz0A4bPcoAA9CmEuAOmB4LP
-doAAVBEB4AeiAIYYuBC5BXmFIRgAYH2KIIsABtgApgDYAKcO8AXYCiHAD+tyiiPKD0okgAC+Du/1
-uHMA2OkAD/bxwHoID/bPdoAAGBEDhgQgvo8AAIIADPQA2AoNL/uMuADZ6gwv+wragOAW9M93gABU
-EQCHz3aAAFgRIIYYuM91AADAFBC5BXmFIRgARQMgAIogiwDPcIAAmG8DgM93AACMqmB/LYaA4Hny
-DoaA4Hf0DIbPdQAAwBQIIIAPAAABFJkgCgBgfySGKI7PcoAA/HHPd4AA9CmA4CliLfJgfYogSwaK
-IMsEYH0shs9xoACoIC+BYH2KIMsEiiDLBGB9JIaKIMsEYH0thuYKQADPcYAANBEA2AWpCI4shwHg
-AeEsp89xgACYbyOJD3gwcAiunPbq8ACHAeAAp2B9iiDLBYogywVgfSyGz3GgAKggL4FgfYogywWK
-IMsFYH0khoogywVgfS2Gz3eAAFQRAIfPdoAAWBEghhi4ELkFeVUCIACFIRgAhSEMAHoOb/aKIIsA
-A9gAp6l2ANgApqzwv/2WDGAAGnDPdYAAWBGA4CCFJvJMIACgJPRIjs9wgADwcVV4FpAQuQq4DKbP
-cIAA3HFIYIC4BaYA2Aamz3aAAFQRAIYYuAV5hSGQARoOb/aKIIsABNgApgbYAKV+8IDhlvTPcIAA
-mG8DkIDgBfJMIACgEvLPdoAAVBEghoogiwDPdwAAwBQYuYUhVAFAfwXYAKYApdfwz3CAAJhvApAK
-uGB/JIaA4M3yz3KAAMBJN4IWgiJ4IoJDgs93AADAFEJ5GWHPcIAAmG8DkDBwpgAFAGB/iiCLBM9x
-oACoIC+BYH+KIIsEz3GAAPQpAYEB4GYJYAABoQiOAeAIrob9z3GAADQRANgFqc9wgACYbwOIKI4Q
-cVgACgCyCi/7DIYacAPYqgov+wu4CHEKcIYKL/sK2s92gABUESCFQIaA4EApAwQYumV6DPKFIgwA
-RXlgf4ogiwAD2ACmANh28IUiGABFeWB/iiCLAAbY9/HiCkAA9PHPdoAAVBEAhiCFGLgQuQV5hSFU
-AYogiwCD8YXhXvQMhmB/JIaA4FXyiiDLBMoMb/Yshs9xoACoIC+Bugxv9oogywSiCEAAz3GAADQR
-ANgFqQiOz3eAAFQRAeAIrgCHIIUYuBC5BXmFIRQAigxv9oogiwAF2ACnANgApc9wgACYbwOIKI4Q
-cXQHyv9G/c4JL/sMhhpwA9jCCS/7C7gIcQpwogkv+wraIIdAhYDgGLkQusoF4v9FeYUhGACpds91
-AADAFIogiwBAfQbYwQXv/wCnAdhBBc/1BdgKIcAP63KKI04NSiSAAAIL7/W4c37x8cDGDO/1iiBL
-As92gABYEc91AADAFGB9IIYAhoDgRfQA2c9woADQDzWgiiALB89xgABUEWB9IIGqCc/3z3eAAABS
-QIdTIgAAPggv/ymXAYfluADYAvIJlyYLwACKIMsDYH0pl89woACwHwHf9qDPcaAAyB+8EQEAz3CA
-ABgRJKDPcIAAVBEAgCCGQCgCBhC5RXkIuAV5grlgfYogiwAE2ACm6XB28ITgaPSeD8/+9g/v9QLY
-+gsP9lIN7/4B2M9wgAAUUroOj/ZGDy/3AdiiCs/3z3eAAFQRiiBLB2B9IIeKIAsEYH1AEgE3AIdA
-hkAoAQYIuBC6RXkFeWB9iiCLAADYAKYfyOW4IIcT8s9wgAAYEQ6AgOAN9HDKg+AJ9Bi5hSEcAGB9
-iiCLAAfYIvDCDs/+z3CAAJhvBIBAhyCGgOAYuhC5RXkL8s9wgAAYEQOABCC+jwAAgwAH8oi5YH2K
-IIsAAdgG8Iu5YH2KIIsACNgApwDYAKYO8AXYCiHAD+tyiiNQCkokgAByCe/1uHMA2J0Dz/XxwDIL
-7/WKIIsCz3aAAFgRz3UAAMAUYH0ghgCGgOBE9M9ygAAYEWOCz3eAAFQRAIcEI76PAACCAEAoAQYc
-9E6CgOIY9Ai4BXmAuWB9iiCLAAHf4KbPcwEAKFEA2AbZIg+gAATaiiALBWB9ANnpcFrw4LsE8oi5
-RfDPcoAAmG9EgoDiCvKLuWB9iiCLAAjYAKcA2AjwCLgFeWB9iiCLAADYAKZA8IHgGPTPcIAAGBED
-gAQgvo8AAIIAyiBhADLykg+P9893gABUEQCHIIYYuBC5BXnS8YLgGvTPcYAAGBEDgc93gABUEYW4
-A6HPcYAA9CkIgQHgCKEghxi5iLmRuWB9iiCLAAHYxfEF2AohwA/rcoojkQxKJIAATgjv9bhzANh5
-As/18cAOCu/1iiDLAs91gABYEc92AADAFGB+IIWKIMsCz3eAAJhvYH4khwCFgOA+9ASHz3EBADxP
-Bto+Ci/7CtvPcYAAGBEBoc9ygAD0KSqCjCDDjwHhKqIO9AXYCiHAD+tyiiMSBUokgADaD6/1SiUA
-AKYK7/UO2L4L7/wE2LoMz/7PcIAAVBEAgCCFQCgCBhC5RXkIuCV4RSDBAGB+iiCLAAPYAKUB2Crw
-g+Ac9M9xgAD0KQuBz3eAAFQRAeALoSCHGLmIuZC5kblgfoogiwAB2ACnANkgpc9wgAAYESugDfAF
-2AohwA/rcoojUgpKJIAAUg+v9bhzANh9Ac/18cB2C8/10cDgfwDY8cDhxaPBCHWKIIsDOghv9qlx
-z3CAACARIIgBHEIzz3CAAPtxKGBgwQHaz3GgAMgfAxwCMADYAhwCMM9woACwH1agwBEAAELAvBEA
-AAzZQcCLcJ4Jb/aE2iUB7/WjwOB48cCqCM/1z3WAAFQRIIXPdoAAWBEAhhi5ELgFecoPL/aKIIsA
-ANkgpSCmz3CAACARIKjPcIAAJBEgoM9wgABEESCg/9nPcIAAHBHNAO/1IKDxwOHFCHVaCe/1Dthu
-Cu/8BNipcM//5/9mC8/+iiALAHYPL/apcakAz/XgePHAKgjv9YHYocFgwGnMz3YAAMAUAhwEMIog
-iwdgflrZz3WAAFQRiiCLB2B+IIWKIIsHz3eAAFgRYH4ghwCFgOAC2Q/yz3GAACQRAIGBuAChz3GA
-APQpA4EB4AOhAdkCCa/2AMDPcIAAHBEAgIwgw48c8oogCwBgfnXZz3CAABwRAIguCS/7Ctn/2c9w
-gAAcESCgIIUAhxi5ELgFeWB+iiCLAADYAKUApwCFgOAE9ACHgOAG8gIKz/2A4A/yiiALAGB+fdnP
-cIAAJBEAgC8oAQBOIMAHwP+9B6/1ocDxwM9wgACgckGIz3GAALBwpgtv9gLiz3CAABgRIJDPcIAA
-mG/RwOB/LrDgeM9xgABUESCBANiA4eB8geHgfIjh4HzgfwHY4HjxwAoPj/Uodc9xgABUEUCBgOIG
-9IDl4iBCA0Dwz3GAAEARoKHPc4AAJBEgg4jih7kgo89zgAD0KSKDAeEio89xgAA8EQChKvTPcIAA
-WBEAgIPgJPSKIAsA7g0v9oohyATPdoAAHBEAhowgw48N9AXYCiHAD+tyiiMIBUokgAC+DK/1SiUA
-AACOAggv+wrZ/9gApgLYh//A8d0Gj/XxwM9wgABUEQCAgOAJ8s9xgAD0KQmBAeAJoQLYfv/RwOB+
-4HjxwM9xgABUEYogCwZ6DS/2IIEiD6/1DtiSD6/8BNj/2c9wgAAcEdHA4H8goPHAGg6P9c9xAQAE
-Us9zgACMbyKjz3KAACgqQKPPcYAAxHIhoyCCHN3PcoAAmG+goSCDQCINB1Uiww1joRjboaFioWGB
-mHEhg4Dgjbkhowr0z3eAALBwz3CAADQR4KA38M9xgAA0ESCBRCi+CCGJL3BAIYUAz3GAAMtvCWEv
-JUcBANvPdYAAOBEC4S95oI0O8AAjjg+AALRvf2cW5g5mAeNfZ2973B+CEzBzAiVPELL2VSLADR9n
-z3CAADQRbpLgoAIjQwFwe3lhLrIUHMADLpKxBa/1EBxAAPHARg2P9aXBz3WAACARAI3PdoAA/HEJ
-ZmoML/aKIAsDz3CAAJhvBYAB28C4DRwCMACNANoIZs9xoADIH2PAz3CgALAfdqDAEQAADhyCMEHA
-vBEAAA8cgjBAwBKBRMMU2ULAi3DGDS/2gtpJBa/1pcDxwNYMj/Wkwc92gAAgEQCOz3WAAPxxCWX6
-Cy/2iiBLA89wgACYbwWAAdrAuAEcAjAAjs9xoADIHwhlYMAA2AIcAjADHAIwz3CgALAfVqDAEQAA
-QsC8EQAAQcDPcIAAwEk7gAeAOGBDwItwENlODS/2g9rRBK/1pMDxwFoMj/XPdYAAWBEAhYHgDPIF
-2AohwA/rcoojBAJKJAAAbgqv9bhzz3aAAFQRAIaC4Mwg4oEO8gXYCiHAD+tyiiNEAkokAABGCq/1
-uHMAhs9xgACkVyWBz3cAAMAU4Lku8oLgDfQghRC5iLmJuZm5YH+KIIsAA9gApgDYLPAGD4/+z3CA
-ACQRAIAgheC4AIYQuRi4BXkI9M9wgACYbwSAgOAI9Ii5YH+KIIsAAdjm8Yu5YH+KIIsACNjg8UCF
-QCgBBgi4ELpFeQV5gblgf4ogiwAC2O0Dr/UApeB48cB+C4/1z3aAAFQRAIbPdYAAWBGE4AX0IIWB
-4Q3yBdgKIcAP63KKI4UCSiQAAIYJr/W4cwCGz3GAAMRyJYFAKAIG4LkghQi4ELlFeQV5IvLPdoAA
-MBEAhgDaDyICAM9wgAAsEWCAAd9FIYEBRntgoE4KL/aKIIsABtgApc9wgAA5EeCoiiBLBDYKL/Yg
-hgnwgbkuCi/2iiCLAALYAKVJA4/14HjxwN4Kj/XPcYAAJBEAgc91gABUEYC4AKHPcYAA9CkFgc92
-gABYEQHgBaEghQCGGLkQuAV5hSEYAOIJL/aKIIsABtgApQDYBQOv9QCm8cDPcIAAmG9EkIDiFfLP
-cIAAOREAiIDgD/TPcYAAwEkbgSeBGWEwcgf3pgkv9oogywcB2ALwANjRwOB+8cBSCo/1z3aAAFQR
-ABYFEEwlQIKK9wXYCiHAD+tyVNtmCK/1SiSAAM93gAC0OQCGoYYIuCKGBX0wdQnyELmleVIJL/aK
-IEsFoqYAhvAnABBAeIDg7fNlAo/14HjPcYAAQCoCoc9wgACkVwGhz3KAANxyAIFgggCAYKAggQRq
-AaFWIgACA6EY2AKhViLAAgWhAYIEoSGBAYGNuJC44H8BofHAugxAAM9wgABAKlIMT/fRwOB+8cBw
-yoTgB/TGC0ABug0AAATwgeBUCAEA0cDgfvHAhgmP9c91gADccgAWAUAAFgBAViUOEgClBG32DC/2
-D9nJcHIOL/YilR6Vz3GAAGQR2GAAoQPIBSCADwAAAHwDGhgwKg1P9akBj/XxwO3/ogwP9s9wAQC0
-VDYPz/+ODkAAgOAL9M9yAQCAVADYig5gAAXZag5gAAXY0cDgfuB48cDhxc91oADIH7gVABDPcZ8A
-2P/VuA6hOg/P/xUVAJbPcaAA0BuOuByhNg5gAADYSQGP9fHA4cUB2s9xoADIH89woACwH1agvBEA
-AKnBRsDAEQAAz3WAAKRXR8AFheC4CPLnuAb0qglP+4YJr/UQ2ItxqXD2DC/2GNqLcCTZbgkv9pDa
-AtnPcJ8A2P8uoN4NQACA4Av0z3IBAIBUANjaDWAABdm6DWAABdjRAK/1qcDxwFIIr/Uw2s9xnwDY
-/06hDRoYMM9zoADUB89yoAAUBAqiHxMAhgHZNBoYMBkTDYYD2BCiJKIPEw6GABYPQAAWD0AAFgBB
-z3egAJgD3qdA4BB4sXAW9w8TAIZWIAACDqIdEwOGDqKtu22iA8gFIIAPAAAAfAMaGDADyKy4AxoY
-MM4NL/cJGlgwMQCv9QDY4HjxwL4PT/XMdwAXkBAAjwCPAI9MIACozfYF2AohwA/rckzbSiRAANIN
-b/UKJQAEAN3PcIAAZCpMIACgSAAuAKugwI/PcIAAgD3WeACA6bgN8gXYCiHAD+tyWttKJAAAmg1v
-9QolAAHPcIAAZCoLgM9xgABkKgHlEnUPIIADC6Gi97IKD/adB0/1z3KAAGQqLIIA2IDhCPQvgoDh
-BvQmgoHhyiBiAOB/D3jxwOHFagkgAAh1z3GAAERbJZGA4WAADACA4C7yz3CAAJxTLIgA2s9zgABk
-Kg6DDyJCAAsggIAg9IwhAoAc8oQlAx+MJQKQDvKMJQKUB/KKIM8OCg7v9Z3ZDvAPg0V4D6MNg0V4
-DaPPcIAAgD02eCCAqLkgoB0HT/XxwKIOb/UA2UokwHfgeKgggAcB3c9ygACAPTZ6AILPc4AAZCro
-uMolIRAA3g8mThCA5e6DBPTGf+6jB/ALJ4CTA/SouACiAeHBBk/1SiTAdwDaqCBABgDZz3OAAGQq
-DoMPIYEACyBAgAz0DYMLIECACPTPcIAAgD1WeCCAiLkgoAHi4H7xwOHFz3WAAGQqKBUFEEwlwICL
-9wXYCiHAD+tySds2DG/1SiSAACqFz3CAANg58CBAAEB4YQZP9fHA6g1P9Qh1z3aAAGQqiiBPChYN
-7/UqhgqGEHVF94DlyiUCEAL0qqaKII8K+gzv9alxJQZP9eB4z3CAAGQq4H8KgOB48cCKIE8L3gzv
-9YohxAWeDm/1AtgA2Or/0cDgfvHA9v8A2YLgzCBigMogQgAC9AHY0cDgfw944HjxwM9woADQGxOA
-z3GgAMgf7rgM8gDYjrgVGRiAiiAPDIoM7/WKIYQAiiAPDH4M7/WKIUQBUgpP99HA4H7xwAHYz3GA
-AGQqA6HPcKAAqCAPgAShAoGB4KwPwf/RwOB+4HjxwIogTwxGDO/1gtkGDm/1AtjRwOB+4HjxwPYM
-T/XQ/4HgDPIF2AohwA/rcpTbiiTDDw4Lb/W4c891gABkKiOFgeEChQ/0geAA2QXyFI2A4AXybgkg
-ACalDPAjpQHYBqUI8IDgBvQB3vIK7//GpcKlz3CAAERbBZCA4PANyf/9BE/14HjxwIYMT/XPdYAA
-ZCpLhYDiyiGBD4AAgCo28giFgeA29CQVgBAA2Q8hAQAkekIiAoBshcoiYgAke4DjAdvNhcB7JH6A
-5gHe7oXAfuR5gOEB2cB5gOLMIyKAzCYikMwhIoAG8hytANmaCSAAKKUkFYAQz3GAAIAqAeAPeAip
-JBWAEKDgBPQA2AipZQRP9fHAz3CAAOQ5z3GAAGQqVggv9kDaQglgAADY0cDgfuB48cDhxcx1AIXP
-cIAAAFIBgOW4DPQF2AohwA/rcnjbiiTDD+4Jb/W4cwCFz3WAANxyAKUEbTYP7/UP2VYlABKyCC/2
-IpUGD8/1z3ABADRamgnP//IIQACA4Bf0z3CAAERbBZCA4IogjwvH9rIK7/WJ2T4LAAAG8KYK7/WO
-2c4KAAC2CGAADdjNA0/14HjxwE4LT/XPd4AApFcFh+C4qcEJ8ue4B/RCDA/7Hgxv9RDYi3HpcJIP
-7/UY2s9xoADIH89yoACwHwHYFqK8EQAAAN1GwMARAADPdoAAZCpHwAaGJNlIwItw3gvv9ZDaobel
-p6Gno6YGDe//AtjPcIAARFsFkIDgxfaspq+mBfCpcGoLIACpcQaGgeAB2soiIgDPdYAAcBEghYDg
-WWEgpQHYyiAiAEGFWGABpeYJ7/WKII8NiiCPDdoJ7/UhhfkCb/WpwOB48cCKCm/1ANkIdxjYz3aA
-AGxXALYqyKLBAabwrs9ygACIVzeqiiD/DwqmBtgVqhaqKcgxrjK2O7YDpjq2QCYAE64PL/fpcZDY
-z3WAAExXALWLcYHCUghv+OlwgeAL8gXYCiHAD+tycdtKJEAAUghv9bh3AMDguAHYyiAhAIDgCvKK
-IE8ORgnv9XXZAYajuAGmi3AkbV4O7/UG2s9wgACkKpYMD/fPcIAAZCr8qEUCb/WiwOB48cDWCW/1
-iiBPDs91AADAFGB9jNkB2M92gABkKgimz3eAAKRXiiBPDmB9JYd8jgDYLoYPIMAACyEAgCT0LIbl
-h89ygACAPXZ6BXkspuC/LYZgggzy578K9CV4Daaou2CiiiAPDp3ZCfAGeS2miLtgooogDw6k2UB9
-iiAPDmB9LYa9AU/18cBSCW/1ANrPcIAAZCoAgADdlr3PcQEAKF8dZalwz3YAADisYH4F2wDYlrjP
-d4AARFslhx1lBZe5YQDaCrgOIEAAz3EBABxeYH4M289xAQDsX6lwAtpgfg3bz3CAAGQqoKAA2Ja4
-uGClh89xAQAcXh1lBZcA2gq4DiBAA2B+DNs5AU/18cDOCG/1ANrPdoAAZCqghgDflr/PcQEAKF/9
-Zalwag9v+gXb/WXPcQEA7F+pcALaVg9v+g3bAQFv9aCm8cCSCG/1ANrPcKAAsB+4gADflr/PcQEA
-KF8EJY0fwP8AAP1lFOUAJY4fgAAAAKlwGg9v+gXb+GXPcQEAKF8A2goPb/oF2891gABkKsClz3EB
-AOxfyXAC2vIOb/oN250Ab/XApfHAKghv9QDaz3CgALAfGIAA35a/z3EBAChfBCCAD8D/AAAfZxDn
-ACeQH4AAAADpcM91AAA4rGB9BdsA2Ja4z3aAAERbJYYfZwWW+WEA2gq4DiBAAM9xAQAcXmB9DNvp
-cM9xAQAoXwDaYH0F2wDYlrgfZwWGz3EBABxeH2cFlgDaCrgOIMADYH0M289xAQDsXwpwAtpgfQ3b
-z3GAAGQqABkABADZlrkAIEAgJYYA2hlhBZYKuA4gQADPcQEAHF5gfQzbzQcP9eB48cBmDy/1iiBP
-Dc91AADAFGB9osHPdoAAZCoBhoHgEPSKIE8NYH2KIcYKAN2hpkIIb/UC2E4J7/+pcGbwfgnP/4Hg
-AdjAeC8nB5AQ8oogDw1gfYohhg6qCc//Adi+C+//BqYiCe//AthSCc//guAN8gXYCiHAD+tyiiOH
-AYokww8aDS/1uHMDyAUggA8AAAB8AxoYML4KD/XqCO//ANjSDy/1AtjPcIAARFsFkIDgWAAMAAyG
-QcANhnYPr/9AwIDgBvKA5wT0xghv/EDYi3AI2X4Pr/WU2oogjw5gfYohxwiKII8OYH0thoogjw5g
-fSyGgOcI9B4Iz/8GCc//AdgIpgDYDabJBi/1osDgePHAXg4v9YogDwqSDa/1iiHFBtYJT/7PdYAA
-ZCqA4Bf0iiDPDnYNr/WKIUUIAdgBpc9wgABEWwWQgODF9n4Pj/9A8ADYANms/zzwA8gEIIAP////
-gwMaGDADyIe4AxoYMAPIjrgDGhgw3gkv9QDe0gkP+tYOL/UC2CSFz3CgAKggD4CWIQoAInjXcACA
-AABJ94ogDwoGDa/1iiFFD8OlEgjv/8KlgODKIGEAzA+B/89wgABEWwWQgODE9gYPL/xA2AkGD/Xx
-wJoND/UIdih1zgyv9YogDwvPcIAARFsFkIDgw/YK/wLwKv/JcKlxxf/dBQ/14HjxwF4ND/XPcKAA
-yB/ygOQQEABTJ0AVACANBDpwz3CAAERbBYAQddr3iiDPDs92AADAFGB+iiHIDIogzw5gfulxiiDP
-DmB+CnGKIM8OYH4qcYogzw5gfqlxz3CAAERbBYAQdQDYyiBuAFUFD/XxwPYMD/XPcIAAmFIxgM9w
-gAAgUTR4EYiA4DXyNBIQNg0SDjYNGlgwz3KgANQHz3WgABQEKqULyM9xgAC8M7QYQACB2ZC5nBhA
-AAHYA6UOEgCGMxIPNjMaGDAfEgCGNBoYMAoJL/oA2A0amDPKpTMa2DPPcYAA/BUYgTQaGDQB4Bih
-2QQP9eB48cBqDA/1OnBIcBpzGNrPdoAAbFdAtioSAjaId891gACIVxq2QaYA2lCuV61Rrooj/w9q
-pjWtNq1btkAmABMaD+/1SHEDhum4DfQMjs9xgAAsLsO4HHgJYc9wgAAwDyhgDK7PcQAASBHPcIAA
-TFcgsEwhQKAE8oohBQIgsIDnBvLPcoAA4Crios9ygACYUkCC4LoO8hraQLaHuUwgAKAgsAbyz3CA
-AEAlBIAXrbP/z3CAAOAqag7P9hEED/XxwLILD/UIdhpxSHeWC6/7aHWA4MwmIpAJ8s9wgAD8XLCg
-ggwv9QPYB/DJcApx6XIA25h1xP/hAw/14HjxwOHFz3CAAKRXAdkloM91gAD8XBCFQHgA2BClZgwv
-9QPY0QMP9eB48cBSCw/1iHUQ3s9zgABsV8CzpN/PdoAATFeB4OC2BfSk2Iy4ALY7zM93gACIV464
-j7gBtirIAN7Qq9GrmbgBo9eviiD/DwqjNa82r9uzWrNAIwADYggv98lxz3aAAOAqgOUD8qKmff+W
-De/2yXBNAw/14HjPcIAApFclgM9wnwDY/y6gCNgAHwBAA9vPcKAA1AcVGNiANMgA2gAfAEDPcKAA
-0A8OGJiA4H7geM9xgAB4EeB/AKHgeM9wgAB4EeB/AIDgePHA4cUoc0hxz3KgALAfWIIEIoIPwP8A
-AAAijQ9AAAAAz3KfANj/rqLPcoAARFtFgnC6umJYYBIJb/oC2skCD/XxwOHFz3WAAOwqqXDSDa/1
-A9kBjYPgxPZjuAGtog2P9aUCD/XxwCoKD/UB3s91oACwH89zoADIH9alvBMCANdxAAAAgH4TD4YE
-9OG/BPIM8OG/CvLWpbwTDwBCf/FwcfcA2APwAdhRAg/14HjxwOIJL/WYcAHdj73Pd6AAwB0gh892
-oADIH+G5MtgG9A3wzr0I2AvwAd0J8AHYfh4YkLt9sH2PvQjYLyZH8xXy770V8gDZj7nc/4Dg6/UA
-h89xqqqqqoQggw9+HhiQiiCTAcIIj/XlAQ/1z3EAAP9/0v+A4AbyCyUAkdr1ANjZ8QCHz3G7u7u7
-hCCDD34eGJCKIJMB5/HgePHASgkP9Qh1iiATAX4Ir/Wpcc9wgAAUEQCIAd6A4MB+iiBTAQK+Zgiv
-9clxjuUE9oDlA/YA3XDKg+DMICKBJPTPcYAA7CoAieC4HvIKkRB1BPQLkRB2GPIA2s93oADIHwzY
-fh8YkKqxy7GA5comgRAUbqV4Ddl+H1iQxri7/wzYfh8YkC0BD/XxwL4IL/UA2QAWj0AB3al2z3Cg
-ANAPNaAocM9xoADALx6hhS8BGgokQH7geKggAAHgeOB4z3CgAMgfXxAAhoUvBB4vIAcgCiRAfuB4
-qCAAAeB44HgA2M9xoADIHB6hiiH/D89woADALz6gz3CgAMgc3qDbfkUvPh0KJEB+4HioIEAB4Hjg
-eLt9jCUIkN4Hxf8A2M9xoADALx6hCsjiuAHYyiAhAM9xoADQDxWhCNgAHwBANMgAHwBASguv9Qpw
-ZQAP9eB48cD+D+/0ANoAFghAABYHQAAWA0AAFgVAABYOQAHZz3CgALAfNqDPcKAAyB+8EAAApsFA
-wM9woADIH8AQAABRIMCRwC6iEs9woADQD1Wgz3CgAMgfGBAAhs9xoADQG6G4FqEA2Z25z3CgALAf
-NaAAFw8AUyBBEAAUBjDpcgDdBPAAFw8Ag+HKIsIDBfQEI40A532B4Qj0BCOAAAQlzwDxcMolYRCC
-4Qf0BCOPALB3yiViEAHfz3CgALAf9qDPcKAAyB+8EA8AwBAAAIDlAiePEQj0gObW8/F2qAft/0TH
-A/BExwrI4rgB2cohIQDPcKAA0A81oM9woADIHxgQAIZRIICRRCCBAM9woADQGzagANmduc9woACw
-HzSgEfQM2OxxAKE0yIDlAKGKIP8PAvIEwAChAgmv9UhwB/AD2c9woADUBxUYWIAhB+/0psDxwLIO
-7/QA2c9woAC0DzygzHFgkQCR6bu4cAzgz3UAAPz/7HKkeM8gYgfPIOIHAKI0yOi7AKIAGkQBANgA
-sk3yQCXAAAQghA8AAPz/47sA3Qzyz3WgAHQDANjMHQIQAd1CJEQALyQIAeS7EPIBbQi4pXjPdqAA
-XAPkHgQQAuWvfUIkhAAvJAgBANgV8MNtGL7ibe9/EL/lfuFt738Iv+V+pX7Pd6AA1AcbH5iTBOWv
-fQHgQiyOANFwqvcA3gnwz3CgAHQDzBhCAwHlr30B5lMkQAAQdrX35bsG8gHdz3CgANQLsKDmuwvy
-A9jPdaAA1AcgHRiQAdgUHRiQ47sF8gCJQiVFAACq5LsI8kwlQIDG9wCRQiWFAACyRCONgUEtgACY
-dRL0AN4J8M91oAAABKyN4ImgqgHmsmixdkb357v29aCJ+fFMJICAEfQA3gjwz3WgANQDvJXgkaCy
-AeYbfbF2Rffnu/X1oJH48eK7EfKA4ADez/fnuwjyz3WgAJgDvYXggQPwoIGgogHm0XA09wDbBPAA
-iQHjAKpTJUAAEHO79wHdUgiv9alwz3CgANQLANkwoM9woADUBxQYWIAKyOK4yiVBEM9woAC0D7yg
-TQXP9PHA1gzv9ADZz3CgALQPPKDMcQAREAEAEQQBUSCAokAkAATscgQggA8AAPz/zyBiB88g4gcA
-ojTIUSBAoQCiABoEAQDYALIH8s9zoADUCwHYEKNRIIChC/ID2M9zoADUByAbGIAB2BQbGIBRIMCg
-CPIAiUIkRAAvJAgBAKpRIAChB/IAkUIkhAAvJAgBALIA2M9zoADIH0cbGIDPdaAAyBwwFRIQGBUR
-EAQggK8AAAABuHAU8lEgQKIA2MogYgAB3UgbWINMGxiAANhGGxiAz3OgALQPtaMH8AHYz3OgALQP
-FKMB2M9zoADUBwyjDaNTIACg2HBx9EQggKFCLE0BUyQOAfhwLXMX9IDl1fcA30okAHjgeKggQAEA
-iQAYAlBKJAB44HioIAABAIsAqgHn8XUv90wngIAX9IDlAN/T90okAHTgeKggQAEAkQAYBFBKJAB0
-4HioIAABAJMAsgHn8XUv91EggKAX8oDlAN/T90okAHLgeKggQAEAgQAYAFBKJABy4HioIAABAIMA
-ogHn8XUv94DmAN3I9wCJAeUAGAJQsXY894DmANnG9wCLAeEwdgCqPfcA2c9woADUByygYINMJQCA
-KHDPcaAAtA8D8hWhAvAUoWCiTCYAgMolIRAv8gHYz3GgANQHE6E8GQABUSDAoc9xoADUCwryiHCM
-IASAxvZYIMAPFaEB3QbwQCQAARWhAN0D2lehz3CgANQHUKDgeOB44HgF8LoNb/UB2FEggMT89VEg
-QMP49VEgAMP/9VEgAKLPcaAA0A8A2BHyDqFKJIBy4HioIEAB4HjgeM9yoADIH0wamIRGGliEAvAN
-oQrI4rgB2MogIQAVoVEgQMf+81EggMYB2coh4gBRIMDGzyGiAIDlANoO8kokAHjgeKggQAEAH4BA
-4HgD289woADQD3qgz3CgANAPERiYgM9woADUBxQYmIBaDW/1L3hlAs/04HjxwOHFgOAaACEAKHVF
-KD4NCiRAfuB4qCBAAeB44HgA2s9woADIH5m6TqDPcKAA0A8A2TWgA8gEIIAP////gwMaGDADyIe4
-AxoYMLYIL/ypcAIIL/ypcIohkwTPcIAABAQgoCUCz/TgePHAognP9Ah3z3WgAKwvFYXPdqAAwC/p
-uBpxB/KaCg/8iiAIABKmGYVMIACg0CDiAtAgIgPPIOECFKaA5wTyiiAQABGmwQHP9PHAXgnP9Eh1
-AN/PdqAAwC/PcqAArC8+os9xgADQAwAZQAfPcaAAyB8OGdiDDxnYgxAZ2IMRGdiDiiH/DzyigOAG
-8p+9z3CgACgwqKAThoi4GKIKJMBw4HioIAAB4HjgeGUBz/TxwPYIz/QIdyIPb/wacQDez3WgAMAv
-z3GgACgwiB2AEwaBgOD89V4PL/wKcIDnAdhCCG/8wHjGCG/8ANgKyITgDvQfyOW4DPJWDc/9HhIC
-NlMiAABmDO/9QBIBNx4PD/UKyITgB/QfyOW4yiAiANAJwv3PcIAA/FyAHYATK4DPcKAAyB9IGFiA
-CsjiuAHYyiAhAM9xoADQDxWhigvP/b0Az/TgePHAVgjv9ChzCHXPcKAArC8YgADeSHemv1IgAADA
-uAHgBX/PcIAAfBEBgIHg738b8ua67HEM8hTYAKE0yAChoKHPcIAACAQAgAChB/AQ2AChNMgAoaCh
-YKHAscCpOgtv9elwXQDP9OB48cDqD6/0AdvPd4AA3HQgj89yoADAL1wSEAC6gkQhgACA4M9wgAAI
-BMB7oKCAEg4AgOMI8oASAAAQdv7zgBIOAFEgAKAE8gGHEHaE9wDdA/AE3ea5zyWiEROC47nPcqAA
-rC+EIOsPGKIcAAIAiiEIADaiFtgKJABw4HioIEAB4HjgeCCP0Nqfus9wnwDY/1WgUSDApwbyBdrP
-cIAA/FxHoOG5B/ID2s9wgAD8XEegRCEAAUYO7/9EIQECz3Gw/kUAz3CfANj/LqDPcQD3AQDPcKAA
-rC88oADZm7nPcKAAyB8TGFiAKgkP+ACP5LgU9OW4DfLPcIAAfBEBgIHgDPI0yM9xnwDY/xChBvAK
-cMlxjg7v/6lygg2P9gDZz3CgACgwIKAtB4/04HjxwMYOr/QE2c9wgAD8XCegz3CAAHwRAYDPdYAA
-3HSB4AvyqXAyCm/1A9kQ2c9woADIHxIYWIAgjcGNAd9EIYAAgODAf+e5wC6iEs9woADIHCiAz3CA
-APxcK6CuDS/1iiAJBslwVgzv/+lxz3Cw/kQAz3afANj/DqYU2AokAHDgeKggAAHgeOB4ANgVpiCN
-wLmSDO//6XDPcqAArC8Ygs9xoADAL6m4E6EYgoq4E6FBhc9xAQCUbc9wgAB8ESOgIoXpcKoM7/9Q
-2xIOz/9hBo/08cDuDY/0z3CAAPxcAd7HoM9woADAL89xAPcBADegz3eAAHwRAYfPdYAA3HSB4Azy
-qXBWCW/1A9kQ2c9woADIHxIYWIAgjQEVkBBKIUAgRCGAAIDgwiFCJOe5wCiiIljYyg4v9QHZz3EA
-AFVVz3CgAMgfWhhYgFkYmIMiDs/7z3Cw/kIAz3afANj/DqYU2AokAHDgeKggAAHgeOB4ANgVps9w
-qqq7uw6mDqYOpg6mz3GgAMg7DoHPcqAAuD+IuBIaGIAdgQCvHoEBrwpwHgvv/ypxz3ABAAhzA6e6
-Cm/8Adgg2Iu4CiQAcOB4qCBAAeB44Hi6CU/8Eg7P+54Oz/vGD8/7AtnPcIAAJA8gqM9xAAAAAc9w
-gAAIDw4IL/wgoCCNwLkyC+//KnDPcKAArC8YgM9xoADAL4m4E6EihUGFKnBaC+//oNsJBY/04HgI
-2gAfgEA0EgI2CHEAH4BAANoAH4RAAB+CQNEHL/UocPHA4cWhwYtwEghv9QHZAhSAMM91gAB8EQit
-AxSAMAAUATHnuMApogIA2pm6z3CgAMgfTqCA4RgAAQBFKT4NCiRAfuB4qCAAAeB44HgDFIAw5LgQ
-9OW4C/IBhYHgCvI0yM9xnwDY/xChBPB6D+//AdiRBK/0ocDgePHAEgyP9KHBi3AB35YPL/XpcSDA
-ARSBMOe4wCmiAgDambrPcKAAsB9UoIDhFgABAEUpPg0KJEB+4HioIEAB4HjgeM91oACsLxiFz3ag
-AMAv8LgI9BiFkLgTphiF4Lj/8xiFkbgTphbYCiQAcOB4qCBAAeB44HgYhbO4E6Yj2AokAHDgeKgg
-AAHgeOB4FYVEIAIMIMBEIAEMMHIG8jDZMqYA2TGm57jPcqAAyByA2QTyKaID8Cqi5rhA2QTyKaID
-8Cqi4bgA2coh4QAmouK4BPLpogPw6qLjuALYBPIJogPwCqIyCy/8AdgCFIAw5LgT9OW4DvLPcIAA
-fBEBgIHgC/I0yM9xnwDY/xChBfBeDu//AdhpA6/0ocDPcIAAfBEoiOC5C/LPcKAArC8ZgM9yoADA
-L4q4FKLhueB8z3CgAKwvGYDPcaAAwC+OuBSh4H7geM9zoADQGxSDz3KAAOhRAKIQgwDZAaIRgwKi
-EoMDohODBKLPcJ8A2P9OoM9woADAL4oi/w9XoM9wgAD8XCegz3CAAHwR4H8joPHAdgqv9DzYz3ag
-AMAvgBYNEFIIT/UIcaG5lgsv9TzYz3CAANx0AoDguAjygBYAEBB1/vOAFg0Qz3CAAAQEAIDguAT0
-ANgJ8M9wgADcdAGAEHV69wTYGnDPcIAA3HQAiOa4zyCiIQDY8g5v9Ahxz3GAACQPANgAqc9xAACU
-Ac9wgAAIDyCgzf/PcIAABAQggM9wgADsAyCgANjCDm/0CHHPcLD+QwDPd58A2P8OpxTYCiQAcOB4
-qCBAAeB44HjPcIAAEA8AgIDgGPTPcoAA4AMggs9woAC4PyEYWICC2RgYWIAhgiIYWIDQ2Z+5NafP
-cQCAERQSGFiAz3CAANx0IIhEIQABfgjv/0QhAQIXhv+4GAwB/PIJT/Vc2JYKL/UB2ReG+bjKICIC
-yiGiAIAKAvUg2Iu4CiQAcOB4qCBAAeB44HhaC8/34g+P96YNj/TeDM/1Mgwv/ADYQgvP9wPIBSCA
-DwAAAHwDGhgw8g4P+foMT/SyD0/2z3CAAAQEAICpcaYI7/8Kcs9xAPcBAM9woACsLzygANjPcaAA
-KDAAoc9wsP5GAA6nAdjPcYAAEA8Aoc9wqqq7uw6nDqcOpw6nz3CgAMg7DoDPcaAAuD+IuBIZGIAJ
-AY/04HjxwOHFz3WAABRSqXAA2SoJL/WE2kYLb/WpcAEBj/TgePHAhgiP9IHgKHYW9I7mzPYF2Aoh
-wA/rcoojSgCYc5oOb/S4djDZLH4CIUBwx3CAADQEGPDPcIAAqCzNYIwlw58L9AXYCiHAD+tyiiOK
-AZhzZg5v9Lh2FG0UeMdwgADUBpEAj/TxwB4Ij/TPdYAAEhEAjc93gAAQESCP4v9BiM92gACUEeS6
-IJcv8s9zgAAAUgmTEHEp9ACV8IvxcCX0z3CAABQRAIhuixBzH/RBhoDiANsR8h/I5bgN8s9woAAs
-IB2AQnjXcDEBAC1F9wHYAK4D8GCuANgQuAV5z3IAAMAUiiBHAwrw47rPcgAAwBQK8gHYAK6KIMcD
-QHrxB2/0AI4BjoDgBvIB2ACuiiAHA/bxANgAroogBwTw8eB48cBWD0/0GnB6cQomgJAKIQAhzCMi
-gAbyQiMTIS8jxyQKcGpxsP8Idc93gACUEYDmB6cm8gaNBLgUeEAg0gADjeC4wo0M9AXYCiHAD+ty
-iiOQDZhzRg1v9AolwAQyIkAj4bgP9AXYCiHAD+tyiiNQDphzKg1v9AolwAQD8MGN4L4M9AXYCiHA
-D+tyiiMRAZhzCg1v9AolwARRIUCg0SYikQzyBdgKIcAP63KKI5ECmHPqDG/0CiXABFEhAKAO8uO+
-DPQF2AohwA/rcoojEQSYc8oMb/QKJcAEB4cLgIDgDfIF2AohwA/rcoojkQWYc64Mb/QKJcAEz3GA
-ACg6TCBAoAr0ViEABAinz3CAAOArCacG2A3wKHAIp89wgAAIKwmnTCPAqgjYyiBsAhwXEhAMFxAQ
-OnAA3gLdQCIAKvUggQNhvQIhAAQYYHYLr/kqcRUnjBMKpAHmgOXPfjD3UQZP9PHAAg5P9Bpwz3GA
-AABSSZHPdYAAEBEAlc92gACUERByEfTPcIAAEhEAkFCJEHIL9M9wgAAUEQCILokQcQP0Ao4C8ADY
-Aa5p/89wgAAUEUCIz3GAABIRAIkgjYDiAdrAegpzSiQAAI//B4YA3wGI5LgglQfyAdgDroogRwME
-8OOuiiCHA8IMz/TdBU/0z3GAAABSz3CAABARAJBJkRBy4H3PcIAAEhEAkFCJEHLgfc9wgAAUEQCI
-LokQceB9z3GAAJQRAYngfwKpH8jluBjyz3KAAABSQMwpkhBxEvQeyDCKUyADADBzDPQEIIAPAAYA
-AIDgAdkOisB5EHHgfADYz3GAAJQRAqkBoeB/AKmA4PHAD/QA2Bz/z3GgACwgPYHHcUlrANIroCIM
-7/SKIIcF0cDgfuB48cDhxYDgKHUK9ADYEf8A2SugiiDHBf4L7/SpcS0FT/TxwOHFz3WAAJQRiiBH
-BuYL7/QpjQTYFg9v/QHZCI0pjeb//9gFBW/0Cq3gePHA4cXPdYAAlBGKIMcGugvv9CmNCo2MIMOP
-yiGiAewNgvndBE/04HjhxVMgDQCgqQQggQ8ABgAAQiEBgAQggA9AAAAAyiFiACCq13BAAAAAAdjA
-eACr4H/BxeB48cAaDE/0GnB6cYh1qHAKIoAhCiHAIc92gACUEaDgAN8E9AeGBYgp8EQgAQbCuIfg
-LgAtAEO5R4YzJgBwgAAoO0AnjHNZYRR8VG0gfFlhCIkT8AyJEfAQiQ/wFIkN8AXYCiHAD+tyiiOS
-CJhz8glv9EolAADpcBUmTRPqhR9ngOfKJysQTCAAoAXy4+eG9mLfBPDs54L2a98JhkiG9HggiAGI
-9CJBACx4ABKBIC9w9CJDAAARgiBsejdwANhY90ArACZALwMUZXgIuQV5RXmeCu/0iiCHAAmG9Hgg
-iAAaQiAJhvR4IYgB2AAZQiCFA0/08cAiC0/0ocGacDpxGnJodQDfz3CgALQPcBATAIogxwBaCu/0
-inHPcKAA0A/1oItxQCRCMEAkgzAqcKn/gOUE9Jh3CvDPcIAASGIBiIDg+vVKJIAAIMABFIIwinEC
-FIMw3f4A3kohQCgVII0jANkC2FpwAm0AIEcAIMABFIIwunECFIMwACVGEC8lhwOKcQokQAWg/4Dg
-BvJTJgARDycPEEAlQSBCIkAggOAveSL3AeZCIUAggOC0B+3/OnDPcYAAlBEDgQShz3GgANAPVBnA
-BOlwoQJv9KHA8cBmCk/0KHZIdQQgvo8AAAAYAdnKISEA6LggrgnyD3kArQCOgOAw8oS5IK0s8Om4
-BPIg2ACtKPAPeGG4juAoAA0AMyYAcIAAMDtAJ4xyFHwAfATYAK0T8AXYAK0P8AbYAK0N8AXYCiHA
-D+tyiiMLDJhzJghv9EolAAAAjoDgBPIgjdTxTQJP9PHAwglP9KHBAN7PcKAAtA9wEBIAz3CgANAP
-1aDPdYAAmG8DFZMQiiAHAfII7/RqcQSVgODKJIIjyiShIAWFi3FAJIMwQCROMMlyTf8KhUAkwjDJ
-ccn/SiEAIEwjAKCOAC4AKnXPcIAAXHEAIFAEACGBL4AAXHGAEYAA4LgB2cohIQAFIQEFLyRHACDA
-oBCBIM92gABccQEUgjAVJk4UAhSDMHX+ANgC37pwACYGEAJuACBHBQMUhTAgwKAQgSABFIIwAhSD
-MAokQAU6/4DgzyVCFEAlQCBhv4DnD3gm90AhQCBycIAH5f86cM9xoADQD1QZgASpcB0Bb/ShwPHA
-yghP9KHBOnAA3c9woAC0D3AQEwDPcKAA0A+1oIogRwH+D6/0KnGEKQYpACGQf4AA6GJadQTwQCJS
-IBgQASFKcDBwhAAGABYgDiAhFoAQBCC+jwAAYADw8wpwBICLcUAkgzBAJE8w6XIG/wpwqBAAAEAk
-wjDpcYH/IMAgFoEQARSCMAIUgzBKJMAAO/4A2ALfmnADFIUwIMBAJoYYIBaBEAEUgjBAJscYAhSD
-MAokAAUB/4DgzyWCFEAkQCBhv4DnD3gn97rxz3GAAJQRQ4EVIUEEqXBFoc9xoADQD1QZwAQ9AG/0
-ocDxwPoPD/QeyADeBCC+jwAGAADKJmIQz3CAALAQoID3vcogQQMF8gUlgB8A/wAAz3GAAMgOz3KA
-ALgO8CKCA/AhgQNCec9ygADADvAiggNCeIQoxAD6DG/5L3CEKEEIAiGAfwAAcWfqDG/5ZNnPcYAA
-lBEDoUAtARQPvsV5BXm6Dq/0iiCHAeEHD/TgePHAag8v9IogBwYA354Or/TpcRXdz3aAAJQRDIY0
-aAHgNHnHcYAA1AYMpguBgOAR8s9yoAAsIF2CQnjXcElrANLH9+uhiiDHBWIOr/QgiQyGquCD9+ym
-Yb2A5cIHzf91Bw/04HjxwAYPD/TD/+X/z3CAABARAJCA4NQOgv/Pd4AAlBEEh89x8PDw8DBwGvIj
-h2W4MHDW989xgAAAUhKJQCENBSCBqXIA2+L+og9P/oDgCPRGCU/8gOBoCSH1yiBBAwDeAt3PcIAA
-iGSELgYZMiBADoDgEPIVJ4ATBYDPcfDw8PAwcAjyI4dluBBxoA3l/8oghQMB5mG9gOXPfiT31QYP
-9OB48cBmDg/0ocEIdih3i3FAJEIwQCSDMOlwfP4BFIAwgOAH8gIUgDCA4APyZL7PfiDAyXFt/QEU
-gTCA4QTyoogD8KGIiiDHAWINr/TpcUAuABZALQEUBXkBFIAwCLgleAIUgTAFeUINr/SKIMcB4b3R
-JeKQBPLkvQzyBdgKIcAP63KKIxgImHMWDC/0uHZBBi/0ocDgePHA1g0P9B7IgBKNMFMgDgCKIAcC
-/gyv9KlxyXCpcU39AYjkuAvyBdgKIcAP63KKI9gNmHPSCy/0uHUJBg/0AAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAJQBAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPhhgAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAA/wAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA/wDw8PDw
-8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWBgAAFgYAABYGAAASCEAAFgYAABY
-GAAAICEAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAMgRAADUEQAAdBIAAKwS
-AADAEwAAQBMAAFgYAABYGAAAhCUAADAoAADYKAAAWBgAAFgYAABYGAAAuCQAAFgYAAAEKgAARCsA
-AFgYAABYGAAAWBgAAEwhAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAACEZQEA
-0GYBAKBoAQDAZAEAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABY
-GAAAWBgAAFgYAABYGAAAWBgAALxuAQCMbwEAcHEBAPhwAQBYGAAAkCEAAFgYAABYGAAAWBgAAFgY
-AABYGAAAZCIAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgA
-AFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAA
-WBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAAA8AAEAOAMBAFgYAACcBQEAWBgAAEgHAQAA
-zwAAANAAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAACIOwEAWE0BAFgYAABYGAAAWBgAAFgY
-AABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAORTAQBYGAAAwFUB
-AFgYAABYGAAAWBgAAEwUAAB4GwEAWBgAAFgYAAA0YwEADDEAAFgYAABYGAAAWBgAACTUAABYGAAA
-WBgAALzDAABQIgEAWBgAAFgYAABYGAAAZDIBANjUAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAAD0
-JwEAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgY
-AABYGAAAWBgAAFgYAABcMQAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgA
-AFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAA
-WBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABY
-GAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgYAABYGAAAWBgAAFgY
-AABYGAAAWBgAAFgYAADgIwAA5CMAAFgYAABYGAAAWBgAABgADfwOcw9wHSAfQCBAIUAiMSVmJg8n
-ZigPKx0sRC0dLkQxEDIJMxA0CW9acABxAHIDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQH
-AADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcA
-AOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAAzAgAAAAAAABsxgAA5AcAAOAGAADkBwAA
-0BoBABQHAAAksgAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAAnAcAADgHAAA4BwAAOAcAADgHAAC0
-CAAA5AcAAOQHAADkBwAAsAcAAOQHAADkBwAA5AcAAOQHAADkBwAA0AgAAOQHAADkBwAA0AYAAAMA
-AAAIYgEABAAAADTeAAAOAAAAMFMBAAgAAAAQHQEAAgAAAGRXAQAKAAAA8B0BAAsAAACcCQEADAAA
-ANAJAQARAAAAKMYAAAkAAAAkAQEAEAAAAAgxAAANAAAAAMMAAAEAAAC40wAADwAAAHA4AQASAAAA
-zAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAgICAgICAgIABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAABAAAAOMgAAAjJAAAUzAAATMoAAFDJAADgzAAAZM0AAJzNAADgzQAAAAAAACwBAABeAQAAAQAA
-AAEAAAABAAAAAQAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAgAAAAMAAAADAAAAAwAAAAEAAAAAAAAA
-AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArA0AAAAAAAAAAAAAAAAAAAD/AP8A/wD///8A/wD/
-AAABAAAAAAAAAAUAAAAAAAAAAAAAABAAAAAAgAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUDAEA8A0BAHQQAQBgEgEA0BQBAAAYAQBQ
-DwEAkA+AAGxXgAAYAAAATFeAAAAAAAAAAAAAXCaAAKRXgAAIGgEAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAECAgMEBAUGBgcICAkKCgsMDA0ODg9mZmdoaGlqamtsbG1ubm9wcHFy
-cnN0dHV2dnd4eHl6ent8fH1+fhU/AAAAAAAAAAAAAAAAAAECAgMEBAUGBgcICAkKCgsMDA0oKCkq
-KissLC1HSElJSktLTE1NTk9PUFFRUm1tbm9vcHFxcnNzdHV1dnd3eHl5ent8fQw/DCwBAFBwAAAM
-LAEAUXAAAMAsAQBFAAAAwCwBAEQAAADALAEASQAAAMAsAQBIAAAADCwBAFJwAAAMLAEAU3AAAMAs
-AQBOAAAAwCwBAE0AAADALAEAUgAAAMAsAQBRAAAADCwBAEDSAAAMLAEAQdIAAMAsAQBXAAAAwCwB
-AFYAAADALAEAWwAAAMAsAQBaAAAADCwBAAjSAAAMLAEACdIAAEgsAQAAggAASCwBAAGCAAAMLAEA
-RdIAAAwsAQBG0gAASCwBAACCAABILAEAAYIAAAwsAQAG0gAADCwBAD6QAAAMLAEAQ9IAAAwsAQBE
-0gAADCwBAFDSAAAMLAEAUdIAAAwsAQBS0gAADCwBAFPSAAAMLAEAP5AAAAwsAQAT0gAADCwBAECQ
-AAAMLAEAFdIAAAwsAQA/0gAADCwBAD7SAAAMLAEAP5AAAAwsAQAT0gAAZABkAGkA3ADIAFoAqgC+
-AIYBfQA+AGQAZABpANwAyABaAKoAvgCGAX0APgAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAkA+AAGxXgAAYAAAATFeAAAAAAAAAAAAATCqAAKRXgAAAAAAAkA+AAGxXgAAYAAAATFeA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAALAqgACkV4AArFsBAJAPgABsV4AAGAAAAExXgAAAAAAAAAAAAJAPgABs
-V4AAGAAAAExXgAAAAAAAAAAAAMgqgACkV4AApGIBAAAUBQAAAAAAAAAAAAAAAAAAAAAA/wD/AAAA
-AAA/ez91P24/aD9iPm4+aD5iPW49aD1iPG48aDxiO247aDtiOm46aDpiOW45aDliOG44aDhiN243
-aDdiNm42aDZiNW41aDViNG40aDRiM24zaDNiMm4yaDJiMW4xaDFiMG4waDBiJW4laCViJG4kaCRi
-I24jaCNiIm4YaBhiF24XaBdiFm4WaBZiFW4VaBViFG4UaBRiE24TaBNiEm4IaAhiB24HaAdiBm4G
-aAZiBW4FaAViBG4EaARiA24DaANiAm4CaAJiAW4BaAFiAG4AaABiAF0AWABTAE4/bj9oP2I+bj5o
-PmI9bj1oPWI8bjxoPGI7bjtoO2I6bjpoOmI5bjloOWI4bjhoOGI3bjdoN2I2bjZoNmI1bjVoNWI0
-bjRoNGIzbjNoM2IybjJoMmIxbjFoMWIwbjBoMGIGbgZoBmIFbgVoBWIEbgRoBGIDbgNoA2ICbgJo
-AmIBbgFoAWIAbgBoAGIAYQBgAF8AXgBdAFwAWwBaAFkAWABXAFYAVQBUAFMAUgBRAFAATwBOAE0A
-TABLAEoASQBIAEcARgBFAEQAAP////////8AAf//AgP///8E//////////////////////8F/wb/
-B/8I/wn/Cv8L/wz///8N////Dv///w////8Q////////////////////////////////////////
-//////8R////Ev///xP///8U////Ff///xb///8X////GP///xn///8a////G/////8c////Hf//
-/x7///8f////IP///yH//////////////////////yIjJP8lJif//yj///8p////////////////
-//////////////////////////////////////////////////////////////8AAAAADwA/AAEA
-AAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAA
-AAEAAAAsBAGlAC0qJyQhHhsYFRIPDAkGAwAMCAQAPDg0MCwoJCAcGBQQDAgEf/8HDx8/AQMBAw8H
-AQcPHz9///8FAAcCAwQGBnTRRRfooosuDQ8FBwkLAQMKFDduVVVVAUtoLwFVVVUF4ziOA6qqqgJx
-HMcBqqqqCsdxHAcPDw8HBgcCAwQFAAEICQsKKAAoADAALAAsACgAPAA0ACgAKAA0ADAALAAsAEQA
-PABAADwAjABsAFgASAD0ALAALAAsADwANAAwACwAVABEAFQAVABsAGAAXABUAIwAeAA6AQIB1QDf
-ANoAogB1AH8AagEaAdkA6AAKAboAeQCIAIoFKgM5AagBigXKAtkASAHKAUoB4gD5AMoB6gCCAJkA
-9AJEArUB1QGUAoQB9QBBAqwAkACEAIAAeAB4AHgAdABmDgAAiZ3YCcRO7ASDNEgDYid2AkEapAGx
-EzsBgREYAcAP/AAvob0El9BeAg+LlAFLaC8Bh0XKACW0lwAF2YYA61x5AKqqqgoADQAAABoAAAAn
-AAAANAAAAE4AAABoAAAAdQAAAIIAAAAbAAAANgAAAFEAAABsAAAAogAAANgAAADzAAAADgEAndiJ
-nU7sxE40SIM0J3ZiJxqkQRoTO7ETERiBEQ/8wA9O7MROJ3ZiJxqkQRoTO7ETDdIgDYmd2AkIjMAI
-B37gBzRIgzQapEEaERiBEQ3SIA0IjMAIBmmQBrCy1QUFVEAFJ3ZiJxM7sRMN0iANiZ3YCQZpkAbE
-TuwEBEZgBAM/8AOqqqqqGqRBGhM7sRMP/MAPERiBEQ3SIA0KqIAKEzuxEw/8wA8P/MAPDdIgDQu0
-QAsLtEALiZ3YCQ3SIA0KqIAKCqiACgiMwAgHeIAHB3iABwZpkAYP/MAPDdIgDQu0QAsN0iANC7RA
-C4md2AkIjMAIiZ3YCQiMwAgHfuAHB37gB8EsKQcKqIAKCIzACAd4gAcIjMAIB3iABwZpkAawstUF
-BmmQBrCy1QUFVEAFBVRABdYdxgQAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAAAAAAcICAAAAAcK
-DRARAAAABwsOEBEABwsOFRsfIgAAAAAHCgsNAAAHCg8VFxoAAAgLEBUYGwALEBYhLDE2AAAABwsP
-EBIABwsPFh0hJAAIDA8XHiIlCA8XHi08REsACAsPFh0hJQgPFh0sOkJJCBAXHy49REwQHy49W3mI
-lwAHBw8HDw8PBAwMCAQMBARAAAAAgAAAAAABAAAAAgAAQAAAAAAEAABAAAAAQAAAADMTAAAABQoP
-AQEAAQIBAQGlxoT4me6N9g3/vdax3lSRUGADAqnOfVYZ52K15k2a7EWPnR9AiYf6Fe/rssmOC/vs
-QWez/V/qRb8j91OW5FubwnUc4a49akxabEF+AvVPg1xo9FE00Qj5k+Jzq1NiPyoMCFKVZUZenSgw
-oTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10WC40LTay3O60+1v2pE12YbfOfXtSPt1xXpcT9aZo
-uQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiwSoVruyrF5U8W7cWG15pVZpQRz4oQ6QYEgf7woER4
-uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9jQjAgGuUO/W2/TIEUGDUmL8PhvqI1zIg5LleT8lWC
-/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4MLyowpx9NrPCh5p+K8HRZ2rTvbVmROdB4U25IKDGxI
-5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qMAWSx0pzgSbTY+qwH8yXPr8qO9OlHGBDVb4jwb0py
-XCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5DgQnzEcarM2JAFBgH3Ehyjwl9q+a7QaZEXWJknOrkn
-ONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/qnhQeqWPA/hZgAkXGtplMdfGhLjQw4KwKXdaER7L
-e/yo1m06LJSfAAAUnAAACJ8AAMScAABEQQAAREIAAMBAAACEQgAAAADAAHBEoABsAACAAACwAAQI
-oAAAAAAABACwABgIoAABAAAAAACwABwIoAADAAAAAACwAOwcoAAwAAAAAACwAFAUoAADAAAAAACw
-AAQYoAADAAAAAACwAEBEoAAAAAAAAACwABgIoAAAAAAAAAAAAAQooAACAQAAAAAAAFxIpwAAAAAA
-AAAAAAQooAACaQAAApDxAAQooAABAAAAAIABABgooAAAAAAAAAAAAPAcoAACAAAAAAAAAOwcoAAB
-AAAAAKABAAgArAAAAAAAABACADBApAAAAAAAAAAAABAcoAAAAHAAAAAAAOAcoAAAAAAAAAAAgCQQ
-oAABAAAAAAAwACQQoAAAAAAAAAAAADgcoAAAgAAAAACAAjgcoAAAAAEAAFBAAAQooAACAwAAAGBQ
-AAQooAACBAAABCAAAAQooAABAAAAAEAAAAgArAAAAAAAAACgAOwcoAACAAAAAACQAHBEoAAkAACA
-ALACAAAIqgAAAAAAAMACAAQIqgAAAAAABQAQAXBEoACEAACAADAAABgooAAAAAAAAAAAADgcoAAA
-AAEAAIAAAOAcoAAAAAAAAHCgAAgIqgAAAAAAAJCgAAQAqgAAAAAAAHCQAChIpwAAAAAAAJCQAAAA
-pgAAAAAAAwAAAAQIoAADAAAAAAAAAKQgoAAAAAAAAAAAgAAgoAAAAGAAAAAAgDgcoAAAAAEAAKAB
-gAgArAAAAAAABJABAAQooAABAAAAAJABAAQooAABAAAAAKABgAgArAAAAAAAAAAAAFxIpwABAAAA
-ACACAAgArAAAAAAAAAAAADBJpwACAAAAAAAAAAQooAACAUAAAAAAAAhIpwD/AAAAAAAAAAQooAAC
-aSEAAAAAAGRApgAACAAAAAAAACxJpwAAAAAAAAAAgABIpwABAAAAAQIBAgMEAAAFBgcICQoAAAAF
-BgACBAAAAAUHAQMEAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQA
-BEBAAARAQEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAA
-HDMAAAQAAAAcFQAAAAAAAAAAAABkAAAAAJABAAoAAAAABAQHAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAABxAkAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAA
-AP8AAAAAAAAAAQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAABBhAQBkAgEA
-aAIBAGwCAQDIAgEA0AIBANgCAQAABAsJFSUvAAAEEQkcJzIAAYAAEYAAFgQCIAASgAAWBANAABCA
-ABcEBOAAEIAAFwQFgAARgAAXBAYgABKAABcEB0AAEIAAGAQI4AAQgAAYBAmAABGAABgECiAAEoAA
-GAQLQAAQgAAZBAzgABCAABkEDYAAEYAAGQQOgAAQgAAaBCKAABgAABYAJAAAGQAAFgEmAAAiAAAW
-ASgAABoAABYBKoAAGgAAFgEsAAAgAAAXAS6AABgAABcBMAAAGQAAFwE0AAAaAAAXATaAABoAABcB
-OAAAIAAAGAE8AAAZAAAYAT4AACIAABgBQAAAGgAAGAFkAAAaAAAbAmaAABoAABsCaAAAIAAAHAJs
-AAAZAAAcAm4AACIAABwCcAAAGgAAHAJ0AAAgAAAdAnaAABgAAB0CeAAAGQAAHQJ8AAAaAAAdAn6A
-ABoAAB0CgAAAIAAAHgKEAAAZAAAeAoYAACIAAB4CiAAAGgAAHgKMAAAgAAAfApFAABkAAB8DlQAA
-IwAAHwOXwAAaAAAfA5lAABgAACADnUAAGQAAIAOfwAAZAAAgA6EAACMAACADpUAAGAAAIQNwTAEA
-kD0BAFw/AQCQQAEAvEIBAARFAQC8SAEAUEoBAHRLAQB4WAEAkFgBAPxYAQAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0A
-EAATABYAGgAgACYALQA1AEAATABaAGsAgACYALQAJgAtADUAQABMAFoAawCAAJgAtADWAAABMAFp
-Aa0BAAJrAIAAmAC0ANYAAAEwAWkBrQEAAmAC0wJdAwAEwQSmBTABaQGtAQACYALTAl0DAATBBKYF
-twYACIIJTAtuDQAQUABfAHEAhwChAL8A4wAPAUIBfwHHAR4ChAL+Ao4DPAT/////////////////
-////////////////////////////////////////////////////////////////////MAFpAa0B
-AAJgAtMCXQMABMEEpgW3BgAIgglMC24NABAAAAAAAAIEBgMJBgkACQAJAAkACQAJAAAAAAAAAAAA
-AAAAAAAAAAAA/////wAAAABgAAAABQUFBQUFBQUAAAAAAQAAAAAAAAAAAAAAAAAAAAAOAAAADgAA
-AA4AAAAOAAAABAAAgAAAAIAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABpIAAA
-aSBAAGkgAABpIEAAICCADwAAGAFpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEolAABK
-JgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMAIEok
-ACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAACgQSycMEAsnDBCJBw0CiKAP4AADCcKIwA3UggA
-AEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAAQPQHggIECHAAAAAAAAAAAAAIoh/w/PcKAA
-yB8TGFiAICCADwAAAADgfuB+4HjxwFYJIAAB2M91AACECEB9z3agAMAvFIbPd6AArC+LuBmnFIbj
-uP/1YH0C2IogCAAWp2B9A9jPd6AAyB8A2A4fGJAPHxiQEB8YkBEfGJCOCyAAPNhPIEEAGgogADzY
-SgtAAGIKAABgfQXYz3GgAIQ0BIHPcqAAvDf/uPnzFBESABgREwAMEREABIHTuBpwNhoYgGB9B9jP
-cYAAAA8CIYAPgAAAAEEoAgEAIoMEAiMCIGhwMghgAAHbYH0J2M9woADQGxGA/bj882B9CtgA2J24
-Ex8YkGB9C9jPcYAA7AMC2AChN4bPcIAABAQgoDqGz3CAAAgEIKBgfQzYKnAA2Qpy4g8gAChzANid
-uA8fGJDPcIAA2AMAEBoAz3EAbQAQz3CfANj/MaBgfQ3YaSCAAG8hPwB9AAAA4Hj8HIi2/BxItvwc
-CLb8HMi1/ByItfwcSLX8HAi1/BzItPwciLT8HEi0/BwItPwcyLP8HIiz/BxIs+B+4HgE3DjdNfDg
-eATcNN0z8OB4BNww3THw4HgE3CzdL/DgeATcKN0t8OB4BNwk3Svw4HgE3CDdKfDgeATcHN0n8OB4
-BNwY3SXw4HgE3BTdI/DgeATcEN0h8OB4BNwM3R/w4HgE3AjdHPDgeATcBN0Z8DQUGjAwFBkwLBQY
-MCgUFzAkFBYwIBQVMBwUFDAYFBMwFBQSMBAUETAMFBAwAscBxrAkTTOwJB8z4H7hxaHBCHPPdYAA
-CA8BlQAchDBPIMIDAeAQeAIchDCPuAG1R2kEIoIPAAD8/+xwQKAAwkCgIrkF8ECgBONhuYHhQIM8
-989woADQDw4YmIChwOB/wcXxwPYO7/+YcM9woADMK9SAANrPdaAAwC8XHZiQz3OfANj/FYPPcp8A
-uP/m3/2i94MEJ76fAPAAAPv1HaJoGgABO6Jp2Bi4GaIXHZiTEQfP//HAqg7v/wDZu8GPuc91gAAI
-DyG1ANkhrc9yAQAsBEDCQcFCwQHbz3KAAEglQIpjw0fAz3CAALQODRyCMA4cwjAPHEIwz3KAAHwQ
-RMLPcoAA7A9FwkbBAIBKJIBwSMCoIIAHz3CAALgO8CBCABUkQDBJoM9ygADADvAiQgBLoM9ygADI
-DvAiQgBNoM9ygADQDvAiQgAB4U+gANkF2kokgHAA26ggAAMSazZ4z3aAANgOBmaDcAHj0aBhuoDi
-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
-puFI9xYjQgBAilBw+fUK8M9wAAAHMCoJz/9vIT8AANnRwOB/KHDgeM9wgABsLQGAzvHgeM9wgABs
-LUCAIoDPcIAATCWA4jZ4A/LgfweI4H93EIAAz3GsANQBANiLGRiAjBkYgAfYjRkYgAbZkbnPcKAA
-xCcwoM9xGAAHAjCgz3KAAGwtNIqA4QX0z3EQAAYCMKAggoDhUfIG2Za5MKDPcXgAAoUwoM9xAgAC
-gTCgz3FVAAKCMKDPcRAAAoYwoM9xQQAChzCgz3EHAALTMKDPcQEAAoowoM9xAAACpTCgz3EAAAKm
-MKDPcQAAAqcwoM9xBgACqDCgz3EGAAKpMKDPcQYAAqowoM9x/wAHxTCgz3H/AAfbMKDPcf8AByYw
-oM9x/wAHIzCgz3EYAAIfMKDPccwAAh5X8AfZlrkwoM9xAQAChzCgz3EDAALFMKDPcYAAAtswoM9x
-cAAChTCgz3FwAAKBMKDPcQYAAtMwoM9xIQACijCgz3EFAAKlMKDPcQUAAqYwoM9xBQACpzCgz3EM
-AAKoMKDPcQwAAqkwoM9xDAACqjCgz3FEAAImMKDPcUQAAiMwoM9xKAACFjCgz3GZAAIVMKDPcf8A
-B4IwoM9x/wAHhjCgz3H/AAcfMKDPcf8ABx4woOB+4HjxwFIJj//PdYAAFA8AjYDgHAACAM9wAACQ
-ZQokAHDgeKggAAHgeOB4AdgArQbYkLjPdaAAxCcQpc9wgABsLUCAIoDPdqAA7CfPcIAATCWA4gXy
-NngG2Za5BfBw4DZ4B9mWuTClz3EEAAe8MKXPcRAAB7gwpc9xCgAHvDClz3E/AALBMKUiiBC5BSGB
-DwAAArIwpSGIELkFIYEPAAACszClJYgQuQUhgQ8AAAK0MKUkiBC5BSGBDwAAArUwpSOIELkFIYEP
-AAACtjClBogQuAUggA8AAAK3EKXPcAQABrwQpc9wAQAGsRClz3ADAAauEKXPcAEABrwQpc9wAwAG
-ABClz3AIAAa8EKXPcBAABrgQpc9wAACgKAokAHDgeKggAAHgeOB4z3AgAAa8EKXPcAAAKAoKJABw
-4HioIAAB4HjgeM9wAAAD8BCl6obPcCAAB7wQpc9wAAAD7xClqoaEJwEfqXCEIAEI4OAivwnyz3AA
-AAkw5g2P/28hPwCG58S9VPeP5colYRTAJWIQEL0FJY0fAAAC289xoADEJ7Chz3AEAAe8EKEVAI//
-8cDhxc9woAAsIL2AgCUGFAjwz3AAAAgwlg2P/28hPwDPcgAAA/DPcaAAxCfPcKAA7CdQoQqA57gI
-9M9woAAsIB2AEHVu9+fx2QdP/+HF/NnPcqwAHAAmonPZJ6Jw2SiiINk2olrZz3WsAJABK6UH2Sel
-gOAA2wTyZaUE8ArYBaVA2BiiGaIaouB/wcXxwOHFz3WAAGwtAKUhpVSt/gvv/3WtBgzv/wKlHgzv
-/wOlrg3P/9T/FI3m/2kHT//xwOHFWgqv/37Yz3GAABgPCLGAuBC4BSCADwAAAn7PdaAAxCcQpc9w
-gACMHMIJj//PcAAAATQQpS0HT//xwOHFosEeCq//d9gIcc9wgAAYD0SQhCEBDMO6h7pFeRC5BSGB
-DwAAAnfPcqAAxCcwogCIz3OnADREz3WAAIwcHXj2GxgABpXPcaYAuDwdeusZmAAZ2fMbWAD6Ca//
-JbiLcCYKr/+BwQHBAMA4YAi4Sgnv/yaVtQZv/6LA8cDhxQLYz3WAABgPAK3e/wK4FXgVeAoJ7/+K
-IQYCkQZv/wOl8cDhxQzYz3WAABgPAK0Q8CK1DvAAIECAwCBkABx4BLXQ/0OFUHAklbT3I7UjlQKV
-QWlQcDD2BLXK/wWlA5UEtcj/Q4UlhUJ5gOEGpUL2M3lCeIDgQvYTeBBxRPYClQPwA5UpBm//AbXx
-wK4Nb/932BIJj//PdoAAGA8kloQgAQzPdaAAxCfDuYe5JXgQuAUggA8AAAJ3EKXqCK//edgkloQg
-AQzDuYe5JXgQuAUggA8AAAJ5EKXNBU//4HjxwOHFz3CAABgPCJDPdaAAxCcQuAUggA8AAAJ+EKXP
-cIAAjBxuCI//AdgQpaEFT//xwADYKNkB2gIO7/8Ic4v/uP/B/9r/7//RwOB+8cACDU//osEIdzpx
-z3CnADREAdnzGFgAz3WAAEwdBpWKCK//JbiLcBIJr/+BwaaVAMC+Zbhg3g+v/8lxGnABwLhg0g+v
-/8lxQcAAHwAUAcEAGUAgDQVv/6LA4HjxwIYMT/8acTNoz3KAAPwdNHlAIgAFKGA6YhQiAgQkiowh
-w4/lirPyCLhPIFIAz3KAAOwdFCIRBAARgCDPdqAAxCfPdYAANA8IuRC4BSCABBCmgbkAjXpxCL+B
-vxC4BXkwpuV4EKYEbUAlARLO/wERgSAQuQUhgAQQpiCNELkFIcAEEKbleTCmQCUAE0AlARTF/wAR
-gSAQuQUhgAQQpgGNELgFIMEE5XgwphCmQCUAFUAlARa8/wERgCAQuAUggAQQpgGNELgFIMEE5Xgw
-phCmQCUAF0AlARiz/wOFIYXacAIgUgAFhSeFQnACIECAOnAEhbpxIoX6cCJ45oWacB9nCIUbcAJ/
-zCcikEHyAI3BjUEpzScqcXpwAn4ELr4UInW8fZYOr/8AJUAeACDZBAQuPhVBL84X/mbcfgAmQB56
-Dq//6XEAIxMgAiZAJQQovgQAIUBzYg6v/ypxAiYNIAInASYEKT4FACGAc04Or//pcQInAiDPcYAA
-hC0WIQEEABlEBgIZxASisUOxPQNP/+B48cAeC0//CHfPcIAATB0SDm//AN7PcKcAMExAGNiDCN3p
-cMlxk/9hvYDlAeY6989wgABMHSYOT/9NA0//BbgUeMdwgACAAM9ygACELWKaNngjmmCwIbAgmiSo
-PJolqCGaJqg9muB/J6jxwLYKb/+YcCh2AN0M3zMmS3OAAOwmQCcMcxQkzBIAfIDmC/QD8IHmB/SI
-cKlx6v8D8ILm+/Nhv4Dn1gft/wHl3QJP//HAbgpP/wDfSiBAIc9wgABYHs9xgABEHvAgwAPwIcED
-AdoA3TIL7/+pcwPeqXDK/+lwqXHi/2G+gOYB5Tj3AedCIEAggOAacCL3z3GAAAAAAdiBAm//AKHx
-wBYKT/9od4DgCiAAIQr0z3CnADRE+xhYAPwYmAAJ8M9wpwAwTDkYWIA6GJiAz3CnADREAdnzGFgA
-z3WAAGweBpV6DW//JbjPdoAAWA/JcJ4Nb/8kbgCGJpUGuMYMr/8kuQCnAYYmlQa4ugyv/yS5CQJv
-/wAYACAMeS9wTHvgfwIgQA7xwIoJT/9acBpxOnLPdoAAWA9khgOGp4YlhkaGuWGieqKGYni7Y891
-AADgGEB9mHAnhuaGAidAEEOGIoZkhkJ5YnplhmB94nvYcCOGYoYCI0AAJ4ZFhuaGWWHieuSGYH37
-Ywh3RIYjhgIhgABGhmWGAiOFAGeGYnpihiJ7YH2ocQh1QixBATq5gHFGuQQpvgQvcEIuQQE6ucBx
-Bgyv/0a5ABgAID1vOrn5YUa5BCm+BC9wPW06ublh5guv/0a5KQFv/wAZACDgePHAwghP/xpwKHVa
-cjpzz3aAAGAPyXNAJgQTKHKm/7N/ZG5AJgQUCnCpcelyov9AJgMSQCYEFQpw6XHpcp7/qXBKcSpy
-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
-yXHpcrb/gg3v/qlwnQLP/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAA
-AAAAAAIAAAAPAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAF+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoPERQAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-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
-KAAGAQgAAAAqAAgBCQAAACwACgEKAAAALgAMAQsAAAAwAA4BDAAAADQAEAENAAAAOAASAQ4AAAA8
-ABQBDwAAAEAAFgEQAAAAZAAaAREAAABoABwBEgAAAGwAHgETAAAAcAAgARQAAAB0ACIBFQAAAHgA
-JAEWAAAAfAAmARcAAACAACgBGAAAAIQAKgEZAAAAiAAsARoAAACMAC4BGwAAAJEAMgEcAAAAlQA0
-AR0AAACZADYBHgAAAJ0AOAEfAAAAoQA6ASAAAAClADwBIQAAACQAUAEGAAIALABSAQoAAgA0AFQB
-DQABADwAVgEPAAEAZABYAREAAQBsAFoBEwABAHQAXAEVAAEAfABeARcAAQCEAGABGQABAJUAYgEd
-AAEAnQBkAR8AAQCCAALS/wAAAIIAGZBAHwAAAgAI0gAAAAACAAnSAAAAAAIARdIAAAAAAgBG0gAA
-AACCAAXSAAAAAIIABtIAAAAAggA+kAAAAACCAEPSAAAAAIIARNIAAAAAAAAAAAAAAAAAAAAAAAAA
-AJQKAACcCgAAuAoAANQKAADwBQAAmAoAAKgKAADECgAA4AoAAAwGAAAJAAAAAYAAEYAAFgQCIAAS
-gAAWBANAABCAABcEBOAAEIAAFwQFgAARgAAXBAYgABKAABcEB0AAEIAAGAQI4AAQgAAYBAmAABGA
-ABgECiAAEoAAGAQLQAAQgAAZBAzgABCAABkEDYAAEYAAGQQOgAAQgAAaBCKAABgAABYAJAAAGQAA
-FgEmAAAiAAAWASgAABoAABYBKoAAGgAAFgEsAAAgAAAXAS6AABgAABcBMAAAGQAAFwE0AAAaAAAX
-ATaAABoAABcBOAAAIAAAGAE8AAAZAAAYAT4AACIAABgBQAAAGgAAGAFkAAAaAAAbAmaAABoAABsC
-aAAAIAAAHAJsAAAZAAAcAm4AACIAABwCcAAAGgAAHAJ0AAAgAAAdAnaAABgAAB0CeAAAGQAAHQJ8
-AAAaAAAdAn6AABoAAB0CgAAAIAAAHgKEAAAZAAAeAoYAACIAAB4CiAAAGgAAHgKMAAAgAAAfApFA
-ABkAAB8DlQAAIwAAHwOXwAAaAAAfA5lAABgAACADnUAAGQAAIAOfwAAZAAAgA6EAACMAACADpUAA
-GAAAIQMAAwkAAwMJAAkAAwkOAAAAKgAAAAcAAAALAAAAAAIEBgAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABA
-AGkgAABpIEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAABgAWkgAABpIEAA
-aSAAAEogAABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBK
-JQAQSiYAEEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4AA
-AKBBLJwwQCycMEIkHDQKIoA/gAAIDwojADeaCAAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYA
-cIAABA9AeCAgQIcAAAAAAAAAAAAA4cWYcCh1BLjPcZ8A2P8SoQQkgA8A8AAARXgTobahgOMF8s9w
-AG0AEBGh4H/BxeB4z3KfANj/EqIzomnYGLgRouB+4HjPcZ8A2P/Pcp8AuP8SoWrYGLgRoRyC4H7g
-fuB44H7gePHA+gggAADZz3agAMAvFIbPcqAArC/PdaAAhDSLuBmiZYUYFQQQDBUFEBAVBhAUhuO4
-//WKIAgAFqLPdaAAyB/Pd6AA0BsOHViQDx1YkBAdWJARHViQPNji/08gQQA82Nv/aHAA2Ze5iHIB
-28z/EYf9uP/zAN+dv89xgADsAwHYEx3YkwChN4bPcIAABATIciCgOobPcIAACAQgoKhwANkoc7//
-Dx3Yk89wgADYAwAQGgDPcQBtABDPcJ8A2P8xoGkggABvIT8AmQAAAPwciLb8HEi2/BwItvwcyLX8
-HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8HEiz4H7geATcON018OB4BNw03TPw
-4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATcIN0p8OB4BNwc3Sfw4HgE3BjdJfDg
-eATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE3RnwNBQaMDAUGTAsFBgwKBQXMCQU
-FjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRNM7AkHzPgfg==
-====
diff --git a/sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu b/sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu
new file mode 100644
index 00000000000..4047c279c33
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu
@@ -0,0 +1,6094 @@
+Copyright (c) 2006-2008, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without 
+modification, are permitted provided that the following conditions are 
+met:
+
+* Redistributions must reproduce the above copyright notice and the 
+  following disclaimer in the documentation and/or other materials 
+  provided with the distribution. 
+* Neither the name of Intel Corporation nor the names of its suppliers 
+  may be used to endorse or promote products derived from this software 
+  without specific prior written permission. 
+* No reverse engineering, decompilation, or disassembly of this software 
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide, 
+royalty-free, non-exclusive license under patents it now or hereafter 
+owns or controls to make, have made, use, import, offer to sell and 
+sell ("Utilize") this software, but solely to the extent that any 
+such patent is necessary to Utilize the software alone, or in 
+combination with an operating system licensed under an approved Open 
+Source license as listed by the Open Source Initiative at 
+http://opensource.org/licenses.  The patent license shall not apply to 
+any other combinations which include this software.  No hardware per 
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-5000-5.4.A.11.fw.uu
+EAEEBfj1AQAAwAAAoM0BAADAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABp
+IAAAaSBAAGkgAABpIEAAICCADwAAAAZpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEol
+AABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMA
+IEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAADAQSycMEAsnDBCJBw0CiKAP4AAEF8KIwA3
+dg8AAEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAFgEQHggIECHAAAAAAAAAAAAAOHE4cDh
+weHCz3CgAMgfFhABhs9ygABgcyCiEhABhiGiExABhiKiFBABhiOiFRABhiSiJBABhiaiz3GfALj/
+VqGKIf8PEhhYgBMYWIAUGFiAFRhYgCQYWIDBwsHBwcDBxCAgQIcKyM9yoADIHw4aGIALyA8aGIAM
+yBAaGIANEgE2AMgkeBEaGIAOyC0aGIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwc
+yLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAVAQEIICPz1EE
+4QChCvIvKQEAz3CAAMwN8CBAAEB42v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0
+BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwrIh7gKGhgwC8ib
+uAsaGDAMyAwaGDANyIe4DRoYMA7IhSDDDw4aGDDgfuB48cAKyJW4ChoYMAvIm7gLGhgwDciKuI24
+kLgNGhgwz3CAAOwOGIiB4Av0DcjPcQAA9AqsuA0aGDDGDSAAD9hn2G4N4ACKIcYI0cDgfs9wgACk
+nwCAhCABjgj0DcgFIIAPAAAA1A0aGDBA8eB48cDPcQMAQA3PcKAAqCAtoM9ygACEBCCCAWkAohII
+IAFI2M9wgACcCCWAI4EggcdxAACIE/INQAjS8eB4z3CAAJwIlQVACOB48cCSCUABgODPdoAAVAQG
+8oHgBvQB2APwANgLroDhBvKB4Qb0AdgD8ADYCq6A4gbygeIG9AHYA/AA2AyuANjPdaAAyB8YHRiQ
+C46A4IohEAAO8giOgOAM8s9wAwBADUUdGBAwpQLYGB0YkAPwMaUKjoDgGvIJjoDgFvLPcAEA9vUg
+HRiQz3CAACQAIR0YkM9wgABQBCIdGJAYFQCWRSAAAxgdGJAMjoDgB/IYFQCWhSABBBgdGJCA4xjy
+ANiUuM92gAB4BACmcdgGuB4P4AD82SCGz3AAAEwcDg/gAJ+5GBUAloW4GB0YkBUBQAHPcaqqu7vP
+cJ8AuP82oDagNqA2oM9xoADIOw6BiLgOoWkgQAD+8eB48cClwUHAQsEMHAAxEBxAMc9wgAB8YDQY
+wA8wGAAPLBjADigYgA4kGEAOz3GAAHxgIBlAC89wgAB8YBwYAAvPcIAAfGAYGMAKz3GAAHxgFBmA
+Cs9wgAB8YBAYwAjPcYAAfGAMGYAIz3GAAHxgCBlACM9xgAAAYIAZAAh8GcAHeBmAB3QZQAdwGQAH
+bBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE76HOoa2hjKEs
+GcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkAAGoggALQGQAA
+aiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAAaiCAAcwZAADQ
+2J+4z3GfALj/HaHPcIAAAADEgFMlxDVTJsU117oB5tO+xKBTI8AEBSaOH9D+AADWoQUggA+w/gAA
+FqEYgVMnzjUA3ZS4GKFAwwHAAsHJcwwUBjCyCuAAEBQHMM9woAC0D7ygz3GgAMg7LoFGCuAAfdim
+CUABRg3gAKlwCNgA2R4N4ACZuRDx8cCWDgABz3CAAHxgNBjADzAYAA8sGMAOKBiADiQYQA7PcIAA
+fGAgGEALz3CAAHxgHBgAC89wgAB8YBgYwArPcIAAfGAUGIAKz3CAAHxgEBjACM9wgAB8YAwYgAjP
+cIAAfGAIGEAIz3GAAABggBkACHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZ
+gAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcABGBmA
+ARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDAAMAZ
+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
+pwCYRwC2iiDEAAalCoXPd6sAoP8BtoogxQAGpQqFAraKIMsABqUKhQO2iiDPAAalCoUEts9wAACD
+DQalCoUFts9wAADDDQalCoUGts9wAAADDgalCoUHts9wpwAUSAiABKYcgQWmz3CnABRIV4AWgEam
+B6bPcKUACAwCgMbaCKYYh5C6CaYZhwqmGocLps9wBQDGAwalAdhGpc9yLAACAUalz3JaAEIBRqWK
+IosARqXPckAAhw1Gpc9y0QDCDUalz3LAAAcORqXPcqcAFEgIos9yUAD/AFyhz3GnABRIF6EA2Bah
+z3ClAAgMUNkioPzYGKdz2BmnGoeBuBqnz3ARAAYOBqWLcIHBlf8zhgDAUoYieDSGCrhiCe/7QnmE
+KIQDQilBcja5AcIncUq5giHEAs9wgABcdjCmVaA2oM9wQACGDQalz3AQAAIOBqWLcIHBg/8zhgDA
+UoYieDSGCrgaCe/7QnkEKIAPAAB0CUIpQXI2uQHCJ3FKuU/hz3CAAFx2MaZXoDigAZYQuIUghAAG
+pQKWELiFIIUABqUDlhC4hSCLAAalBJYQuIUgjwAGpQWWELgFIIAPAACCDQalBpYQuAUggA8AAMIN
+BqUHlhC4BSCADwAAAg4GpSSGz3CnABRIKKAmhiAWBRA3oCeGTCUAgDagz3ClAAgMCBhAAcogYgHK
+IcIPyiLCB8ojgg8AAPUATAOi88okIgAJhhinCoYZpwuGGqeWCu/+DIaKINEFFg9v9DCGz3CAANQ9
+EIABBO/0osDgePHAkgvP9M9wgABwaAeIgOAcAiEAosEeCe/+BdjPdYAA1D0MpcPYz3agAOwnBqYK
+hgDbALWKIMQABqYKhs9ypwCYRwG1iiDFAAamCobPd6sAoP8CtYogywAGpgqGA7WKIM8ABqYKhgS1
+z3AAAIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1z3CnABRICIAEpRyCBaXPcKcAFEg3
+gBaAJqUHpc9wpQAIDAKAxtkIpRiHkLkJpRmHCqUahwulz3AFAMYDBqYB2Camz3EsAAIBJqbPcVoA
+QgEmpoohiwAmps9xQACHDSamz3HRAMINJqbPccAABw4mps9xpwAUSAihz3FQAP8APKLPcacAFEgX
+oXahz3ClAAgMUNkioPzYGKdz2BmnGoeBuBqnz3AqAAIOBqaLcIHB+P4Awc9wgABcdjKlMqABwS+g
+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
+j7thtmCFHN6EKQsKwKPPc4AAQKIwI04OYYWZvsGjgOHKIWIAMKsA2TMbQgAxqwqjMRtCATIbQgE7
+s1qzQCMAAzYOb/IwiwGFCNkyqATBgOEF8s9wgAAoCCSg0glv9alwfQdP8s9wgABwhCiAz3CfALj/
+ANo2oAjZ7HAgoAPZz3CgABQEJaAByOxxAKHPcKAA1AtNoOB+4HjPcYAAPAjgfwCh4HjPcIAAPAjg
+fwCA4HhlBg/yYQYP8uB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwDY4H8A2OB+4HihweB/
+ocDgeOB+4HjgfuB48cDhxQHIz3WAAFRHAKUEbfIOL/IC2c9wgACgBCCABSGBD4AOBADscCCgZg0v
+8gCFzQZP8uB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7gePHAzHAAkM9xgABURwax
+zHAAEAUBQCECBA4ZRAFMJYCEyiBiAcohwg/KIsIHyiOCDwAAcwCABSLxyiQiAADZCPDMcACQFCJM
+AAHhALQvIEIBEHG49gYOD/LRwOB+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+z3CAAEAI4H8AgOB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8B2OB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjxwOHFz3WAAJRHqXBKDS/y
+A9kAFYUQRCVAAYXgyiBhAcohwQ/KIsEHyiOBDwAATwAwBCHxyiRhAAGNg+DD9mO4Aa3GDA/yDQVP
+8uB48cCODE/yz3KAAJRHYIrguzbyz3OAAEgIoIuA5cwhIYAu8oHgBvTPcIAAjI2hgAPwAN2O5QP3
+gOUC9ADdz3eAAIyNGI+A4AT0gOUE9ADeBPCihwTez3CAAOwOGIiD4MwgIoHMIOKBzCAiggr0CpIQ
+dQj0C5IQdswhIYAE9ADYEPAB2M9xoADIHw2hqrLLskGLBL7FfRC6pXp/GZiAWQRP8vHA7gtv8ghx
+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
+MBzAEQAAACEPHB0iGAEdJhgAxxCkhICBAADAFyAAxxCshICBAADAFwAAACEIMYCB+EHEEA8bCSIA
+Cwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEIAAlAAgAAYQoACUAAAABhAgAJQQAJGigAAMAWAQAbJgAA
+wBcEAB0mAQAIJ+sACGQAAAAhAAAAAJABAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKQyAABwMwAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPB2gAAA
+AAAAAQAAAAcAAAAAAAAAwACQANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD
+AAAAAAAAAHyIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAABcjYAAdGQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAABgAIAAkAAAAHAAAAAAAA
+AAIAAAACAAAAgwAAAJIAAADoAAAA9wAAAE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyc
+gABkxwEAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwhIAADM8B
+AAAAAABwhIAAiNUBAAAAAAAAAAAAcISAAPDWAQAAAAAAAAAAAAAAAABwhIAAAAAAAAAAAAAAAAAA
+/wAAAAAHAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECBAgA
+CBAgAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwIAAAVAAAAYC2AAFwk
+AABcJAAAXCQAAOw0AABcJAAAXCQAAOA0AABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQA
+AFwkAABMGgAAvBsAAMAbAAA4HQAAvB0AADwdAABcJAAAXCQAAMQ9AAD0QAAA3EEAAFwkAABcJAAA
+XCQAAIg8AACAUgAAfFIAAMBSAABcJAAAXCQAAFwkAADwNAAAXCQAAFwkAABcJAAAXCQAAFwkAABc
+JAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwk
+AABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQA
+AOA1AABcJAAAXCQAAFwkAABcJAAAXCQAAMQ2AABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAA
+XCQAAFwkAABcJAAAXCQAAKRXAABcJAAAmFgAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABc
+JAAAxFoAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAdEsBALhO
+AQBcJAAAoFABAFwkAAAEUgEAFCgBAFwkAABcJAAAWEIAAFwkAABcJAAAXCQAAFwkAABcJAAABLAB
+AMTCAQBcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAA+N0BAPzdAQBcJAAAXCQAAFwkAABcJAAA
+XCQAAFwkAACUzQEAXCQAAEjRAQBcJAAAXCQAAFwkAAAkIAAAVO4BAFwkAABcJAAA5N8BAFhdAABc
+JAAAXCQAAFwkAACsywEAXCQAAFwkAACUIAEAoGcBAFwkAABcJAAAXCQAAExvAQA4KQEAXCQAAFwk
+AABcJAAAXCQAAFwkAABcJAAAOHkBAFwkAADs3gEA8N4BAPzeAQAA3wEA9N4BAPjeAQAE3wEAXCQA
+AFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAANEQAAFwkAABcJAAAXCQAAFwkAABcJAAA
+ON4BAJDeAQD4OAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABc
+JAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwk
+AABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAFwkAABcJAAAXCQAAJg5AAA0OgAAxDoA
+AGw7AABsagAARDsAAFwkAABcJAAAXCQAAFwkAABcJAAAkDkAAJQ5AABcJAAAXCQAAIhCAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAoAAMwKAADMCgAAzAoAAMwKAADMCgAAzAoA
+AMwKAADMCgAAzAoAAMwKAADMCgAAzAoAAMwKAADMCgAAzAoAAMwKAADMCgAAzAoAAMwKAADMCgAA
+zAoAAMwKAADMCgAAzAoAAMwKAADMCgAAzAoAAMwKAADMCgAAzAoAABAMAAAAAAAA1C4BAMwKAAAU
+CQAAzAoAAMwKAADMCgAARAkAAFgPAQAEawAAzAoAAMwKAAB4CQAAeAkAAHgJAAB4CQAAeAkAAHgJ
+AAB4CQAAzAoAAMwKAADMCgAAzAoAAJgKAADMCgAAzAoAAMwKAADMCgAAzAoAABQMAADMCgAAzAoA
+APgIAAADAAAArNwBAAIAAAAwOQEABAAAALwuAAAGAAAAbN4BABAAAADwyAEABwAAAPDSAQAIAAAA
+CN8BAAwAAABAZQEADQAAABRUAQAOAAAASFQBABUAAAA8LgEACwAAAKhMAQATAAAAVF0AAA8AAADI
+HwEAAQAAADzNAQARAAAAfHYBABIAAAC0ZwEABQAAACBbAAAUAAAAOO0BABYAAAAQDAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAw4e4eEDDh7hwQIKHuGB
+BQwe4eEDDh7h4QMOHuHBAgYe4YEFDB7hAQEBAQEBAQEBAQEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0D
+AwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0N
+DQ0NDQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0N
+DQ0NDQ0NDQ0NDQ0NDQMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAkQIAADHKLwCRAgAA
+McovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAEMBAAAx
+yi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHK
+LwBADQAA3gMJAAAAAAAAAAAAAAAAADz7AAABAAAAIC2AAAAAAAAAAAAAAgAAAAMAAAAAAAAABwAA
+AAAAAABAQg8AfPsAADj8AABE/QAA/P4AAET9AAD8/gAANAABAKwAAQCAgICAgICAgAGAAoCAgICA
+AAAAACQIAQAkCAEAAAAAAAAAAAAAAAAAAAAAACQIAQAkCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAJwKAQAVAAAAYC2AACAtgAAgLYAApCCgADggoAABAAAA/P///wAA
+AAAAAAAAQC2AAEAtgACoIKAAPCCgAAgAAADz////AAAAAAAAAABgLYAAYC2AAKwgoABsIKAAMAAA
+AM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAA
+2CABAAUAAAAgLYAAxCYBAAD/AwDkJgEAAP8FAMwnAQAA/y0A8CcBAAD/PQCoJwEAAP8EAIwnAQAA
+/yUAAAAAAAAAAAAAAAAA0CwBAAYAAAAgLYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADALwEAiDAB
+AKAzAQB4MQEA8DABAFw0AQC8NAEAADUBAEQ1AQAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAA
+AwAAAAAAAAAAAAAAAAAAAAMAAAACAAAAAwAAAAMAAAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAA
+AAAAjDoBAAoAAAAgLYAAAAAAAAAAAAAAAAAA7DoBAAoAAAAgLYAAAAAAAAAAAAAAAAAAADsBAAoA
+AAAgLYAAAAAAAAAAAAAAAAAATDsBAAoAAAAgLYAAAAAAAAAAAAAAAAAAFDwBAAoAAAAgLYAAAAAA
+AAAAAAAAAAAAuDsBAAoAAAAgLYAAAAAAABAAAAAAgAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAA
+AAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAK
+AAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAA
+AAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAA
+APwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAA
+IC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAAAAAAAAAAAPwRAQAKAAAAIC2AAAAAAAAA
+AAAAAAAAAFhQAQAKAAAAIC2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw
+VwEAOFgBAKhaAQA8XQEAnF8BANRiAQCgWQEAOAWAADiEgAAYAAAA+IOAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAA6GQBAAYAAAAgLYAAAAAAAP//////////AAAAAAAAAAAAAAAALGcBAAUAAABgLYAAZABk
+AGkA3ADIAFoAqgC+AIYBfQA+AGQAZABpANwAyABaAKoAvgCGAX0APgAAAAAAAQEAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgECAQIAAgABAgMAAAAAoHgBAHCJAQDEjYAA
+wAMAAAAAAACgeAEAzHkBAISRgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0I0BANiLAQB8
+k4AAVAAAAAAAAACgeAEACIwBAPyTgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAoHgBAHiI
+AQB0N4AAUAEAAAAAAADkjQEAjIoBAMgGgAACAAAAAAAAAKB4AQC4igEAzAaAAAQAAAAAAAAAvI0B
+AMx5AQDQk4AALAAAAAAAAACgeAEAJIsBAAAAAAAAAAAAAAAAAKB4AQDkigEA0AaAAAQAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHACAAIAAhACIAIgAj
+ACQAJAAlACYAJgBDAEQARABFAEYARgBHAEgASABJAEoASgBLAEwATABNAE4ATgBPAFAAUABRAG4A
+bgBvAHAAcABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4AA8APwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkACgAjACMA
+JAAlACUAJgAnACcAKAApACkARgBHAEcASABJAEkAZgBnAGcAaABpAGkAagBrAGsAbABtAG0AbgBv
+AG8AcABxAHEAcgBzAHMAdAB1AHUAdgB3AHcAeAB4AHgAeAB4AHgAeAB4AA4APwAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHACAAIAAhACIAIgAjACQAJAAl
+ACYAJgBDAEQARABFAEYARgBHAEgASABJAEoASgBLAEwATABNAE4ATgBPAFAAUABRAG4AbgBvAHAA
+cABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4AA8AQwAAAAAAAAAAAAAAAAAA
+AAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkACgAjACMAJAAlACUAJgAnACcAKAApACkA
+RgBHAEcASABJAEkAZgBnAGcAaABpAGkAagBrAGsAbABtAG0AbgBvAG8AcABxAHEAcgBzAHMAdAB1
+AHUAdgB3AHcAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AAgAQwCgbAEAEtIAAAAAAAD//w8A
+zIUBALYAAAAAAAAA/wAAAMyFAQC3AAAAAAAAAP8AAADMhQEAuAAAAAAAAAD/AAAAzIUBALkAAAAA
+AAAA/wAAAMyFAQC6AAAAAAAAAP8AAADMhQEAuwAAAAAAAAD/AAAAzIUBAL0AAAAAAAAA/wAAAMyF
+AQC+AAAAAAAAAP8AAADMhQEAvwAAAAAAAAD/AAAAzIUBAMAAAAAAAAAA/wAAAMyFAQDBAAAAAAAA
+AP8AAADMhQEAwgAAAAAAAAD/AAAAoGwBABPSAAAAAAAA//8PAMyFAQAbAQAAAAAAAP8AAADMhQEA
+HAEAAAAAAAD/AAAAzIUBAB0BAAAAAAAA/wAAAMyFAQAeAQAAAAAAAP8AAADMhQEAHwEAAAAAAAD/
+AAAAzIUBACABAAAAAAAA/wAAAMyFAQAiAQAAAAAAAP8AAADMhQEAIwEAAAAAAAD/AAAAzIUBACQB
+AAAAAAAA/wAAAMyFAQAlAQAAAAAAAP8AAADMhQEAJgEAAAAAAAD/AAAAzIUBACcBAAAAAAAA/wAA
+AKBsAQAU0gAAAAAAAP//DwDMhQEAggEAAAAAAAD/AAAAzIUBAIMBAAAAAAAA/wAAAMyFAQCEAQAA
+AAAAAP8AAADMhQEAhQEAAAAAAAD/AAAAzIUBAIYBAAAAAAAA/wAAAMyFAQCHAQAAAAAAAP8AAADM
+hQEAiQEAAAAAAAD/AAAAzIUBAIoBAAAAAAAA/wAAAMyFAQCLAQAAAAAAAP8AAADMhQEAjAEAAAAA
+AAD/AAAAzIUBAI0BAAAAAAAA/wAAAMyFAQCOAQAAAAAAAP8AAACgbAEACNIAAAAAAAD//wMA4GwB
+AACCAAAAAAAA/wEAAOBsAQABggAAAAAAAP8BAACgbAEACdIAAAAAAAD//wMA4GwBAAKCAAAAAAAA
+/wEAAOBsAQADggAAAAAAAP8BAACgbAEACtIAAAAAAAD//wMA4GwBAASCAAAAAAAA/wEAAOBsAQAF
+ggAAAAAAAP8BAACgbAEABtIAAAAAAAD/AQAAoGwBAAfSAAAAAAAA/wMAAKBsAQAG0gAACQAAAAD+
+AwCgbAEAB9IAAAoAAAAA/A8AoGwBAAbSAAASAAAAAAD8B6BsAQAH0gAAFAAAAAAA8D+gbAEAFdIA
+AAAAAAD/AwAAoGwBAAzSAAAAAAAA/wEAAKBsAQAV0gAACgAAAAD8DwCgbAEADNIAAAkAAAAA/gMA
+oGwBABXSAAAUAAAAAADwP6BsAQAM0gAAEgAAAAAA/AcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAQAAgABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAFAAIAAQAB
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAkABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAACAA
+EwAKAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAAAAQAAmABQACgAFAAMAAQABAAAAAAAAAAAAAAAA
+AAAAAACAAEwAKAAUAAoABQADAAEAAQAAAAAAAAAAAAAAAAAAAAABlwBQACkAFAAKAAUAAwABAAEA
+AAAAAAAAAAAAAAAAAAIuAaAAUQApABQACgAFAAMAAQABAAAAAAAAAAAAAAAABF0CPwGiAFEAKQAU
+AAoABQADAAEAAQAAAAAAAAAAAAAIuQR/AkQBowBRACkAFAAKAAUAAwABAAEAAAAAAAAAABByCf4E
+iQJGAaMAUQApABQACgAFAAMAAQABAAAAAAAAIOQS+wkRBYsCRgGjAFEAKQAUAAoABQADAAEAAQAA
+ABzSDdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwbSB9IE0gkQAAC1ABoBgQEFAAQABgAIAAkA
+CgALAAwAgwCSAOgA9wBOAV0BDwAuAAAAbAAAAHQAAACAAAAAjAAAAJ0AAAAHAAAABAAAAAgAAAAQ
+AAAAQAAAAIAAAAAgAAAAAAAAAAkAAAASAAAAAAAAAAoAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAIA
+AQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABQACAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAEAAJAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABMACgAFAAMAAQABAAAAAAAAAAAA
+AAAAAAAAAAAAAEAAJgAUAAoABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAgABMACgAFAAKAAUAAwAB
+AAEAAAAAAAAAAAAAAAAAAAAAAZcAUAApABQACgAFAAMAAQABAAAAAAAAAAAAAAAAAAACLgGgAFEA
+KQAUAAoABQADAAEAAQAAAAAAAAAAAAAAAARdAj8BogBRACkAFAAKAAUAAwABAAEAAAAAAAAAAAAA
+CLkEfwJEAaMAUQApABQACgAFAAMAAQABAAAAAAAAAAAQcgn+BIkCRgGjAFEAKQAUAAoABQADAAEA
+AQAAAAAAACDkEvsJEQWLAkYBowBRACkAFAAKAAUAAwABAAEAAAA4BYAAOISAABgAAAD4g4AAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAArMQBAAYAAAAgLYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4BYAAOISAABgAAAD4g4AAAAAAAAAAAAAAAAAAAAAAAAAA
+AADszgEABgAAACAtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAADgFgAA4hIAAGAAAAPiDgAAAAAAAAAAAAAAAAAAAAAAAAAAAADDaAQAEAAAA
+IC2AAAAAAAAAAAAAAAAAAFDZAQAEAAAAIC2AAAAAAAAAAAAAAAAAANTaAQAGAAAAIC2AAAAAAAAA
+AAAAAAAAAFDZAQAEAAAAIC2AAAAAAAAAAAAAAAAAADDaAQAEAAAAIC2AAAAAAAAAAAAAAAAAAFDZ
+AQAEAAAAIC2AAAAAAAAAAAAAAAAAADDaAQAEAAAAIC2AAAAAAAAAAAAAAAAAAFDZAQAEAAAAIC2A
+AAAAAAAAAAAAAAAAANTaAQAGAAAAIC2AAAAAAAAAAAAAAAAAAFDZAQAEAAAAIC2AAAAAAAAAAAAA
+AAAAADDaAQAEAAAAIC2AAAAAAAAAAAAAAAAAANTaAQAGAAAAIC2AAAAAAAAAAAAAAAAAADDaAQAE
+AAAAIC2AAAAAAAAAAAAAAAAAADDaAQAEAAAAIC2AAAAAAAAAAAAAAAAAANTaAQAGAAAAIC2AADgF
+gAA4hIAAGAAAAPiDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAFAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQE
+BQYHCAgICAgJCgsMDQAAAAUGBwgNDg8QFRYXGBkAAAoNERQKDREUCg0RFAoKAAAAAAAABgYGBgkJ
+CQkABgAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbiho
+KGIoXChuJ2gnYidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gH
+YgdcB24GaAZiBlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABi
+AFwAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIo
+XChuJ2gnYidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdc
+B24GaAZiBlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwA
+AAAAAAAAAAAAAAAAWPIBAAgAAABgLYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA/////////wAB//8CA////wT//////////////////////wX/Bv8H/wj/Cf8K
+/wv/DP///w3///8O////D////xD//////////////////////////////////////////////xH/
+//8S////E////xT///8V////Fv///xf///8Y////Gf///xr///8b/////xz///8d////Hv///x//
+//8g////If//////////////////////IiMk/yUmJ///KP///yn/////////////////////////
+/////////////////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAF
+CAQABgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUEABAJCAQQDQwIEBEQDBAVF
+BAQGRgUEB0cGBLcTIgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4D
+ABAfBAAiIQUAJCIGACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEA
+aC8SAGwwEwBwMRQAdDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwCh
+PiAApT8hACRJBgIsSgoCNEsNATxMDwFkTREBbEMTAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAEFggWFhYMFhYWFhYWFhAAAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/
+AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAAAAABAAAAAgAAAAMAAAAAAAAA
+BAAAAAIAAAAFAAAACgUBpREBAKUAPDg0MCwoJCAcGBQQDAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQC
+ABUPAAAAABsAAAABAQABAgEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAApcaE+JnujfYN/73Wsd5UkVBgAwKpzn1WGediteZNmuxFj50fQImH+hXv67LJjgv7
+7EFns/1f6kW/I/dTluRbm8J1HOGuPWpMWmxBfgL1T4NcaPRRNNEI+ZPic6tTYj8qDAhSlWVGXp0o
+MKE3Dwq1LwkONiSbGz3fJs1pTs1/n+obEp4ddFguNC02stzutPtb9qRNdmG3zn17Uj7dcV6XE/Wm
+aLkAACzBYEAf48h57ba+1EaN2WdLct6U1JjosEqFa7sqxeVPFu3FhteaVWaUEc+KEOkGBIH+8KBE
+eLol40vzov5dwICKBa0/vCFIcATx32PBd3WvY0IwIBrlDv1tv0yBFBg1Ji/D4b6iNcyIOS5Xk/JV
+gvxHeqzI57orMpXmoMCYGdGef6NmRH5UqzuDC8qMKcfTazwoeafivB0Wdq0721ZkTnQeFNuSCgxs
+SOS4XZ9uve9DpsSoOaQxN9OL8jLVQ4tZbrfajAFksdKc4Em02PqsB/Mlz6/KjvTpRxgQ1W+I8G9K
+clwkOPFXx3NRlyPLfKGc6CE+3ZbcYYYNhQ+Q4EJ8xHGqzNiQBQYB9xIco8Jfavmu0GmRF1iZJzq5
+JzjZE+uzKzMiu9JwqYkHpzO2LSI8khUgyUmH/6p4UHqljwP4WYAJFxraZTHXxoS40MOCsCl3WhEe
+y3v8qNZtOiwBAQEBAQEBAQICAgICAgICAwMDAwMDAwMEBAQEBAQEBAECAgICAgIDAwMDAwMDAwMD
+AwMDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAABAQIBAgIDf/8HDx8/AQMBAw8HAQcPHz9/
+//8FAAcCAwQGBnTRRRfooosuDQ8FBwkLAQMKFDduVVVVAUtoLwFVVVUF4ziOA6qqqgJxHMcBqqqq
+CsdxHAcPDw8HBgcCAwQFAAEICQsKKAAoADAALAAsACgAPAA0ACgAKAA0ADAALAAsAEQAPABAADwA
+jABsAFgASAD0ALAALAAsADwANAAwACwAVABEAFQAVABsAGAAXABUAIwAeAA6AQIB1QDfANoAogB1
+AH8AagEaAdkA6AAKAboAeQCIAIoFKgM5AagBigXKAtkASAHKAUoB4gD5AMoB6gCCAJkA9AJEArUB
+1QGUAoQB9QBBAqwAkACEAIAAeAB4AHgAdABm5gAAndiJnU7sxE40SIM0J3ZiJxqkQRoTO7ETERiB
+EQ/8wA9O7MROJ3ZiJxqkQRoTO7ETDdIgDYmd2AkIjMAIB37gBzRIgzQapEEaERiBEQ3SIA0IjMAI
+BmmQBrCy1QUFVEAFJ3ZiJxM7sRMN0iANiZ3YCQZpkAbETuwEBEZgBAM/8AOqqqqqGqRBGhM7sRMP
+/MAPERiBEQ3SIA0KqIAKEzuxEw/8wA8P/MAPDdIgDQu0QAsLtEALiZ3YCQ3SIA0KqIAKCqiACgiM
+wAgHeIAHB3iABwZpkAYP/MAPDdIgDQu0QAsN0iANC7RAC4md2AkIjMAIiZ3YCQiMwAgHfuAHB37g
+B8EsKQcKqIAKCIzACAd4gAcIjMAIB3iABwZpkAawstUFBmmQBrCy1QUFVEAFBVRABdYdxgQNABoA
+JwA0AE4AaAB1AIIAGgA0AE4AaACcANAA6gAEAScATgB1AJwA6gA4AV8BhgE0AGgAnADQADgBoAHU
+AQgCDABOAGgAggB1AJwAwwBoAIIAggCcALYAtgDQAJwAwwDDAOoAEQERATgBggCcALYAnAC2ANAA
+6gDQAOoABAEEAR4BwwDqABEB6gARATgBXwE4AV8BhgGGAa0BAAAwAAAANgAAAAwAAAASAAAAGAAA
+ACQAAAAGAAAACQAAAAAAAAAAAAAAGCAUFA4OFBQFBgECAwQAAAABAQIBAgIDBAwMCAQMBARAAAAA
+gAAAAAABAAAAAgAAQAAAAAAEAABAAAAAQAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss
+LS4vQEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1
+dnd4eXp7fH1+fzMTAAAABwcPBw8PFy0ADyAA8GEAAAAAAAAAAAAAAQIEBAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAFQ1twBtt6WVt2YAAAB1dV0GdXV1dUIAAAgAAAACAAAAAAAAAAAAAAAIAAAAAgAA
+AAAAAAAAAAAACAAAAAMAAAABAAAACAAAAAgAAAACAAAAAgAAAAgAAAABAgECAwQAAAUGBwgJCgAA
+AAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBAQAUFQEAMDEANDAwB
+AQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAFBQVABUAFBQUFBQQA
+AAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAAAGQAAAAAkAEACgAA
+AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA
+/wAAAP8AAAAAAAAAAAAAABzbAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA
+AAAFAAAAAAQAAGQAAADkTQEA7E0BAPRNAQBMTgEAVE4BAFxOAQAHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBgYGBgUFBQUFBAQEBAQDAwMD
+AwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAQOCR0tOQAABBEJHy07AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAA
+AAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAAB
+RgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIA
+AOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAA
+AAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAAB
+XAAuFwAAgAAAAwAAAV0AMBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAAOBgA
+AAAAAAQAAAFgADwYAAEAAAADAAABYgA+GAACAAAABAAAAWIAQBgAAgAAAAMAAAFjAGQbAAIAAAAD
+AAABbwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAAAXIB
+cBwAAgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2AnwdAAIA
+AAADAAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAABAAA
+AXoEiB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/BZcf
+AALAAAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAADAAAA
+BAAAAYMFpSEAAEAAAAMAAAGFBQAAAAAAAAAAAAC0wQEAbLIBAEy0AQCAtQEAoLcBAEC6AQAYvgEA
+oL8BANTAAQCs0wEAtNMBACDUAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQkSFBgAAA4AAAAqAAAABwAAAAsAAAD/////AAAAAAAA
+AAABAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAA
+gA0AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAgIIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkg
+QAAgIIAPAADwBWkgAABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAA
+EEohABBKIgAQSiMAEEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAg
+SicAIEogADBKIQAwCiSAP4AAAMBBLJwwQCycMEIkHDQKIoA/gACsTwojADdiDwAASiYAcGkgQABK
+JgBwSiYAcEomAHBKJgBwABYAcIAAWARAeCAgQIcAAAAAAAAAAAAA4cThwOHB4cLPcKAAyB8WEAGG
+z3KAAOBjIKISEAGGIaITEAGGIqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8AuP9WoYoh/w8SGFiAExhY
+gBQYWIAVGFiAJBhYgMHCwcHBwMHEICBAhwrIz3KgAMgfDhoYgAvIDxoYgAzIEBoYgA0SATYAyCR4
+ERoYgA7ILRoYgOB+4cT8HMi+/BxIvuHA4cHhwuHD/BwIsfwcSLH8HIix/BzIsfwcCLL8HEiy/ByI
+svwcyLL8HAi/aiSAEOHEaiTAEOHE8cDPcKAA0BsUgM9xgABUBAQggI/PUQThAKEK8i8pAQDPcIAA
+0A3wIEAAQHja/9HAwcRrJMAQwcRrJIAQwcSfdAQUCzQEFAo0BBQJNAQUCDQEFAc0BBQGNAQUBTQE
+FAQ0wcPBwsHBwcDBxEUsfhAKJkB+wcRrJIAUwcQgIECHCsiHuAoaGDALyJu4CxoYMAzIDBoYMA3I
+h7gNGhgwDsiFIMMPDhoYMOB+4HjxwArIlbgKGhgwC8ibuAsaGDANyIq4jbiQuA0aGDDPcIAA6A4Y
+iBsIUQANyM9xAADYCqy4DRoYMLINIAAP2GfYLg3gAIohxgjRwOB+z3CAAHiKAICEIAGOCPQNyAUg
+gA8AAADUDRoYMEDx4HjxwM9xAwBADc9woACoIC2gz3KAAIQEIIIBaQCiqg/gAEjYz3CAAKAIJYAj
+gSCBx3EAAIgTyg4ACNLx4HjPcIAAoAhtBgAI4HjxwOYIQAHPdoAAVAQF6A8IUQAB2ALwANgLrgbp
+DQlRAAHYA/AA2AquBeoPClEAAdgC8ADYDK4A2M91oADIHxgdGJALjoohEAAN6AiOC+jPcAMAQA1F
+HRgQMKUC2BgdGJAC8DGlCo4Z6AmOF+jPcAEAns0gHRiQz3CAACQAIR0YkM9wgABQBCIdGJAYFQCW
+RSAAAxgdGJAMjgfoGBUAloUgAQQYHRiQGesA2JS4z3aAAHgEAKZx2Aa4xg7gAPzZIIbPcAAATBy6
+DuAAn7kYFQCWhbgYHRiQfQBAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFpIEAA
+/vHgePHApcFBwELBDBwAMRAcQDHPcIAA/FA0GMAPMBgADywYwA4oGIAOJBhADs9xgAD8UCAZQAvP
+cIAA/FAcGAALz3CAAPxQGBjACs9xgAD8UBQZgArPcIAA/FAQGMAIz3GAAPxQDBmACM9xgAD8UAgZ
+QAjPcYAAgFCAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZQAVQ
+GQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlAARAZ
+AAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGoggAC8
+GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybFNde6
+AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYwXgrg
+ABAUBzDPcKAAtA+8oM9xoADIOy6BFgrgAH3YAglAAe4M4ACpcAjYANnGDOAAmbkQ8fHA+g0AAc9w
+gAD8UDQYwA8wGAAPLBjADigYgA4kGEAOz3CAAPxQIBhAC89wgAD8UBwYAAvPcIAA/FAYGMAKz3CA
+APxQFBiACs9wgAD8UBAYwAjPcIAA/FAMGIAIz3CAAPxQCBhACM9xgACAUIAZAAh8GcAHeBmAB3QZ
+QAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE76HO
+oa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkAAGog
+gALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAAaiCA
+AcwZAAAKIMAnz3agAMgfGRYRls9wAABEHJYIIAEKJcAfWnDPcIAAyCADgM9znwC4/893gAAAACSH
+AeHTuSPoGRYClj8K3gBdg0Ddn729oySnBSGBD9D+AAA2o1gbgAchFgGWIhYBlgQggA//APz/AIAW
+owjYGR4YkFajXaOZBAAB0NifuB2jJKcFIYEP0P4AAM9wgAB4BDajAIALIICEB/JYG4AE6gkAAgzY
+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
+GIDgeOB44HjgeOB44HjgeOB4HIHgfuB4A9rPcaAAFARFoc9xoAD8Cwyp4H4D2s9xoAAUBEWhz3Gg
+AAgMALHgfgPMz3GAAKAEIIHXcAAAAEDFIYsPgA4EAM8hqgDPIWoGzyGqBs8h6gaduZ+57HAgoM9w
+oAAUBAPZJaAByM9xoADUCwDaDaHPcKAARB1VoOB+pwkQAEAhwgPDuZ8JNQQkujMmQXCAAIhEQCcM
+cjR8AHzMcSCBBBhQAMxxIIEEGFAAzHEggQQYUADMcSCBBBhQAMxxIIEEGFAAzHEggQQYUADMcSCB
+BBhQAMxxIIEEGFAAzHEggQQYUADMcSCBBBhQAMxxIIEEGFAAzHEggQQYUADMcSCBBBhQAMxxIIEE
+GFAAzHEggQQYUADMcSCBQiJCgAQYUAC+9eB+IepjasG6Pwo1ASK7MyaCcIAAmERAJwxyVHwAfAQQ
+AgQEGZAABBACBAQZkAAEEAIEBBmQAEIjQ4AEEAIEBBmQAO714H6nChAAQCLDA8O6nwo1BCS7MyaC
+cIAAnERAJwxyVHwAfAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIE
+ARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQB
+GZIAARCCBAEZkgABEIIEARmSAEIjQ4ABEIIEARmSAL714H7xwOHFKHUoc4QjPw8bYyK5l//BvR0N
+UBARDZAQGw3REMxwAIgBGxIAzHAAiAEbEgDMcACIAKvxBQAA4HiA4cokTXDoIO0BzHEgkQIYVADg
+foDhyiRNcOgg7QHMcSCJARhSAOB+8cBODSAAUyFCAE4iDQHPcqAAFATJggDbDiaCHwAAAAZQccog
+ZgHKIcYPyiLGB8ojhg8AACMCyiRmADQF5v7KJcYAgOHKJE1wyiLNAOggLQJOYM9xoAA4BAHiyKkd
+DVAQEQ2QEB0N0RDPcKAAOARoqM9woAA4BGioz3CgADgEaKg5BQAA4cUA2g/woIANc6CjoYANc6Cj
+ooANc6Cjo4ANc6CjEOAB4kEpAwHjCsSAANsG8AQQDQQNcqCiAeNTIcIAIrrzC4SAANsG8AEQjQQN
+cqCqAeNTIUIA8wuEgOB/wcXPc58AuP8aoz6jwroFIoIPAGwAAFmj4H7hxc91gACgBCGFz3KfALj/
+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
+4H8PeAoiAIDxwBTy+P+A4MogYQHKIcEPyiLBB8ojgQ8AAMcGyiQhABwBoffKJQEBz3CAAGQlQKDR
+wOB+8cDPcoAAZCUggoDhyiBhAcohwQ/KIsEHyiOBDwAA0AbKJCEA5ACh98olAQEBogHaz3GgAMgf
+UKFKGZgASBkYAN7x4HjxwKIIz/jPcqQAtEUpEgCGz3aAAHxZEaYrEgCGAN0Sps9wpQAIDAOAGKYO
+EgCGEHkEIIAP//8AADC4FKYzpg8SAIYVps9wgABQaXCIUoh5pjSIWqYLkCzgAiDPAAIggwAieB6m
+z3KAAGQlAIL8pjumNwg1AX2mMyYAcIAAiEpAJ4xyFHwAfAPYv/9A2Mz/t6YL8M9zoACoIDGDAoKi
+ojhgF6YB2BKjAdhhAO/4FqbgeM9wgABsBRSIBujPcIAAcCUBiAPwAdjgfvHA3g+P+M91gAC4jMMV
+ABYRCF4Bz3CAAKyPDIgLCBACCYXluInyz3GAABRpA4GiDu/8JIEnCFEAz3GAAHiKIIEbCV4Az3GA
+AKyPLIkPCRECz3EBAPAQAdgT8JToz3CAAHiKAIDPcQEA8BAVCF4Az3CAAKyPDIiH4ALYA/IA2EB5
+TgtAAs9xgADkdQaBRSBAAQahz3CAAOgOGIjPdoAAtHVFCBABz3CAAPxjVoh3js9xgAB8WQsLgAAA
+gB8IHwDPcoAAbAUEggHgBKIA2BCiD4EB4A+hBPAOgQHgDqEJheW41AjCAM9xgABsBQOBC+gA2AOh
+z3GAAHwGAIGiuLoPIAIAoS8WgBDjuLwPgv8vFoAQ4rhAD4L/if+0/4DgPAui98og4gTPcIAAgHsR
+iIDgLAui98ogYgQVB4/44HjxwM9wgACYdQyQDQgeAJIOz/wF8OG4HA7C/M9wgADQdROIEQhQABMI
+kQCo/YkFz/+I/YUFz/+BBc//4HjxwGYOj/jPcKAAxCdSEAGGQRAAhoQgHIAA3gby67nRIaKBPvLP
+cIAA6A4JgM91gAC0dSkIXgEUjYHgyiAhAVgOIQLKIWEAz3CAAGBxAIANCJ4Aeghv/RCV1K3PcIAA
+YHHAoE1whCADDIwgAoAU9M9xgABsBQaBAeAGoc9wgADoDhiIhOA0CQEFgP+iD+AELyCICgbwjCAD
+hCwPwf81Bo/4z3GAAGwFCIEPCFEAz3CgALAfG4AKoeB+Nrg2uTBw1iCFDwAAgADgfyJ44HjxwM9y
+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
+AAFBKIMhd6LPcqAAgERwgs93pQCs/4Qj/wpwogDCBCKCDyEAAMEmulWnyiCCDwEA//8G9ADAtgmv
++BThGKcgwIm4jrgZpwCODwheAEAmABNyD+/yFNnPdoAAlInPd6AA9AcA2ASn5gnP8QGOhOgAjhEI
+XwAB2ZC5z3CnAJhHPKAD2ASnAQgeQwGOhegAjhUIXwDPcacAmEe8oQiOgLgaoQCOdQheALkIHsP/
+CN7BUgtP9YwgAoPMIIKPAAD8AA3yBdgKIcAP63KKI44BSiRAAMUC7/G4c4wgAoMY9M91gACUialw
+Tgvv8gPZAI3guMogYgHKIcIPyiOCDwAAiwPKIsIH5vVa/wTwfguP834K7/KA2Abwdgrv8oDYVf8A
+2s9xoAD0B0ShA9gKoQmhSaGSCO/8KnCVAi/zocDgePHAz3GAAPBYJJEA2ILhzCFigAP0AdgvJgfw
+z3GAAJSJAIkH8kQgwApFIAAKAKkLCB4AWP8C8D//HwHP//HAz3CAAJSJsgrv8gPZ7v8LAc//yQHP
+8sUBz/LgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8A2OB/ANjgfuB4ocHgf6HA4HjgfuB4
+4H7gePHA4cUByM91gACwQwClBG1WCu/yAtnPcIAAoAQggAUhgQ+ADgQA7HAgoMoI7/IAhe0BD/Pg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjxwMxwAJDPcYAAsEMGscxwABAFAUAh
+AgQOGUQBTCWAhMogYgHKIcIPyiLCB8ojgg8AAHMAPAHi8cokIgAA2QjwzHAAkBQiTAAB4QC0LyBC
+AfEJAoBqCc/y0cDgfuB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geM9wgACUCOB/
+AIDgeOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB/AdjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB48cDhxc91gADwQ6lwrgjv8gPZABWFEEQl
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAB8doAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsA
+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXHuAANhaAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAP8BAAAAAAAAAAAAAAEBAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQACAAAABgAIAAkAAAAHAAAAAAAAAAIAAAACAAAAgwAAAJIAAADoAAAA9wAA
+AE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAcHKAAPyyAQAAAAAAcHKAAFi5AQAAAAAAAAAAAHBygAC8ugEAAAAAAAAAAAAAAAAA
+cHKAAAAAAAAAAAAAAQAPAGQAAQB0CIAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAA/wAAAAAHAAAAAAAAAAAAAAAAAAAoCAAAFQAAAEQlgAD0IwAA9CMAAPQjAACQOAAA9CMAAPQj
+AAAUNAAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAAEBoAAHwbAACAGwAA+BwA
+AHwdAAD8HAAA9CMAAPQjAABMQQAAdEQAAFhFAAD0IwAA9CMAAPQjAAAUQAAA8FYAAOxWAAD0VgAA
+BDUAACQ2AABMawEAlDgAAPA2AAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0
+IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQj
+AAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAACAOQAA9CMAAPQjAAD0IwAA9CMA
+APQjAABgOgAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAAYVwAA
+9CMAAAxYAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAACxaAAD0IwAA9CMAAPQjAAD0
+IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAHxCAQC8RQEA9CMAAHRHAQD0IwAAzEgBANwf
+AQD0IwAA9CMAAFhIAAD0IwAA9CMAAPQjAAD0IwAA9CMAAMysAQAgrQEA9CMAAPQjAAD0IwAA6MYB
+APQjAAD0IwAAwEcAACzKAQAwygEA9CMAABjKAQD0IwAA9CMAAPQjAAD0IwAAlLEBAPQjAAAwtQEA
+9CMAAPQjAAD0IwAA5B8AAPQjAAD0IwAAWF4BABjMAQC8XAAA9CMAAPQjAAD0IwAAtK8BAPQjAAD0
+IwAAgBgBAJRgAQD0IwAA9CMAAPQjAABAZgEA/CABAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAFBv
+AQD0IwAAIMsBACTLAQAwywEANMsBACjLAQAsywEAOMsBAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMA
+APQjAAD0IwAA9CMAAFBKAAD0IwAA9CMAAPQjAAD0IwAA9CMAAGzKAQDEygEAiDwAAPQjAAD0IwAA
+9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0
+IwAA9CMAAHRtAQD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQj
+AAD0IwAA9CMAAPQjAAD0IwAA9CMAAPQjAAAoPQAAxD0AAFQ+AAD8PgAApGkAANQ+AAD0IwAA9CMA
+APQjAAD0IwAA9CMAACA9AAAkPQAA9CMAAPQjAACISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAALAKAACwCgAAsAoAALAKAACwCgAAsAoAALAKAACwCgAAsAoAALAKAACwCgAAsAoA
+ALAKAACwCgAAsAoAALAKAACwCgAAsAoAALAKAACwCgAAsAoAALAKAACwCgAAsAoAALAKAACwCgAA
+sAoAALAKAACwCgAAsAoAALAKAAD0CwAAAAAAAHAmAQCwCgAAAAkAALAKAACwCgAAsAoAADAJAAA4
+CAEANGoAALAKAACwCgAAZAkAAGQJAABkCQAAZAkAAGQJAABkCQAAZAkAALAKAACwCgAAsAoAALAK
+AAB8CgAAsAoAALAKAACwCgAAsAoAALAKAAD4CwAAsAoAALAKAADkCAAAAwAAAGDAAQACAAAAlDAB
+AAQAAAAMLgAABgAAAKDKAQAQAAAArK0BAAcAAADMtgEACAAAADzLAQAMAAAApFsBAA0AAADQSgEA
+DgAAAARLAQAUAAAA2CUBAAsAAACwQwEAEwAAALhcAAAPAAAAvBcBAAEAAABAsQEAEQAAAMRmAQAS
+AAAAqGABAAUAAACIWgAAFQAAAPQLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAA
+AAEAAAABAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAADhAw4e4eEDDh7hwQIKHuGBBQwe4eEDDh7h4QMOHuHBAgYe4YEFDB7h
+AQEBAQEBAQEBAQEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAA
+AAAAAAAAAAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0NDQ0NDQ0NAwMDAwMDAwMDAwMDAwMDAwAA
+AAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0NDQ0NDQ0NDQ0NDQ0NDQMDAwMDAwMDAwMD
+AwMDAwMAAAAAAAAAAAAAAAAAAAAAkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAA
+McovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAx
+yi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBADQAA3gMJAAAAAAAAAAAAAAAAACz4
+AAABAAAABCWAAAAAAAAAAAAAAgAAAAMAAAAAAAAABwAAAAAAAABAQg8AaPgAACT5AAAs+gAA4PsA
+ACz6AADg+wAAFP0AAIz9AACAgICAgICAgAGAAoCAgICAAAAAAJQBAQCUAQEAAAAAAAAAAAAAAAAA
+AAAAAJQBAQCUAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQlgAAEJYAApCCgADggoAAB
+AAAA/P///wAAAAAAAAAAJCWAACQlgACoIKAAPCCgAAgAAADz////AAAAAAAAAABEJYAARCWAAKwg
+oABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAADAAAAAAAA
+AAAAAAAAAAAAwBgBAAUAAAAEJYAAlB4BAAD/AwC0HgEAAP8FAJQfAQAA/y0AuB8BAAD/PQBwHwEA
+AP8EAFQfAQAA/yUAAAAAAAAAAAAAAAAAdCQBAAYAAAAEJYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AABYJwEAHCgBACQrAQAEKQEAgCgBANwrAQA4LAEAfCwBAMAsAQAAAAAALAEAAF4BAAABAAAAAQAA
+AAEAAAABAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAACAAAAAwAAAAMAAAADAAAAAQAAAAAAAAABAAAA
+AAAAAAAAAAAAAAAA6DEBAAoAAAAEJYAAAAAAAAAAAAAAAAAASDIBAAoAAAAEJYAAAAAAAAAAAAAA
+AAAAXDIBAAoAAAAEJYAAAAAAAAAAAAAAAAAAqDIBAAoAAAAEJYAAAAAAAAAAAAAAAAAAcDMBAAoA
+AAAEJYAAAAAAAAAAAAAAAAAAFDMBAAoAAAAEJYAAAAAAABAAAAAAgAAAAACgABAnAADoAwAA6AMA
+AAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAA
+AAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAK
+AAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAA
+AAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAA
+AMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAABCWAAAAAAAAAAAAAAAAAAMwKAQAKAAAA
+BCWAAAAAAAAAAAAAAAAAACxHAQAKAAAABCWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAADkTQEA5E4BADxRAQDEUwEAIFYBAEBZAQBEUAEAMAWAADhygAAYAAAA+HGAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAATFsBAAYAAAAEJYAAAAAAAP//////////AAAAAAAAAAAAAAAAJGABAAUA
+AABEJYAAZABkAGkA3ADIAFoAqgC+AIYBfQA+AGQAZABpANwAyABaAKoAvgCGAX0APgAAAAAAAQEA
+AAAAAAAAAQIBAQACAQABAgICAAEBAAIBAgECAAIAAQIDAAAAAMBuAQDQewEAgHyAAMADAAAAAAAA
+wG4BAOBvAQBAgIAA+AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCAAQA0fgEAOIKAAFQAAAAA
+AAAAwG4BAGB+AQC4goAAUAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAMBuAQDYegEAnC6AAFAB
+AAAAAAAAFIABAOx8AQDIBoAAAgAAAAAAAADAbgEAGH0BAMwGgAAEAAAAAAAAAAyAAQDgbwEAjIKA
+ACwAAAAAAAAAwG4BAIR9AQAAAAAAAAAAAAAAAADAbgEARH0BANAGgAAEAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAgACAAIQAiACIAIwAkACQAJQAm
+ACYAQwBEAEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBOAE4ATwBQAFAAUQBuAG4AbwBwAHAA
+cQByAHIAcwB0AHQAdQB2AHYAdwB4AHgAeAB4AHgAeAB4AHgAeAAPAD8AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYA
+JwAnACgAKQApAEYARwBHAEgASQBJAGYAZwBnAGgAaQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBx
+AHIAcwBzAHQAdQB1AHYAdwB3AHgAeAB4AHgAeAB4AHgAeAAOAD8AAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAgACAAIQAiACIAIwAkACQAJQAmACYAQwBE
+AEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBOAE4ATwBQAFAAUQBuAG4AbwBwAHAAcQByAHIA
+cwB0AHQAdQB2AHYAdwB4AHgAeAB4AHgAeAB4AHgAeAAPAEMAAAAAAAAAAAAAAAAAAAAAAAAAAQAB
+AAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYAJwAnACgAKQApAEYARwBHAEgA
+SQBJAGYAZwBnAGgAaQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBxAHIAcwBzAHQAdQB1AHYAdwB3
+AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAIAEMAlGMBABLSAAAAAAAA//8PADB4AQC2AAAA
+AAAAAP8AAAAweAEAtwAAAAAAAAD/AAAAMHgBALgAAAAAAAAA/wAAADB4AQC5AAAAAAAAAP8AAAAw
+eAEAugAAAAAAAAD/AAAAMHgBALsAAAAAAAAA/wAAADB4AQC9AAAAAAAAAP8AAAAweAEAvgAAAAAA
+AAD/AAAAMHgBAL8AAAAAAAAA/wAAADB4AQDAAAAAAAAAAP8AAAAweAEAwQAAAAAAAAD/AAAAMHgB
+AMIAAAAAAAAA/wAAAJRjAQAT0gAAAAAAAP//DwAweAEAGwEAAAAAAAD/AAAAMHgBABwBAAAAAAAA
+/wAAADB4AQAdAQAAAAAAAP8AAAAweAEAHgEAAAAAAAD/AAAAMHgBAB8BAAAAAAAA/wAAADB4AQAg
+AQAAAAAAAP8AAAAweAEAIgEAAAAAAAD/AAAAMHgBACMBAAAAAAAA/wAAADB4AQAkAQAAAAAAAP8A
+AAAweAEAJQEAAAAAAAD/AAAAMHgBACYBAAAAAAAA/wAAADB4AQAnAQAAAAAAAP8AAACUYwEAFNIA
+AAAAAAD//w8AMHgBAIIBAAAAAAAA/wAAADB4AQCDAQAAAAAAAP8AAAAweAEAhAEAAAAAAAD/AAAA
+MHgBAIUBAAAAAAAA/wAAADB4AQCGAQAAAAAAAP8AAAAweAEAhwEAAAAAAAD/AAAAMHgBAIkBAAAA
+AAAA/wAAADB4AQCKAQAAAAAAAP8AAAAweAEAiwEAAAAAAAD/AAAAMHgBAIwBAAAAAAAA/wAAADB4
+AQCNAQAAAAAAAP8AAAAweAEAjgEAAAAAAAD/AAAAlGMBAAjSAAAAAAAA//8DANRjAQAAggAAAAAA
+AP8BAADUYwEAAYIAAAAAAAD/AQAAlGMBAAnSAAAAAAAA//8DANRjAQACggAAAAAAAP8BAADUYwEA
+A4IAAAAAAAD/AQAAlGMBAArSAAAAAAAA//8DANRjAQAEggAAAAAAAP8BAADUYwEABYIAAAAAAAD/
+AQAAlGMBAAbSAAAAAAAA/wEAAJRjAQAH0gAAAAAAAP8DAACUYwEABtIAAAkAAAAA/gMAlGMBAAfS
+AAAKAAAAAPwPAJRjAQAG0gAAEgAAAAAA/AeUYwEAB9IAABQAAAAAAPA/lGMBABXSAAAAAAAA/wMA
+AJRjAQAM0gAAAAAAAP8BAACUYwEAFdIAAAoAAAAA/A8AlGMBAAzSAAAJAAAAAP4DAJRjAQAV0gAA
+FAAAAAAA8D+UYwEADNIAABIAAAAAAPwHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAEAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAEAAIAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABQACAAEAAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAEAAJAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABMACgAFAAMA
+AQABAAAAAAAAAAAAAAAAAAAAAAAAAEAAJgAUAAoABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAgABM
+ACgAFAAKAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAZcAUAApABQACgAFAAMAAQABAAAAAAAAAAAA
+AAAAAAACLgGgAFEAKQAUAAoABQADAAEAAQAAAAAAAAAAAAAAAARdAj8BogBRACkAFAAKAAUAAwAB
+AAEAAAAAAAAAAAAACLkEfwJEAaMAUQApABQACgAFAAMAAQABAAAAAAAAAAAQcgn+BIkCRgGjAFEA
+KQAUAAoABQADAAEAAQAAAAAAACDkEvsJEQWLAkYBowBRACkAFAAKAAUAAwABAAEAAAAc0g3SEdIQ
+0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMG0gfSBNIJEAAAtQAaAYEBBQAEAAYACAAJAAoACwAMAIMA
+kgDoAPcATgFdAQ8ALgAAAGwAAAB0AAAAgAAAAIwAAACdAAAABwAAAAQAAAAIAAAAEAAAAEAAAACA
+AAAAIAAAAAAAAAAJAAAAEgAAAAAAAAAKAAAAFAAAAP////8AAAAALQEAAN0BAABaAgAAugIAAAoD
+AABNAwAAhwMAALoDAADoAwAAEQQAADcEAABZBAAAegQAAJgEAAC0BAAAzgQAAOcEAAD+BAAAFQUA
+ACoFAAA+BQAAUQUAAGQFAAB1BQAAhgUAAJcFAACnBQAAtgUAAMUFAADTBQAA4QUAAO4FAAD7BQAA
+CAYAABQGAAAgBgAAKwYAADcGAABCBgAATAYAAFcGAABhBgAAawYAAHUGAAB+BgAAiAYAAJEGAACa
+BgAAogYAAKsGAAC0BgAAvAYAAMQGAADMBgAA1AYAANsGAADjBgAA6gYAAPIGAAD5BgAAAAcAAAcH
+AAAOBwAAFAcAABsHAAAiBwAAKAcAAC4HAAA1BwAAOwcAAEEHAABHBwAATQcAAFMHAABYBwAAXgcA
+AGQHAABpBwAAbwcAAHQHAAB5BwAAfwcAAIQHAACJBwAAjgcAAJMHAACYBwAAnQcAAKIHAACnBwAA
+qwcAALAHAAC1BwAAuQcAAL4HAADCBwAAxwcAAMsHAADQBwAA1AcAANgHAADcBwAA4QcAAOUHAADp
+BwAA7QcAAPEHAAD1BwAA+QcAAP0HAAABCAAABQgAAAgIAAAMCAAAEAgAABQIAAAXCAAAGwgAAB8I
+AAAiCAAAJggAACkIAAAtCAAAMAgAADQIAAA3CAAAOwgAAD4IAABBCAAARQgAAEgIAABLCAAATwgA
+AFIIAABVCAAAWAgAAFsIAABfCAAAYggAAGUIAABoCAAAawgAAG4IAABxCAAAdAgAAHcIAAB6CAAA
+fQgAAIAIAACCCAAAhQgAAIgIAACLCAAAjggAAJEIAACTCAAAlggAAJkIAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAQAAgABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAFAAIAAQABAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAQAAkABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEwAKAAUAAwABAAEAAAAA
+AAAAAAAAAAAAAAAAAAAAQAAmABQACgAFAAMAAQABAAAAAAAAAAAAAAAAAAAAAACAAEwAKAAUAAoA
+BQADAAEAAQAAAAAAAAAAAAAAAAAAAAABlwBQACkAFAAKAAUAAwABAAEAAAAAAAAAAAAAAAAAAAIu
+AaAAUQApABQACgAFAAMAAQABAAAAAAAAAAAAAAAABF0CPwGiAFEAKQAUAAoABQADAAEAAQAAAAAA
+AAAAAAAIuQR/AkQBowBRACkAFAAKAAUAAwABAAEAAAAAAAAAABByCf4EiQJGAaMAUQApABQACgAF
+AAMAAQABAAAAAAAAIOQS+wkRBYsCRgGjAFEAKQAUAAoABQADAAEAAQAAAC4AAABsAAAAdAAAAIAA
+AACMAAAAnQAAAAcAAAAAAAAAAAAAAAoAAAAN0hHSENIC0gHSA9Ib0gvSAIAF0hLSE9IU0gRDCNIJ
+0grSHNIG0gfSAQAAAAAAAAAAAAAAAAAAAAMAAAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAA
+AAAAAP8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1ABoBgQEEAA8AgwDoAE4BkgD3AF0BBgAI
+AAkACgALAAwABQAAAAAAAAAsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgACAAIAAADfAAAAGQEAAGIB
+AAC+AQAAMgIAAMMCAAB7AwAAYgQAAIQFAADyBgAAvggAAAILAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAgAB
+AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAFAAIAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAQAAkABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEwAKAAUAAwABAAEAAAAAAAAAAAAA
+AAAAAAAAAAAAQAAmABQACgAFAAMAAQABAAAAAAAAAAAAAAAAAAAAAACAAEwAKAAUAAoABQADAAEA
+AQAAAAAAAAAAAAAAAAAAAAABlwBQACkAFAAKAAUAAwABAAEAAAAAAAAAAAAAAAAAAAIuAaAAUQAp
+ABQACgAFAAMAAQABAAAAAAAAAAAAAAAABF0CPwGiAFEAKQAUAAoABQADAAEAAQAAAAAAAAAAAAAI
+uQR/AkQBowBRACkAFAAKAAUAAwABAAEAAAAAAAAAABByCf4EiQJGAaMAUQApABQACgAFAAMAAQAB
+AAAAAAAAIOQS+wkRBYsCRgGjAFEAKQAUAAoABQADAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAWAADhygAAYAAAA+HGAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAA3LIBAAYAAAAEJYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwBYAAOHKAABgAAAD4cYAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAD0vQEABAAAAAQlgAAAAAAAAAAAAAAAAAAcvQEABAAAAAQlgAAAAAAAAAAAAAAAAACUvgEA
+BgAAAAQlgAAAAAAAAAAAAAAAAAAcvQEABAAAAAQlgAAAAAAAAAAAAAAAAAD0vQEABAAAAAQlgAAA
+AAAAAAAAAAAAAAAcvQEABAAAAAQlgAAAAAAAAAAAAAAAAAD0vQEABAAAAAQlgAAAAAAAAAAAAAAA
+AAAcvQEABAAAAAQlgAAAAAAAAAAAAAAAAACUvgEABgAAAAQlgAAAAAAAAAAAAAAAAAAcvQEABAAA
+AAQlgAAAAAAAAAAAAAAAAAD0vQEABAAAAAQlgAAAAAAAAAAAAAAAAACUvgEABgAAAAQlgAAAAAAA
+AAAAAAAAAAD0vQEABAAAAAQlgAAAAAAAAAAAAAAAAAD0vQEABAAAAAQlgAAAAAAAAAAAAAAAAACU
+vgEABgAAAAQlgAAwBYAAOHKAABgAAAD4cYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQFAAAAAAAAAAAAAAAAAAAAAAD/AP8A
+AAAAAAAEFggWFhYMFhYWFhYWFhAAAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAP
+AD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAAAAIA
+AAAFAAAACgUBpREBAKUAPDg0MCwoJCAcGBQQDAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCABQOAAAA
+ABoAAAABAQABAgEBAQEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQEBAQEAQICAgICAgMDAwMD
+AwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAEBAgECAgN//wcPHz8BAwEDDwcB
+Bw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gvAVVVVQXjOI4DqqqqAnEc
+xwGqqqoKx3EcBw8PDwcGBwIDBAUAAQgJCwooACgAMAAsACwAKAA8ADQAKAAoADQAMAAsACwARAA8
+AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABcAFQAjAB4ADoBAgHVAN8A
+2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoBSgHiAPkAygHqAIIAmQD0
+AkQCtQHVAZQChAH1AEECrACQAIQAgAB4AHgAeAB0AGbmAACd2ImdTuzETjRIgzQndmInGqRBGhM7
+sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAHNEiDNBqkQRoRGIERDdIg
+DQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQERmAEAz/wA6qqqqoapEEa
+EzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0QAuJndgJDdIgDQqogAoK
+qIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3YCQiMwAiJndgJCIzACAd+
+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAGsLLVBQVUQAUFVEAF1h3G
+BA0AGgAnADQATgBoAHUAggAaADQATgBoAJwA0ADqAAQBJwBOAHUAnADqADgBXwGGATQAaACcANAA
+OAGgAdQBCAIMAE4AaACCAHUAnADDAGgAggCCAJwAtgC2ANAAnADDAMMA6gARAREBOAGCAJwAtgCc
+ALYA0ADqANAA6gAEAQQBHgHDAOoAEQHqABEBOAFfATgBXwGGAYYBrQEAADAAAAA2AAAADAAAABIA
+AAAYAAAAJAAAAAYAAAAJAAAAAAAAAAAAAAAYIBQUDg4UFAUGAQIDBAAAAAEBAgECAgMEDAwIBAwE
+BEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAEBESExQVFhcYGRobHB0eHyAhIiMkJSYn
+KCkqKywtLi9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9w
+cXJzdHV2d3h5ent8fX5/MxMAAAAHBw8HDw8XLQAPIADwYQAAAAAAAAAAAAABAgQEAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAUzS1AGy1o5O1ZQAAAHR0XAZ0dHR0QQAACAAAAAIAAAAAAAAAAAAAAAgA
+AAACAAAAAAAAAAAAAAAIAAAAAwAAAAEAAAAIAAAACAAAAAIAAAACAAAACAAAAAECAQIDBAAABQYH
+CAkKAAAABQYAAgQABQAAAAAABQcBAwQABQEAAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwM
+QA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUF
+BQUFbABwBHQIdAwABAQGAAAAAAAAAABkAAAAAJABAAoAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAA
+AAAAAAAAAAAAAAEAAAAQAAAAAAAAAAEAAAABAAAAAAAAAP8AAAD/AAAAAAAAAAAAAADcvgEAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAEAABkAAAA7EQBAPREAQD8
+RAEAUEUBAFhFAQBgRQEABwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBgYGBgYFBQUFBQQEBAQEAwMDAwMCAgICAgEBAQEBAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKJUPIToCbAAcUJ2Au
+AAAABA4JHS05AAAEEQkfLTsAARAAAQAAAAKAAAFCBgIQAAIgAAADwAABQwYDEAACwAAAA8AAAUMG
+BBAAAkAAAAKAAAFEBgURAABAAAADwAABRQYGEQAA4AAAA8AAAUUGBxEAAQAAAAKAAAFGBggRAAIg
+AAADwAABRwYJEQACwAAAA8AAAUcGChEAAkAAAAKAAAFIBgsSAABAAAADwAABSQYMEgAA4AAAA8AA
+AUkGDRIAAQAAAAKAAAFKBg4SAAIAAAACgAABTAYAACIWAACAAAADAAABWQAkFgABAAAAAwAAAVoA
+JhYAAgAAAAQAAAFaACgWAAIAAAADAAABWwAqFgACgAAAAwAAAVwALBcAAAAAAAQAAAFcAC4XAACA
+AAADAAABXQAwFwABAAAAAwAAAV4ANBcAAgAAAAMAAAFfADYXAAKAAAADAAABYAA4GAAAAAAABAAA
+AWAAPBgAAQAAAAMAAAFiAD4YAAIAAAAEAAABYgBAGAACAAAAAwAAAWMAZBsAAgAAAAMAAAFvAWYb
+AAKAAAADAAABcAFoHAAAAAAABAAAAXABbBwAAQAAAAMAAAFyAW4cAAIAAAAEAAABcgFwHAACAAAA
+AwAAAXMCdB0AAAAAAAQAAAF0AnYdAACAAAADAAABdQJ4HQABAAAAAwAAAXYCfB0AAgAAAAMAAAF3
+A34dAAKAAAADAAABeAOAHgAAAAAABAAAAXgDhB4AAQAAAAMAAAF6A4YeAAIAAAAEAAABegSIHgAC
+AAAAAwAAAXsEjB8AAAAAAAQAAAF8BJEfAAFAAAADAAABfgSVHwADAAAABAAAAX8Flx8AAsAAAAMA
+AAGABZkgAABAAAADAAABgQWdIAABQAAAAwAAAYIFnyAAAcAAAAMAAAGDBaEgAAMAAAAEAAABgwWl
+IQAAQAAAAwAAAYUFAAAAAAAAAAAAAIi3AQCQtwEA+LcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAACQAAAP////8AAAAAAAAAAAEAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAABQUFBQUF
+BQUAAAAAgA0AAAAgAACADQAAgA0AAAAgAACADQAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+====
diff --git a/sys/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu b/sys/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu
new file mode 100644
index 00000000000..861fcff6873
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu
@@ -0,0 +1,5961 @@
+Copyright (c) 2006-2009, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without 
+modification, are permitted provided that the following conditions are 
+met:
+
+* Redistributions must reproduce the above copyright notice and the 
+  following disclaimer in the documentation and/or other materials 
+  provided with the distribution. 
+* Neither the name of Intel Corporation nor the names of its suppliers 
+  may be used to endorse or promote products derived from this software 
+  without specific prior written permission. 
+* No reverse engineering, decompilation, or disassembly of this software 
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide, 
+royalty-free, non-exclusive license under patents it now or hereafter 
+owns or controls to make, have made, use, import, offer to sell and 
+sell ("Utilize") this software, but solely to the extent that any 
+such patent is necessary to Utilize the software alone, or in 
+combination with an operating system licensed under an approved Open 
+Source license as listed by the Open Source Initiative at 
+http://opensource.org/licenses.  The patent license shall not apply to 
+any other combinations which include this software.  No hardware per 
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-5150-8.24.2.2.fw.uu
+AgIYCCjXAQAAwAAAuM4BAADAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABp
+IAAAaSBAAGkgAABpIEAAICCADwAArAVpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEol
+AABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMA
+IEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAADAQSycMEAsnDBCJBw0CiKAP4AAiFYKIwA3
+Kg8AAEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAFgEQHggIECHAAAAAAAAAAAAAArIz3Gg
+AMgfDhkYgAvIDxkYgAzIEBkYgA0SAjYAyER4ERkYgA7ILRkYgOB+4cT8HMi+/BxIvuHA4cHhwuHD
+/BwIsfwcSLH8HIix/BzIsfwcCLL8HEiy/ByIsvwcyLL8HAi/aiSAEOHEaiTAEOHE8cDPcKAA0BsU
+gM9xgABUBAQggI/PUQThAKEK8i8pAQDPcIAApAjwIEAAQHja/9HAwcRrJMAQwcRrJIAQwcSfdAQU
+CzQEFAo0BBQJNAQUCDQEFAc0BBQGNAQUBTQEFAQ0wcPBwsHBwcDBxEUsfhAKJkB+wcRrJIAUwcQg
+IECHCsiHuAoaGDALyJu4CxoYMAzIDBoYMA3Ih7gNGhgwDsiFIMMPDhoYMOB+4HjxwArIlbgKGhgw
+C8ibuAsaGDANyIq4jbiQuA0aGDDPcIAAzAkYiIHgC/QNyM9xAACwCqy4DRoYMN4NIAAP2GfY+g7g
+AIohhgjRwOB+8cDPcIAAWKMAgIYg/oEJ9A3IBSCADwAAANQNGhgwoP+KIFUFyg7gAIohxgzo8eB4
+8cDPcQMAQA3PcKAAqCAtoM9ygACUBCCCAWkAomIOIAFI2M9wgAAICCWAI4EggcdxAACIE54IAAjK
+8eB4z3CAAAgILQAACOB48cDSCkABgODPdoAAVAQG8oHgBvQB2APwANgLroDhBvKB4Qb0AdgD8ADY
+Cq6A4gbygeIG9AHYA/AA2AyuANjPdaAAyB8YHRiQC46A4IohEAAO8giOgOAM8s9wAwBADUUdGBAw
+pQLYGB0YkAPwMaUKjoDgGvIJjoDgFvLPcAEAJtcgHRiQz3CAACQAIR0YkM9wgABQBCIdGJAYFQCW
+RSAAAxgdGJAMjoDgB/IYFQCWhSABBBgdGJCA4xjyANiUuM92gACIBACmcdgGuLoIIAH82SCGz3AA
+AEwcqgggAZ+5GBUAloW4GB0YkFUCQAHPcaqqu7vPcJ8AuP82oDagNqA2oM9xoADIOw6BiLgOoWkg
+QAD+8eB48cClwUHAQsEMHAAxEBxAMc9xgAD8VzQZwA8wGQAPLBnADigZgA4kGUAOz3CAAPxXIBhA
+C89wgAD8VxwYAAvPcIAA/FcYGMAKz3CAAPxXFBiACs9wgAD8VxAYwAjPcIAA/FcMGIAIz3CAAPxX
+CBhACM9xgACAV4AZAAh8GcAHeBmAB3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlA
+BVAZAAVMGcAESBmABEQZQARAGQAE76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUAB
+EBkAAWOhaiAAA9gZAABqIMAC1BkAAGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCA
+ALwZAABqIEAAuBkAAGogAAC0GQAAaiCAAcwZAADQ2J+4z3GfALj/HaHPcIAAAADEgFMlxDVTJsU1
+17oB5tO+xKBTI8AEBSaOH9D+AADWoQUggA+w/gAAFqEYgVMnzjUA3ZS4GKFAwwHAAsHJcwwUBjAq
+DOAAEBQHMM9woAC0D7ygz3GgAMg7LoHCC+AAfdhiDEAB+g7gAKlwCNgA2boO4ACZuRDx8cDWDyAB
+e9ieC+AA19nPcYAA/Fc0GcAPMBkADywZwA4oGYAOJBlADs9wgAD8VyAYQAvPcIAA/FccGAALz3CA
+APxXGBjACs9wgAD8VxQYgArPcIAA/FcQGMAIz3CAAPxXDBiACM9wgAD8VwgYQAjPcYAAgFeAGQAI
+fBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZQAVQGQAFTBnABEgZgARE
+GUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlAARAZAAFjoWogAAPYGQAA
+aiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGoggAC8GQAAaiBAALgZAABq
+IAAAtBkAAGoggAHMGQAA63bPdaAAyB8ZFRGWz3AAAEQcVgogAQogwC9acM9wgABEKCOAz3OfALj/
+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
+AIXpAI/z4HjgfuB44H7gePHAABYAQc9ygAAQQgayABYFQUAiAQQOGkQBTCWAhMohwg/KIsIHyiBi
+Acojgg8AAEQAeAYi8sokIgAA2gfwABYAQRQhjAAAtAHiLyBCARByt/aqCE/z0cDgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4z3CAAKQH4H8AgOB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fwHY4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7gePHA4cXPdYAAUEKpcNoPL/MD2QAVhRBEJUABheDKIcEPyiLBB8ogYQHKI4EPAABP
+ACgFIfLKJGEAAY2D4MP2Y7gBrWoPD/NFB0/z4HjxwMIOT/Macc92gABQQiCOUSEAgEbyz3GAAKwH
+IImA4cwgIaA+8oHgBvTPcIAA/IOhgAPwAN2O5QP3gOUC9ADdz3GAAPyDGImA4AT0gOUE9ADfBPCi
+gQTfiiATARIKL/OpcYogUwEKCi/z6XHPcIAAzAkYiIPgzCAigcwg4oHMICKCCPKKIBMB5gkv84vZ
+CvAKlhB1CPQLlhB3zCAhoAT0ANgh8AHYz3GgAMgfDaHPcIAArAcBiOu2qrYEvxC45X0FfYogEwGq
+CS/zotmKIBMBngkv86lxz3CgAMgffxhYgwHYRQZP8+B48cDeDW/zCHHE/4DgPPIg3c92oADIH7Cm
+MthDHhgQANj+DS/zjbixprCmHthDHhgQANjuDS/zjbixpn8WD5aKIBMBQS8NFMS9Pgkv88zZiiAT
+ATYJL/PpcYogEwEqCS/zqXHPcYAArAcBiQHaEHXCIooAgOVAqcj2ANgNpoHiBPQE2AGpwQVP889w
+gABQQgCIUSCAgAfyz3GgAMAdAIGAuACh4H7PcIAAUEIAiFEggIAH8s9xoADAHQCBoLgAoeB+8cDh
+xc9wgAAACACQz3WAANCrqXFmDqAAiiIECwCNhODKIcsPyiLLB8ogawHKI4sPAAB5CcokKwAsAyvy
+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
+AAATJAEAEyU4HMAR4EGAgQAAwBYIABNiAAATJQMAEyRUBMURfwITJAQAxRHkQYCBAADAFggAxREA
+AAAh7FaAgQAAwBY8BMARAAWAgQAAwBYEARtiEATAEAMAGyRUBMARJATAEQgEwBCsVoCBAADAFwgE
+wBCMVoCBAADAFwAAGyUDHBtiQAAbJDAcwBEFAABhBAWAgQAAwBYPGxkiCASggTjwxIAAABskAgAb
+JTgcwBEAAAAhAAWAgQAAwBZMBMARBAWAgQAAwBYPGxkiSASggTjwxIAAABskAgAbJTgcwBEAAAAh
+AAAAhQAFgIEAAMAWDxsEIhAEG2YPARtoFBzAEAoAG0AEABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAA
+wAYRAQAEJ/wABGQAABskAgAbJTgcwBEAAAAhAAAbJUAAGyQwHMARAAAAIQ8cHSIYAR0mGADHEIh4
+gIEAAMAXIADHEJB4gIEAAMAXAAAAIRAtgIH4QcQQDxsJIgALCTkCAApiAwEKYgQCCmIAAAlABAAA
+YQkACUACAABhCgAJQAAAAGECAAlBAAkaKAAAwBYBABsmAADAFwQAHSYBAAgn6wAIZAAAACEAAAAA
+LAEAAAEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcNAAAwDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAQAAAMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArHmAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4goAA
+tFYBAAAAAAAAAAAAAAAAAAAAAAAAAAAAnIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIEAoAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAcKCAAASTAQAAAAAA
+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFR4gACkrAEAAAAAAAAAAAAAAAAAAAAAAFR4
+gADYswEAAAAAAAAAAABUeIAATLUBAAAAAAAAAAAAAAAAAFR4gAAAAAAAAAAAAAAAAAD/AAAAAAcA
+AAAAAAAAAAAAAAAAAH9/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgQI
+AAgQIAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwBwAAFQAAAKAqgACI
+CgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoAAIgK
+AACICgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoAAIgKAACICgAAiAoA
+AIgKAACICgAAzAsAAAAAAAAYGwEAiAoAAMgIAACICgAAiAoAAIgKAAD4CAAA/AEBACxUAACICgAA
+iAoAADAJAAAwCQAAMAkAADAJAAAwCQAAMAkAADAJAACICgAAiAoAAIgKAACICgAAVAoAAIgKAACI
+CgAAiAoAAIgKAACICgAA0AsAAIgKAACICgAArAgAAAMAAACQuwEAAgAAAPQnAQAEAAAANDEAAAYA
+AABAvQEAEQAAAIiMAQAHAAAAJK8BAAgAAADAvQEADAAAAIxAAQANAAAAIEUBAA4AAABYRQEAFgAA
+AIAaAQALAAAAXFoBABQAAABIVQAADwAAALx4AQAQAAAAFBIBAAEAAAAAqwEAEgAAAEBvAQATAAAA
+sGABAAUAAAB0VQAAFQAAAEDNAQAXAAAAzAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtCUAALQl
+AAC0JQAAVDcAALQlAAC0JQAASDcAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUA
+AHwaAAAgHAAAJBwAAJwdAAAkHgAAoB0AALQlAAC0JQAABEAAAHhDAABMRAAAtCUAALQlAAC0JQAA
+yD4AAKieAACkngAA4J4AALQlAAC0JQAAtCUAAFg3AAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0
+JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQl
+AAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAASDgA
+ALQlAAC0JQAAtCUAALQlAAC0JQAALDkAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAA
+tCUAALQlAAC0JQAAdOoAALQlAACc6wAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAACM
+VQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAAcWQEAsFwBALQl
+AAA8QQEAtCUAAOxCAQBwMgEAtCUAALQlAADIRAAAtCUAALQlAAC0JQAAtCUAALQlAACYlAEAQI4B
+ALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAADYvAEA3LwBALQlAAC0JQAAtCUAALQlAAC0JQAA
+tCUAAPCuAQC0JQAAJLIBALQlAAB0zgEAtCUAAAghAAAMIQAAtCUAALQlAACYvgEATFUAALQlAAC0
+JQAAtCUAAGypAQC0JQAAtCUAABATAQCcYAEAtCUAALQlAAC0JQAAmGcBAIwtAQC0JQAAtCUAALQl
+AAC0JQAAtCUAALQlAAC8dQEAtCUAAKS9AQCovQEAtL0BALi9AQCsvQEAsL0BALy9AQC0JQAAtCUA
+ALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAACgRgAAtCUAALQlAAC0JQAAtCUAALQlAAAUvQEA
+SL0BAGA7AAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0
+JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQl
+AAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAAtCUAALQlAAC0JQAABDwAAIQ8AAAMPQAAqD0A
+ALQlAACAPQAAtCUAALQlAAC0JQAAtCUAALQlAAD8OwAAADwAALQlAAC0JQAA+EQAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAQEAAAAAAAAQAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0NDQ0N
+DQ0NDQ0NDQ0NDQMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEB
+AQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEB
+AQEBAQEBAQENDQ0NDQ0NDQ0NDQ0NDQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAACR
+AgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJEC
+AAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEA
+ADHKLwBDAQAAMcovAEANAADeAwkAAAAAAAAAAAAAAAAAbOoAAAEAAABgKoAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAABAQg8ANO4AABjvAAAo
+8AAA9PEAACjwAAD08QAAoPMAACT0AACAgICAgICAgAGAAoCAgICAAAAAAJj7AACY+wAAAAAAAAAA
+AAAAAAAAAAAAAJj7AACY+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAqgABgKoAApCCg
+ADggoAABAAAA/P///wAAAAAAAAAAgCqAAIAqgACoIKAAPCCgAAgAAADz////AAAAAAAAAACgKoAA
+oCqAAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAD
+AAAAAAAAAAAAAAAAAAAAJBMBAAUAAACgKoAAUBgBAAD/AwBwGAEAAP8FAFwZAQAA/y0AgBkBAAD/
+PQA4GQEAAP8EABwZAQAA/yUAPCABACghAQCcIQEAvBwBAPQbAQCIIgEAECMBAFQjAQCkIwEAAAAA
+ACwBAABeAQAAAQAAAAEAAAABAAAAAQAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAgAAAAMAAAADAAAA
+AwAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAFwpAQAKAAAAYCqAAAAAAAAAAAAAAAAAAOgpAQAK
+AAAAYCqAAAAAAAAAAAAAAAAAABwqAQAKAAAAYCqAAAAAAAAAAAAAAAAAAJQqAQAKAAAAYCqAAAAA
+AAAAAAAAAAAAALQrAQAKAAAAYCqAAAAAAAAAAAAAAAAAACwrAQAKAAAAYCqAAAAAAAAAAAAAAAAA
+AKwxAQAGAAAAYCqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAgAAAAACgABAnAADo
+AwAA6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0SAEAQEkBAARMAQC0
+TgEAMFEBALRUAQDcSgEAFAWAABx4gAAYAAAA3HeAAAAAAAAAAAAAAAAAAAAAAAAAAAAARFcBAAYA
+AABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAA
+AAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAA
+DAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABg
+KoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAA
+AAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQBAAoAAABgKoAAAAAAAAAAAAAAAAAADAQB
+AAoAAABgKoAAAAAAAAAAAAAAAAAAqF4BAAoAAABgKoAAAAAAAP//////////AAAAAAAAAAAAAAAA
+LGABAAUAAACgKoAAZABkAGkA3ADIAFoAqgC+AIYBfQA+AGQAZABpANwAyABaAKoAvgCGAX0APgAA
+AAAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgECAQIAAgABAgMA
+AAAAZIEBABB/AQBMhIAAMAIAAAAAAAAkdQEAUHYBACCYgABQAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAJHUBAEx/AQBwmIAAFAAAAAAAAAAkdQEAfH8BANSZgABQAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAABAAAAJHUBAER6AQC0NIAAUAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACR1AQA8gAEA
+tAaAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkdQEArIABAAAAAAAAAAAAAAAAACR1AQBA
+gAEAwAaAAAQAAAD/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B
+/wH/Af8B/wH/Af4B/QH8AfsBvwG+Ab0BvAG7AboBuQG4AbcBfwF+AX0BfAF7AXoBeQF4AXcBdgF1
+AX8AfgB9AHwAewA/AD4APQA8ADsAOgA5ADkAOQA5ADkAOQA5ADkAOQA5ADkAOQA5ADkAOQA5ADkA
+OQA5AAoAPwD/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/gH9AfwB+wH6AfkB+AH3
+AfYB/wD+AP0A/AD7APoA+QD4APcA9gC/AL4AvQC8ALsAfwB+AH0AfAB7AD8APgA9ADwAOwA6ADkA
+OAA3ADYANQA0ADMAMgAxADAAJwAmACYAJgAmACYAJgAmACYAJgAmACYAJgAmACYAJgAmACYAJgAm
+AAoAPwABAQAAAgEBAAMCAgMYZgEAEtIAAAAAAAD//w8AFIEBAAFAAAAAAAAABgAAABSBAQACQAAA
+AAAAAAkAAACEgwEAGwAAAAAAAAD/BwAAhIMBABsAAAAAAAAA/wcAABSBAQACQAAAAAAAAAgAAACE
+gwEAGwAAAAAAAAD/BwAAhIMBABsAAAAAAAAA/wcAABSBAQACQAAAAAAAAAkAAACEgwEAGwAAAAAA
+AAD/BwAAhIMBABsAAAAAAAAA/wcAABSBAQABQAAAAAAAAAYAAAAUgQEAAkAAAAAAAAAAAAAAhIMB
+AA8AAAAAAAAA/wcAAISDAQAQAAAAAAAAAP8HAAAUgQEAAkAAAAAAAAABAAAAhIMBAA8AAAAAAAAA
+/wcAAISDAQAQAAAAAAAAAP8HAAAUgQEAAkAAAAAAAAACAAAAhIMBAA8AAAAAAAAA/wcAAISDAQAQ
+AAAAAAAAAP8HAAAUgQEAAkAAAAAAAAADAAAAhIMBAA8AAAAAAAAA/wcAAISDAQAQAAAAAAAAAP8H
+AAAUgQEAAkAAAAAAAAAEAAAAhIMBAA8AAAAAAAAA/wcAAISDAQAQAAAAAAAAAP8HAAAUgQEAAkAA
+AAAAAAAFAAAAhIMBAA8AAAAAAAAA/wcAAISDAQAQAAAAAAAAAP8HAAAUgQEAAUAAAAAAAAAHAAAA
+GGYBABPSAAAAAAAA//8PABSBAQABQAAAAAAAAAYAAAAUgQEAAkAAAAAAAAAJAAAAhIMBABwAAAAA
+AAAA/wcAAISDAQAcAAAAAAAAAP8HAAAUgQEAAkAAAAAAAAAIAAAAhIMBABwAAAAAAAAA/wcAAISD
+AQAcAAAAAAAAAP8HAAAUgQEAAkAAAAAAAAAJAAAAhIMBABwAAAAAAAAA/wcAAISDAQAcAAAAAAAA
+AP8HAAAUgQEAAUAAAAAAAAAGAAAAFIEBAAJAAAAAAAAAAAAAAISDAQARAAAAAAAAAP8HAACEgwEA
+EgAAAAAAAAD/BwAAFIEBAAJAAAAAAAAAAQAAAISDAQARAAAAAAAAAP8HAACEgwEAEgAAAAAAAAD/
+BwAAFIEBAAJAAAAAAAAAAgAAAISDAQARAAAAAAAAAP8HAACEgwEAEgAAAAAAAAD/BwAAFIEBAAJA
+AAAAAAAAAwAAAISDAQARAAAAAAAAAP8HAACEgwEAEgAAAAAAAAD/BwAAFIEBAAJAAAAAAAAABAAA
+AISDAQARAAAAAAAAAP8HAACEgwEAEgAAAAAAAAD/BwAAFIEBAAJAAAAAAAAABQAAAISDAQARAAAA
+AAAAAP8HAACEgwEAEgAAAAAAAAD/BwAAFIEBAAFAAAAAAAAABwAAADCBAQAG0gAAAAAAAP8BAAAw
+gQEAB9IAAAAAAAD/AwAAmGUBABXSAAAAAAAA/wMAAJhlAQAM0gAAAAAAAP8BAACYZQEAFdIAAAoA
+AAAA/A8AmGUBAAzSAAAJAAAAAP4DABIAAAAAALwAAQAAAIwBAQDgB1gGEAMAAH8EAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAMAAAABAAAAgAIrAM0EmQMEAAIAAACAAqsAzQQZAQQA
+AwAAAIACqwDNBJkCBAAEAAAAgAIrAc0EGQAEAAUAAACAAisBzQSZAQQABgAAAIACKwHNBBkDBAAH
+AAAAgAKrAc0EmQAEAAgAAACAAqsBzQQZAgQACQAAAAACqwHNBJkDBAAKAAAAAAJLAM0EGQEEAAsA
+AAAAAksAzQSZAgQADAAAAAACywDNBBkABAANAAAAAALLAM0EmQEEAA4AAAAAAssAzQQZAwQAIgAC
+AIEBjAABAIADAAAkAAIAgQEMAQEAAAEAACYAAgCBAQwBAQCAAgAAKAACAIEBjAEBAAAAAAAqAAIA
+AQGMAQEAgAEAACwAAgABAYwBAQAAAwAALgACAAEBLAABAIAAAAAwAAIAAQEsAAEAAAIAADQAAgAB
+AawAAQAAAQAANgACAAEBrAABAIACAAA4AAIAAQEsAQEAAAAAADwAAgABASwBAQAAAwAAPgACAAEB
+rAEBAIAAAABAAAIAAQGsAQEAAAIAAGQAAgCBAGwBAQAAAQEAZgACAIEAbAEBAIACAQBoAAIAgQDs
+AQEAAAABAGwAAgCBAOwBAQAAAwEAbgACAIEADQABAIAAAQBwAAIAgQANAAEAAAIBAHQAAgCBAI0A
+AQAAAQEAdgACAIEAjQABAIACAQB4AAIAAQANAQEAAAABAHwAAgABAA0BAQAAAwEAfgACAAEAjQEB
+AIAAAgCAAAIAAQCNAQEAAAICAIQAAgABAC0AAQAAAQIAhgACAAEALQABAIACAgCIAAIAAQCtAAEA
+AAACAIwAAgABAK0AAQAAAwIAkQACAAEALQEBAMACAgCVAAIAAQCtAQEAwAEDAJcAAgABAK0BAQBA
+AwMAmQACAAEATQABAMAAAwCdAAIAAQBNAAEAwAMDAJ8AAgABAM0AAQBAAQMAoQACAAEAzQABAMAC
+AwClAAIAAQBNAQEAwAEDAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAWAABx4gAAYAAAA3HeAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAACyQAQAGAAAAYCqAAAAAAAAAAAAAAAAAAHSsAQAGAAAAYCqAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAWAABx4gAAYAAAA
+3HeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAUBYAAHHiAABgAAADcd4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuQEABAAAAGAq
+gAAAAAAAAAAAAAAAAADYtwEABAAAAGAqgAAAAAAAAAAAAAAAAADMuQEABgAAAGAqgAAAAAAAAAAA
+AAAAAADYtwEABAAAAGAqgAAAAAAAAAAAAAAAAAAEuQEABAAAAGAqgAAAAAAAAAAAAAAAAADYtwEA
+BAAAAGAqgAAAAAAAAAAAAAAAAAAEuQEABAAAAGAqgAAAAAAAAAAAAAAAAADYtwEABAAAAGAqgAAA
+AAAAAAAAAAAAAADMuQEABgAAAGAqgAAAAAAAAAAAAAAAAADYtwEABAAAAGAqgAAAAAAAAAAAAAAA
+AAAEuQEABAAAAGAqgAAAAAAAAAAAAAAAAADMuQEABgAAAGAqgAAAAAAAAAAAAAAAAAAEuQEABAAA
+AGAqgAAAAAAAAAAAAAAAAAAEuQEABAAAAGAqgAAAAAAAAAAAAAAAAADMuQEABgAAAGAqgAAUBYAA
+HHiAABgAAADcd4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAABQFAAAAAAAAAAAAAAAAAAAAAAD/AP8AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMEBAQEBAUG
+BwgICAgICQoLDA0AAAAFBgcIDQ4PEBUWFxgZAAAKDREUCg0RFAoNERQKCgAAAAAAAAYGBgYJCQkJ
+AAYAAPgA6gDdANAAxAC5AK8ApQCcAJMAigCDAHsAdABuAGgAbgFoAW4CaAJuA2gDbgRoBG4FaAVu
+BmgGbgdoB24IaAhuCWgJbgpoCm4LaAtuDGgMbg1oDW4OaA5uD2gPbhBoEG4RaBFuEmgSbhNoE24U
+aBRuFWgVbhZoFm4XaBduGGgYbhloGW4aaBpuG2gbbhxoHG4daB1uHmgebh9oH24gaCBuAGgAbgFo
+AW4CaAJuA2gDbgRoBG4FaAVuBmgGbgdoB24IaAhuCWgJbgpoCm4LaAtuDGgMbg1oDW4OaA5uD2gP
+bhBoEG4RaBFuEmgSbhNoE24UaBRuFWgVbhZoFm4XaBduGGgYbhloGW4aaBpuG2gbbhxoHG4daB1u
+Hmgebh9oH24gaCBuIWghbiJoIm4jaCNuJGgkbiVoJW4maCZuJ2gnAAAAAAAAAAAAAAAA7NIBAAgA
+AACgKoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
+/wAB//8CA////wT//////////////////////wX/Bv8H/wj/Cf8K/wv/DP///w3///8O////D///
+/xD//////////////////////////////////////////////xH///8S////E////xT///8V////
+Fv///xf///8Y////Gf///xr///8b/////xz///8d////Hv///x////8g////If//////////////
+////////IiMk/yUmJ///KP///yn/////////////////////////////////////////////////
+/////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQABgkFAAcKBgAICwcACQwI
+AAoNCQALDgoADA8LAA0QDAAOEQ0AAUEABAJCAQQDQwIEBEQDBAVFBAQGRgUEB0cGBLcTIgC4FCMA
+uRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIGACYjBwAo
+JAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQAdDIVAHgz
+FgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIsSgoCNEsN
+ATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQWCBYWFgwW
+FhYWFhYWEAAAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEA
+AAAPAD8AAgAAAA8APwABAAAAAAAAAAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAYCAGlAgIA
+pQA8ODQwLCgkIBwYFBAMCAQADAgEADw4NDAsKCQgHBgUEAwIBAIAFQ8AAAAAGwAAAAEBAAECAQEB
+AQEBAQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQE
+BAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgME
+BgZ00UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHKAAo
+ADAALAAsACgAPAA0ACgAKAA0ADAALAAsAEQAPABAADwAjABsAFgASAD0ALAALAAsADwANAAwACwA
+VABEAFQAVABsAGAAXABUAIwAeAA6AQIB1QDfANoAogB1AH8AagEaAdkA6AAKAboAeQCIAIoFKgM5
+AagBigXKAtkASAHKAUoB4gD5AMoB6gCCAJkAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEY
+gREP/MAPTuzETid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzA
+CAZpkAawstUFBVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ET
+D/zADxEYgREN0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoI
+jMAIB3iABwd4gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+
+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEDQAa
+ACcANABOAGgAdQCCABoANABOAGgAnADQAOoABAEnAE4AdQCcAOoAOAFfAYYBNABoAJwA0AA4AaAB
+1AEIAgwATgBoAIIAdQCcAMMAaACCAIIAnAC2ALYA0ACcAMMAwwDqABEBEQE4AYIAnAC2AJwAtgDQ
+AOoA0ADqAAQBBAEeAcMA6gARAeoAEQE4AV8BOAFfAYYBhgGtAQAAMAAAADYAAAAMAAAAEgAAABgA
+AAAkAAAABgAAAAkAAAAAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAA
+AIAAAAAAAQAAAAIAAEAAAAAABAAAQAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSor
+LC0uL0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0
+dXZ3eHl6e3x9fn8tAA8gAPBhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApcaE+JnujfYN/73W
+sd5UkVBgAwKpzn1WGediteZNmuxFj50fQImH+hXv67LJjgv77EFns/1f6kW/I/dTluRbm8J1HOGu
+PWpMWmxBfgL1T4NcaPRRNNEI+ZPic6tTYj8qDAhSlWVGXp0oMKE3Dwq1LwkONiSbGz3fJs1pTs1/
+n+obEp4ddFguNC02stzutPtb9qRNdmG3zn17Uj7dcV6XE/WmaLkAACzBYEAf48h57ba+1EaN2WdL
+ct6U1JjosEqFa7sqxeVPFu3FhteaVWaUEc+KEOkGBIH+8KBEeLol40vzov5dwICKBa0/vCFIcATx
+32PBd3WvY0IwIBrlDv1tv0yBFBg1Ji/D4b6iNcyIOS5Xk/JVgvxHeqzI57orMpXmoMCYGdGef6Nm
+RH5UqzuDC8qMKcfTazwoeafivB0Wdq0721ZkTnQeFNuSCgxsSOS4XZ9uve9DpsSoOaQxN9OL8jLV
+Q4tZbrfajAFksdKc4Em02PqsB/Mlz6/KjvTpRxgQ1W+I8G9KclwkOPFXx3NRlyPLfKGc6CE+3Zbc
+YYYNhQ+Q4EJ8xHGqzNiQBQYB9xIco8Jfavmu0GmRF1iZJzq5JzjZE+uzKzMiu9JwqYkHpzO2LSI8
+khUgyUmH/6p4UHqljwP4WYAJFxraZTHXxoS40MOCsCl3WhEey3v8qNZtOiwAAQIEBAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAFk4wAB0wLLAnMBtAACwsGUGsH2GsLBKAAkAAAACAAAAAAAAAAAAAAAJ
+AAAAAgAAAAAAAAAAAAAACQAAAAMAAAABAAAACQAAAAkAAAACAAAAAgAAAAkAAAABAgECAwQAAAUG
+BwgJCgAAAAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBAQAUFQEAM
+DEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAFBQVABUAF
+BQUFBQQAAAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAAAGQAAAAA
+kAEACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAAAAAAAAAAAAAA
+AP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAA
+AAAAAAC6AQAAAAAAAAQAAGQAAAAHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcGBgYGBgUFBQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmFsBAKBbAQCo
+WwEAAFwBAAhcAQAQXAEAAAgAAEAIAACACAAAAAkAAEAJAACACQAA/ykAAAAAAACYCQAApAkAACQA
+AABkAAAApAAAACQBAABkAQAApAEAACQAAABkAAAApAAAACQBAADkAAAApAEAAKimAQAolwEA6JgB
+AEyaAQBYnAEA2J4BALiiAQCApAEAyKUBACywAQBAsAEArLABAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCRIUGAAADgAAACoAAAAH
+AAAACwAAAP////8AAAAAAAAAAAEAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAABQUFBQUFBQUAAAAAgA0A
+AAAgAACADQAAgA0AAAAgAACADQAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAggA8AAEAAaSAA
+AGkgQABpIAAAaSBAACAggA8AAOgAaSAAAGkgQABpIAAAaSBAACAggA8AAJwFaSAAAGkgQABpIAAA
+SiAAAEohAABKIgAASiMAAEokAABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBK
+JgAQSicAEEogACBKIQAgSiIAIEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gAAAwEEs
+nDBALJwwQiQcNAoigD+AAFRZCiMANxIPAABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgABY
+BEB4ICBAhwAAAAAAAAAAAAAKyM9xoADIHw4ZGIALyA8ZGIAMyBAZGIANEgI2AMhEeBEZGIAOyC0Z
+GIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwcyLH8HAiy/BxIsvwciLL8HMiy/BwI
+v2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAVAQEIICPz1EE4QChCvIvKQEAz3CAAPAJ8CBAAEB4
+2v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0BBQHNAQUBjQEFAU0BBQENMHDwcLB
+wcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwrIh7gKGhgwC8ibuAsaGDAMyAwaGDANyIe4DRoYMA7I
+hSDDDw4aGDDgfuB48cAKyJW4ChoYMAvIm7gLGhgwDciKuI24kLgNGhgwz3CAABgLGIgbCFEADcjP
+cQAAjAqsuA0aGDDGDSAAD9hn2HYO4ACKIYYI0cDgfvHAz3CAAFyhAICGIP6BCfQNyAUggA8AAADU
+DRoYMKD/iiBVBUYO4ACKIcYM6PHgePHAz3EDAEANz3CgAKggLaDPcoAAlAQgggFpAKLSDSABSNjP
+cIAAVAklgCOBIIHHcQAAiBOeDYAHyvHgeM9wgABUCTEFgAfgePHAJgpAAc92gABUBAXoDwhRAAHY
+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
+AHkA2R7wJJCG6SWQgeHMIaKABPIA2QPwAdkC3RLwJJAF3YHhAdnAeQzwJJAE3YPhAdnAeQbwJJAK
+3YThAdnAeRsJUAAIEAUBCiHAD+tyENiKI44NbQHv/ph1/QIAAOB4ocHxwHoKAADPcoAA/QhAioDi
+RMCJ8o3pCiHAD+tyBdiKIw8CSiRAADkB7/64c2CBA+tBgYjqz3KAAFhbd4JgoViCQaEkxoDmyiHB
+D8oiwQfKI4EPAADSA8ogYQHk84DiyiHBD8oiwQfKI4EPAADTA8ogYQHY8y8IXgIEIIAPAQAAwM9y
+gAA0US64CmJJIoIAYbrPcIAATHlWeHGgIYEyoEPwOwgeAqDmyiWCE8olIRAEIIIPAQAAwM93gADk
+UM5nBCCADwYAAAAxuC66HmbPcIAANFFIYMJ4EvBTIMIAXXrPdYAAIFRNZQQggA8BAADALrjPcoAA
+NFEIYmG4Fn3PcIAA0Hi2eGCgIYEfDTQWIaAKIcAP63IF2IojTwyKJIMPQQDv/rh1CNy/AQAA4cXh
+xs9xgAD9CCCJIukA2kokAHbPc4AA0HioIAADFiCBAMCBFiONAMClIYEB4iGlwBABAMAbQADEEAEA
+xBtAAMgQAQDIG0AAzBAAAMwbAACvBo//8cACCSAAuHECuc9ygAAoXTR5MCJEAKLBDQxeA89ygAAk
+pwXwz3KAADykQCIDBkAiAQdRJECCyiHCD8oiwgfKI4IPAAAbBJwHov7KIGIBz3aAAPBfQC2NAaZm
+QMYgxQ0OHhLCvaphDvARDl4SRCUBHES5KmOJugbwUyXBEDx5KmLPcYAA8F4WIUEBIokOuUV5IKDd
+ACAAosAdeM9xoABgHRKxFJHgfuB48cDhxQh1KHMJ8Klw+f8Aq0i4AasC5bB9AuNhuowi/4/19a0A
+AADgePwciLb8HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8
+HEiz4H7geATcON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATc
+IN0p8OB4BNwc3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE
+3RnwNBQaMDAUGTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRNM7Ak
+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
+BCKQDwAGAABMIACgAd3AfQQigg9AAAAA13JAAAAAAd/PdoAAuIQ4jsB/Ew1BEIXtOY4LD0EQANkC
+8AHZYIYvegDZEQjBAGGGkHPMIiGAA/IB2S8mR/A6rj3yANrPcaAAtA9coc9zqwCg/1mjB9k6o1ij
+iHGpch4P4ADpc3YKIACpcNT/hujKDQAAtg9P/QTw3g9P/RYLgAMBhs91gACABgS1AIYFtRiODK12
+CqAD6XAElc9ygAAYCyWVFLIIgoDh0CAhAM8gIgC5uLq4BSAABAiiLQeP9uB44cXhxs9xoADIHMiB
+CKEG3RHw4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HhhvYwl/5/t9clwwcbgf8HF4Hjh
+xQDaz3GsANQBrRmYgDfYqBkYgKDd6BlAgwXb7BnAgFrYgRkYAIIZWAODGdgAB9u+GdiACBnAgHfY
+GBkAgL8Z2IAMGcCAf9gcGQCAvBmYgAAZgIAQGYCAvRmYgAQZgIAUGYCASNiqGRiAqxkYgKwZGIAB
+2pMZmIAq2JgZGIB62JkZGIAQ2JoZGIB+GZgAfxmYAIAZmADgf8HF4HjPcAAAAT3PcaoA8EMFoc9y
+AAA8PEahz3AAADw+B6GKIFQACKHPcAAACxIJoc9wAAAYHAqhz3AAAB8fC6HPcAAAHBgMoc9wAAAS
+Cw2hiiBEAQ6hz3AAAD48D6FQoYogRA8RoeB+4cXPcaAAyBwIoQbdEfDgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeGG9jCX/n+31sfHxwEYNr/YH2ADfn/8acK//z3WkALg9rBUAFs92pQDY
+y6K4rB0YEAHY7Kb2HRgQ3gkgAOlwiiDEAJ8dGBA52c9wpQAIDD6gyP8KcOD/GNiVHRgQz3GAANQ1
+4KFvIEMAAaECoc9xAQAcVM9wgAAcKtQYQAD42AumNQWP9uB48cDPcIAA0Hh6Cm/20NnPcIAA3Fpu
+Cm/26NnRwOB+4HjPcoAA8GMnioPpJooL6c9xrACQAQDaBOhFoeB+AtgFoeB+4H7xwOHFCHUgkAKV
+QZUQuAV6KdgSuBUgQQBAoSCV8CBBAB0KQAA2CG/2iiDRAwKVIZUQuAV5Jghv9oog0QPFBI/28cDh
+xQh1IJAClUGVELgFehXYE7gVIEEAQKEglfAgQQAdCkAA9g8v9oog0QMClSGVELgFeeYPL/aKINED
+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
+wgfKIGIByiOCDwAARABEBmLyyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIB8woCgP4PT/PRwOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAA8AjgfwCA4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB/AdjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB48cDhxc91gADISKlwLg9v8wPZABWFEEQlQAGF4MohwQ/KIsEHyiBhAcoj
+gQ8AAE8A9ARh8sokYQABjQsIEgFjuAGtvg5P83UGj/PgePHA8g2P8xpxz3aAAMhIII6JCR4Az3GA
+APgIIImA4cwgIaA88g8IUQDPcIAAuIShgALwAN0HDdUTgu0A3c9xgAC4hBiJguiE7QDfBPCigQTf
+iiATAXIJb/OpcYogUwFqCW/z6XHPcIAAGAsYiIPgzCAigcwg4oHMICKCCPKKIBMBRglv84vZCvAK
+lhUNARALlhB3zCAhoAT0ANgh8AHYz3GgAMgfDaHPcIAA+AgBiOu2qrYEvxC45X0FfYogEwEKCW/z
+otmKIBMB/ghv86lxz3CgAMgffxhYgwHYfQWP8+B48cAWDa/zCHHG/z3oIN3PdqAAyB+wpjLYQx4Y
+EADYXg1v8424saawph7YQx4YEADYSg1v8424saZ/Fg+WiiATAUEvDRTEvaIIb/PM2YogEwGWCG/z
+6XGKIBMBjghv86lxz3GAAPgIAYkB2hB1wiKKABMNchBAqQDYDaYLClEABNgBqf0Ej/PgeM9wgADI
+SACIEQieAM9xoADAHQCBgLgAoeB+4HjPcIAAyEgAiBEIngDPcaAAwB0AgaC4AKHgfuB48cDhxc9w
+gABMCQCQz3WAANSpqXHaDaAAiiIECwCNhODKIcsPyiLLB8ogawHKI4sPAAB5CcokKwAAA2vyyiXL
+AM9wgABOCQCQz3GAACysVOAQeJ4NoAAO2nUEj/PxwOHFz3WAAPCrHZ3+C+/5iiH/DjydAnnPcIAA
+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
+DxsZIkgEoIE48MSAAAAbJAIAGyU4HMARAAAAIQAAAIUABYCBAADAFg8bBCIQBBtmDwEbaBQcwBAK
+ABtABAAbbgMAAGEPHB0iAQAdJvkPAGFkDAAQAMAGEQEABCf8AARkAAAbJAIAGyU4HMARAAAAIQAA
+GyVAABskMBzAEQAAACEPHB0iGAEdJhgAxxAIe4CBAADAFyAAxxAQe4CBAADAFwAAACFUMICB+EHE
+EA8bCSIACwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEJAAlAAgAAYQoACUAAAABhAgAJQQAJGigAAMAW
+AQAbJgAAwBcEAB0mAQAIJ+sACGQAAAAhAAAAACwBAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFDQAAPQ0
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAADAAJAA0AAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAHiCgADQSQEAAAAAAAAAAAAAAAAAAAAAAAAAAACcgoAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8B
+AAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAACBAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAACAAAA/wCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAgADAAQAAAAZABgAFAAVAEACBAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAgADAAQAAAAZABgAFAAVAAAAAAAHAAAAAgADAAQAAAAZABgAFAAVAEAC
+BAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANR6gAAIpQEA
+AAAAAAAAAAAAAAAAAAAAANR6gAAYrAEAAAAAAAAAAADUeoAAjK0BAAAAAAAAAAAAAAAAANR6gAAA
+AAAAAAAAAAAAAAD/AAAAAAcAAAAAAAAAAAAAAAAAAH9/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAgQIAAgQIAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAADYBwAAFQAAAOQtgABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAA
+ZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABk
+CgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAqAsAAAAAAACQDwEAZAoAALAIAABkCgAAZAoAAGQK
+AADgCAAACPcAAKhSAABkCgAAZAoAABQJAAAUCQAAFAkAABQJAAAUCQAAFAkAABQJAABkCgAAZAoA
+AGQKAABkCgAAMAoAAGQKAABkCgAAZAoAAGQKAABkCgAArAsAAGQKAABkCgAAlAgAAAMAAAC4swEA
+AgAAACgcAQAEAAAAfDAAAAYAAABktQEAEQAAADyeAQAHAAAAfKcBAAgAAADktQEADAAAACA0AQAN
+AAAAoDgBAA4AAADYOAEAFgAAAPgOAQALAAAAaE0BABQAAADAUwAADwAAAOBjAQAQAAAAvAYBAAEA
+AABoowEAEgAAALBbAQATAAAApFMBAAUAAABsVgAAFQAAABDFAQAXAAAAqAsAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAALCUAACwlAAAsJQAAgDYAACwlAAAsJQAAdDYAACwlAAAsJQAALCUAACwlAAAs
+JQAALCUAACwlAAAsJQAALCUAABwaAAC0GwAAuBsAACwdAACsHQAAMB0AACwlAAAsJQAADD8AAHRC
+AABEQwAALCUAACwlAAAsJQAA2D0AAKydAAConQAAsJ0AACwlAAAsJQAALCUAAIQ2AAAsJQAALCUA
+ACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAA
+LCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAs
+JQAALCUAACwlAAAsJQAAcDcAACwlAAAsJQAALCUAACwlAAAsJQAAUDgAACwlAAAsJQAALCUAACwl
+AAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAAeOMAACwlAACY5AAALCUAACwlAAAsJQAALCUA
+ACwlAAAsJQAALCUAACwlAAAAVgAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAA
+LCUAACwlAAAoTAEAuE8BACwlAADMNAEALCUAAHg2AQBgJgEALCUAACwlAAC8QwAALCUAACwlAAAs
+JQAALCUAACwlAADgngEAVJ4BACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAD8tAEAALUBACwl
+AAAsJQAALCUAACwlAAAsJQAALCUAAEinAQAsJQAAcKoBACwlAAA4xgEALCUAAIQgAACIIAAALCUA
+ACwlAAC8tgEAxFMAACwlAAAsJQAALCUAAOChAQAsJQAALCUAALAHAQCQUwEALCUAACwlAAAsJQAA
+cFoBAKwhAQAsJQAALCUAACwlAAAsJQAALCUAACwlAADwYAEALCUAAMi1AQDMtQEA2LUBANy1AQDQ
+tQEA1LUBAOC1AQAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAACURQAALCUAACwl
+AAAsJQAALCUAACwlAAA4tQEAbLUBAHg6AAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUA
+ACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAA
+LCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAsJQAALCUAACwlAAAs
+JQAAHDsAAJw7AAAgPAAAvDwAACwlAACUPAAALCUAACwlAAAsJQAALCUAACwlAAAUOwAAGDsAACwl
+AAAsJQAA7EMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAB
+AAAAAQEAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEB
+AQEBDQ0NDQ0NDQ0NDQ0NDQ0NDQMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAQEBAQEB
+AQEBAQEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAA
+AAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0NDQ0NDQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAA
+AAAAAAAAAACRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCR
+AgAAMcovAJECAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMB
+AAAxyi8AQwEAADHKLwBDAQAAMcovAEANAADeAwkAAAAAAAAAAAAAAAAAcOMAAAEAAACkLYAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAABAQg8A
+JOcAAAjoAAAY6QAA4OoAABjpAADg6gAAiOwAAAztAACAgICAgICAgAGAAoCAgICAAAAAALzwAAC8
+8AAAAAAAAAAAAAAAAAAAAAAAALzwAAC88AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKQt
+gACkLYAApCCgADggoAABAAAA/P///wAAAAAAAAAAxC2AAMQtgACoIKAAPCCgAAgAAADz////AAAA
+AAAAAADkLYAA5C2AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
+AAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAxAcBAAUAAADkLYAA2AwBAAD/AwD4DAEAAP8FANwNAQAA
+/y0AAA4BAAD/PQC4DQEAAP8EAJwNAQAA/yUAmBQBAIAVAQDwFQEALBEBAGwQAQDYFgEAXBcBAKAX
+AQDwFwEAAAAAACwBAABeAQAAAQAAAAEAAAABAAAAAQAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAgAA
+AAMAAAADAAAAAwAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAIgdAQAKAAAApC2AAAAAAAAAAAAA
+AAAAABQeAQAKAAAApC2AAAAAAAAAAAAAAAAAAEgeAQAKAAAApC2AAAAAAAAAAAAAAAAAAMAeAQAK
+AAAApC2AAAAAAAAAAAAAAAAAANwfAQAKAAAApC2AAAAAAAAAAAAAAAAAAFQfAQAKAAAApC2AAAAA
+AAAAAAAAAAAAAKglAQAGAAAApC2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAgAAA
+AACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsOwEA
+sDwBAFg/AQAAQgEAdEQBANhHAQBAPgEAFAWAAJx6gAAYAAAAXHqAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAYEoBAAYAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoA
+AACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAA
+AAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAA
+BPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACk
+LYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAABPkAAAoAAACkLYAAAAAAAAAA
+AAAAAAAABPkAAAoAAACkLYAAAAAAAAAAAAAAAAAArFEBAAoAAACkLYAAAAAAAP//////////AAAA
+AAAAAAAAAAAAJFMBAAUAAADkLYAAZABkAGkA3ADIAFoAqgC+AIYBfQA+AGQAZABpANwAyABaAKoA
+vgCGAX0APgAAAAAAAQEAAAAAAAAAAQIBAQACAQABAgICAAEBAAIBAgECAAIAAQIDAAAAAHxsAQAs
+agEACIWAADACAAAAAAAAYGABAHxhAQDcmIAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBg
+AQBoagEALJmAABQAAAAAAAAAYGABAJRqAQCQmoAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA
+AGBgAQBkZQEAPDeAAFABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAABgYAEAVGsBALQGgAAEAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYGABAMRrAQAAAAAAAAAAAAAAAABgYAEAWGsBAMAGgAAE
+AAAA/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B
+/wH+Af0B/AH7Ab8BvgG9AbwBuwG6AbkBuAG3AX8BfgF9AXwBewF6AXkBeAF3AXYBdQF/AH4AfQB8
+AHsAPwA+AD0APAA7ADoAOQA5ADkAOQA5ADkAOQA5ADkAOQA5ADkAOQA5ADkAOQA5ADkAOQAKAD8A
+/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af8B/wH/Af4B/QH8AfsB+gH5AfgB9wH2Af8A/gD9
+APwA+wD6APkA+AD3APYAvwC+AL0AvAC7AH8AfgB9AHwAewA/AD4APQA8ADsAOgA5ADgANwA2ADUA
+NAAzADIAMQAwACcAJgAmACYAJgAmACYAJgAmACYAJgAmACYAJgAmACYAJgAmACYAJgAKAD8AAQEA
+AAIBAQADAgID9FgBABLSAAAAAAAA//8PACxsAQABQAAAAAAAAAYAAAAsbAEAAkAAAAAAAAAJAAAA
+lG4BABsAAAAAAAAA/wcAAJRuAQAbAAAAAAAAAP8HAAAsbAEAAkAAAAAAAAAIAAAAlG4BABsAAAAA
+AAAA/wcAAJRuAQAbAAAAAAAAAP8HAAAsbAEAAkAAAAAAAAAJAAAAlG4BABsAAAAAAAAA/wcAAJRu
+AQAbAAAAAAAAAP8HAAAsbAEAAUAAAAAAAAAGAAAALGwBAAJAAAAAAAAAAAAAAJRuAQAPAAAAAAAA
+AP8HAACUbgEAEAAAAAAAAAD/BwAALGwBAAJAAAAAAAAAAQAAAJRuAQAPAAAAAAAAAP8HAACUbgEA
+EAAAAAAAAAD/BwAALGwBAAJAAAAAAAAAAgAAAJRuAQAPAAAAAAAAAP8HAACUbgEAEAAAAAAAAAD/
+BwAALGwBAAJAAAAAAAAAAwAAAJRuAQAPAAAAAAAAAP8HAACUbgEAEAAAAAAAAAD/BwAALGwBAAJA
+AAAAAAAABAAAAJRuAQAPAAAAAAAAAP8HAACUbgEAEAAAAAAAAAD/BwAALGwBAAJAAAAAAAAABQAA
+AJRuAQAPAAAAAAAAAP8HAACUbgEAEAAAAAAAAAD/BwAALGwBAAFAAAAAAAAABwAAAPRYAQAT0gAA
+AAAAAP//DwAsbAEAAUAAAAAAAAAGAAAALGwBAAJAAAAAAAAACQAAAJRuAQAcAAAAAAAAAP8HAACU
+bgEAHAAAAAAAAAD/BwAALGwBAAJAAAAAAAAACAAAAJRuAQAcAAAAAAAAAP8HAACUbgEAHAAAAAAA
+AAD/BwAALGwBAAJAAAAAAAAACQAAAJRuAQAcAAAAAAAAAP8HAACUbgEAHAAAAAAAAAD/BwAALGwB
+AAFAAAAAAAAABgAAACxsAQACQAAAAAAAAAAAAACUbgEAEQAAAAAAAAD/BwAAlG4BABIAAAAAAAAA
+/wcAACxsAQACQAAAAAAAAAEAAACUbgEAEQAAAAAAAAD/BwAAlG4BABIAAAAAAAAA/wcAACxsAQAC
+QAAAAAAAAAIAAACUbgEAEQAAAAAAAAD/BwAAlG4BABIAAAAAAAAA/wcAACxsAQACQAAAAAAAAAMA
+AACUbgEAEQAAAAAAAAD/BwAAlG4BABIAAAAAAAAA/wcAACxsAQACQAAAAAAAAAQAAACUbgEAEQAA
+AAAAAAD/BwAAlG4BABIAAAAAAAAA/wcAACxsAQACQAAAAAAAAAUAAACUbgEAEQAAAAAAAAD/BwAA
+lG4BABIAAAAAAAAA/wcAACxsAQABQAAAAAAAAAcAAABIbAEABtIAAAAAAAD/AQAASGwBAAfSAAAA
+AAAA/wMAAHRYAQAV0gAAAAAAAP8DAAB0WAEADNIAAAAAAAD/AQAAdFgBABXSAAAKAAAAAPwPAHRY
+AQAM0gAACQAAAAD+AwASAAAAAAC8AAEAAACMAQEA4AdYBhADAAB/BAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAEAAAAAAAAAAAAAAADAAAAAQAAAIACKwDNBJkDBAACAAAAgAKrAM0EGQEEAAMAAACAAqsA
+zQSZAgQABAAAAIACKwHNBBkABAAFAAAAgAIrAc0EmQEEAAYAAACAAisBzQQZAwQABwAAAIACqwHN
+BJkABAAIAAAAgAKrAc0EGQIEAAkAAAAAAqsBzQSZAwQACgAAAAACSwDNBBkBBAALAAAAAAJLAM0E
+mQIEAAwAAAAAAssAzQQZAAQADQAAAAACywDNBJkBBAAOAAAAAALLAM0EGQMEACIAAgCBAYwAAQCA
+AwAAJAACAIEBDAEBAAABAAAmAAIAgQEMAQEAgAIAACgAAgCBAYwBAQAAAAAAKgACAAEBjAEBAIAB
+AAAsAAIAAQGMAQEAAAMAAC4AAgABASwAAQCAAAAAMAACAAEBLAABAAACAAA0AAIAAQGsAAEAAAEA
+ADYAAgABAawAAQCAAgAAOAACAAEBLAEBAAAAAAA8AAIAAQEsAQEAAAMAAD4AAgABAawBAQCAAAAA
+QAACAAEBrAEBAAACAABkAAIAgQBsAQEAAAEBAGYAAgCBAGwBAQCAAgEAaAACAIEA7AEBAAAAAQBs
+AAIAgQDsAQEAAAMBAG4AAgCBAA0AAQCAAAEAcAACAIEADQABAAACAQB0AAIAgQCNAAEAAAEBAHYA
+AgCBAI0AAQCAAgEAeAACAAEADQEBAAAAAQB8AAIAAQANAQEAAAMBAH4AAgABAI0BAQCAAAIAgAAC
+AAEAjQEBAAACAgCEAAIAAQAtAAEAAAECAIYAAgABAC0AAQCAAgIAiAACAAEArQABAAAAAgCMAAIA
+AQCtAAEAAAMCAJEAAgABAC0BAQDAAgIAlQACAAEArQEBAMABAwCXAAIAAQCtAQEAQAMDAJkAAgAB
+AE0AAQDAAAMAnQACAAEATQABAMADAwCfAAIAAQDNAAEAQAEDAKEAAgABAM0AAQDAAgMApQACAAEA
+TQEBAMABAwAAAAAAAAAAAAAAAAAAAAAAAAAAAA3SEtIT0gLSEdIEQwFAFUECQALSHNIAAAwADQAO
+ABQADQAOAA8AEQAQABIAGwAcAA8AAAARAAAAEAAAABIAAAAbAAAAHAAAABsAAAAcAAAAEtIAABPS
+AAAwAAAAcAAAAIQAAACZAAAABwAAAAAAAAABAAAAAgAAAAIAAAAAAAAAAQAAAAAAAAABAAAAPwAA
+ACQAAAAfAAAAGQAAABcAAAAUAAAAEQAAABgAAAAbAAAAJwAAACAAAAA2AAAAMAAAAH8AAABkAAAA
+XwAAAFkAAABXAAAAVAAAAFEAAABYAAAAWwAAAGcAAABgAAAAdgAAAHAAAAC/AAAApAAAAJ8AAACZ
+AAAAlwAAAJQAAACRAAAAmAAAAJsAAACnAAAAoAAAALYAAACwAAAAPwEAACQBAAAfAQAAGQEAABcB
+AAAUAQAAEQEAABgBAAAbAQAAJwEAACABAAA2AQAAMAEAAP8AAADkAAAA3wAAANkAAADXAAAA1AAA
+ANEAAADYAAAA2wAAAOcAAADgAAAA9gAAAPAAAAC/AQAApAEAAJ8BAACZAQAAlwEAAJQBAACRAQAA
+mAEAAJsBAACnAQAAoAEAALYBAACwAQAAPwAAACQAAAAfAAAAGQAAABcAAAAUAAAAEQAAABgAAAAb
+AAAAJwAAACAAAAA2AAAAMAAAAH8AAABkAAAAXwAAAFkAAABXAAAAVAAAAFEAAABYAAAAWwAAAGcA
+AABgAAAAdgAAAHAAAAC/AAAApAAAAJ8AAACZAAAAlwAAAJQAAACRAAAAmAAAAJsAAACnAAAAoAAA
+ALYAAACwAAAAPwEAACQBAAAfAQAAGQEAABcBAAAUAQAAEQEAABgBAAAbAQAAJwEAACABAAA2AQAA
+MAEAAH8BAABkAQAAXwEAAFkBAABXAQAAVAEAAFEBAABYAQAAGwAAAGcBAABgAQAAdgEAAHABAAC/
+AQAApAEAAJ8BAACZAQAAlwEAAJQBAACRAQAAmAEAAJsBAACnAQAAoAEAALYBAACwAQAAIgAAAEAA
+AABkAAAAjAAAAAcAAAAHAAAA/wAAAP8AAAAN0hHSENIC0gHSA9IL0hvSCNIAgAXSEtIT0hTSBEMc
+0gEAAAAAAAAAAAAAAAAAAAADAAAABAAAADAAAAABAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA
+/wMAAAIAAADoAwAAewMAABoDAADDAgAAdwIAADICAAD1AQAAvgEAABzSDdIR0hDSAtIB0gPSG9IL
+0gCABdIS0hPSFNIEQwbSB9IAACIAAABAAAAAZAAAAIwAAAAHAAAAIgAAAEAAAABkAAAAjAAAAAcA
+AAAHAAAA/wAAAP8AAAAN0hHSENIC0gHSA9IL0hvSCNIAgAXSEtIT0hTSBEMc0gEAAAAAAAAAAAAA
+AAAAAAADAAAABAAAADAAAAABAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA/wMAAAIAAAAAAAAA
+AAAAAAAAAADYpAEABgAAAKQtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAABQFgACceoAAGAAAAFx6gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAWAAJx6gAAYAAAAXHqA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAOLEBAAQAAACkLYAAAAAAAAAAAAAAAAAAFLABAAQAAACkLYAA
+AAAAAAAAAAAAAAAAALIBAAYAAACkLYAAAAAAAAAAAAAAAAAAFLABAAQAAACkLYAAAAAAAAAAAAAA
+AAAAOLEBAAQAAACkLYAAAAAAAAAAAAAAAAAAFLABAAQAAACkLYAAAAAAAAAAAAAAAAAAOLEBAAQA
+AACkLYAAAAAAAAAAAAAAAAAAFLABAAQAAACkLYAAAAAAAAAAAAAAAAAAALIBAAYAAACkLYAAAAAA
+AAAAAAAAAAAAFLABAAQAAACkLYAAAAAAAAAAAAAAAAAAOLEBAAQAAACkLYAAAAAAAAAAAAAAAAAA
+ALIBAAYAAACkLYAAAAAAAAAAAAAAAAAAOLEBAAQAAACkLYAAAAAAAAAAAAAAAAAAOLEBAAQAAACk
+LYAAAAAAAAAAAAAAAAAAALIBAAYAAACkLYAAFAWAAJx6gAAYAAAAXHqAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUBQAAAAAA
+AAAAAAAAAAAAAAAA/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAAAABQYHCA0ODxAVFhcY
+GQAACg0RFAoNERQKDREUCgoAAAAAAAAGBgYGCQkJCQAGAAD4AOoA3QDQAMQAuQCvAKUAnACTAIoA
+gwB7AHQAbgBoAG4BaAFuAmgCbgNoA24EaARuBWgFbgZoBm4HaAduCGgIbgloCW4KaApuC2gLbgxo
+DG4NaA1uDmgObg9oD24QaBBuEWgRbhJoEm4TaBNuFGgUbhVoFW4WaBZuF2gXbhhoGG4ZaBluGmga
+bhtoG24caBxuHWgdbh5oHm4faB9uIGggbgBoAG4BaAFuAmgCbgNoA24EaARuBWgFbgZoBm4HaAdu
+CGgIbgloCW4KaApuC2gLbgxoDG4NaA1uDmgObg9oD24QaBBuEWgRbhJoEm4TaBNuFGgUbhVoFW4W
+aBZuF2gXbhhoGG4ZaBluGmgabhtoG24caBxuHWgdbh5oHm4faB9uIGggbiFoIW4iaCJuI2gjbiRo
+JG4laCVuJmgmbidoJwAAAAAAAAAAAAAAAJTKAQAIAAAA5C2AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////8AAf//AgP///8E////////////////////
+//8F/wb/B/8I/wn/Cv8L/wz///8N////Dv///w////8Q////////////////////////////////
+//////////////8R////Ev///xP///8U////Ff///xb///8X////GP///xn///8a////G/////8c
+////Hf///x7///8f////IP///yH//////////////////////yIjJP8lJif//yj///8p////////
+//////////////////////////////////////////////////////////////////////8BBAAA
+AgUBAAMGAgAEBwMABQgEAAYJBQAHCgYACAsHAAkMCAAKDQkACw4KAAwPCwANEAwADhENAAFBAAQC
+QgEEA0MCBAREAwQFRQQEBkYFBAdHBgS3EyIAuBQjALkVJAC7FiUAvBcmAL0YJwDAGSgAxBopAAcb
+AAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAmIwcAKCQIAColCQAsJgoALicLADAoDAA0KQ0AOCoO
+ADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQyFQB4MxYAfDQXAIA1GACENhkAiDcaAIw4GwCROhwA
+lTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoKAjRLDQE8TA8BZE0RAWxOEwF0TxUBfFAXAYRRGQGV
+Uh0BnVMfAQAEFggWFhYMFhYWFhYWFhAAAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEA
+AAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAA
+AAIAAAAFAAAAGAgBpQICAKUAPDg0MCwoJCAcGBQQDAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCABQO
+AAAAABoAAAABAQABAgEBAQEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQEBAQEAQICAgICAgMD
+AwMDAwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAEBAgECAgN//wcPHz8BAwED
+DwcBBw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gvAVVVVQXjOI4Dqqqq
+AnEcxwGqqqoKx3EcBygAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA
+9ACwACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZ
+AOgACgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAGbmAACd2ImdTuzETjRI
+gzQndmInGqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAHNEiD
+NBqkQRoRGIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQERmAE
+Az/wA6qqqqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0QAuJ
+ndgJDdIgDQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3YCQiM
+wAiJndgJCIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAGsLLV
+BQVUQAUFVEAF1h3GBA0AGgAnADQATgBoAHUAggAaADQATgBoAJwA0ADqAAQBJwBOAHUAnADqADgB
+XwGGATQAaACcANAAOAGgAdQBCAIMAE4AaACCAHUAnADDAGgAggCCAJwAtgC2ANAAnADDAMMA6gAR
+AREBOAGCAJwAtgCcALYA0ADqANAA6gAEAQQBHgHDAOoAEQHqABEBOAFfATgBXwGGAYYBrQEAADAA
+AAA2AAAADAAAABIAAAAYAAAAJAAAAAYAAAAJAAAAAAAAAAAAAAAYIBQUDg4UFAUGAQIDBAAAAAEB
+AgECAgMEDAwIBAwEBEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAEBESExQVFhcYGRob
+HB0eHyAhIiMkJSYnKCkqKywtLi9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNk
+ZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/LQAPIADwYQAAAAAAAAAAAAABAgQEAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAWDe+AHO+sL6avmwAAK6uZAaufIWurkkACQAAAAIAAAAAAAAAAAAAAAkA
+AAACAAAAAAAAAAAAAAAJAAAAAwAAAAEAAAAJAAAACQAAAAIAAAACAAAACQAAAAECAQIDBAAABQYH
+CAkKAAAABQYAAgQABQAAAAAABQcBAwQABQEAAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwM
+QA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUF
+BQUFbABwBHQIdAwABAQGAAAAAAAAAABkAAAAAJABAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAQAAAAUAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAQAAAA
+AAAAAAEAAAABAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAA0sgEAAAAAAAAEAABkAAAABwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBgYGBgYFBQUF
+BQQEBAQEAwMDAwMCAgICAgEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAKROAQCsTgEAtE4BAAhPAQAQTwEAGE8BAAAIAABACAAAgAgAAAAJ
+AABACQAAgAkAAP8pAAAAAAAAmAkAAKQJAAAkAAAAZAAAAKQAAAAkAQAAZAEAAKQBAAAkAAAAZAAA
+AKQAAAAkAQAA5AAAAKQBAAAAAAAAAQAAAAIAAAADAAAABAAAAAAAAAABAAAAAgAAAAMAAAAAAAAA
+AQAAAAIAAAADAAAABAAAAAUAAAAMAAAACgAAAISoAQCYqAEAAKkBAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQAAAAAFCRETFwAADgAAACoA
+AAAHAAAACwAAAP////8AAAAAAAAAAAEAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAABQUFBQUFBQUAAAAA
+gA0AAAAgAACADQAAgA0AAAAgAACADQAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAA=
+====
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 51dea2236b7..eb2182eb7c5 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2007
+ * Copyright (c) 2007-2009
  *	Damien Bergamini 
  * Copyright (c) 2008
  *	Benjamin Close 
@@ -19,7 +19,8 @@
  */
 
 /*
- * Driver for Intel Wireless WiFi Link 4965AGN 802.11 network adapters.
+ * Driver for Intel Wireless WiFi Link 4965 and Intel WiFi Link 5000 Series
+ * 802.11 network adapters.
  */
 
 #include 
@@ -73,29 +74,28 @@ __FBSDID("$FreeBSD$");
 
 static int	iwn_probe(device_t);
 static int	iwn_attach(device_t);
-static int 	iwn_detach(device_t);
-static int	iwn_cleanup(device_t);
+const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
+void		iwn_radiotap_attach(struct iwn_softc *);
 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
 		    const char name[IFNAMSIZ], int unit, int opmode,
 		    int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
 		    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static void	iwn_vap_delete(struct ieee80211vap *);
-static int	iwn_shutdown(device_t);
-static int	iwn_suspend(device_t);
-static int	iwn_resume(device_t);
+static int	iwn_cleanup(device_t);
+static int 	iwn_detach(device_t);
+int		iwn_nic_lock(struct iwn_softc *);
+int		iwn_eeprom_lock(struct iwn_softc *);
+int		iwn_init_otprom(struct iwn_softc *);
+int		iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
 static int	iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
 		    void **, bus_size_t, bus_size_t, int);
 static void	iwn_dma_contig_free(struct iwn_dma_info *);
-int		iwn_alloc_shared(struct iwn_softc *);
-void		iwn_free_shared(struct iwn_softc *);
+int		iwn_alloc_sched(struct iwn_softc *);
+void		iwn_free_sched(struct iwn_softc *);
 int		iwn_alloc_kw(struct iwn_softc *);
 void		iwn_free_kw(struct iwn_softc *);
 int		iwn_alloc_fwmem(struct iwn_softc *);
 void		iwn_free_fwmem(struct iwn_softc *);
-struct		iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
-void		iwn_free_rbuf(void *, void *);
-int		iwn_alloc_rpool(struct iwn_softc *);
-void		iwn_free_rpool(struct iwn_softc *);
 int		iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
 void		iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
 void		iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
@@ -103,76 +103,112 @@ int		iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
 		    int);
 void		iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
 void		iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
-static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN]);
+int		iwn_read_eeprom(struct iwn_softc *,
+		    uint8_t macaddr[IEEE80211_ADDR_LEN]);
+void		iwn4965_read_eeprom(struct iwn_softc *);
+void		iwn4965_print_power_group(struct iwn_softc *, int);
+void		iwn5000_read_eeprom(struct iwn_softc *);
+static void	iwn_read_eeprom_channels(struct iwn_softc *, uint32_t, int);
+struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
+		    const uint8_t mac[IEEE80211_ADDR_LEN]);
 void		iwn_newassoc(struct ieee80211_node *, int);
 int		iwn_media_change(struct ifnet *);
 int		iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-void		iwn_mem_lock(struct iwn_softc *);
-void		iwn_mem_unlock(struct iwn_softc *);
-uint32_t	iwn_mem_read(struct iwn_softc *, uint32_t);
-void		iwn_mem_write(struct iwn_softc *, uint32_t, uint32_t);
-void		iwn_mem_write_region_4(struct iwn_softc *, uint32_t,
-		    const uint32_t *, int);
-int		iwn_eeprom_lock(struct iwn_softc *);
-void		iwn_eeprom_unlock(struct iwn_softc *);
-int		iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
-int		iwn_transfer_microcode(struct iwn_softc *, const uint8_t *, int);
-int		iwn_transfer_firmware(struct iwn_softc *);
-int		iwn_load_firmware(struct iwn_softc *);
-void		iwn_unload_firmware(struct iwn_softc *);
+void		iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
+		    struct iwn_rx_data *);
 static void	iwn_timer_timeout(void *);
 static void	iwn_calib_reset(struct iwn_softc *);
-void		iwn_ampdu_rx_start(struct iwn_softc *, struct iwn_rx_desc *);
-void		iwn_rx_intr(struct iwn_softc *, struct iwn_rx_desc *,
+void		iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
 		    struct iwn_rx_data *);
-void		iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *);
-void		iwn_tx_intr(struct iwn_softc *, struct iwn_rx_desc *);
-void		iwn_cmd_intr(struct iwn_softc *, struct iwn_rx_desc *);
+void		iwn5000_rx_calib_results(struct iwn_softc *,
+		    struct iwn_rx_desc *, struct iwn_rx_data *);
+void		iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
+		    struct iwn_rx_data *);
+void		iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
+		    struct iwn_rx_data *);
+void		iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
+		    struct iwn_rx_data *);
+void		iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
+		    uint8_t);
+void		iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
 void		iwn_notif_intr(struct iwn_softc *);
+void		iwn_wakeup_intr(struct iwn_softc *);
+void		iwn_rftoggle_intr(struct iwn_softc *);
+void		iwn_fatal_intr(struct iwn_softc *, uint32_t, uint32_t);
 void		iwn_intr(void *);
-void		iwn_read_eeprom(struct iwn_softc *,
-		    uint8_t macaddr[IEEE80211_ADDR_LEN]);
-static void	iwn_read_eeprom_channels(struct iwn_softc *);
-void		iwn_print_power_group(struct iwn_softc *, int);
-uint8_t		iwn_plcp_signal(int);
+void		iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
+		    uint16_t);
+void		iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
+		    uint16_t);
+void		iwn5000_reset_sched(struct iwn_softc *, int, int);
 int		iwn_tx_data(struct iwn_softc *, struct mbuf *,
 		    struct ieee80211_node *, struct iwn_tx_ring *);
-void		iwn_start(struct ifnet *);
-void		iwn_start_locked(struct ifnet *);
 static int	iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
 		    const struct ieee80211_bpf_params *);
-static void	iwn_watchdog(struct iwn_softc *);
+void		iwn_start(struct ifnet *);
+void		iwn_start_locked(struct ifnet *);
+static void	iwn_watchdog(struct iwn_softc *sc);
 int		iwn_ioctl(struct ifnet *, u_long, caddr_t);
 int		iwn_cmd(struct iwn_softc *, int, const void *, int, int);
+int		iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
+		    int);
+int		iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
+		    int);
 int		iwn_set_link_quality(struct iwn_softc *, uint8_t,
 		    const struct ieee80211_channel *, int);
-int		iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
-		    const struct ieee80211_key *);
+int		iwn_add_broadcast_node(struct iwn_softc *,
+		    const struct ieee80211_channel *, int);
 int		iwn_wme_update(struct ieee80211com *);
 void		iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
 int		iwn_set_critical_temp(struct iwn_softc *);
-void		iwn_enable_tsf(struct iwn_softc *, struct ieee80211_node *);
-void		iwn_power_calibration(struct iwn_softc *, int);
-int		iwn_set_txpower(struct iwn_softc *,
+int		iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
+void		iwn4965_power_calibration(struct iwn_softc *, int);
+int		iwn4965_set_txpower(struct iwn_softc *,
 		    struct ieee80211_channel *, int);
-int8_t		iwn_get_rssi(struct iwn_softc *, const struct iwn_rx_stat *);
+int		iwn5000_set_txpower(struct iwn_softc *,
+		    struct ieee80211_channel *, int);
+int		iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
+int		iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
 int		iwn_get_noise(const struct iwn_rx_general_stats *);
-int		iwn_get_temperature(struct iwn_softc *);
+int		iwn4965_get_temperature(struct iwn_softc *);
+int		iwn5000_get_temperature(struct iwn_softc *);
 int		iwn_init_sensitivity(struct iwn_softc *);
-void		iwn_compute_differential_gain(struct iwn_softc *,
+void		iwn_collect_noise(struct iwn_softc *,
 		    const struct iwn_rx_general_stats *);
+int		iwn4965_init_gains(struct iwn_softc *);
+int		iwn5000_init_gains(struct iwn_softc *);
+int		iwn4965_set_gains(struct iwn_softc *);
+int		iwn5000_set_gains(struct iwn_softc *);
 void		iwn_tune_sensitivity(struct iwn_softc *,
 		    const struct iwn_rx_stats *);
 int		iwn_send_sensitivity(struct iwn_softc *);
-int		iwn_auth(struct iwn_softc *, struct ieee80211vap *);
-int		iwn_run(struct iwn_softc *, struct ieee80211vap *);
-int		iwn_scan(struct iwn_softc *);
+int		iwn_set_pslevel(struct iwn_softc *, int, int, int);
 int		iwn_config(struct iwn_softc *);
-void		iwn_post_alive(struct iwn_softc *);
-void		iwn_stop_master(struct iwn_softc *);
-int		iwn_reset(struct iwn_softc *);
-void		iwn_hw_config(struct iwn_softc *);
+int		iwn_scan(struct iwn_softc *);
+int		iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
+int		iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
+int		iwn5000_query_calibration(struct iwn_softc *);
+int		iwn5000_send_calibration(struct iwn_softc *);
+int		iwn4965_post_alive(struct iwn_softc *);
+int		iwn5000_post_alive(struct iwn_softc *);
+int		iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
+		    int);
+int		iwn4965_load_firmware(struct iwn_softc *);
+int		iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
+		    const uint8_t *, int);
+int		iwn5000_load_firmware(struct iwn_softc *);
+int		iwn_read_firmware(struct iwn_softc *);
+void		iwn_unload_firmware(struct iwn_softc *);
+int		iwn_clock_wait(struct iwn_softc *);
+int		iwn4965_apm_init(struct iwn_softc *);
+int		iwn5000_apm_init(struct iwn_softc *);
+void		iwn_apm_stop_master(struct iwn_softc *);
+void		iwn_apm_stop(struct iwn_softc *);
+int		iwn4965_nic_config(struct iwn_softc *);
+int		iwn5000_nic_config(struct iwn_softc *);
+int		iwn_hw_prepare(struct iwn_softc *sc);
+int		iwn_hw_init(struct iwn_softc *);
+void		iwn_hw_stop(struct iwn_softc *);
 void		iwn_init_locked(struct iwn_softc *);
 void		iwn_init(void *);
 void		iwn_stop_locked(struct iwn_softc *);
@@ -182,10 +218,13 @@ static void 	iwn_scan_end(struct ieee80211com *);
 static void 	iwn_set_channel(struct ieee80211com *);
 static void 	iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
 static void 	iwn_scan_mindwell(struct ieee80211_scan_state *);
-static void	iwn_hwreset(void *, int);
-static void	iwn_radioon(void *, int);
-static void	iwn_radiooff(void *, int);
+static void	iwn_hw_reset(void *, int);
+static void	iwn_radio_on(void *, int);
+static void	iwn_radio_off(void *, int);
 static void	iwn_sysctlattach(struct iwn_softc *);
+static int	iwn_shutdown(device_t);
+static int	iwn_suspend(device_t);
+static int	iwn_resume(device_t);
 
 #define IWN_DEBUG
 #ifdef IWN_DEBUG
@@ -224,26 +263,95 @@ struct iwn_ident {
 };
 
 static const struct iwn_ident iwn_ident_table [] = {
-        { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
-        { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
-        { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
-        { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
-        { 0, 0, NULL }
+	{ 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
+	{ 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
+	{ 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
+	{ 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
+	{ 0x8086, 0x4232, "Intel(R) PRO/Wireless 5100" },
+	{ 0x8086, 0x4237, "Intel(R) PRO/Wireless 5100" },
+	{ 0x8086, 0x423C, "Intel(R) PRO/Wireless 5150" },
+	{ 0x8086, 0x423D, "Intel(R) PRO/Wireless 5150" },
+	{ 0x8086, 0x4235, "Intel(R) PRO/Wireless 5300" },
+	{ 0x8086, 0x4236, "Intel(R) PRO/Wireless 5300" },
+	{ 0x8086, 0x4236, "Intel(R) PRO/Wireless 5350" },
+	{ 0x8086, 0x423A, "Intel(R) PRO/Wireless 5350" },
+	{ 0x8086, 0x423B, "Intel(R) PRO/Wireless 5350" },
+	{ 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" },
+	{ 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" },
+	{ 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" },
+	{ 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" },
+	{ 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" },
+	{ 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" },
+	{ 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" },
+	{ 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" },
+	{ 0, 0, NULL }
+};
+
+static const struct iwn_hal iwn4965_hal = {
+	iwn4965_load_firmware,
+	iwn4965_read_eeprom,
+	iwn4965_post_alive,
+	iwn4965_apm_init,
+	iwn4965_nic_config,
+	iwn4965_update_sched,
+	iwn4965_get_temperature,
+	iwn4965_get_rssi,
+	iwn4965_set_txpower,
+	iwn4965_init_gains,
+	iwn4965_set_gains,
+	iwn4965_add_node,
+	iwn4965_tx_done,
+	&iwn4965_sensitivity_limits,
+	IWN4965_NTXQUEUES,
+	IWN4965_NDMACHNLS,
+	IWN4965_ID_BROADCAST,
+	IWN4965_RXONSZ,
+	IWN4965_SCHEDSZ,
+	IWN4965_FW_TEXT_MAXSZ,
+	IWN4965_FW_DATA_MAXSZ,
+	IWN4965_FWSZ,
+	IWN4965_SCHED_TXFACT,
+};
+
+static const struct iwn_hal iwn5000_hal = {
+	iwn5000_load_firmware,
+	iwn5000_read_eeprom,
+	iwn5000_post_alive,
+	iwn5000_apm_init,
+	iwn5000_nic_config,
+	iwn5000_update_sched,
+	iwn5000_get_temperature,
+	iwn5000_get_rssi,
+	iwn5000_set_txpower,
+	iwn5000_init_gains,
+	iwn5000_set_gains,
+	iwn5000_add_node,
+	iwn5000_tx_done,
+	&iwn5000_sensitivity_limits,
+	IWN5000_NTXQUEUES,
+	IWN5000_NDMACHNLS,
+	IWN5000_ID_BROADCAST,
+	IWN5000_RXONSZ,
+	IWN5000_SCHEDSZ,
+	IWN5000_FW_TEXT_MAXSZ,
+	IWN5000_FW_DATA_MAXSZ,
+	IWN5000_FWSZ,
+	IWN5000_SCHED_TXFACT,
 };
 
 static int
 iwn_probe(device_t dev)
 {
-        const struct iwn_ident *ident;
+	const struct iwn_ident *ident;
 
-        for (ident = iwn_ident_table; ident->name != NULL; ident++) {
-                if (pci_get_vendor(dev) == ident->vendor &&
-                    pci_get_device(dev) == ident->device) {
-                        device_set_desc(dev, ident->name);
-                        return 0;
-                }
-        }
-        return ENXIO;
+	for (ident = iwn_ident_table; ident->name != NULL; ident++) {
+		if (pci_get_vendor(dev) == ident->vendor &&
+		    pci_get_device(dev) == ident->device) {
+			device_set_desc(dev, ident->name);
+			return 0;
+		}
+	}
+	return ENXIO;
 }
 
 static int
@@ -252,30 +360,44 @@ iwn_attach(device_t dev)
 	struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
 	struct ieee80211com *ic;
 	struct ifnet *ifp;
+	const struct iwn_hal *hal;
+	uint32_t tmp;
 	int i, error, result;
 	uint8_t macaddr[IEEE80211_ADDR_LEN];
 
 	sc->sc_dev = dev;
 
-	/* XXX */
-	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
-		device_printf(dev, "chip is in D%d power mode "
-		    "-- setting to D0\n", pci_get_powerstate(dev));
-		pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+	/*
+	 * Get the offset of the PCI Express Capability Structure in PCI
+	 * Configuration Space.
+	 */
+	error = pci_find_extcap(dev, PCIY_EXPRESS, &sc->sc_cap_off);
+	if (error != 0) {
+		device_printf(dev, "PCIe capability structure not found!\n");
+		return error;
 	}
 
-	/* clear device specific PCI configuration register 0x41 */
+	/* Clear device-specific "PCI retry timeout" register (41h). */
 	pci_write_config(dev, 0x41, 0, 1);
 
-	/* enable bus-mastering */
+	/* Hardware bug workaround. */
+	tmp = pci_read_config(dev, PCIR_COMMAND, 1);
+	if (tmp & PCIM_CMD_INTxDIS) {
+		DPRINTF(sc, IWN_DEBUG_RESET, "%s: PCIe INTx Disable set\n",
+		    __func__);
+		tmp &= ~PCIM_CMD_INTxDIS;
+		pci_write_config(dev, PCIR_COMMAND, tmp, 1);
+	}
+
+	/* Enable bus-mastering. */
 	pci_enable_busmaster(dev);
 
-	sc->mem_rid= PCIR_BAR(0);
+	sc->mem_rid = PCIR_BAR(0);
 	sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
-					 RF_ACTIVE);
+	    RF_ACTIVE);
 	if (sc->mem == NULL ) {
 		device_printf(dev, "could not allocate memory resources\n");
-		error = ENOMEM; 
+		error = ENOMEM;
 		return error;
 	}
 
@@ -286,63 +408,68 @@ iwn_attach(device_t dev)
 	    pci_alloc_msi(dev, &result) == 0)
 		sc->irq_rid = 1;
 	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
-					 RF_ACTIVE | RF_SHAREABLE);
+	    RF_ACTIVE | RF_SHAREABLE);
 	if (sc->irq == NULL) {
 		device_printf(dev, "could not allocate interrupt resource\n");
 		error = ENOMEM;
-		return error;
+		goto fail;
 	}
 
 	IWN_LOCK_INIT(sc);
 	callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
-        TASK_INIT(&sc->sc_reinit_task, 0, iwn_hwreset, sc );
-        TASK_INIT(&sc->sc_radioon_task, 0, iwn_radioon, sc );
-        TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radiooff, sc );
+	TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc );
+	TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc );
+	TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc );
 
-	/*
-	 * Put adapter into a known state.
-	 */
-	error = iwn_reset(sc);
-	if (error != 0) {
-		device_printf(dev,
-		    "could not reset adapter, error %d\n", error);
+	/* Attach Hardware Abstraction Layer. */
+	hal = iwn_hal_attach(sc);
+	if (hal == NULL) {
+		error = ENXIO;	/* XXX: Wrong error code? */
 		goto fail;
 	}
 
-	/*
-	 * Allocate DMA memory for firmware transfers.
-	 */
+	error = iwn_hw_prepare(sc);
+	if (error != 0) {
+		device_printf(dev, "hardware not ready, error %d\n", error);
+		goto fail;
+	}
+
+	/* Power ON adapter. */
+	error = hal->apm_init(sc);
+	if (error != 0) {
+		device_printf(dev, "could not power ON adapter, error %d\n",
+		    error);
+		goto fail;
+	}
+
+	/* Allocate DMA memory for firmware transfers. */
 	error = iwn_alloc_fwmem(sc);
 	if (error != 0) {
 		device_printf(dev,
-		    "could not allocate firmware memory, error %d\n", error);
+		    "could not allocate memory for firmware, error %d\n",
+		    error);
 		goto fail;
 	}
 
-	/*
-	 * Allocate a "keep warm" page.
-	 */
+	/* Allocate "Keep Warm" page. */
 	error = iwn_alloc_kw(sc);
 	if (error != 0) {
 		device_printf(dev,
-		    "could not allocate keep-warm page, error %d\n", error);
+		    "could not allocate \"Keep Warm\" page, error %d\n", error);
 		goto fail;
 	}
 
-	/*
-	 * Allocate shared area (communication area).
-	 */
-	error = iwn_alloc_shared(sc);
+	/* Allocate TX scheduler "rings". */
+	error = iwn_alloc_sched(sc);
 	if (error != 0) {
 		device_printf(dev,
-		    "could not allocate shared area, error %d\n", error);
+		    "could not allocate TX scheduler rings, error %d\n",
+		    error);
 		goto fail;
 	}
 
-	/*
-	 * Allocate Tx rings.
-	 */
-	for (i = 0; i < IWN_NTXQUEUES; i++) {
+	/* Allocate TX rings (16 on 4965AGN, 20 on 5000). */
+	for (i = 0; i < hal->ntxqs; i++) {
 		error = iwn_alloc_tx_ring(sc, &sc->txq[i], i);
 		if (error != 0) {
 			device_printf(dev,
@@ -352,6 +479,7 @@ iwn_attach(device_t dev)
 		}
 	}
 
+	/* Allocate RX ring. */
 	error = iwn_alloc_rx_ring(sc, &sc->rxq);
 	if (error != 0 ){
 		device_printf(dev,
@@ -359,6 +487,12 @@ iwn_attach(device_t dev)
 		goto fail;
 	}
 
+	/* Clear pending interrupts. */
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+
+	/* Initialization firmware has not been loaded yet. */
+	sc->sc_flags |= IWN_FLAG_FIRST_BOOT;
+
 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
 	if (ifp == NULL) {
 		device_printf(dev, "can not allocate ifnet structure\n");
@@ -366,11 +500,11 @@ iwn_attach(device_t dev)
 	}
 	ic = ifp->if_l2com;
 
-	ic->ic_ifp = ifp;	
+	ic->ic_ifp = ifp;
 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
 
-	/* set device capabilities */
+	/* Set device capabilities. */
 	ic->ic_caps =
 		  IEEE80211_C_STA		/* station mode supported */
 		| IEEE80211_C_MONITOR		/* monitor mode supported */
@@ -399,8 +533,21 @@ iwn_attach(device_t dev)
 		| IEEE80211_HTC_AMSDU		/* tx A-MSDU */
 		;
 #endif
-	/* read supported channels and MAC address from EEPROM */
-	iwn_read_eeprom(sc, macaddr);
+
+	/* Read MAC address, channels, etc from EEPROM. */
+	error = iwn_read_eeprom(sc, macaddr);
+	if (error != 0) {
+		device_printf(dev, "could not read EEPROM, error %d\n",
+		    error);
+		goto fail;
+	}
+
+	/* Power OFF adapter. */
+	iwn_apm_stop(sc);
+
+	device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
+	    sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
+	    macaddr, ":");
 
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_softc = sc;
@@ -408,7 +555,7 @@ iwn_attach(device_t dev)
 	ifp->if_init = iwn_init;
 	ifp->if_ioctl = iwn_ioctl;
 	ifp->if_start = iwn_start;
-        IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
 	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
 	IFQ_SET_READY(&ifp->if_snd);
 
@@ -418,85 +565,124 @@ iwn_attach(device_t dev)
 	ic->ic_raw_xmit = iwn_raw_xmit;
 	ic->ic_node_alloc = iwn_node_alloc;
 	ic->ic_newassoc = iwn_newassoc;
-        ic->ic_wme.wme_update = iwn_wme_update;
-        ic->ic_scan_start = iwn_scan_start;
-        ic->ic_scan_end = iwn_scan_end;
-        ic->ic_set_channel = iwn_set_channel;
-        ic->ic_scan_curchan = iwn_scan_curchan;
-        ic->ic_scan_mindwell = iwn_scan_mindwell;
-
-	ieee80211_radiotap_attach(ic,
-            &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
-		IWN_TX_RADIOTAP_PRESENT,
-            &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
-		IWN_RX_RADIOTAP_PRESENT);
+	ic->ic_wme.wme_update = iwn_wme_update;
+	ic->ic_scan_start = iwn_scan_start;
+	ic->ic_scan_end = iwn_scan_end;
+	ic->ic_set_channel = iwn_set_channel;
+	ic->ic_scan_curchan = iwn_scan_curchan;
+	ic->ic_scan_mindwell = iwn_scan_mindwell;
 
+	iwn_radiotap_attach(sc);
 	iwn_sysctlattach(sc);
 
-        /*
-         * Hook our interrupt after all initialization is complete.
-         */
-        error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
+	/*
+	 * Hook our interrupt after all initialization is complete.
+	 */
+	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
 	    NULL, iwn_intr, sc, &sc->sc_ih);
-        if (error != 0) {
-                device_printf(dev, "could not set up interrupt, error %d\n", error);
-                goto fail;
-        }
+	if (error != 0) {
+		device_printf(dev, "could not set up interrupt, error %d\n",
+		    error);
+		goto fail;
+	}
 
-        ieee80211_announce(ic);
+	ieee80211_announce(ic);
 	return 0;
 fail:
 	iwn_cleanup(dev);
 	return error;
 }
 
-static int
-iwn_detach(device_t dev)
+const struct iwn_hal *
+iwn_hal_attach(struct iwn_softc *sc)
 {
-	iwn_cleanup(dev);
-        return 0;
+	sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
+
+	switch (sc->hw_type) {
+	case IWN_HW_REV_TYPE_4965:
+		sc->sc_hal = &iwn4965_hal;
+		sc->fwname = "iwnfw-4965";
+		sc->critical_temp = IWN_CTOK(110);
+		sc->txantmsk = IWN_ANT_A | IWN_ANT_B;
+		sc->rxantmsk = IWN_ANT_ABC;
+		sc->ntxchains = 2;
+		sc->nrxchains = 3;
+		break;
+	case IWN_HW_REV_TYPE_5100:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-5000";
+		sc->critical_temp = 110;
+		sc->txantmsk = IWN_ANT_B;
+		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
+		sc->ntxchains = 1;
+		sc->nrxchains = 2;
+		break;
+	case IWN_HW_REV_TYPE_5150:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-5150";
+		/* NB: critical temperature will be read from EEPROM. */
+		sc->txantmsk = IWN_ANT_A;
+		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
+		sc->ntxchains = 1;
+		sc->nrxchains = 2;
+		break;
+	case IWN_HW_REV_TYPE_5300:
+	case IWN_HW_REV_TYPE_5350:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-5000";
+		sc->critical_temp = 110;
+		sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
+		sc->ntxchains = sc->nrxchains = 3;
+		break;
+	case IWN_HW_REV_TYPE_1000:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-1000";
+		sc->critical_temp = 110;
+		sc->txantmsk = IWN_ANT_A;
+		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
+		sc->ntxchains = 1;
+		sc->nrxchains = 2;
+		break;
+	case IWN_HW_REV_TYPE_6000:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-6000";
+		sc->critical_temp = 110;
+		sc->txantmsk = IWN_ANT_ABC;
+		sc->rxantmsk = IWN_ANT_ABC;
+		sc->ntxchains = 3;
+		sc->nrxchains = 3;
+		break;
+	case IWN_HW_REV_TYPE_6050:
+		sc->sc_hal = &iwn5000_hal;
+		sc->fwname = "iwnfw-6050";
+		sc->critical_temp = 110;
+		sc->txantmsk = IWN_ANT_ABC;
+		sc->rxantmsk = IWN_ANT_ABC;
+		sc->ntxchains = 3;
+		sc->nrxchains = 3;
+		break;
+	default:
+		device_printf(sc->sc_dev, "adapter type %d not supported\n",
+		    sc->hw_type);
+		return NULL;
+	}
+	return sc->sc_hal;
 }
 
 /*
- * Cleanup any device resources that were allocated
+ * Attach the interface to 802.11 radiotap.
  */
-int
-iwn_cleanup(device_t dev)
+void
+iwn_radiotap_attach(struct iwn_softc *sc)
 {
-	struct iwn_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	int i;
 
-	ieee80211_draintask(ic, &sc->sc_reinit_task);
-	ieee80211_draintask(ic, &sc->sc_radioon_task);
-	ieee80211_draintask(ic, &sc->sc_radiooff_task);
-
-	if (ifp != NULL) {
-		iwn_stop(sc);
-		callout_drain(&sc->sc_timer_to);
-		ieee80211_ifdetach(ic);
-	}
-
-	iwn_unload_firmware(sc);
-
-	iwn_free_rx_ring(sc, &sc->rxq);
-	for (i = 0; i < IWN_NTXQUEUES; i++)
-		iwn_free_tx_ring(sc, &sc->txq[i]);
-	iwn_free_kw(sc);
-	iwn_free_fwmem(sc);
-	if (sc->irq != NULL) {
-		bus_teardown_intr(dev, sc->irq, sc->sc_ih);
-		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
-		if (sc->irq_rid == 1)
-			pci_release_msi(dev);
-	}
-	if (sc->mem != NULL)
-		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
-	if (ifp != NULL)
-		if_free(ifp);
-	IWN_LOCK_DESTROY(sc);
-	return 0;
+	ieee80211_radiotap_attach(ic,
+	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+		IWN_TX_RADIOTAP_PRESENT,
+	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+		IWN_RX_RADIOTAP_PRESENT);
 }
 
 static struct ieee80211vap *
@@ -517,17 +703,18 @@ iwn_vap_create(struct ieee80211com *ic,
 	vap = &ivp->iv_vap;
 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
 	vap->iv_bmissthreshold = 10;		/* override default */
-	/* override with driver methods */
+	/* Override with driver methods. */
 	ivp->iv_newstate = vap->iv_newstate;
 	vap->iv_newstate = iwn_newstate;
 
 	ieee80211_amrr_init(&ivp->iv_amrr, vap,
 	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
 	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
-	    500 /*ms*/);
+	    500 /* ms */);
 
-	/* complete setup */
-	ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+	/* Complete setup. */
+	ieee80211_vap_attach(vap, ieee80211_media_change,
+	    ieee80211_media_status);
 	ic->ic_opmode = opmode;
 	return vap;
 }
@@ -542,71 +729,280 @@ iwn_vap_delete(struct ieee80211vap *vap)
 	free(ivp, M_80211_VAP);
 }
 
-static int
-iwn_shutdown(device_t dev)
-{
-	struct iwn_softc *sc = device_get_softc(dev);
-
-	iwn_stop(sc);
-	return 0;
-}
-
-static int
-iwn_suspend(device_t dev)
-{
-	struct iwn_softc *sc = device_get_softc(dev);
-
-	iwn_stop(sc);
-	return 0;
-}
-
-static int
-iwn_resume(device_t dev)
+int
+iwn_cleanup(device_t dev)
 {
 	struct iwn_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic;
+	int i;
 
-	pci_write_config(dev, 0x41, 0, 1);
+	if (ifp != NULL) {
+		ic = ifp->if_l2com;
 
-	if (ifp->if_flags & IFF_UP)
-		iwn_init(sc);
+		ieee80211_draintask(ic, &sc->sc_reinit_task);
+		ieee80211_draintask(ic, &sc->sc_radioon_task);
+		ieee80211_draintask(ic, &sc->sc_radiooff_task);
+
+		iwn_stop(sc);
+		callout_drain(&sc->sc_timer_to);
+		ieee80211_ifdetach(ic);
+	}
+
+	iwn_unload_firmware(sc);
+
+	iwn_free_rx_ring(sc, &sc->rxq);
+
+	if (sc->sc_hal != NULL)
+		for (i = 0; i < sc->sc_hal->ntxqs; i++)
+			iwn_free_tx_ring(sc, &sc->txq[i]);
+
+	iwn_free_sched(sc);
+	iwn_free_kw(sc);
+	iwn_free_fwmem(sc);
+
+	if (sc->irq != NULL) {
+		bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
+		if (sc->irq_rid == 1)
+			pci_release_msi(dev);
+	}
+
+	if (sc->mem != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
+
+	if (ifp != NULL)
+		if_free(ifp);
+
+	IWN_LOCK_DESTROY(sc);
+	return 0;
+}
+
+static int
+iwn_detach(device_t dev)
+{
+	iwn_cleanup(dev);
+	return 0;
+}
+
+int
+iwn_nic_lock(struct iwn_softc *sc)
+{
+	int ntries;
+
+	/* Request exclusive access to NIC. */
+	IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
+
+	/* Spin until we actually get the lock. */
+	for (ntries = 0; ntries < 1000; ntries++) {
+		if ((IWN_READ(sc, IWN_GP_CNTRL) &
+		     (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
+		    IWN_GP_CNTRL_MAC_ACCESS_ENA)
+			return 0;
+		DELAY(10);
+	}
+	return ETIMEDOUT;
+}
+
+static __inline void
+iwn_nic_unlock(struct iwn_softc *sc)
+{
+	IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
+}
+
+static __inline uint32_t
+iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
+{
+	IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
+	return IWN_READ(sc, IWN_PRPH_RDATA);
+}
+
+static __inline void
+iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
+{
+	IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
+	IWN_WRITE(sc, IWN_PRPH_WDATA, data);
+}
+
+static __inline void
+iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
+{
+	iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
+}
+
+static __inline void
+iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
+{
+	iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask);
+}
+
+static __inline void
+iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr,
+    const uint32_t *data, int count)
+{
+	for (; count > 0; count--, data++, addr += 4)
+		iwn_prph_write(sc, addr, *data);
+}
+
+static __inline uint32_t
+iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
+{
+	IWN_WRITE(sc, IWN_MEM_RADDR, addr);
+	return IWN_READ(sc, IWN_MEM_RDATA);
+}
+
+static __inline void
+iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
+{
+	IWN_WRITE(sc, IWN_MEM_WADDR, addr);
+	IWN_WRITE(sc, IWN_MEM_WDATA, data);
+}
+
+static __inline void
+iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
+{
+	uint32_t tmp;
+
+	tmp = iwn_mem_read(sc, addr & ~3);
+	if (addr & 3)
+		tmp = (tmp & 0x0000ffff) | data << 16;
+	else
+		tmp = (tmp & 0xffff0000) | data;
+	iwn_mem_write(sc, addr & ~3, tmp);
+}
+
+static __inline void
+iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data,
+    int count)
+{
+	for (; count > 0; count--, addr += 4)
+		*data++ = iwn_mem_read(sc, addr);
+}
+
+static __inline void
+iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
+    int count)
+{
+	for (; count > 0; count--, addr += 4)
+		iwn_mem_write(sc, addr, val);
+}
+
+int
+iwn_eeprom_lock(struct iwn_softc *sc)
+{
+	int i, ntries;
+
+	for (i = 0; i < 100; i++) {
+		/* Request exclusive access to EEPROM. */
+		IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
+		    IWN_HW_IF_CONFIG_EEPROM_LOCKED);
+
+		/* Spin until we actually get the lock. */
+		for (ntries = 0; ntries < 100; ntries++) {
+			if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
+			    IWN_HW_IF_CONFIG_EEPROM_LOCKED)
+				return 0;
+			DELAY(10);
+		}
+	}
+	return ETIMEDOUT;
+}
+
+static __inline void
+iwn_eeprom_unlock(struct iwn_softc *sc)
+{
+	IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED);
+}
+
+/*
+ * Initialize access by host to One Time Programmable ROM.
+ * NB: This kind of ROM can be found on 1000 or 6000 Series only.
+ */
+int
+iwn_init_otprom(struct iwn_softc *sc)
+{
+	int error;
+
+	error = iwn_clock_wait(sc);
+	if (error != 0)
+		return error;
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+	iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
+	DELAY(5);
+	iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
+	iwn_nic_unlock(sc);
+
+	IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
+	/* Clear ECC status. */
+	IWN_SETBITS(sc, IWN_OTP_GP,
+	    IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
+
+	return 0;
+}
+
+int
+iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
+{
+	uint32_t val, tmp;
+	int ntries;
+	uint8_t *out = data;
+
+	for (; count > 0; count -= 2, addr++) {
+		IWN_WRITE(sc, IWN_EEPROM, addr << 2);
+		for (ntries = 0; ntries < 100; ntries++) {
+			val = IWN_READ(sc, IWN_EEPROM);
+			if (val & IWN_EEPROM_READ_VALID)
+				break;
+			DELAY(5);
+		}
+		if (ntries == 100) {
+			device_printf(sc->sc_dev,
+			    "timeout reading ROM at 0x%x\n", addr);
+			return ETIMEDOUT;
+		}
+		if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
+			/* OTPROM, check for ECC errors. */
+			tmp = IWN_READ(sc, IWN_OTP_GP);
+			if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {
+				device_printf(sc->sc_dev,
+				    "OTPROM ECC error at 0x%x\n", addr);
+				return EIO;
+			}
+			if (tmp & IWN_OTP_GP_ECC_CORR_STTS) {
+				/* Correctable ECC error, clear bit. */
+				IWN_SETBITS(sc, IWN_OTP_GP,
+				    IWN_OTP_GP_ECC_CORR_STTS);
+			}
+		}
+		*out++ = val >> 16;
+		if (count > 1)
+			*out++ = val >> 24;
+	}
 	return 0;
 }
 
 static void
 iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
-        if (error != 0)
-                return;
-        KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
-        *(bus_addr_t *)arg = segs[0].ds_addr;
+	if (error != 0)
+		return;
+	KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
+	*(bus_addr_t *)arg = segs[0].ds_addr;
 }
 
-static int 
+static int
 iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
 	void **kvap, bus_size_t size, bus_size_t alignment, int flags)
 {
-	int error, lalignment, i;
+	int error;
 
-	/*
-	 * FreeBSD can't guarrenty 16k alignment at the moment (11/2007) so
-	 * we allocate an extra 12k with 4k alignement and walk through
-	 * it trying to find where the alignment is. It's a nasty fix for
-	 * a bigger problem.
-	*/
-	DPRINTF(sc, IWN_DEBUG_RESET,
-	    "Size: %zd - alignment %zd\n", size, alignment);
-	if (alignment == 0x4000) {
-		size += 12*1024;
-		lalignment = 4096;
-		DPRINTF(sc, IWN_DEBUG_RESET, "%s\n",
-		    "Attempting to find a 16k boundary");
-	} else
-		lalignment = alignment;
 	dma->size = size;
 	dma->tag = NULL;
 
-	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), lalignment,
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), alignment,
 	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
 	    1, size, flags, NULL, NULL, &dma->tag);
 	if (error != 0) {
@@ -623,22 +1019,6 @@ iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
 		   __func__, error);
 		goto fail;
 	}
-	if (alignment == 0x4000) {
-		for (i = 0; i < 3 && (((uintptr_t)dma->vaddr) & 0x3fff); i++) {
-			DPRINTF(sc, IWN_DEBUG_RESET,  "%s\n",
-			    "Memory Unaligned, shifting pointer by 4k");
-			dma->vaddr += 4096;
-			size -= 4096;
-		}
-		if ((((uintptr_t)dma->vaddr ) & (alignment-1))) {
-			DPRINTF(sc, IWN_DEBUG_ANY,
-			    "%s: failed to align memory, vaddr %p, align %zd\n",
-			    __func__, dma->vaddr, alignment);
-			error = ENOMEM;
-			goto fail;
-		}
-	}
-
 	error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
 	    size, iwn_dma_map_addr, &dma->paddr, flags);
 	if (error != 0) {
@@ -672,26 +1052,25 @@ iwn_dma_contig_free(struct iwn_dma_info *dma)
 }
 
 int
-iwn_alloc_shared(struct iwn_softc *sc)
+iwn_alloc_sched(struct iwn_softc *sc)
 {
-	/* must be aligned on a 1KB boundary */
-	return iwn_dma_contig_alloc(sc, &sc->shared_dma,
-	    (void **)&sc->shared, sizeof (struct iwn_shared), 1024,
-	    BUS_DMA_NOWAIT);
+	/* TX scheduler rings must be aligned on a 1KB boundary. */
+	return iwn_dma_contig_alloc(sc, &sc->sched_dma,
+	    (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
 }
 
 void
-iwn_free_shared(struct iwn_softc *sc)
+iwn_free_sched(struct iwn_softc *sc)
 {
-	iwn_dma_contig_free(&sc->shared_dma);
+	iwn_dma_contig_free(&sc->sched_dma);
 }
 
 int
 iwn_alloc_kw(struct iwn_softc *sc)
 {
-	/* must be aligned on a 4k boundary */
-	return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL,
-	    PAGE_SIZE, PAGE_SIZE, BUS_DMA_NOWAIT);
+	/* "Keep Warm" page must be aligned on a 4KB boundary. */
+	return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096,
+	    BUS_DMA_NOWAIT);
 }
 
 void
@@ -703,10 +1082,9 @@ iwn_free_kw(struct iwn_softc *sc)
 int
 iwn_alloc_fwmem(struct iwn_softc *sc)
 {
-	/* allocate enough contiguous space to store text and data */
+	/* Must be aligned on a 16-byte boundary. */
 	return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
-	    IWN_FW_MAIN_TEXT_MAXSZ + IWN_FW_MAIN_DATA_MAXSZ, 16,
-	    BUS_DMA_NOWAIT);
+	    sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
 }
 
 void
@@ -718,46 +1096,71 @@ iwn_free_fwmem(struct iwn_softc *sc)
 int
 iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 {
+	bus_size_t size;
 	int i, error;
 
 	ring->cur = 0;
 
+	/* Allocate RX descriptors (256-byte aligned). */
+	size = IWN_RX_RING_COUNT * sizeof (uint32_t);
 	error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
-	    (void **)&ring->desc, IWN_RX_RING_COUNT * sizeof (uint32_t),
-	    IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
+	    (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not allocate rx ring DMA memory, error %d\n",
+		    "%s: could not allocate Rx ring DMA memory, error %d\n",
 		    __func__, error);
 		goto fail;
 	}
 
-        error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
 	    BUS_SPACE_MAXADDR_32BIT,
-            BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
-            MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
-        if (error != 0) {
-                device_printf(sc->sc_dev,
+	    BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
+	    MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
 		    "%s: bus_dma_tag_create_failed, error %d\n",
 		    __func__, error);
-                goto fail;
-        }
+		goto fail;
+	}
+
+	/* Allocate RX status area (16-byte aligned). */
+	error = iwn_dma_contig_alloc(sc, &ring->stat_dma,
+	    (void **)&ring->stat, sizeof (struct iwn_rx_status),
+	    16, BUS_DMA_NOWAIT);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not allocate Rx status DMA memory, error %d\n",
+		    __func__, error);
+		goto fail;
+	}
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT,
+	    BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
+	    MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: bus_dma_tag_create_failed, error %d\n",
+		    __func__, error);
+		goto fail;
+	}
 
 	/*
-	 * Setup Rx buffers.
+	 * Allocate and map RX buffers.
 	 */
 	for (i = 0; i < IWN_RX_RING_COUNT; i++) {
 		struct iwn_rx_data *data = &ring->data[i];
 		struct mbuf *m;
 		bus_addr_t paddr;
 
-		error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
+		error = bus_dmamap_create(ring->desc_dma.tag, 0, &data->map);
 		if (error != 0) {
 			device_printf(sc->sc_dev,
 			    "%s: bus_dmamap_create failed, error %d\n",
 			    __func__, error);
 			goto fail;
 		}
+
 		m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 		if (m == NULL) {
 			device_printf(sc->sc_dev,
@@ -765,8 +1168,9 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 			error = ENOMEM;
 			goto fail;
 		}
-		/* map page */
-		error = bus_dmamap_load(ring->data_dmat, data->map,
+
+		/* Map page. */
+		error = bus_dmamap_load(ring->desc_dma.tag, data->map,
 		    mtod(m, caddr_t), MJUMPAGESIZE,
 		    iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 		if (error != 0 && error != EFBIG) {
@@ -777,11 +1181,12 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 			error = ENOMEM;	/* XXX unique code */
 			goto fail;
 		}
-		bus_dmamap_sync(ring->data_dmat, data->map, 
+		bus_dmamap_sync(ring->desc_dma.tag, data->map,
 		    BUS_DMASYNC_PREWRITE);
 
 		data->m = m;
-		/* Rx buffers are aligned on a 256-byte boundary */
+
+		/* Set physical address of RX buffer (256-byte aligned). */
 		ring->desc[i] = htole32(paddr >> 8);
 	}
 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
@@ -797,21 +1202,23 @@ iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 {
 	int ntries;
 
-	iwn_mem_lock(sc);
-
-	IWN_WRITE(sc, IWN_RX_CONFIG, 0);
-	for (ntries = 0; ntries < 100; ntries++) {
-		if (IWN_READ(sc, IWN_RX_STATUS) & IWN_RX_IDLE)
-			break;
-		DELAY(10);
-	}
+	if (iwn_nic_lock(sc) == 0) {
+		IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
+		for (ntries = 0; ntries < 1000; ntries++) {
+			if (IWN_READ(sc, IWN_FH_RX_STATUS) &
+			    IWN_FH_RX_STATUS_IDLE)
+				break;
+			DELAY(10);
+		}
+		iwn_nic_unlock(sc);
 #ifdef IWN_DEBUG
-	if (ntries == 100)
-		DPRINTF(sc, IWN_DEBUG_ANY, "%s\n", "timeout resetting Rx ring");
+		if (ntries == 1000)
+			DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
+			    "timeout resetting Rx ring");
 #endif
-	iwn_mem_unlock(sc);
-
+	}
 	ring->cur = 0;
+	sc->last_rx_valid = 0;
 }
 
 void
@@ -820,64 +1227,84 @@ iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 	int i;
 
 	iwn_dma_contig_free(&ring->desc_dma);
+	iwn_dma_contig_free(&ring->stat_dma);
 
-	for (i = 0; i < IWN_RX_RING_COUNT; i++)
-		if (ring->data[i].m != NULL)
-			m_freem(ring->data[i].m);
+	for (i = 0; i < IWN_RX_RING_COUNT; i++) {
+		struct iwn_rx_data *data = &ring->data[i];
+
+		if (data->m != NULL) {
+			bus_dmamap_unload(ring->desc_dma.tag, data->map);
+			m_freem(data->m);
+		}
+	}
 }
 
 int
 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
 {
 	bus_size_t size;
+	bus_addr_t paddr;
 	int i, error;
 
 	ring->qid = qid;
 	ring->queued = 0;
 	ring->cur = 0;
 
+	/* Allocate TX descriptors (256-byte aligned.) */
 	size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_desc);
 	error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
-	    (void **)&ring->desc, size, IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
+	    (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not allocate tx ring DMA memory, error %d\n",
+		    "%s: could not allocate TX ring DMA memory, error %d\n",
 		    __func__, error);
 		goto fail;
 	}
 
+	/*
+	 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
+	 * to allocate commands space for other rings.
+	 */
+	if (qid > 4)
+		return 0;
+
 	size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_cmd);
 	error = iwn_dma_contig_alloc(sc, &ring->cmd_dma,
 	    (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not allocate tx cmd DMA memory, error %d\n",
+		    "%s: could not allocate TX cmd DMA memory, error %d\n",
 		    __func__, error);
 		goto fail;
 	}
 
-        error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
 	    BUS_SPACE_MAXADDR_32BIT,
-            BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
-            MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
-        if (error != 0) {
-                device_printf(sc->sc_dev,
+	    BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
+	    MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
 		    "%s: bus_dma_tag_create_failed, error %d\n",
 		    __func__, error);
-                goto fail;
-        }
+		goto fail;
+	}
 
+	paddr = ring->cmd_dma.paddr;
 	for (i = 0; i < IWN_TX_RING_COUNT; i++) {
 		struct iwn_tx_data *data = &ring->data[i];
 
-		error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
+		data->cmd_paddr = paddr;
+		data->scratch_paddr = paddr + 12;
+		paddr += sizeof (struct iwn_tx_cmd);
+
+		error = bus_dmamap_create(ring->desc_dma.tag, 0, &data->map);
 		if (error != 0) {
 			device_printf(sc->sc_dev,
 			    "%s: bus_dmamap_create failed, error %d\n",
 			    __func__, error);
 			goto fail;
 		}
-		bus_dmamap_sync(ring->data_dmat, data->map, 
+		bus_dmamap_sync(ring->desc_dma.tag, data->map,
 		    BUS_DMASYNC_PREWRITE);
 	}
 	return 0;
@@ -889,35 +1316,20 @@ fail:
 void
 iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 {
-	uint32_t tmp;
-	int i, ntries;
-
-	iwn_mem_lock(sc);
-
-	IWN_WRITE(sc, IWN_TX_CONFIG(ring->qid), 0);
-	for (ntries = 0; ntries < 20; ntries++) {
-		tmp = IWN_READ(sc, IWN_TX_STATUS);
-		if ((tmp & IWN_TX_IDLE(ring->qid)) == IWN_TX_IDLE(ring->qid))
-			break;
-		DELAY(10);
-	}
-#ifdef IWN_DEBUG
-	if (ntries == 20)
-		DPRINTF(sc, IWN_DEBUG_RESET,
-		    "%s: timeout resetting Tx ring %d\n", __func__, ring->qid);
-#endif
-	iwn_mem_unlock(sc);
+	int i;
 
 	for (i = 0; i < IWN_TX_RING_COUNT; i++) {
 		struct iwn_tx_data *data = &ring->data[i];
 
 		if (data->m != NULL) {
-			bus_dmamap_unload(ring->data_dmat, data->map);
+			bus_dmamap_unload(ring->desc_dma.tag, data->map);
 			m_freem(data->m);
 			data->m = NULL;
 		}
 	}
-
+	/* Clear TX descriptors. */
+	memset(ring->desc, 0, ring->desc_dma.size);
+	sc->qfullmsk &= ~(1 << ring->qid);
 	ring->queued = 0;
 	ring->cur = 0;
 }
@@ -935,13 +1347,327 @@ iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 			struct iwn_tx_data *data = &ring->data[i];
 
 			if (data->m != NULL) {
-				bus_dmamap_unload(ring->data_dmat, data->map);
+				bus_dmamap_unload(ring->desc_dma.tag, data->map);
 				m_freem(data->m);
 			}
 		}
 	}
 }
 
+int
+iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	int error;
+	uint16_t val;
+
+	/* Check whether adapter has an EEPROM or an OTPROM. */
+	if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
+	    (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
+		sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s found\n",
+	    (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM");
+
+	if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
+		device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__);
+		return EIO;
+	}
+	error = iwn_eeprom_lock(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not lock ROM, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	if ((sc->sc_flags & IWN_FLAG_HAS_OTPROM) &&
+	    ((error = iwn_init_otprom(sc)) != 0)) {
+		device_printf(sc->sc_dev,
+		    "%s: could not initialize OTPROM, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
+	sc->rfcfg = le16toh(val);
+	DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
+
+	/* Read MAC address. */
+	iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
+
+	/* Read adapter-specific information from EEPROM. */
+	hal->read_eeprom(sc);
+
+	iwn_eeprom_unlock(sc);
+	return 0;
+}
+
+void
+iwn4965_read_eeprom(struct iwn_softc *sc)
+{
+	int i;
+	uint16_t val;
+
+	/* Read regulatory domain (4 ASCII characters.) */
+	iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
+
+	/* Read the list of authorized channels. */
+	for (i = 0; i < 7; i++)
+		iwn_read_eeprom_channels(sc, iwn4965_regulatory_bands[i], i);
+
+	/* Read maximum allowed TX power for 2GHz and 5GHz bands. */
+	iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
+	sc->maxpwr2GHz = val & 0xff;
+	sc->maxpwr5GHz = val >> 8;
+	/* Check that EEPROM values are within valid range. */
+	if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
+		sc->maxpwr5GHz = 38;
+	if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
+		sc->maxpwr2GHz = 38;
+	DPRINTF(sc, IWN_DEBUG_RESET, "maxpwr 2GHz=%d 5GHz=%d\n",
+	    sc->maxpwr2GHz, sc->maxpwr5GHz);
+
+	/* Read samples for each TX power group. */
+	iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands,
+	    sizeof sc->bands);
+
+	/* Read voltage at which samples were taken. */
+	iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
+	sc->eeprom_voltage = (int16_t)le16toh(val);
+	DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
+	    sc->eeprom_voltage);
+
+#ifdef IWN_DEBUG
+	/* Print samples. */
+	if (sc->sc_debug & IWN_DEBUG_ANY || 1) {
+		for (i = 0; i < IWN_NBANDS; i++)
+			iwn4965_print_power_group(sc, i);
+	}
+#endif
+}
+
+#ifdef IWN_DEBUG
+void
+iwn4965_print_power_group(struct iwn_softc *sc, int i)
+{
+	struct iwn4965_eeprom_band *band = &sc->bands[i];
+	struct iwn4965_eeprom_chan_samples *chans = band->chans;
+	int j, c;
+
+	printf("===band %d===\n", i);
+	printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
+	printf("chan1 num=%d\n", chans[0].num);
+	for (c = 0; c < 2; c++) {
+		for (j = 0; j < IWN_NSAMPLES; j++) {
+			printf("chain %d, sample %d: temp=%d gain=%d "
+			    "power=%d pa_det=%d\n", c, j,
+			    chans[0].samples[c][j].temp,
+			    chans[0].samples[c][j].gain,
+			    chans[0].samples[c][j].power,
+			    chans[0].samples[c][j].pa_det);
+		}
+	}
+	printf("chan2 num=%d\n", chans[1].num);
+	for (c = 0; c < 2; c++) {
+		for (j = 0; j < IWN_NSAMPLES; j++) {
+			printf("chain %d, sample %d: temp=%d gain=%d "
+			    "power=%d pa_det=%d\n", c, j,
+			    chans[1].samples[c][j].temp,
+			    chans[1].samples[c][j].gain,
+			    chans[1].samples[c][j].power,
+			    chans[1].samples[c][j].pa_det);
+		}
+	}
+}
+#endif
+
+void
+iwn5000_read_eeprom(struct iwn_softc *sc)
+{
+	int32_t temp, volt, delta;
+	uint32_t addr, base;
+	int i;
+	uint16_t val;
+
+	/* Read regulatory domain (4 ASCII characters.) */
+	iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
+	base = le16toh(val);
+	iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
+	    sc->eeprom_domain, 4);
+
+	/* Read the list of authorized channels. */
+	for (i = 0; i < 7; i++) {
+		addr = base + iwn5000_regulatory_bands[i];
+		iwn_read_eeprom_channels(sc, addr, i);
+	}
+
+	iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
+	base = le16toh(val);
+	if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
+		/* Compute critical temperature (in Kelvin.) */
+		iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
+		temp = le16toh(val);
+		iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
+		volt = le16toh(val);
+		delta = temp - (volt / -5);
+		sc->critical_temp = (IWN_CTOK(110) - delta) * -5;
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d delta=%dK\n",
+		    temp, volt, delta);
+	} else {
+		/* Read crystal calibration. */
+		iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
+		    &sc->eeprom_crystal, sizeof (uint32_t));
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n",
+		le32toh(sc->eeprom_crystal));
+	}
+}
+
+static void
+iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band,
+    uint32_t flags, uint32_t addr)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
+	struct ieee80211_channel *c;
+	int i, chan, nflags;
+
+	iwn_read_prom_data(sc, addr, channels,
+	    band->nchan * sizeof (struct iwn_eeprom_chan));
+
+	for (i = 0; i < band->nchan; i++) {
+		if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
+			DPRINTF(sc, IWN_DEBUG_RESET,
+			    "skip chan %d flags 0x%x maxpwr %d\n",
+			    band->chan[i], channels[i].flags,
+			    channels[i].maxpwr);
+			continue;
+		}
+		chan = band->chan[i];
+
+		/* Translate EEPROM flags to net80211 */
+		nflags = 0;
+		if ((channels[i].flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
+			nflags |= IEEE80211_CHAN_PASSIVE;
+		if ((channels[i].flags & IWN_EEPROM_CHAN_IBSS) == 0)
+			nflags |= IEEE80211_CHAN_NOADHOC;
+		if (channels[i].flags & IWN_EEPROM_CHAN_RADAR) {
+			nflags |= IEEE80211_CHAN_DFS;
+			/* XXX apparently IBSS may still be marked */
+			nflags |= IEEE80211_CHAN_NOADHOC;
+		}
+
+		DPRINTF(sc, IWN_DEBUG_RESET,
+		    "add chan %d flags 0x%x maxpwr %d\n",
+		    chan, channels[i].flags, channels[i].maxpwr);
+
+		c = &ic->ic_channels[ic->ic_nchans++];
+		c->ic_ieee = chan;
+		c->ic_freq = ieee80211_ieee2mhz(chan, flags);
+		c->ic_maxregpower = channels[i].maxpwr;
+		c->ic_maxpower = 2*c->ic_maxregpower;
+		if (flags & IEEE80211_CHAN_2GHZ) {
+			/* G =>'s B is supported */
+			c->ic_flags = IEEE80211_CHAN_B | nflags;
+
+			c = &ic->ic_channels[ic->ic_nchans++];
+			c[0] = c[-1];
+			c->ic_flags = IEEE80211_CHAN_G | nflags;
+		} else {	/* 5GHz band */
+			c->ic_flags = IEEE80211_CHAN_A | nflags;
+			sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
+		}
+		/* XXX no constraints on using HT20 */
+		/* add HT20, HT40 added separately */
+		c = &ic->ic_channels[ic->ic_nchans++];
+		c[0] = c[-1];
+		c->ic_flags |= IEEE80211_CHAN_HT20;
+		/* XXX NARROW =>'s 1/2 and 1/4 width? */
+	}
+}
+
+static void
+iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band,
+    uint32_t flags, uint32_t addr)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
+	struct ieee80211_channel *c, *cent, *extc;
+	int i;
+
+	iwn_read_prom_data(sc, addr, channels,
+	    band->nchan * sizeof (struct iwn_eeprom_chan));
+
+	for (i = 0; i < band->nchan; i++) {
+		if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
+		    !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
+			DPRINTF(sc, IWN_DEBUG_RESET,
+			    "skip chan %d flags 0x%x maxpwr %d\n",
+			    band->chan[i], channels[i].flags,
+			    channels[i].maxpwr);
+			continue;
+		}
+		/*
+		 * Each entry defines an HT40 channel pair; find the
+		 * center channel, then the extension channel above.
+		 */
+		cent = ieee80211_find_channel_byieee(ic, band->chan[i],
+		    flags & ~IEEE80211_CHAN_HT);
+		if (cent == NULL) {	/* XXX shouldn't happen */
+			device_printf(sc->sc_dev,
+			    "%s: no entry for channel %d\n",
+			    __func__, band->chan[i]);
+			continue;
+		}
+		extc = ieee80211_find_channel(ic, cent->ic_freq+20,
+		    flags & ~IEEE80211_CHAN_HT);
+		if (extc == NULL) {
+			DPRINTF(sc, IWN_DEBUG_RESET,
+			    "skip chan %d, extension channel not found\n",
+			    band->chan[i]);
+			continue;
+		}
+
+		DPRINTF(sc, IWN_DEBUG_RESET,
+		    "add ht40 chan %d flags 0x%x maxpwr %d\n",
+		    band->chan[i], channels[i].flags, channels[i].maxpwr);
+
+		c = &ic->ic_channels[ic->ic_nchans++];
+		c[0] = cent[0];
+		c->ic_extieee = extc->ic_ieee;
+		c->ic_flags &= ~IEEE80211_CHAN_HT;
+		c->ic_flags |= IEEE80211_CHAN_HT40U;
+		c = &ic->ic_channels[ic->ic_nchans++];
+		c[0] = extc[0];
+		c->ic_extieee = cent->ic_ieee;
+		c->ic_flags &= ~IEEE80211_CHAN_HT;
+		c->ic_flags |= IEEE80211_CHAN_HT40D;
+	}
+}
+
+static void
+iwn_read_eeprom_channels(struct iwn_softc *sc, uint32_t addr, int n)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	static const uint32_t iwnband_flags[] = {
+		IEEE80211_CHAN_G,
+		IEEE80211_CHAN_A,
+		IEEE80211_CHAN_A,
+		IEEE80211_CHAN_A,
+		IEEE80211_CHAN_A,
+		IEEE80211_CHAN_G | IEEE80211_CHAN_HT40,
+		IEEE80211_CHAN_A | IEEE80211_CHAN_HT40
+	};
+
+	if (n < 5)
+		iwn_read_eeprom_band(sc, &iwn_bands[n], iwnband_flags[n], addr);
+	else
+		iwn_read_eeprom_ht40(sc, &iwn_bands[n], iwnband_flags[n], addr);
+	ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
+}
+
 struct ieee80211_node *
 iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
 {
@@ -954,7 +1680,7 @@ iwn_newassoc(struct ieee80211_node *ni, int isnew)
 	struct ieee80211vap *vap = ni->ni_vap;
 
 	ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
-	   &IWN_NODE(ni)->amn, ni);
+	    &IWN_NODE(ni)->amn, ni);
 }
 
 int
@@ -983,7 +1709,10 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 
 	if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
 		/* !AUTH -> AUTH requires adapter config */
-		error = iwn_auth(sc, vap);
+		error = 1;
+		while (error) {
+			error = iwn_auth(sc, vap);
+		}
 	}
 	if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
 		/*
@@ -1005,314 +1734,20 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 }
 
 /*
- * Grab exclusive access to NIC memory.
+ * Process an RX_PHY firmware notification.  This is usually immediately
+ * followed by an MPDU_RX_DONE notification.
  */
 void
-iwn_mem_lock(struct iwn_softc *sc)
+iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
 {
-	uint32_t tmp;
-	int ntries;
+	struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
 
-	tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_MAC);
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received PHY stats\n", __func__);
 
-	/* spin until we actually get the lock */
-	for (ntries = 0; ntries < 1000; ntries++) {
-		if ((IWN_READ(sc, IWN_GPIO_CTL) &
-		    (IWN_GPIO_CLOCK | IWN_GPIO_SLEEP)) == IWN_GPIO_CLOCK)
-			break;
-		DELAY(10);
-	}
-	if (ntries == 1000)
-		device_printf(sc->sc_dev,
-		    "%s: could not lock memory\n", __func__);
-}
-
-/*
- * Release lock on NIC memory.
- */
-void
-iwn_mem_unlock(struct iwn_softc *sc)
-{
-	uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	IWN_WRITE(sc, IWN_GPIO_CTL, tmp & ~IWN_GPIO_MAC);
-}
-
-uint32_t
-iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
-{
-	IWN_WRITE(sc, IWN_READ_MEM_ADDR, IWN_MEM_4 | addr);
-	return IWN_READ(sc, IWN_READ_MEM_DATA);
-}
-
-void
-iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
-{
-	IWN_WRITE(sc, IWN_WRITE_MEM_ADDR, IWN_MEM_4 | addr);
-	IWN_WRITE(sc, IWN_WRITE_MEM_DATA, data);
-}
-
-void
-iwn_mem_write_region_4(struct iwn_softc *sc, uint32_t addr,
-    const uint32_t *data, int wlen)
-{
-	for (; wlen > 0; wlen--, data++, addr += 4)
-		iwn_mem_write(sc, addr, *data);
-}
-
-int
-iwn_eeprom_lock(struct iwn_softc *sc)
-{
-	uint32_t tmp;
-	int ntries;
-
-	tmp = IWN_READ(sc, IWN_HWCONFIG);
-	IWN_WRITE(sc, IWN_HWCONFIG, tmp | IWN_HW_EEPROM_LOCKED);
-
-	/* spin until we actually get the lock */
-	for (ntries = 0; ntries < 100; ntries++) {
-		if (IWN_READ(sc, IWN_HWCONFIG) & IWN_HW_EEPROM_LOCKED)
-			return 0;
-		DELAY(10);
-	}
-	return ETIMEDOUT;
-}
-
-void
-iwn_eeprom_unlock(struct iwn_softc *sc)
-{
-	uint32_t tmp = IWN_READ(sc, IWN_HWCONFIG);
-	IWN_WRITE(sc, IWN_HWCONFIG, tmp & ~IWN_HW_EEPROM_LOCKED);
-}
-
-/*
- * Read `len' bytes from the EEPROM.  We access the EEPROM through the MAC
- * instead of using the traditional bit-bang method.
- */
-int
-iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int len)
-{
-	uint8_t *out = data;
-	uint32_t val;
-	int ntries, tmp;
-
-	iwn_mem_lock(sc);
-	for (; len > 0; len -= 2, addr++) {
-		IWN_WRITE(sc, IWN_EEPROM_CTL, addr << 2);
-		tmp = IWN_READ(sc, IWN_EEPROM_CTL);	
-		IWN_WRITE(sc, IWN_EEPROM_CTL, tmp & ~IWN_EEPROM_MSK );
-
-		for (ntries = 0; ntries < 10; ntries++) {
-			if ((val = IWN_READ(sc, IWN_EEPROM_CTL)) &
-			    IWN_EEPROM_READY)
-				break;
-			DELAY(5);
-		}
-		if (ntries == 10) {
-			device_printf(sc->sc_dev,"could not read EEPROM\n");
-			return ETIMEDOUT;
-		}
-		*out++ = val >> 16;
-		if (len > 1)
-			*out++ = val >> 24;
-	}
-	iwn_mem_unlock(sc);
-
-	return 0;
-}
-
-/*
- * The firmware boot code is small and is intended to be copied directly into
- * the NIC internal memory.
- */
-int
-iwn_transfer_microcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
-{
-	int ntries;
-
-	size /= sizeof (uint32_t);
-
-	iwn_mem_lock(sc);
-
-	/* copy microcode image into NIC memory */
-	iwn_mem_write_region_4(sc, IWN_MEM_UCODE_BASE,
-	    (const uint32_t *)ucode, size);
-
-	iwn_mem_write(sc, IWN_MEM_UCODE_SRC, 0);
-	iwn_mem_write(sc, IWN_MEM_UCODE_DST, IWN_FW_TEXT);
-	iwn_mem_write(sc, IWN_MEM_UCODE_SIZE, size);
-
-	/* run microcode */
-	iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_RUN);
-
-	/* wait for transfer to complete */
-	for (ntries = 0; ntries < 1000; ntries++) {
-		if (!(iwn_mem_read(sc, IWN_MEM_UCODE_CTL) & IWN_UC_RUN))
-			break;
-		DELAY(10);
-	}
-	if (ntries == 1000) {
-		iwn_mem_unlock(sc);
-		device_printf(sc->sc_dev,
-		    "%s: could not load boot firmware\n", __func__);
-		return ETIMEDOUT;
-	}
-	iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_ENABLE);
-
-	iwn_mem_unlock(sc);
-
-	return 0;
-}
-
-int
-iwn_load_firmware(struct iwn_softc *sc)
-{
-	int error;
-
-	KASSERT(sc->fw_fp == NULL, ("firmware already loaded"));
-
-	IWN_UNLOCK(sc);
-	/* load firmware image from disk */
-	sc->fw_fp = firmware_get("iwnfw");
-	if (sc->fw_fp == NULL) {
-		device_printf(sc->sc_dev,
-		    "%s: could not load firmare image \"iwnfw\"\n", __func__);
-		error = EINVAL;
-	} else
-		error = 0;
-	IWN_LOCK(sc);
-	return error;
-}
-
-int
-iwn_transfer_firmware(struct iwn_softc *sc)
-{
-	struct iwn_dma_info *dma = &sc->fw_dma;
-	const struct iwn_firmware_hdr *hdr;
-	const uint8_t *init_text, *init_data, *main_text, *main_data;
-	const uint8_t *boot_text;
-	uint32_t init_textsz, init_datasz, main_textsz, main_datasz;
-	uint32_t boot_textsz;
-	int error = 0;
-	const struct firmware *fp = sc->fw_fp;
-
-	/* extract firmware header information */
-	if (fp->datasize < sizeof (struct iwn_firmware_hdr)) {
-		device_printf(sc->sc_dev,
-		    "%s: truncated firmware header: %zu bytes, expecting %zu\n",
-		    __func__, fp->datasize, sizeof (struct iwn_firmware_hdr));
-		error = EINVAL;
-		goto fail;
-	}
-	hdr = (const struct iwn_firmware_hdr *)fp->data;
-	main_textsz = le32toh(hdr->main_textsz);
-	main_datasz = le32toh(hdr->main_datasz);
-	init_textsz = le32toh(hdr->init_textsz);
-	init_datasz = le32toh(hdr->init_datasz);
-	boot_textsz = le32toh(hdr->boot_textsz);
-
-	/* sanity-check firmware segments sizes */
-	if (main_textsz > IWN_FW_MAIN_TEXT_MAXSZ ||
-	    main_datasz > IWN_FW_MAIN_DATA_MAXSZ ||
-	    init_textsz > IWN_FW_INIT_TEXT_MAXSZ ||
-	    init_datasz > IWN_FW_INIT_DATA_MAXSZ ||
-	    boot_textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
-	    (boot_textsz & 3) != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: invalid firmware header, main [%d,%d], init [%d,%d] "
-		    "boot %d\n", __func__, main_textsz, main_datasz,
-		    init_textsz, init_datasz, boot_textsz);
-		error = EINVAL;
-		goto fail;
-	}
-
-	/* check that all firmware segments are present */
-	if (fp->datasize < sizeof (struct iwn_firmware_hdr) + main_textsz +
-	    main_datasz + init_textsz + init_datasz + boot_textsz) {
-		device_printf(sc->sc_dev, "%s: firmware file too short: "
-		    "%zu bytes, main [%d, %d], init [%d,%d] boot %d\n",
-		    __func__, fp->datasize, main_textsz, main_datasz,
-		    init_textsz, init_datasz, boot_textsz);
-		error = EINVAL;
-		goto fail;
-	}
-
-	/* get pointers to firmware segments */
-	main_text = (const uint8_t *)(hdr + 1);
-	main_data = main_text + main_textsz;
-	init_text = main_data + main_datasz;
-	init_data = init_text + init_textsz;
-	boot_text = init_data + init_datasz;
-
-	/* copy initialization images into pre-allocated DMA-safe memory */
-	memcpy(dma->vaddr, init_data, init_datasz);
-	memcpy(dma->vaddr + IWN_FW_INIT_DATA_MAXSZ, init_text, init_textsz);
-
-	/* tell adapter where to find initialization images */
-	iwn_mem_lock(sc);
-	iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
-	iwn_mem_write(sc, IWN_MEM_DATA_SIZE, init_datasz);
-	iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
-	    (dma->paddr + IWN_FW_INIT_DATA_MAXSZ) >> 4);
-	iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, init_textsz);
-	iwn_mem_unlock(sc);
-
-	/* load firmware boot code */
-	error = iwn_transfer_microcode(sc, boot_text, boot_textsz);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not load boot firmware, error %d\n",
-		    __func__, error);
-		goto fail;
-	}
-
-	/* now press "execute" ;-) */
-	IWN_WRITE(sc, IWN_RESET, 0);
-
-	/* wait at most one second for first alive notification */
-	error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
-	if (error != 0) {
-		/* this isn't what was supposed to happen.. */
-		device_printf(sc->sc_dev,
-		    "%s: timeout waiting for first alive notice, error %d\n",
-		    __func__, error);
-		goto fail;
-	}
-
-	/* copy runtime images into pre-allocated DMA-safe memory */
-	memcpy(dma->vaddr, main_data, main_datasz);
-	memcpy(dma->vaddr + IWN_FW_MAIN_DATA_MAXSZ, main_text, main_textsz);
-
-	/* tell adapter where to find runtime images */
-	iwn_mem_lock(sc);
-	iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
-	iwn_mem_write(sc, IWN_MEM_DATA_SIZE, main_datasz);
-	iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
-	    (dma->paddr + IWN_FW_MAIN_DATA_MAXSZ) >> 4);
-	iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, IWN_FW_UPDATED | main_textsz);
-	iwn_mem_unlock(sc);
-
-	/* wait at most one second for second alive notification */
-	error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
-	if (error != 0) {
-		/* this isn't what was supposed to happen.. */
-		device_printf(sc->sc_dev,
-		   "%s: timeout waiting for second alive notice, error %d\n",
-		   __func__, error);
-		goto fail;
-	}
-	return 0;
-fail:
-	return error;
-}
-
-void
-iwn_unload_firmware(struct iwn_softc *sc)
-{
-        if (sc->fw_fp != NULL) {
-                firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
-                sc->fw_fp = NULL;
-        }
+	/* Save RX statistics, they will be used on MPDU_RX_DONE. */
+	memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
+	sc->last_rx_valid = 1;
 }
 
 static void
@@ -1339,18 +1774,6 @@ iwn_calib_reset(struct iwn_softc *sc)
 	sc->calib_cnt = 60;		/* do calibration every 60s */
 }
 
-void
-iwn_ampdu_rx_start(struct iwn_softc *sc, struct iwn_rx_desc *desc)
-{
-	struct iwn_rx_stat *stat;
-
-	DPRINTF(sc, IWN_DEBUG_RECV, "%s\n", "received AMPDU stats");
-	/* save Rx statistics, they will be used on IWN_AMPDU_RX_DONE */
-	stat = (struct iwn_rx_stat *)(desc + 1);
-	memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
-	sc->last_rx_valid = 1;
-}
-
 static __inline int
 maprate(int iwnrate)
 {
@@ -1375,25 +1798,29 @@ maprate(int iwnrate)
 	return 0;
 }
 
+/*
+ * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
+ * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
+ */
 void
-iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     struct iwn_rx_data *data)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct iwn_rx_ring *ring = &sc->rxq;
 	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
-	struct mbuf *m, *mnew;
+	struct mbuf *m, *m1;
 	struct iwn_rx_stat *stat;
 	caddr_t head;
-	uint32_t *tail;
-	int8_t rssi, nf;
-	int len, error;
 	bus_addr_t paddr;
+	uint32_t flags;
+	int error, len, rssi, nf;
 
-	if (desc->type == IWN_AMPDU_RX_DONE) {
-		/* check for prior AMPDU_RX_START */
+	if (desc->type == IWN_MPDU_RX_DONE) {
+		/* Check for prior RX_PHY notification. */
 		if (!sc->last_rx_valid) {
 			DPRINTF(sc, IWN_DEBUG_ANY,
 			    "%s: missing AMPDU_RX_START\n", __func__);
@@ -1412,24 +1839,26 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 		ifp->if_ierrors++;
 		return;
 	}
-	if (desc->type == IWN_AMPDU_RX_DONE) {
-		struct iwn_rx_ampdu *ampdu = (struct iwn_rx_ampdu *)(desc + 1);
-		head = (caddr_t)(ampdu + 1);
-		len = le16toh(ampdu->len);
+	if (desc->type == IWN_MPDU_RX_DONE) {
+		struct iwn_rx_mpdu *mpdu = (struct iwn_rx_mpdu *)(desc + 1);
+		head = (caddr_t)(mpdu + 1);
+		len = le16toh(mpdu->len);
 	} else {
 		head = (caddr_t)(stat + 1) + stat->cfg_phy_len;
 		len = le16toh(stat->len);
 	}
 
-	/* discard Rx frames with bad CRC early */
-	tail = (uint32_t *)(head + len);
-	if ((le32toh(*tail) & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
+	flags = le32toh(*(uint32_t *)(head + len));
+
+	/* Discard frames with a bad FCS early. */
+	if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
 		DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
-		    __func__, le32toh(*tail));
+		    __func__, flags);
 		ifp->if_ierrors++;
 		return;
 	}
-	if (len < sizeof (struct ieee80211_frame)) {
+	/* Discard frames that are too short. */
+	if (len < sizeof (*wh)) {
 		DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
 		    __func__, len);
 		ifp->if_ierrors++;
@@ -1437,41 +1866,40 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	}
 
 	/* XXX don't need mbuf, just dma buffer */
-	mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
-	if (mnew == NULL) {
+	m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
+	if (m1 == NULL) {
 		DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
 		    __func__);
 		ifp->if_ierrors++;
 		return;
 	}
-	error = bus_dmamap_load(ring->data_dmat, data->map,
-	    mtod(mnew, caddr_t), MJUMPAGESIZE,
+	error = bus_dmamap_load(ring->desc_dma.tag, data->map,
+	    mtod(m1, caddr_t), MJUMPAGESIZE,
 	    iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 	if (error != 0 && error != EFBIG) {
 		device_printf(sc->sc_dev,
 		    "%s: bus_dmamap_load failed, error %d\n", __func__, error);
-		m_freem(mnew);
+		m_freem(m1);
 		ifp->if_ierrors++;
 		return;
 	}
-	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
 
-	/* finalize mbuf and swap in new one */
 	m = data->m;
+	data->m = m1;
+	/* Update RX descriptor. */
+	ring->desc[ring->cur] = htole32(paddr >> 8);
+	bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_PREWRITE);
+
+	/* Finalize mbuf. */
 	m->m_pkthdr.rcvif = ifp;
 	m->m_data = head;
 	m->m_pkthdr.len = m->m_len = len;
 
-	data->m = mnew;
-	/* update Rx descriptor */
-	ring->desc[ring->cur] = htole32(paddr >> 8);
+	rssi = hal->get_rssi(sc, stat);
 
-	rssi = iwn_get_rssi(sc, stat);
-
-	/* grab a reference to the source node */
+	/* Grab a reference to the source node. */
 	wh = mtod(m, struct ieee80211_frame *);
 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
-
 	nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
 	    (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
 
@@ -1480,7 +1908,7 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 
 		tap->wr_tsft = htole64(stat->tstamp);
 		tap->wr_flags = 0;
-		if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
+		if (stat->flags & htole16(IWN_RXON_SHPREAMBLE))
 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 		tap->wr_rate = maprate(stat->rate);
 		tap->wr_dbm_antsignal = rssi;
@@ -1489,9 +1917,10 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 
 	IWN_UNLOCK(sc);
 
-	/* send the frame to the 802.11 layer */
+	/* Send the frame to the 802.11 layer. */
 	if (ni != NULL) {
 		(void) ieee80211_input(ni, m, rssi - nf, nf);
+		/* Node is no longer needed. */
 		ieee80211_free_node(ni);
 	} else
 		(void) ieee80211_input_all(ic, m, rssi - nf, nf);
@@ -1499,93 +1928,172 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	IWN_LOCK(sc);
 }
 
+/*
+ * Process a CALIBRATION_RESULT notification sent by the initialization
+ * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
+ */
 void
-iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc)
+iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
 {
+	struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
+	int len, idx = -1;
+
+	/* Runtime firmware should not send such a notification. */
+	if (!(sc->sc_flags & IWN_FLAG_FIRST_BOOT))
+		return;
+
+	len = (le32toh(desc->len) & 0x3fff) - 4;
+
+	switch (calib->code) {
+	case IWN5000_PHY_CALIB_DC:
+		if (sc->hw_type == IWN_HW_REV_TYPE_5150)
+			idx = 0;
+		break;
+	case IWN5000_PHY_CALIB_LO:
+		idx = 1;
+		break;
+	case IWN5000_PHY_CALIB_TX_IQ:
+		idx = 2;
+		break;
+	case IWN5000_PHY_CALIB_TX_IQ_PERD:
+		if (sc->hw_type != IWN_HW_REV_TYPE_5150)
+			idx = 3;
+		break;
+	case IWN5000_PHY_CALIB_BASE_BAND:
+		idx = 4;
+		break;
+	}
+	if (idx == -1)	/* Ignore other results. */
+		return;
+
+	/* Save calibration result. */
+	if (sc->calibcmd[idx].buf != NULL)
+		free(sc->calibcmd[idx].buf, M_DEVBUF);
+	sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT);
+	if (sc->calibcmd[idx].buf == NULL) {
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+		    "not enough memory for calibration result %d\n",
+		    calib->code);
+		return;
+	}
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+	    "saving calibration result code=%d len=%d\n", calib->code, len);
+	sc->calibcmd[idx].len = len;
+	memcpy(sc->calibcmd[idx].buf, calib, len);
+}
+
+/*
+ * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
+ * The latter is sent by the firmware after each received beacon.
+ */
+void
+iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 	struct iwn_calib_state *calib = &sc->calib;
 	struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
+	int temp;
 
-	/* beacon stats are meaningful only when associated and not scanning */
+	/* Beacon stats are meaningful only when associated and not scanning. */
 	if (vap->iv_state != IEEE80211_S_RUN ||
 	    (ic->ic_flags & IEEE80211_F_SCAN))
 		return;
 
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
-	iwn_calib_reset(sc);
+	iwn_calib_reset(sc);	/* Reset TX power calibration timeout. */
 
-	/* test if temperature has changed */
+	/* Test if temperature has changed. */
 	if (stats->general.temp != sc->rawtemp) {
-		int temp;
-
+		/* Convert "raw" temperature to degC. */
 		sc->rawtemp = stats->general.temp;
-		temp = iwn_get_temperature(sc);
+		temp = hal->get_temperature(sc);
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
 		    __func__, temp);
 
-		/* update Tx power if need be */
-		iwn_power_calibration(sc, temp);
+		/* Update TX power if need be (4965AGN only.) */
+		if (sc->hw_type == IWN_HW_REV_TYPE_4965)
+			iwn4965_power_calibration(sc, temp);
 	}
 
 	if (desc->type != IWN_BEACON_STATISTICS)
-		return;	/* reply to a statistics request */
+		return;	/* Reply to a statistics request. */
 
 	sc->noise = iwn_get_noise(&stats->rx.general);
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: noise %d\n", __func__, sc->noise);
 
-	/* test that RSSI and noise are present in stats report */
-	if (stats->rx.general.flags != htole32(1)) {
+	/* Test that RSSI and noise are present in stats report. */
+	if (le32toh(stats->rx.general.flags) != 1) {
 		DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
 		    "received statistics without RSSI");
 		return;
 	}
 
 	if (calib->state == IWN_CALIB_STATE_ASSOC)
-		iwn_compute_differential_gain(sc, &stats->rx.general);
+		iwn_collect_noise(sc, &stats->rx.general);
 	else if (calib->state == IWN_CALIB_STATE_RUN)
 		iwn_tune_sensitivity(sc, &stats->rx);
 }
 
+/*
+ * Process a TX_DONE firmware notification.  Unfortunately, the 4965AGN
+ * and 5000 adapters have different incompatible TX status formats.
+ */
 void
-iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
+iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
+{
+	struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
+
+	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
+	    "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
+	    __func__, desc->qid, desc->idx, stat->retrycnt,
+	    stat->killcnt, stat->rate, le16toh(stat->duration),
+	    le32toh(stat->status));
+
+	iwn_tx_done(sc, desc, stat->retrycnt, le32toh(stat->status) & 0xff);
+}
+
+void
+iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
+{
+	struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
+
+	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
+	    "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
+	    __func__, desc->qid, desc->idx, stat->retrycnt,
+	    stat->killcnt, stat->rate, le16toh(stat->duration),
+	    le32toh(stat->status));
+
+	/* Reset TX scheduler slot. */
+	iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
+
+	iwn_tx_done(sc, desc, stat->retrycnt, le16toh(stat->status) & 0xff);
+}
+
+/*
+ * Adapter-independent backend for TX_DONE firmware notifications.
+ */
+void
+iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int retrycnt,
+    uint8_t status)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
 	struct iwn_tx_data *data = &ring->data[desc->idx];
-	struct iwn_tx_stat *stat = (struct iwn_tx_stat *)(desc + 1);
-	struct iwn_node *wn = IWN_NODE(data->ni);
 	struct mbuf *m;
 	struct ieee80211_node *ni;
-	uint32_t status;
 
 	KASSERT(data->ni != NULL, ("no node"));
 
-	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
-	    "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
-	    __func__, desc->qid, desc->idx, stat->ntries,
-	    stat->nkill, stat->rate, le16toh(stat->duration),
-	    le32toh(stat->status));
-
-	/*
-	 * Update rate control statistics for the node.
-	 */
-	status = le32toh(stat->status) & 0xff;
-	if (status & 0x80) {
-		DPRINTF(sc, IWN_DEBUG_ANY, "%s: status 0x%x\n",
-		    __func__, le32toh(stat->status));
-		ifp->if_oerrors++;
-		ieee80211_amrr_tx_complete(&wn->amn,
-		    IEEE80211_AMRR_FAILURE, stat->ntries);
-	} else {
-		ieee80211_amrr_tx_complete(&wn->amn,
-		    IEEE80211_AMRR_SUCCESS, stat->ntries);
-	}
-
-	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
-	bus_dmamap_unload(ring->data_dmat, data->map);
-
+	/* Unmap and free mbuf. */
+	bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(ring->desc_dma.tag, data->map);
 	m = data->m, data->m = NULL;
 	ni = data->ni, data->ni = NULL;
 
@@ -1614,34 +2122,45 @@ iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 	m_freem(m);
 	ieee80211_free_node(ni);
 
-	ring->queued--;
-
 	sc->sc_tx_timer = 0;
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	iwn_start_locked(ifp);
+	if (--ring->queued < IWN_TX_RING_LOMARK) {
+		sc->qfullmsk &= ~(1 << ring->qid);
+		if (sc->qfullmsk == 0 &&
+		    (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
+			printf("hier :(\n");
+			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+			iwn_start_locked(ifp);
+		}
+	}
 }
 
+/*
+ * Process a "command done" firmware notification.  This is where we wakeup
+ * processes waiting for a synchronous command completion.
+ */
 void
-iwn_cmd_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
+iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 {
 	struct iwn_tx_ring *ring = &sc->txq[4];
 	struct iwn_tx_data *data;
 
 	if ((desc->qid & 0xf) != 4)
-		return;	/* not a command ack */
+		return;	/* Not a command ack. */
 
 	data = &ring->data[desc->idx];
 
-	/* if the command was mapped in a mbuf, free it */
+	/* If the command was mapped in an mbuf, free it. */
 	if (data->m != NULL) {
-		bus_dmamap_unload(ring->data_dmat, data->map);
+		bus_dmamap_unload(ring->desc_dma.tag, data->map);
 		m_freem(data->m);
 		data->m = NULL;
 	}
-
 	wakeup(&ring->cmd[desc->idx]);
 }
 
+/*
+ * Process an INT_FH_RX or INT_SW_RX interrupt.
+ */
 void
 iwn_notif_intr(struct iwn_softc *sc)
 {
@@ -1650,41 +2169,50 @@ iwn_notif_intr(struct iwn_softc *sc)
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 	uint16_t hw;
 
-	hw = le16toh(sc->shared->closed_count) & 0xfff;
+	bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
+	    BUS_DMASYNC_POSTREAD);
+
+	hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
 	while (sc->rxq.cur != hw) {
 		struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
-		struct iwn_rx_desc *desc = (void *)data->m->m_ext.ext_buf;
+		struct iwn_rx_desc *desc;
+
+		bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+		    BUS_DMASYNC_PREWRITE);
+		desc = mtod(data->m, struct iwn_rx_desc *);
 
 		DPRINTF(sc, IWN_DEBUG_RECV,
 		    "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
-		    __func__, desc->qid, desc->idx, desc->flags,
+		    __func__, desc->qid /*& 0xf*/, desc->idx, desc->flags,
 		    desc->type, iwn_intr_str(desc->type),
 		    le16toh(desc->len));
 
-		if (!(desc->qid & 0x80))	/* reply to a command */
-			iwn_cmd_intr(sc, desc);
+		if (!(desc->qid & 0x80))	/* Reply to a command. */
+			iwn_cmd_done(sc, desc);
 
 		switch (desc->type) {
-		case IWN_RX_DONE:
-		case IWN_AMPDU_RX_DONE:
-			iwn_rx_intr(sc, desc, data);
+		case IWN_RX_PHY:
+			iwn_rx_phy(sc, desc, data);
 			break;
 
-		case IWN_AMPDU_RX_START:
-			iwn_ampdu_rx_start(sc, desc);
+		case IWN_RX_DONE:		/* 4965AGN only. */
+		case IWN_MPDU_RX_DONE:
+			/* An 802.11 frame has been received. */
+			iwn_rx_done(sc, desc, data);
 			break;
 
 		case IWN_TX_DONE:
-			/* a 802.11 frame has been transmitted */
-			iwn_tx_intr(sc, desc);
+			/* An 802.11 frame has been transmitted. */
+			sc->sc_hal->tx_done(sc, desc, data);
 			break;
 
 		case IWN_RX_STATISTICS:
 		case IWN_BEACON_STATISTICS:
-			iwn_rx_statistics(sc, desc);
+			iwn_rx_statistics(sc, desc, data);
 			break;
 
-		case IWN_BEACON_MISSED: {
+		case IWN_BEACON_MISSED:
+		{
 			struct iwn_beacon_missed *miss =
 			    (struct iwn_beacon_missed *)(desc + 1);
 			int misses = le32toh(miss->consecutive);
@@ -1692,9 +2220,11 @@ iwn_notif_intr(struct iwn_softc *sc)
 			/* XXX not sure why we're notified w/ zero */
 			if (misses == 0)
 				break;
+
 			DPRINTF(sc, IWN_DEBUG_STATE,
 			    "%s: beacons missed %d/%d\n", __func__,
 			    misses, le32toh(miss->total));
+
 			/*
 			 * If more than 5 consecutive beacons are missed,
 			 * reinitialize the sensitivity state machine.
@@ -1705,11 +2235,13 @@ iwn_notif_intr(struct iwn_softc *sc)
 				ieee80211_beacon_miss(ic);
 			break;
 		}
-		case IWN_UC_READY: {
+		case IWN_UC_READY:
+		{
 			struct iwn_ucode_info *uc =
 			    (struct iwn_ucode_info *)(desc + 1);
 
-			/* the microcontroller is ready */
+			/* The microcontroller is ready. */
+
 			DPRINTF(sc, IWN_DEBUG_RESET,
 			    "microcode alive notification version=%d.%d "
 			    "subtype=%x alive=%x\n", uc->major, uc->minor,
@@ -1717,16 +2249,19 @@ iwn_notif_intr(struct iwn_softc *sc)
 
 			if (le32toh(uc->valid) != 1) {
 				device_printf(sc->sc_dev,
-				"microcontroller initialization failed");
+				    "microcontroller initialization failed");
 				break;
 			}
 			if (uc->subtype == IWN_UCODE_INIT) {
-				/* save microcontroller's report */
+				/* Save microcontroller's report. */
 				memcpy(&sc->ucode_info, uc, sizeof (*uc));
 			}
+			/* Save the address of the error log in SRAM. */
+			sc->errptr = le32toh(uc->errptr);
 			break;
 		}
-		case IWN_STATE_CHANGED: {
+		case IWN_STATE_CHANGED:
+		{
 			uint32_t *status = (uint32_t *)(desc + 1);
 
 			/*
@@ -1734,11 +2269,13 @@ iwn_notif_intr(struct iwn_softc *sc)
 			 * noted. However, we handle this in iwn_intr as we
 			 * get both the enable/disble intr.
 			 */
+
 			DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
 			    le32toh(*status));
 			break;
 		}
-		case IWN_START_SCAN: {
+		case IWN_START_SCAN:
+		{
 			struct iwn_start_scan *scan =
 			    (struct iwn_start_scan *)(desc + 1);
 
@@ -1747,7 +2284,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			    __func__, scan->chan, le32toh(scan->status));
 			break;
 		}
-		case IWN_STOP_SCAN: {
+		case IWN_STOP_SCAN:
+		{
 			struct iwn_stop_scan *scan =
 			    (struct iwn_stop_scan *)(desc + 1);
 
@@ -1758,43 +2296,125 @@ iwn_notif_intr(struct iwn_softc *sc)
 			ieee80211_scan_next(vap);
 			break;
 		}
+		case IWN5000_CALIBRATION_RESULT:
+			iwn5000_rx_calib_results(sc, desc, data);
+			break;
+
+		case IWN5000_CALIBRATION_DONE:
+			wakeup(sc);
+			break;
 		}
+
 		sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
 	}
 
-	/* tell the firmware what we have processed */
+	/* Tell the firmware what we have processed. */
 	hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
-	IWN_WRITE(sc, IWN_RX_WIDX, hw & ~7);
+	IWN_WRITE(sc, IWN_FH_RX_WPTR, hw & ~7);
 }
 
-static void
+/*
+ * Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
+ * from power-down sleep mode.
+ */
+void
+iwn_wakeup_intr(struct iwn_softc *sc)
+{
+	int qid;
+
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: ucode wakeup from power-down sleep\n",
+	    __func__);
+
+	/* Wakeup RX and TX rings. */
+	IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
+	for (qid = 0; qid < 6; qid++) {
+		struct iwn_tx_ring *ring = &sc->txq[qid];
+		IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
+	}
+}
+
+void
 iwn_rftoggle_intr(struct iwn_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
+	uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
 
 	IWN_LOCK_ASSERT(sc);
 
 	device_printf(sc->sc_dev, "RF switch: radio %s\n",
-	    (tmp & IWN_GPIO_RF_ENABLED) ? "enabled" : "disabled");
-	if (tmp & IWN_GPIO_RF_ENABLED)
+	    (tmp & IWN_GP_CNTRL_RFKILL) ? "enabled" : "disabled");
+	if (tmp & IWN_GP_CNTRL_RFKILL)
 		ieee80211_runtask(ic, &sc->sc_radioon_task);
 	else
 		ieee80211_runtask(ic, &sc->sc_radiooff_task);
 }
 
-static void
-iwn_error_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
+/*
+ * Dump the error log of the firmware when a firmware panic occurs.  Although
+ * we can't debug the firmware because it is neither open source nor free, it
+ * can help us to identify certain classes of problems.
+ */
+void
+iwn_fatal_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
 {
+#define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	struct iwn_fw_dump dump;
+	int i;
 
 	IWN_LOCK_ASSERT(sc);
 
-	device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
-	    r1, IWN_INTR_BITS, r2);
+	/* Check that the error log address is valid. */
+	if (sc->errptr < IWN_FW_DATA_BASE ||
+	    sc->errptr + sizeof (dump) >
+	    IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
+		printf("%s: bad firmware error log address 0x%08x\n",
+		    __func__, sc->errptr);
+		return;
+	}
+	if (iwn_nic_lock(sc) != 0) {
+		printf("%s: could not read firmware error log\n",
+		    __func__);
+		return;
+	}
+	/* Read firmware error log from SRAM. */
+	iwn_mem_read_region_4(sc, sc->errptr, (uint32_t *)&dump,
+	    sizeof (dump) / sizeof (uint32_t));
+	iwn_nic_unlock(sc);
+
+	if (dump.valid == 0) {
+		printf("%s: firmware error log is empty\n",
+		    __func__);
+		return;
+	}
+	printf("firmware error log:\n");
+	printf("  error type      = \"%s\" (0x%08X)\n",
+	    (dump.id < nitems(iwn_fw_errmsg)) ?
+		iwn_fw_errmsg[dump.id] : "UNKNOWN",
+	    dump.id);
+	printf("  program counter = 0x%08X\n", dump.pc);
+	printf("  source line     = 0x%08X\n", dump.src_line);
+	printf("  error data      = 0x%08X%08X\n",
+	    dump.error_data[0], dump.error_data[1]);
+	printf("  branch link     = 0x%08X%08X\n",
+	    dump.branch_link[0], dump.branch_link[1]);
+	printf("  interrupt link  = 0x%08X%08X\n",
+	    dump.interrupt_link[0], dump.interrupt_link[1]);
+	printf("  time            = %u\n", dump.time[0]);
+
+	/* Dump driver status (TX and RX rings) while we're here. */
+	printf("driver status:\n");
+	for (i = 0; i < hal->ntxqs; i++) {
+		struct iwn_tx_ring *ring = &sc->txq[i];
+		printf("  tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
+		    i, ring->qid, ring->cur, ring->queued);
+	}
+	printf("  rx ring: cur=%d\n", sc->rxq.cur);
+
 	if (vap != NULL)
 		ieee80211_cancel_scan(vap);
 	ieee80211_runtask(ic, &sc->sc_reinit_task);
@@ -1804,114 +2424,155 @@ void
 iwn_intr(void *arg)
 {
 	struct iwn_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
 	uint32_t r1, r2;
 
 	IWN_LOCK(sc);
 
-	/* disable interrupts */
+	/* Disable interrupts. */
 	IWN_WRITE(sc, IWN_MASK, 0);
 
-	r1 = IWN_READ(sc, IWN_INTR);
-	r2 = IWN_READ(sc, IWN_INTR_STATUS);
-
-	if (r1 == 0 && r2 == 0) {
-		IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
-		goto done;	/* not for us */
-	}
-
-	if (r1 == 0xffffffff)
-		goto done;	/* hardware gone */
-
-	/* ack interrupts */
-	IWN_WRITE(sc, IWN_INTR, r1);
-	IWN_WRITE(sc, IWN_INTR_STATUS, r2);
+	r1 = IWN_READ(sc, IWN_INT);
+	r2 = IWN_READ(sc, IWN_FH_INT);
 
 	DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
 
-	if (r1 & IWN_RF_TOGGLED)
+	if (r1 == 0 && r2 == 0) {
+		if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+			IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
+		goto done;	/* Interrupt not for us. */
+	}
+	if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
+		goto done;	/* Hardware gone! */
+
+	/* Acknowledge interrupts. */
+	IWN_WRITE(sc, IWN_INT, r1);
+	IWN_WRITE(sc, IWN_FH_INT, r2);
+
+	DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
+
+	if (r1 & IWN_INT_RF_TOGGLED) {
 		iwn_rftoggle_intr(sc);
-	if (r1 & IWN_CT_REACHED)
-		device_printf(sc->sc_dev, "critical temperature reached!\n");
-	if (r1 & (IWN_SW_ERROR | IWN_HW_ERROR)) {
-		iwn_error_intr(sc, r1, r2);
+	}
+	if (r1 & IWN_INT_CT_REACHED) {
+		device_printf(sc->sc_dev, "%s: critical temperature reached!\n",
+		    __func__);
+		/* XXX Reduce TX power? */
+	}
+	if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
+		iwn_fatal_intr(sc, r1, r2);
 		goto done;
 	}
-	if ((r1 & (IWN_RX_INTR | IWN_SW_RX_INTR)) || (r2 & IWN_RX_STATUS_INTR))
+	if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) ||
+	    (r2 & IWN_FH_INT_RX))
 		iwn_notif_intr(sc);
-	if (r1 & IWN_ALIVE_INTR)
-		wakeup(sc);
 
-	/* re-enable interrupts */
-	IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
+	if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX))
+		wakeup(sc);	/* FH DMA transfer completed. */
+
+	if (r1 & IWN_INT_ALIVE)
+		wakeup(sc);	/* Firmware is alive. */
+
+	if (r1 & IWN_INT_WAKEUP)
+		iwn_wakeup_intr(sc);
+
+	/* Re-enable interrupts. */
+	IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
+
 done:
 	IWN_UNLOCK(sc);
 }
 
-uint8_t
-iwn_plcp_signal(int rate)
+/*
+ * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
+ * 5000 adapters use a slightly different format.)
+ */
+void
+iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
+    uint16_t len)
 {
-	switch (rate) {
-	/* CCK rates (returned values are device-dependent) */
-	case 2:		return 10;
-	case 4:		return 20;
-	case 11:	return 55;
-	case 22:	return 110;
+	uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
 
-	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
-	/* R1-R4, (u)ral is R4-R1 */
-	case 12:	return 0xd;
-	case 18:	return 0xf;
-	case 24:	return 0x5;
-	case 36:	return 0x7;
-	case 48:	return 0x9;
-	case 72:	return 0xb;
-	case 96:	return 0x1;
-	case 108:	return 0x3;
-	case 120:	return 0x3;
-	}
-	/* unknown rate (should not get there) */
-	return 0;
+	*w = htole16(len + 8);
+	if (idx < IWN4965_SCHEDSZ)
+		*(w + IWN_TX_RING_COUNT) = *w;
 }
 
-/* determine if a given rate is CCK or OFDM */
-#define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
+void
+iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
+    uint16_t len)
+{
+	uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
+
+	*w = htole16(id << 12 | (len + 8));
+	if (idx < IWN_SCHED_WINSZ)
+		*(w + IWN_TX_RING_COUNT) = *w;
+}
+
+void
+iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
+{
+	uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
+
+	*w = (*w & htole16(0xf000)) | htole16(1);
+	if (idx < IWN_SCHED_WINSZ)
+		*(w + IWN_TX_RING_COUNT) = *w;
+}
+
+/* Determine if a given rate is CCK or OFDM. */
+#define IWN_RATE_IS_OFDM(rate)	((rate) >= 12 && (rate) != 22)
+
+static const struct iwn_rate *
+iwn_plcp_signal(int rate) {
+	int i;
+
+	for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
+		if (rate == iwn_rates[i].rate)
+			return &iwn_rates[i];
+	}
+
+	return &iwn_rates[0];
+}
 
 int
-iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
+iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
     struct iwn_tx_ring *ring)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
+	const struct ieee80211_txparam *tp;
+	const struct iwn_rate *rinfo;
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
-	struct ifnet *ifp = sc->sc_ifp;
-	const struct ieee80211_txparam *tp;
+	struct iwn_node *wn = (void *)ni;
 	struct iwn_tx_desc *desc;
 	struct iwn_tx_data *data;
 	struct iwn_tx_cmd *cmd;
 	struct iwn_cmd_data *tx;
 	struct ieee80211_frame *wh;
-	struct ieee80211_key *k;
-	bus_addr_t paddr;
-	uint32_t flags;
-	uint16_t timeout;
-	uint8_t type;
-	u_int hdrlen;
+	struct ieee80211_key *k = NULL;
 	struct mbuf *mnew;
-	int rate, error, pad, nsegs, i, ismcast, id;
+	bus_addr_t paddr;
 	bus_dma_segment_t segs[IWN_MAX_SCATTER];
+	uint32_t flags;
+	u_int hdrlen;
+	int totlen, error, pad, nsegs, i, rate;
+	uint8_t type, txant;
 
 	IWN_LOCK_ASSERT(sc);
 
-	wh = mtod(m0, struct ieee80211_frame *);
-	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
-	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
+	wh = mtod(m, struct ieee80211_frame *);
 	hdrlen = ieee80211_anyhdrsize(wh);
+	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 
-	/* pick a tx rate */
+	desc = &ring->desc[ring->cur];
+	data = &ring->data[ring->cur];
+
+	/* Choose a TX rate index. */
 	/* XXX ni_chan */
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 	if (type == IEEE80211_FC0_TYPE_MGT)
 		rate = tp->mgmtrate;
-	else if (ismcast)
+	else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
 		rate = tp->mcastrate;
 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 		rate = tp->ucastrate;
@@ -1919,17 +2580,19 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 		(void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
 		rate = ni->ni_txrate;
 	}
+	rinfo = iwn_plcp_signal(rate);
 
+	/* Encrypt the frame if need be. */
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-		k = ieee80211_crypto_encap(ni, m0);
+		k = ieee80211_crypto_encap(ni, m);
 		if (k == NULL) {
-			m_freem(m0);
+			m_freem(m);
 			return ENOBUFS;
 		}
-		/* packet header may have moved, reset our local pointer */
-		wh = mtod(m0, struct ieee80211_frame *);
-	} else
-		k = NULL;
+		/* Packet header may have moved, reset our local pointer. */
+		wh = mtod(m, struct ieee80211_frame *);
+	}
+	totlen = m->m_pkthdr.len;
 
 	if (ieee80211_radiotap_active_vap(vap)) {
 		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1939,58 +2602,217 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 		if (k != NULL)
 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 
-		ieee80211_radiotap_tx(vap, m0);
+		ieee80211_radiotap_tx(vap, m);
 	}
 
-	flags = IWN_TX_AUTO_SEQ;
-	/* XXX honor ACM */
-	if (!ismcast)
+	/* Prepare TX firmware command. */
+	cmd = &ring->cmd[ring->cur];
+	cmd->code = IWN_CMD_TX_DATA;
+	cmd->flags = 0;
+	cmd->qid = ring->qid;
+	cmd->idx = ring->cur;
+
+	tx = (struct iwn_cmd_data *)cmd->data;
+	/* NB: No need to clear tx, all fields are reinitialized here. */
+	tx->scratch = 0;	/* clear "scratch" area */
+
+	flags = 0;
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
 		flags |= IWN_TX_NEED_ACK;
+	if ((wh->i_fc[0] &
+	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
+	    (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
+		flags |= IWN_TX_IMM_BA;		/* Cannot happen yet. */
 
-	if (ismcast || type != IEEE80211_FC0_TYPE_DATA)
-		id = IWN_ID_BROADCAST;
-	else
-		id = IWN_ID_BSS;
+	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
+		flags |= IWN_TX_MORE_FRAG;	/* Cannot happen yet. */
 
-	/* check if RTS/CTS or CTS-to-self protection must be used */
-	if (!ismcast) {
-		/* multicast frames are not sent at OFDM rates in 802.11b/g */
-		if (m0->m_pkthdr.len+IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
-			flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
+	/* Check if frame must be protected using RTS/CTS or CTS-to-self. */
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		/* NB: Group frames are sent using CCK in 802.11b/g. */
+		if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
+			flags |= IWN_TX_NEED_RTS;
 		} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
 		    IWN_RATE_IS_OFDM(rate)) {
 			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
-				flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
+				flags |= IWN_TX_NEED_CTS;
 			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
-				flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
+				flags |= IWN_TX_NEED_RTS;
 		}
-	}
+		if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
+			if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
+				/* 5000 autoselects RTS/CTS or CTS-to-self. */
+				flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
+				flags |= IWN_TX_NEED_PROTECTION;
+			} else
+				flags |= IWN_TX_FULL_TXOP;
+		}
+	} else
+
+	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
+	    type != IEEE80211_FC0_TYPE_DATA)
+		tx->id = hal->broadcast_id;
+	else
+		tx->id = wn->id;
 
 	if (type == IEEE80211_FC0_TYPE_MGT) {
 		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 
-		/* tell h/w to set timestamp in probe responses */
+		/* Tell HW to set timestamp in probe responses. */
 		if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 			flags |= IWN_TX_INSERT_TSTAMP;
 
 		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
 		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
-			timeout = htole16(3);
+			tx->timeout = htole16(3);
 		else
-			timeout = htole16(2);
+			tx->timeout = htole16(2);
 	} else
-		timeout = htole16(0);
+		tx->timeout = htole16(0);
 
 	if (hdrlen & 3) {
-		/* first segment's length must be a multiple of 4 */
+		/* First segment's length must be a multiple of 4. */
 		flags |= IWN_TX_NEED_PADDING;
 		pad = 4 - (hdrlen & 3);
 	} else
 		pad = 0;
 
+	tx->len = htole16(totlen);
+	tx->tid = 0;
+	tx->rts_ntries = 60;		/* XXX? */
+	tx->data_ntries = 15;		/* XXX? */
+	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
+	tx->plcp = rinfo->plcp;
+	tx->rflags = rinfo->flags;
+	if (tx->id == hal->broadcast_id) {
+		/* XXX Alternate between antenna A and B? */
+		txant = IWN_LSB(sc->txantmsk);
+		tx->rflags |= IWN_RFLAG_ANT(txant);
+	} else
+		flags |= IWN_TX_LINKQ;
+
+	/* Set physical address of "scratch area". */
+	paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
+	tx->loaddr = htole32(IWN_LOADDR(paddr));
+	tx->hiaddr = IWN_HIADDR(paddr);
+
+	/* Copy 802.11 header in TX command. */
+	memcpy((uint8_t *)(tx + 1), wh, hdrlen);
+
+	/* Trim 802.11 header. */
+	m_adj(m, hdrlen);
+	tx->security = 0;
+	tx->flags = htole32(flags);
+
+	error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag, data->map, m, segs,
+	    &nsegs, BUS_DMA_NOWAIT);
+	if (error != 0) {
+		if (error == EFBIG) {
+			/* too many fragments, linearize */
+			mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
+			if (mnew == NULL) {
+				IWN_UNLOCK(sc);
+				device_printf(sc->sc_dev,
+				    "%s: could not defrag mbuf\n", __func__);
+				m_freem(m);
+				return ENOBUFS;
+			}
+			m = mnew;
+			error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag,
+			    data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+		}
+		if (error != 0) {
+			IWN_UNLOCK(sc);
+			device_printf(sc->sc_dev,
+			    "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
+			     __func__, error);
+			m_freem(m);
+			return error;
+		}
+	}
+
+	data->m = m;
+	data->ni = ni;
+
+	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
+	    __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
+
+	/* Fill TX descriptor. */
+	desc->nsegs = 1 + nsegs;
+	/* First DMA segment is used by the TX command. */
+	desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
+	desc->segs[0].len  = htole16(IWN_HIADDR(paddr) |
+	    (4 + sizeof (*tx) + hdrlen + pad) << 4);
+	/* Other DMA segments are for data payload. */
+	for (i = 1; i <= nsegs; i++) {
+		desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
+		desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
+		    segs[i - 1].ds_len << 4);
+	}
+
+	bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->cmd_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+
+	/* Update TX scheduler. */
+	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+
+	/* Kick TX ring. */
+	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
+
+	/* Mark TX ring as full if we reach a certain threshold. */
+	if (++ring->queued > IWN_TX_RING_HIMARK)
+		sc->qfullmsk |= 1 << ring->qid;
+
+	return 0;
+}
+
+static int
+iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni, struct iwn_tx_ring *ring,
+    const struct ieee80211_bpf_params *params)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	const struct iwn_rate *rinfo;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211vap *vap = ni->ni_vap;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct iwn_tx_cmd *cmd;
+	struct iwn_cmd_data *tx;
+	struct ieee80211_frame *wh;
+	struct iwn_tx_desc *desc;
+	struct iwn_tx_data *data;
+	struct mbuf *mnew;
+	bus_addr_t paddr;
+	bus_dma_segment_t segs[IWN_MAX_SCATTER];
+	uint32_t flags;
+	u_int hdrlen;
+	int totlen, error, pad, nsegs, i, rate;
+	uint8_t type, txant;
+
+	IWN_LOCK_ASSERT(sc);
+
+	wh = mtod(m0, struct ieee80211_frame *);
+	hdrlen = ieee80211_anyhdrsize(wh);
+	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+
 	desc = &ring->desc[ring->cur];
 	data = &ring->data[ring->cur];
 
+	/* Choose a TX rate index. */
+	rate = params->ibp_rate0;
+	if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
+		/* XXX fall back to mcast/mgmt rate? */
+		m_freem(m0);
+		return EINVAL;
+	}
+	rinfo = iwn_plcp_signal(rate);
+
+	totlen = m0->m_pkthdr.len;
+
 	cmd = &ring->cmd[ring->cur];
 	cmd->code = IWN_CMD_TX_DATA;
 	cmd->flags = 0;
@@ -1999,41 +2821,89 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 
 	tx = (struct iwn_cmd_data *)cmd->data;
 	/* NB: no need to bzero tx, all fields are reinitialized here */
-	tx->id = id;
-	tx->flags = htole32(flags);
-	tx->len = htole16(m0->m_pkthdr.len);
-	tx->rate = iwn_plcp_signal(rate);
-	tx->rts_ntries = 60;		/* XXX? */
-	tx->data_ntries = 15;		/* XXX? */
-	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
-	tx->timeout = timeout;
+	tx->scratch = 0;	/* clear "scratch" area */
 
-	if (k != NULL) {
-		/* XXX fill in */;
+	flags = 0;
+	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
+		flags |= IWN_TX_NEED_ACK;
+	if (params->ibp_flags & IEEE80211_BPF_RTS) {
+		if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
+			/* 5000 autoselects RTS/CTS or CTS-to-self. */
+			flags &= ~IWN_TX_NEED_RTS;
+			flags |= IWN_TX_NEED_PROTECTION;
+		} else
+			flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
+	}
+	if (params->ibp_flags & IEEE80211_BPF_CTS) {
+		if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
+			/* 5000 autoselects RTS/CTS or CTS-to-self. */
+			flags &= ~IWN_TX_NEED_CTS;
+			flags |= IWN_TX_NEED_PROTECTION;
+		} else
+			flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
+	}
+	if (type == IEEE80211_FC0_TYPE_MGT) {
+		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+		if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
+			flags |= IWN_TX_INSERT_TSTAMP;
+
+		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
+		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
+			tx->timeout = htole16(3);
+		else
+			tx->timeout = htole16(2);
 	} else
-		tx->security = 0;
+		tx->timeout = htole16(0);
 
-	/* XXX alternate between Ant A and Ant B ? */
-	tx->rflags = IWN_RFLAG_ANT_B;
-	if (tx->id == IWN_ID_BROADCAST) {
-		tx->ridx = IWN_MAX_TX_RETRIES - 1;
-		if (!IWN_RATE_IS_OFDM(rate))
-			tx->rflags |= IWN_RFLAG_CCK;
-	} else {
-		tx->ridx = 0;
-		/* tell adapter to ignore rflags */
-		tx->flags |= htole32(IWN_TX_USE_NODE_RATE);
+	if (hdrlen & 3) {
+		/* First segment's length must be a multiple of 4. */
+		flags |= IWN_TX_NEED_PADDING;
+		pad = 4 - (hdrlen & 3);
+	} else
+		pad = 0;
+
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
-	/* copy and trim IEEE802.11 header */
-	memcpy((uint8_t *)(tx + 1), wh, hdrlen);
-	m_adj(m0, hdrlen);
+	tx->len = htole16(totlen);
+	tx->tid = 0;
+	tx->id = hal->broadcast_id;
+	tx->rts_ntries = params->ibp_try1;
+	tx->data_ntries = params->ibp_try0;
+	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
+	tx->plcp = rinfo->plcp;
+	tx->rflags = rinfo->flags;
+	if (tx->id == hal->broadcast_id) {
+		txant = IWN_LSB(sc->txantmsk);
+		tx->rflags |= IWN_RFLAG_ANT(txant);
+	} else {
+		flags |= IWN_TX_LINKQ;	/* enable MRR */
+	}
+	/* Set physical address of "scratch area". */
+	paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
+	tx->loaddr = htole32(IWN_LOADDR(paddr));
+	tx->hiaddr = IWN_HIADDR(paddr);
 
-	error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
+	/* Copy 802.11 header in TX command. */
+	memcpy((uint8_t *)(tx + 1), wh, hdrlen);
+
+	/* Trim 802.11 header. */
+	m_adj(m0, hdrlen);
+	tx->security = 0;
+	tx->flags = htole32(flags);
+
+	error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag, data->map, m0, segs,
 	    &nsegs, BUS_DMA_NOWAIT);
 	if (error != 0) {
 		if (error == EFBIG) {
-			/* too many fragments, linearize */
+			/* Too many fragments, linearize. */
 			mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
 			if (mnew == NULL) {
 				IWN_UNLOCK(sc);
@@ -2043,7 +2913,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 				return ENOBUFS;
 			}
 			m0 = mnew;
-			error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
+			error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag,
 			    data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
 		}
 		if (error != 0) {
@@ -2062,37 +2932,77 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
 	    __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
 
-	paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
-	tx->loaddr = htole32(paddr + 4 +
-	    offsetof(struct iwn_cmd_data, ntries));
-	tx->hiaddr = 0;	/* limit to 32-bit physical addresses */
-
-	/* first scatter/gather segment is used by the tx data command */
-	IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
-	IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
+	/* Fill TX descriptor. */
+	desc->nsegs = 1 + nsegs;
+	/* First DMA segment is used by the TX command. */
+	desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
+	desc->segs[0].len  = htole16(IWN_HIADDR(paddr) |
+	    (4 + sizeof (*tx) + hdrlen + pad) << 4);
+	/* Other DMA segments are for data payload. */
 	for (i = 1; i <= nsegs; i++) {
-		IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
-		     segs[i - 1].ds_len);
+		desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
+		desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
+		    segs[i - 1].ds_len << 4);
 	}
-	sc->shared->len[ring->qid][ring->cur] =
-	    htole16(hdrlen + m0->m_pkthdr.len + 8);
 
-	if (ring->cur < IWN_TX_WINDOW)
-		sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
-			htole16(hdrlen + m0->m_pkthdr.len + 8);
+	/* Update TX scheduler. */
+	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 
-	ring->queued++;
-
-	/* kick Tx ring */
+	/* Kick TX ring. */
 	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 
-	ifp->if_opackets++;
-	sc->sc_tx_timer = 5;
+	/* Mark TX ring as full if we reach a certain threshold. */
+	if (++ring->queued > IWN_TX_RING_HIMARK)
+		sc->qfullmsk |= 1 << ring->qid;
 
 	return 0;
 }
 
+static int
+iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+	const struct ieee80211_bpf_params *params)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct iwn_softc *sc = ifp->if_softc;
+	struct iwn_tx_ring *txq;
+	int error = 0;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		ieee80211_free_node(ni);
+		m_freem(m);
+		return ENETDOWN;
+	}
+
+	IWN_LOCK(sc);
+	if (params == NULL)
+		txq = &sc->txq[M_WME_GETAC(m)];
+	else
+		txq = &sc->txq[params->ibp_pri & 3];
+
+	if (params == NULL) {
+		/*
+		 * Legacy path; interpret frame contents to decide
+		 * precisely how to send the frame.
+		 */
+		error = iwn_tx_data(sc, m, ni, txq);
+	} else {
+		/*
+		 * Caller supplied explicit parameters to use in
+		 * sending the frame.
+		 */
+		error = iwn_tx_data_raw(sc, m, ni, txq, params);
+	}
+	if (error != 0) {
+		/* NB: m is reclaimed on tx failure */
+		ieee80211_free_node(ni);
+		ifp->if_oerrors++;
+	}
+	IWN_UNLOCK(sc);
+	return error;
+}
+
 void
 iwn_start(struct ifnet *ifp)
 {
@@ -2115,252 +3025,25 @@ iwn_start_locked(struct ifnet *ifp)
 	IWN_LOCK_ASSERT(sc);
 
 	for (;;) {
+		if (sc->qfullmsk != 0) {
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
 			break;
 		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 		pri = M_WME_GETAC(m);
 		txq = &sc->txq[pri];
-		if (txq->queued >= IWN_TX_RING_COUNT - 8) {
-			/* XXX not right */
-			/* ring is nearly full, stop flow */
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-		}
 		if (iwn_tx_data(sc, m, ni, txq) != 0) {
 			ifp->if_oerrors++;
 			ieee80211_free_node(ni);
 			break;
 		}
+		sc->sc_tx_timer = 5;
 	}
 }
 
-static int
-iwn_tx_handoff(struct iwn_softc *sc,
-	struct iwn_tx_ring *ring,
-	struct iwn_tx_cmd *cmd,
-	struct iwn_cmd_data *tx,
-	struct ieee80211_node *ni,
-	struct mbuf *m0, u_int hdrlen, int pad)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct iwn_tx_desc *desc;
-	struct iwn_tx_data *data;
-	bus_addr_t paddr;
-	struct mbuf *mnew;
-	int error, nsegs, i;
-	bus_dma_segment_t segs[IWN_MAX_SCATTER];
-
-	/* copy and trim IEEE802.11 header */
-	memcpy((uint8_t *)(tx + 1), mtod(m0, uint8_t *), hdrlen);
-	m_adj(m0, hdrlen);
-
-	desc = &ring->desc[ring->cur];
-	data = &ring->data[ring->cur];
-
-	error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
-	    &nsegs, BUS_DMA_NOWAIT);
-	if (error != 0) {
-		if (error == EFBIG) {
-			/* too many fragments, linearize */
-			mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
-			if (mnew == NULL) {
-				IWN_UNLOCK(sc);
-				device_printf(sc->sc_dev,
-				    "%s: could not defrag mbuf\n", __func__);
-				m_freem(m0);
-				return ENOBUFS;
-			}
-			m0 = mnew;
-			error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
-			    data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
-		}
-		if (error != 0) {
-			IWN_UNLOCK(sc);
-			device_printf(sc->sc_dev,
-			    "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
-			     __func__, error);
-			m_freem(m0);
-			return error;
-		}
-	}
-
-	data->m = m0;
-	data->ni = ni;
-
-	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
-	    __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
-
-	paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
-	tx->loaddr = htole32(paddr + 4 +
-	    offsetof(struct iwn_cmd_data, ntries));
-	tx->hiaddr = 0;	/* limit to 32-bit physical addresses */
-
-	/* first scatter/gather segment is used by the tx data command */
-	IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
-	IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
-	for (i = 1; i <= nsegs; i++) {
-		IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
-		     segs[i - 1].ds_len);
-	}
-	sc->shared->len[ring->qid][ring->cur] =
-	    htole16(hdrlen + m0->m_pkthdr.len + 8);
-
-	if (ring->cur < IWN_TX_WINDOW)
-		sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
-			htole16(hdrlen + m0->m_pkthdr.len + 8);
-
-	ring->queued++;
-
-	/* kick Tx ring */
-	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
-
-	ifp->if_opackets++;
-	sc->sc_tx_timer = 5;
-
-	return 0;
-}
-
-static int
-iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
-    struct ieee80211_node *ni, struct iwn_tx_ring *ring,
-    const struct ieee80211_bpf_params *params)
-{
-	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211com *ic = ni->ni_ic;
-	struct iwn_tx_cmd *cmd;
-	struct iwn_cmd_data *tx;
-	struct ieee80211_frame *wh;
-	uint32_t flags;
-	uint8_t type, subtype;
-	u_int hdrlen;
-	int rate, pad;
-
-	IWN_LOCK_ASSERT(sc);
-
-	wh = mtod(m0, struct ieee80211_frame *);
-	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
-	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-	hdrlen = ieee80211_anyhdrsize(wh);
-
-	flags = IWN_TX_AUTO_SEQ;
-	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
-		flags |= IWN_TX_NEED_ACK;
-	if (params->ibp_flags & IEEE80211_BPF_RTS)
-		flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
-	if (params->ibp_flags & IEEE80211_BPF_CTS)
-		flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
-	if (type == IEEE80211_FC0_TYPE_MGT &&
-	    subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
-		/* tell h/w to set timestamp in probe responses */
-		flags |= IWN_TX_INSERT_TSTAMP;
-	}
-	if (hdrlen & 3) {
-		/* first segment's length must be a multiple of 4 */
-		flags |= IWN_TX_NEED_PADDING;
-		pad = 4 - (hdrlen & 3);
-	} else
-		pad = 0;
-
-	/* pick a tx rate */
-	rate = params->ibp_rate0;
-	if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
-		/* XXX fall back to mcast/mgmt rate? */
-		m_freem(m0);
-		return EINVAL;
-	}
-
-	if (ieee80211_radiotap_active_vap(vap)) {
-		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
-
-		tap->wt_flags = 0;
-		tap->wt_rate = rate;
-
-		ieee80211_radiotap_tx(vap, m0);
-	}
-
-	cmd = &ring->cmd[ring->cur];
-	cmd->code = IWN_CMD_TX_DATA;
-	cmd->flags = 0;
-	cmd->qid = ring->qid;
-	cmd->idx = ring->cur;
-
-	tx = (struct iwn_cmd_data *)cmd->data;
-	/* NB: no need to bzero tx, all fields are reinitialized here */
-	tx->id = IWN_ID_BROADCAST;
-	tx->flags = htole32(flags);
-	tx->len = htole16(m0->m_pkthdr.len);
-	tx->rate = iwn_plcp_signal(rate);
-	tx->rts_ntries = params->ibp_try1;		/* XXX? */
-	tx->data_ntries = params->ibp_try0;
-	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
-	/* XXX use try count? */
-	if (type == IEEE80211_FC0_TYPE_MGT) {
-		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
-		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
-			tx->timeout = htole16(3);
-		else
-			tx->timeout = htole16(2);
-	} else
-		tx->timeout = htole16(0);
-	tx->security = 0;
-	/* XXX alternate between Ant A and Ant B ? */
-	tx->rflags = IWN_RFLAG_ANT_B;	/* XXX params->ibp_pri >> 2 */
-	tx->ridx = IWN_MAX_TX_RETRIES - 1;
-	if (!IWN_RATE_IS_OFDM(rate))
-		tx->rflags |= IWN_RFLAG_CCK;
-
-	return iwn_tx_handoff(sc, ring, cmd, tx, ni, m0, hdrlen, pad);
-}
-
-static int
-iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
-	const struct ieee80211_bpf_params *params)
-{
-	struct ieee80211com *ic = ni->ni_ic;
-	struct ifnet *ifp = ic->ic_ifp;
-	struct iwn_softc *sc = ifp->if_softc;
-	struct iwn_tx_ring *txq;
-	int error;
-
-	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-		ieee80211_free_node(ni);
-		m_freem(m);
-		return ENETDOWN;
-	}
-
-	IWN_LOCK(sc);
-	if (params == NULL)
-		txq = &sc->txq[M_WME_GETAC(m)];
-	else
-		txq = &sc->txq[params->ibp_pri & 3];
-	if (txq->queued >= IWN_TX_RING_COUNT - 8) {
-		/* XXX not right */
-		/* ring is nearly full, stop flow */
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-	}
-	if (params == NULL) {
-		/*
-		 * Legacy path; interpret frame contents to decide
-		 * precisely how to send the frame.
-		 */
-		error = iwn_tx_data(sc, m, ni, txq);
-	} else {
-		/*
-		 * Caller supplied explicit parameters to use in
-		 * sending the frame.
-		 */
-		error = iwn_tx_data_raw(sc, m, ni, txq, params);
-	}
-	if (error != 0) {
-		/* NB: m is reclaimed on tx failure */
-		ieee80211_free_node(ni);
-		ifp->if_oerrors++;
-	}
-	IWN_UNLOCK(sc);
-	return error;
-}
-
 static void
 iwn_watchdog(struct iwn_softc *sc)
 {
@@ -2410,272 +3093,28 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 	return error;
 }
 
-void
-iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
-{
-	char domain[4];
-	uint16_t val;
-	int i, error;
-
-	if ((error = iwn_eeprom_lock(sc)) != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not lock EEPROM, error %d\n", __func__, error);
-		return;
-	}
-	/* read and print regulatory domain */
-	iwn_read_prom_data(sc, IWN_EEPROM_DOMAIN, domain, 4);
-	device_printf(sc->sc_dev,"Reg Domain: %.4s", domain);
-
-	/* read and print MAC address */
-	iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
-	printf(", address %6D\n", macaddr, ":");
-
-	/* read the list of authorized channels */
-	iwn_read_eeprom_channels(sc);
-
-	/* read maximum allowed Tx power for 2GHz and 5GHz bands */
-	iwn_read_prom_data(sc, IWN_EEPROM_MAXPOW, &val, 2);
-	sc->maxpwr2GHz = val & 0xff;
-	sc->maxpwr5GHz = val >> 8;
-	/* check that EEPROM values are correct */
-	if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
-		sc->maxpwr5GHz = 38;
-	if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
-		sc->maxpwr2GHz = 38;
-	DPRINTF(sc, IWN_DEBUG_RESET, "maxpwr 2GHz=%d 5GHz=%d\n",
-	    sc->maxpwr2GHz, sc->maxpwr5GHz);
-
-	/* read voltage at which samples were taken */
-	iwn_read_prom_data(sc, IWN_EEPROM_VOLTAGE, &val, 2);
-	sc->eeprom_voltage = (int16_t)le16toh(val);
-	DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
-	    sc->eeprom_voltage);
-
-	/* read power groups */
-	iwn_read_prom_data(sc, IWN_EEPROM_BANDS, sc->bands, sizeof sc->bands);
-#ifdef IWN_DEBUG
-	if (sc->sc_debug & IWN_DEBUG_ANY) {
-		for (i = 0; i < IWN_NBANDS; i++)
-			iwn_print_power_group(sc, i);
-	}
-#endif
-	iwn_eeprom_unlock(sc);
-}
-
-struct iwn_chan_band {
-	uint32_t	addr;	/* offset in EEPROM */
-	uint32_t	flags;	/* net80211 flags */
-	uint8_t		nchan;
-#define IWN_MAX_CHAN_PER_BAND	14
-	uint8_t		chan[IWN_MAX_CHAN_PER_BAND];
-};
-
-static void
-iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
-	struct ieee80211_channel *c;
-	int i, chan, flags;
-
-	iwn_read_prom_data(sc, band->addr, channels,
-	    band->nchan * sizeof (struct iwn_eeprom_chan));
-
-	for (i = 0; i < band->nchan; i++) {
-		if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
-			DPRINTF(sc, IWN_DEBUG_RESET,
-			    "skip chan %d flags 0x%x maxpwr %d\n",
-			    band->chan[i], channels[i].flags,
-			    channels[i].maxpwr);
-			continue;
-		}
-		chan = band->chan[i];
-
-		/* translate EEPROM flags to net80211 */
-		flags = 0;
-		if ((channels[i].flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
-			flags |= IEEE80211_CHAN_PASSIVE;
-		if ((channels[i].flags & IWN_EEPROM_CHAN_IBSS) == 0)
-			flags |= IEEE80211_CHAN_NOADHOC;
-		if (channels[i].flags & IWN_EEPROM_CHAN_RADAR) {
-			flags |= IEEE80211_CHAN_DFS;
-			/* XXX apparently IBSS may still be marked */
-			flags |= IEEE80211_CHAN_NOADHOC;
-		}
-
-		DPRINTF(sc, IWN_DEBUG_RESET,
-		    "add chan %d flags 0x%x maxpwr %d\n",
-		    chan, channels[i].flags, channels[i].maxpwr);
-
-		c = &ic->ic_channels[ic->ic_nchans++];
-		c->ic_ieee = chan;
-		c->ic_freq = ieee80211_ieee2mhz(chan, band->flags);
-		c->ic_maxregpower = channels[i].maxpwr;
-		c->ic_maxpower = 2*c->ic_maxregpower;
-		if (band->flags & IEEE80211_CHAN_2GHZ) {
-			/* G =>'s B is supported */
-			c->ic_flags = IEEE80211_CHAN_B | flags;
-
-			c = &ic->ic_channels[ic->ic_nchans++];
-			c[0] = c[-1];
-			c->ic_flags = IEEE80211_CHAN_G | flags;
-		} else {	/* 5GHz band */
-			c->ic_flags = IEEE80211_CHAN_A | flags;
-		}
-		/* XXX no constraints on using HT20 */
-		/* add HT20, HT40 added separately */
-		c = &ic->ic_channels[ic->ic_nchans++];
-		c[0] = c[-1];
-		c->ic_flags |= IEEE80211_CHAN_HT20;
-		/* XXX NARROW =>'s 1/2 and 1/4 width? */
-	}
-}
-
-static void
-iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
-	struct ieee80211_channel *c, *cent, *extc;
-	int i;
-
-	iwn_read_prom_data(sc, band->addr, channels,
-	    band->nchan * sizeof (struct iwn_eeprom_chan));
-
-	for (i = 0; i < band->nchan; i++) {
-		if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
-		    !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
-			DPRINTF(sc, IWN_DEBUG_RESET,
-			    "skip chan %d flags 0x%x maxpwr %d\n",
-			    band->chan[i], channels[i].flags,
-			    channels[i].maxpwr);
-			continue;
-		}
-		/*
-		 * Each entry defines an HT40 channel pair; find the
-		 * center channel, then the extension channel above.
-		 */
-		cent = ieee80211_find_channel_byieee(ic, band->chan[i],
-		    band->flags & ~IEEE80211_CHAN_HT);
-		if (cent == NULL) {	/* XXX shouldn't happen */
-			device_printf(sc->sc_dev,
-			    "%s: no entry for channel %d\n",
-			    __func__, band->chan[i]);
-			continue;
-		}
-		extc = ieee80211_find_channel(ic, cent->ic_freq+20,
-		    band->flags & ~IEEE80211_CHAN_HT);
-		if (extc == NULL) {
-			DPRINTF(sc, IWN_DEBUG_RESET,
-			    "skip chan %d, extension channel not found\n",
-			    band->chan[i]);
-			continue;
-		}
-
-		DPRINTF(sc, IWN_DEBUG_RESET,
-		    "add ht40 chan %d flags 0x%x maxpwr %d\n",
-		    band->chan[i], channels[i].flags, channels[i].maxpwr);
-
-		c = &ic->ic_channels[ic->ic_nchans++];
-		c[0] = cent[0];
-		c->ic_extieee = extc->ic_ieee;
-		c->ic_flags &= ~IEEE80211_CHAN_HT;
-		c->ic_flags |= IEEE80211_CHAN_HT40U;
-		c = &ic->ic_channels[ic->ic_nchans++];
-		c[0] = extc[0];
-		c->ic_extieee = cent->ic_ieee;
-		c->ic_flags &= ~IEEE80211_CHAN_HT;
-		c->ic_flags |= IEEE80211_CHAN_HT40D;
-	}
-}
-
-static void
-iwn_read_eeprom_channels(struct iwn_softc *sc)
-{
-#define	N(a)	(sizeof(a)/sizeof(a[0]))
-	static const struct iwn_chan_band iwn_bands[] = {
-	    { IWN_EEPROM_BAND1, IEEE80211_CHAN_G, 14,
-		{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
-	    { IWN_EEPROM_BAND2, IEEE80211_CHAN_A, 13,
-		{ 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
-	    { IWN_EEPROM_BAND3, IEEE80211_CHAN_A, 12,
-		{ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
-	    { IWN_EEPROM_BAND4, IEEE80211_CHAN_A, 11,
-		{ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
-	    { IWN_EEPROM_BAND5, IEEE80211_CHAN_A, 6,
-		{ 145, 149, 153, 157, 161, 165 } },
-	    { IWN_EEPROM_BAND6, IEEE80211_CHAN_G | IEEE80211_CHAN_HT40, 7,
-		{ 1, 2, 3, 4, 5, 6, 7 } },
-	    { IWN_EEPROM_BAND7, IEEE80211_CHAN_A | IEEE80211_CHAN_HT40, 11,
-		{ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
-	};
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	int i;
-
-	/* read the list of authorized channels */
-	for (i = 0; i < N(iwn_bands)-2; i++)
-		iwn_read_eeprom_band(sc, &iwn_bands[i]);
-	for (; i < N(iwn_bands); i++)
-		iwn_read_eeprom_ht40(sc, &iwn_bands[i]);
-	ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
-#undef N
-}
-
-#ifdef IWN_DEBUG
-void
-iwn_print_power_group(struct iwn_softc *sc, int i)
-{
-	struct iwn_eeprom_band *band = &sc->bands[i];
-	struct iwn_eeprom_chan_samples *chans = band->chans;
-	int j, c;
-
-	printf("===band %d===\n", i);
-	printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
-	printf("chan1 num=%d\n", chans[0].num);
-	for (c = 0; c < IWN_NTXCHAINS; c++) {
-		for (j = 0; j < IWN_NSAMPLES; j++) {
-			printf("chain %d, sample %d: temp=%d gain=%d "
-			    "power=%d pa_det=%d\n", c, j,
-			    chans[0].samples[c][j].temp,
-			    chans[0].samples[c][j].gain,
-			    chans[0].samples[c][j].power,
-			    chans[0].samples[c][j].pa_det);
-		}
-	}
-	printf("chan2 num=%d\n", chans[1].num);
-	for (c = 0; c < IWN_NTXCHAINS; c++) {
-		for (j = 0; j < IWN_NSAMPLES; j++) {
-			printf("chain %d, sample %d: temp=%d gain=%d "
-			    "power=%d pa_det=%d\n", c, j,
-			    chans[1].samples[c][j].temp,
-			    chans[1].samples[c][j].gain,
-			    chans[1].samples[c][j].power,
-			    chans[1].samples[c][j].pa_det);
-		}
-	}
-}
-#endif
-
 /*
  * Send a command to the firmware.
  */
 int
 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_tx_ring *ring = &sc->txq[4];
 	struct iwn_tx_desc *desc;
+	struct iwn_tx_data *data;
 	struct iwn_tx_cmd *cmd;
 	bus_addr_t paddr;
+	int totlen;
 
 	IWN_LOCK_ASSERT(sc);
 
 	KASSERT(size <= sizeof cmd->data, ("Command too big"));
 
 	desc = &ring->desc[ring->cur];
+	data = &ring->data[ring->cur];
 	cmd = &ring->cmd[ring->cur];
+	totlen = 4 + size;
 
 	cmd->code = code;
 	cmd->flags = 0;
@@ -2683,27 +3122,52 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 	cmd->idx = ring->cur;
 	memcpy(cmd->data, buf, size);
 
-	paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
+	paddr = data->cmd_paddr;
 
-	IWN_SET_DESC_NSEGS(desc, 1);
-	IWN_SET_DESC_SEG(desc, 0, paddr, 4 + size);
-	sc->shared->len[ring->qid][ring->cur] = htole16(8);
-	if (ring->cur < IWN_TX_WINDOW) {
-	    sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
-		htole16(8);
-	}
+	desc->nsegs = 1;
+	desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
+	desc->segs[0].len  = htole16(IWN_HIADDR(paddr) | totlen << 4);
 
 	DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
 	    __func__, iwn_intr_str(cmd->code), cmd->code,
 	    cmd->flags, cmd->qid, cmd->idx);
 
-	/* kick cmd ring */
+	/* Update TX scheduler. */
+	hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
+
+	/* Kick command ring. */
 	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 
 	return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
 }
 
+int
+iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
+{
+	struct iwn4965_node_info hnode;
+	caddr_t src, dst;
+
+	/*
+	 * We use the node structure for 5000 Series internally (it is
+	 * a superset of the one for 4965AGN). We thus copy the common
+	 * fields before sending the command.
+	 */
+	src = (caddr_t)node;
+	dst = (caddr_t)&hnode;
+	memcpy(dst, src, 48);
+	/* Skip TSC, RX MIC and TX MIC fields from ``src''. */
+	memcpy(dst + 48, src + 72, 20);
+	return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
+}
+
+int
+iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
+{
+	/* Direct mapping. */
+	return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
+}
+
 static const uint8_t iwn_ridx_to_plcp[] = {
 	10, 20, 55, 110, /* CCK */
 	0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
@@ -2728,99 +3192,90 @@ static const uint8_t iwn_prev_ridx[] = {
  */
 int
 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
-	const struct ieee80211_channel *c, int async)
+    const struct ieee80211_channel *c, int async)
 {
-	struct iwn_cmd_link_quality lq;
-	int i, ridx;
+	struct iwn_cmd_link_quality linkq;
+	int ridx, i;
+	uint8_t txant;
 
-	memset(&lq, 0, sizeof(lq));
-	lq.id = id;
-	if (IEEE80211_IS_CHAN_HT(c)) {
-		lq.mimo = 1;
-		lq.ssmask = 0x1;
-	} else
-		lq.ssmask = 0x2;
+	/* Use the first valid TX antenna. */
+	txant = IWN_LSB(sc->txantmsk);
+
+	memset(&linkq, 0, sizeof linkq);
+	linkq.id = id;
+	linkq.antmsk_1stream = txant;
+	linkq.antmsk_2stream = IWN_ANT_A | IWN_ANT_B;
+	linkq.ampdu_max = 64;
+	linkq.ampdu_threshold = 3;
+	linkq.ampdu_limit = htole16(4000);	/* 4ms */
+
+	if (IEEE80211_IS_CHAN_HT(c))
+		linkq.mimo = 1;
 
 	if (id == IWN_ID_BSS)
-		ridx = IWN_RATE_OFDM54;
+		ridx = IWN_RIDX_OFDM54;
 	else if (IEEE80211_IS_CHAN_A(c))
-		ridx = IWN_RATE_OFDM6;
+		ridx = IWN_RIDX_OFDM6;
 	else
-		ridx = IWN_RATE_CCK1;
+		ridx = IWN_RIDX_CCK1;
+
 	for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
-		/* XXX toggle antenna for retry patterns */
 		if (IEEE80211_IS_CHAN_HT40(c)) {
-			lq.table[i].rate = iwn_mimo_mcs_to_plcp[ridx]
-					 | IWN_RATE_MCS;
-			lq.table[i].rflags = IWN_RFLAG_HT
-					 | IWN_RFLAG_HT40
-					 | IWN_RFLAG_ANT_A;
+			linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx]
+					 | IWN_RIDX_MCS;
+			linkq.retry[i].rflags = IWN_RFLAG_HT
+					 | IWN_RFLAG_HT40;
 			/* XXX shortGI */
 		} else if (IEEE80211_IS_CHAN_HT(c)) {
-			lq.table[i].rate = iwn_siso_mcs_to_plcp[ridx]
-					 | IWN_RATE_MCS;
-			lq.table[i].rflags = IWN_RFLAG_HT
-					 | IWN_RFLAG_ANT_A;
+			linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx]
+					 | IWN_RIDX_MCS;
+			linkq.retry[i].rflags = IWN_RFLAG_HT;
 			/* XXX shortGI */
 		} else {
-			lq.table[i].rate = iwn_ridx_to_plcp[ridx];
-			if (ridx <= IWN_RATE_CCK11)
-				lq.table[i].rflags = IWN_RFLAG_CCK;
-			lq.table[i].rflags |= IWN_RFLAG_ANT_B;
+			linkq.retry[i].plcp = iwn_ridx_to_plcp[ridx];
+			if (ridx <= IWN_RIDX_CCK11)
+				linkq.retry[i].rflags = IWN_RFLAG_CCK;
 		}
+		linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
 		ridx = iwn_prev_ridx[ridx];
 	}
 
-	lq.dsmask = 0x3;
-	lq.ampdu_disable = 3;
-	lq.ampdu_limit = htole16(4000);
 #ifdef IWN_DEBUG
 	if (sc->sc_debug & IWN_DEBUG_STATE) {
 		printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
-		    __func__, id, lq.mimo, lq.ssmask);
+		    __func__, id, linkq.mimo, linkq.antmsk_1stream);
 		printf("%s:", __func__);
 		for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
-			printf(" %d:%x", lq.table[i].rate, lq.table[i].rflags);
+			printf(" %d:%x", linkq.retry[i].plcp,
+			    linkq.retry[i].rflags);
 		printf("\n");
 	}
 #endif
-	return iwn_cmd(sc, IWN_CMD_TX_LINK_QUALITY, &lq, sizeof(lq), async);
+	return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
 }
 
-#if 0
-
 /*
- * Install a pairwise key into the hardware.
+ * Broadcast node is used to send group-addressed and management frames.
  */
 int
-iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
-    const struct ieee80211_key *k)
+iwn_add_broadcast_node(struct iwn_softc *sc, const struct ieee80211_channel *c,
+    int async)
 {
-	struct iwn_softc *sc = ic->ic_softc;
+	const struct iwn_hal *hal = sc->sc_hal;
+	struct ifnet *ifp = sc->sc_ifp;
 	struct iwn_node_info node;
-
-	if (k->k_flags & IEEE80211_KEY_GROUP)
-		return 0;
+	int error;
 
 	memset(&node, 0, sizeof node);
+	IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
+	node.id = hal->broadcast_id;
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
+	error = hal->add_node(sc, &node, async);
+	if (error != 0)
+		return error;
 
-	switch (k->k_cipher) {
-	case IEEE80211_CIPHER_CCMP:
-		node.security = htole16(IWN_CIPHER_CCMP);
-		memcpy(node.key, k->k_key, k->k_len);
-		break;
-	default:
-		return 0;
-	}
-
-	node.id = IWN_ID_BSS;
-	IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
-	node.control = IWN_NODE_UPDATE;
-	node.flags = IWN_FLAG_SET_KEY;
-
-	return iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
+	return iwn_set_link_quality(sc, node.id, c, async);
 }
-#endif
 
 int
 iwn_wme_update(struct ieee80211com *ic)
@@ -2855,106 +3310,84 @@ iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
 {
 	struct iwn_cmd_led led;
 
+	/* Clear microcode LED ownership. */
+	IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
+
 	led.which = which;
-	led.unit = htole32(100000);	/* on/off in unit of 100ms */
+	led.unit = htole32(10000);	/* on/off in unit of 100ms */
 	led.off = off;
 	led.on = on;
-
-	(void) iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
+	(void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
 }
 
 /*
- * Set the critical temperature at which the firmware will automatically stop
- * the radio transmitter.
+ * Set the critical temperature at which the firmware will notify us.
  */
 int
 iwn_set_critical_temp(struct iwn_softc *sc)
 {
-	struct iwn_ucode_info *uc = &sc->ucode_info;
 	struct iwn_critical_temp crit;
-	uint32_t r1, r2, r3, temp;
 
-	r1 = le32toh(uc->temp[0].chan20MHz);
-	r2 = le32toh(uc->temp[1].chan20MHz);
-	r3 = le32toh(uc->temp[2].chan20MHz);
-	/* inverse function of iwn_get_temperature() */
-	temp = r2 + (IWN_CTOK(110) * (r3 - r1)) / 259;
-
-	IWN_WRITE(sc, IWN_UCODE_CLR, IWN_CTEMP_STOP_RF);
+	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
 
 	memset(&crit, 0, sizeof crit);
-	crit.tempR = htole32(temp);
-	DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n", temp);
+	crit.tempR = htole32(sc->critical_temp);
+	DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n",
+	    crit.tempR);
 	return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
 }
 
-void
-iwn_enable_tsf(struct iwn_softc *sc, struct ieee80211_node *ni)
+int
+iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
 {
-	struct iwn_cmd_tsf tsf;
+	struct iwn_cmd_timing cmd;
 	uint64_t val, mod;
 
-	memset(&tsf, 0, sizeof tsf);
-	memcpy(&tsf.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
-	tsf.bintval = htole16(ni->ni_intval);
-	tsf.lintval = htole16(10);
+	memset(&cmd, 0, sizeof cmd);
+	memcpy(&cmd.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
+	cmd.bintval = htole16(ni->ni_intval);
+	cmd.lintval = htole16(10);
 
-	/* XXX all wrong */
-	/* compute remaining time until next beacon */
+	/* Compute remaining time until next beacon. */
 	val = (uint64_t)ni->ni_intval * 1024;	/* msecs -> usecs */
-	DPRINTF(sc, IWN_DEBUG_ANY, "%s: val = %ju %s\n", __func__,
-	    val, val == 0 ? "correcting" : "");
-	if (val == 0)
-		val = 1;
-	mod = le64toh(tsf.tstamp) % val;
-	tsf.binitval = htole32((uint32_t)(val - mod));
+	mod = le64toh(cmd.tstamp) % val;
+	cmd.binitval = htole32((uint32_t)(val - mod));
 
-	DPRINTF(sc, IWN_DEBUG_RESET, "TSF bintval=%u tstamp=%ju, init=%u\n",
-	    ni->ni_intval, le64toh(tsf.tstamp), (uint32_t)(val - mod));
+	DPRINTF(sc, IWN_DEBUG_RESET, "timing bintval=%u tstamp=%ju, init=%u\n",
+	    ni->ni_intval, le64toh(cmd.tstamp), (uint32_t)(val - mod));
 
-	if (iwn_cmd(sc, IWN_CMD_TSF, &tsf, sizeof tsf, 1) != 0)
-		device_printf(sc->sc_dev,
-		    "%s: could not enable TSF\n", __func__);
+	return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
 }
 
 void
-iwn_power_calibration(struct iwn_softc *sc, int temp)
+iwn4965_power_calibration(struct iwn_softc *sc, int temp)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-#if 0
-	KASSERT(ic->ic_state == IEEE80211_S_RUN, ("not running"));
-#endif
+
+	/* Adjust TX power if need be (delta >= 3 degC.) */
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
 	    __func__, sc->temp, temp);
-
-	/* adjust Tx power if need be (delta >= 3ーC) */
-	if (abs(temp - sc->temp) < 3)
-		return;
-
-	sc->temp = temp;
-
-	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: set Tx power for channel %d\n",
-	    __func__, ieee80211_chan2ieee(ic, ic->ic_bsschan));
-	if (iwn_set_txpower(sc, ic->ic_bsschan, 1) != 0) {
-		/* just warn, too bad for the automatic calibration... */
-		device_printf(sc->sc_dev,
-		    "%s: could not adjust Tx power\n", __func__);
+	if (abs(temp - sc->temp) >= 3) {
+		/* Record temperature of last calibration. */
+		sc->temp = temp;
+		(void)iwn4965_set_txpower(sc, ic->ic_bsschan, 1);
 	}
 }
 
 /*
- * Set Tx power for a given channel (each rate has its own power settings).
+ * Set TX power for current channel (each rate has its own power settings).
  * This function takes into account the regulatory information from EEPROM,
  * the current temperature and the current voltage.
  */
 int
-iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
+iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
+    int async)
 {
-/* fixed-point arithmetic division using a n-bit fractional part */
+/* Fixed-point arithmetic division using a n-bit fractional part. */
 #define fdivround(a, b, n)	\
 	((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
-/* linear interpolation */
+/* Linear interpolation. */
 #define interpolate(x, x1, y1, x2, y2, n)	\
 	((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
 
@@ -2962,14 +3395,14 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct iwn_ucode_info *uc = &sc->ucode_info;
-	struct iwn_cmd_txpower cmd;
-	struct iwn_eeprom_chan_samples *chans;
-	const uint8_t *rf_gain, *dsp_gain;
+	struct iwn4965_cmd_txpower cmd;
+	struct iwn4965_eeprom_chan_samples *chans;
 	int32_t vdiff, tdiff;
 	int i, c, grp, maxpwr;
-	u_int chan;
+	const uint8_t *rf_gain, *dsp_gain;
+	uint8_t chan;
 
-	/* get channel number */
+	/* Get channel number. */
 	chan = ieee80211_chan2ieee(ic, ch);
 
 	memset(&cmd, 0, sizeof cmd);
@@ -2978,15 +3411,15 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 
 	if (IEEE80211_IS_CHAN_5GHZ(ch)) {
 		maxpwr   = sc->maxpwr5GHz;
-		rf_gain  = iwn_rf_gain_5ghz;
-		dsp_gain = iwn_dsp_gain_5ghz;
+		rf_gain  = iwn4965_rf_gain_5ghz;
+		dsp_gain = iwn4965_dsp_gain_5ghz;
 	} else {
 		maxpwr   = sc->maxpwr2GHz;
-		rf_gain  = iwn_rf_gain_2ghz;
-		dsp_gain = iwn_dsp_gain_2ghz;
+		rf_gain  = iwn4965_rf_gain_2ghz;
+		dsp_gain = iwn4965_dsp_gain_2ghz;
 	}
 
-	/* compute voltage compensation */
+	/* Compute voltage compensation. */
 	vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
 	if (vdiff > 0)
 		vdiff *= 2;
@@ -2996,7 +3429,7 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 	    "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
 	    __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
 
-	/* get channel's attenuation group */
+	/* Get channel's attenuation group. */
 	if (chan <= 20)		/* 1-20 */
 		grp = 4;
 	else if (chan <= 43)	/* 34-43 */
@@ -3010,16 +3443,18 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 	    "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
 
-	/* get channel's sub-band */
+	/* Get channel's sub-band. */
 	for (i = 0; i < IWN_NBANDS; i++)
 		if (sc->bands[i].lo != 0 &&
 		    sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
 			break;
+	if (i == IWN_NBANDS)	/* Can't happen in real-life. */
+		return EINVAL;
 	chans = sc->bands[i].chans;
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 	    "%s: chan %d sub-band=%d\n", __func__, chan, i);
 
-	for (c = 0; c < IWN_NTXCHAINS; c++) {
+	for (c = 0; c < 2; c++) {
 		uint8_t power, gain, temp;
 		int maxchpwr, pwr, ridx, idx;
 
@@ -3036,29 +3471,30 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 		    "%s: Tx chain %d: power=%d gain=%d temp=%d\n",
 		    __func__, c, power, gain, temp);
 
-		/* compute temperature compensation */
+		/* Compute temperature compensation. */
 		tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 		    "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
 		    __func__, tdiff, sc->temp, temp);
 
 		for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
-			maxchpwr = ch->ic_maxpower;
-			if ((ridx / 8) & 1) {
-				/* MIMO: decrease Tx power (-3dB) */
-				maxchpwr -= 6;
-			}
+			maxchpwr = sc->maxpwr[chan] * 2;
+			if ((ridx / 8) & 1)
+				maxchpwr -= 6;	/* MIMO 2T: -3dB */
 
-			pwr = maxpwr - 10;
+			pwr = maxpwr;
 
-			/* decrease power for highest OFDM rates */
-			if ((ridx % 8) == 5)		/* 48Mbit/s */
-				pwr -= 5;
-			else if ((ridx % 8) == 6)	/* 54Mbit/s */
-				pwr -= 7;
-			else if ((ridx % 8) == 7)	/* 60Mbit/s */
-				pwr -= 10;
+			/* Adjust TX power based on rate. */
+			if ((ridx % 8) == 5)
+				pwr -= 15;	/* OFDM48: -7.5dB */
+			else if ((ridx % 8) == 6)
+				pwr -= 17;	/* OFDM54: -8.5dB */
+			else if ((ridx % 8) == 7)
+				pwr -= 20;	/* OFDM60: -10dB */
+			else
+				pwr -= 10;	/* Others: -5dB */
 
+			/* Do not exceed channel's max TX power. */
 			if (pwr > maxchpwr)
 				pwr = maxchpwr;
 
@@ -3071,11 +3507,11 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 			if (ridx == IWN_RIDX_MAX)
 				idx += 5;	/* CCK */
 
-			/* make sure idx stays in a valid range */
+			/* Make sure idx stays in a valid range. */
 			if (idx < 0)
 				idx = 0;
-			else if (idx > IWN_MAX_PWR_INDEX)
-				idx = IWN_MAX_PWR_INDEX;
+			else if (idx > IWN4965_MAX_PWR_INDEX)
+				idx = IWN4965_MAX_PWR_INDEX;
 
 			DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 			    "%s: Tx chain %d, rate idx %d: power=%d\n",
@@ -3093,40 +3529,80 @@ iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 #undef fdivround
 }
 
-/*
- * Get the best (maximum) RSSI among the
- * connected antennas and convert to dBm.
- */
-int8_t
-iwn_get_rssi(struct iwn_softc *sc, const struct iwn_rx_stat *stat)
+int
+iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
+    int async)
 {
-	int mask, agc, rssi;
+	struct iwn5000_cmd_txpower cmd;
 
-	mask = (le16toh(stat->antenna) >> 4) & 0x7;
-	agc  = (le16toh(stat->agc) >> 7) & 0x7f;
+	/*
+	 * TX power calibration is handled automatically by the firmware
+	 * for 5000 Series.
+	 */
+	memset(&cmd, 0, sizeof cmd);
+	cmd.global_limit = 2 * IWN5000_TXPOWER_MAX_DBM;	/* 16 dBm */
+	cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
+	cmd.srv_limit = IWN5000_TXPOWER_AUTO;
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: setting TX power\n", __func__);
+	return iwn_cmd(sc, IWN_CMD_TXPOWER_DBM, &cmd, sizeof cmd, async);
+}
+
+/*
+ * Retrieve the maximum RSSI (in dBm) among receivers.
+ */
+int
+iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
+{
+	struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
+	uint8_t mask, agc;
+	int rssi;
+
+	mask = (le16toh(phy->antenna) >> 4) & 0x7;
+	agc  = (le16toh(phy->agc) >> 7) & 0x7f;
 
 	rssi = 0;
 #if 0
-	if (mask & (1 << 0))	/* Ant A */
-		rssi = max(rssi, stat->rssi[0]);
-	if (mask & (1 << 1))	/* Ant B */
-		rssi = max(rssi, stat->rssi[2]);
-	if (mask & (1 << 2))	/* Ant C */
-		rssi = max(rssi, stat->rssi[4]);
+	if (mask & IWN_ANT_A)	/* Ant A */
+		rssi = max(rssi, phy->rssi[0]);
+	if (mask & IWN_ATH_B)	/* Ant B */
+		rssi = max(rssi, phy->rssi[2]);
+	if (mask & IWN_ANT_C)	/* Ant C */
+		rssi = max(rssi, phy->rssi[4]);
 #else
-	rssi = max(rssi, stat->rssi[0]);
-	rssi = max(rssi, stat->rssi[2]);
-	rssi = max(rssi, stat->rssi[4]);
+	rssi = max(rssi, phy->rssi[0]);
+	rssi = max(rssi, phy->rssi[2]);
+	rssi = max(rssi, phy->rssi[4]);
 #endif
+
 	DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d "
 	    "result %d\n", __func__, agc, mask,
-	    stat->rssi[0], stat->rssi[2], stat->rssi[4],
+	    phy->rssi[0], phy->rssi[2], phy->rssi[4],
+	    rssi - agc - IWN_RSSI_TO_DBM);
+	return rssi - agc - IWN_RSSI_TO_DBM;
+}
+
+int
+iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
+{
+	struct iwn5000_rx_phystat *phy = (void *)stat->phybuf;
+	int rssi;
+	uint8_t agc;
+
+	agc = (le32toh(phy->agc) >> 9) & 0x7f;
+
+	rssi = MAX(le16toh(phy->rssi[0]) & 0xff,
+		   le16toh(phy->rssi[1]) & 0xff);
+	rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi);
+
+	DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d rssi %d %d %d "
+	    "result %d\n", __func__, agc,
+	    phy->rssi[0], phy->rssi[2], phy->rssi[4],
 	    rssi - agc - IWN_RSSI_TO_DBM);
 	return rssi - agc - IWN_RSSI_TO_DBM;
 }
 
 /*
- * Get the average noise among Rx antennas (in dBm).
+ * Retrieve the average noise (in dBm) among receivers.
  */
 int
 iwn_get_noise(const struct iwn_rx_general_stats *stats)
@@ -3135,21 +3611,20 @@ iwn_get_noise(const struct iwn_rx_general_stats *stats)
 
 	total = nbant = 0;
 	for (i = 0; i < 3; i++) {
-		noise = le32toh(stats->noise[i]) & 0xff;
-		if (noise != 0) {
-			total += noise;
-			nbant++;
-		}
+		if ((noise = le32toh(stats->noise[i]) & 0xff) == 0)
+			continue;
+		total += noise;
+		nbant++;
 	}
-	/* there should be at least one antenna but check anyway */
+	/* There should be at least one antenna but check anyway. */
 	return (nbant == 0) ? -127 : (total / nbant) - 107;
 }
 
 /*
- * Read temperature (in degC) from the on-board thermal sensor.
+ * Compute temperature (in degC) from last received statistics.
  */
 int
-iwn_get_temperature(struct iwn_softc *sc)
+iwn4965_get_temperature(struct iwn_softc *sc)
 {
 	struct iwn_ucode_info *uc = &sc->ucode_info;
 	int32_t r1, r2, r3, r4, temp;
@@ -3159,121 +3634,227 @@ iwn_get_temperature(struct iwn_softc *sc)
 	r3 = le32toh(uc->temp[2].chan20MHz);
 	r4 = le32toh(sc->rawtemp);
 
-	if (r1 == r3)	/* prevents division by 0 (should not happen) */
+	if (r1 == r3)	/* Prevents division by 0 (should not happen.) */
 		return 0;
 
-	/* sign-extend 23-bit R4 value to 32-bit */
+	/* Sign-extend 23-bit R4 value to 32-bit. */
 	r4 = (r4 << 8) >> 8;
-	/* compute temperature */
+	/* Compute temperature in Kelvin. */
 	temp = (259 * (r4 - r2)) / (r3 - r1);
 	temp = (temp * 97) / 100 + 8;
 
 	return IWN_KTOC(temp);
 }
 
+int
+iwn5000_get_temperature(struct iwn_softc *sc)
+{
+	/*
+	 * Temperature is not used by the driver for 5000 Series because
+	 * TX power calibration is handled by firmware.  We export it to
+	 * users through the sensor framework though.
+	 */
+	return le32toh(sc->rawtemp);
+}
+
 /*
  * Initialize sensitivity calibration state machine.
  */
 int
 iwn_init_sensitivity(struct iwn_softc *sc)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_calib_state *calib = &sc->calib;
-	struct iwn_phy_calib_cmd cmd;
+	uint32_t flags;
 	int error;
 
-	/* reset calibration state */
+	/* Reset calibration state machine. */
 	memset(calib, 0, sizeof (*calib));
 	calib->state = IWN_CALIB_STATE_INIT;
 	calib->cck_state = IWN_CCK_STATE_HIFA;
-	/* initial values taken from the reference driver */
-	calib->corr_ofdm_x1     = 105;
-	calib->corr_ofdm_mrc_x1 = 220;
-	calib->corr_ofdm_x4     =  90;
-	calib->corr_ofdm_mrc_x4 = 170;
-	calib->corr_cck_x4      = 125;
-	calib->corr_cck_mrc_x4  = 200;
-	calib->energy_cck       = 100;
+	/* Set initial correlation values. */
+	calib->ofdm_x1     = hal->limits->min_ofdm_x1;
+	calib->ofdm_mrc_x1 = hal->limits->min_ofdm_mrc_x1;
+	calib->ofdm_x4     = 90;
+	calib->ofdm_mrc_x4 = hal->limits->min_ofdm_mrc_x4;
+	calib->cck_x4      = 125;
+	calib->cck_mrc_x4  = hal->limits->min_cck_mrc_x4;
+	calib->energy_cck  = hal->limits->energy_cck;
 
-	/* write initial sensitivity values */
+	/* Write initial sensitivity. */
 	error = iwn_send_sensitivity(sc);
 	if (error != 0)
 		return error;
 
-	memset(&cmd, 0, sizeof cmd);
-	cmd.code = IWN_SET_DIFF_GAIN;
-	/* differential gains initially set to 0 for all 3 antennas */
+	/* Write initial gains. */
+	error = hal->init_gains(sc);
+	if (error != 0)
+		return error;
+
+	/* Request statistics at each beacon interval. */
+	flags = 0;
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__);
-	return iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1);
+	return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
 }
 
 /*
  * Collect noise and RSSI statistics for the first 20 beacons received
  * after association and use them to determine connected antennas and
- * set differential gains.
+ * to set differential gains.
  */
 void
-iwn_compute_differential_gain(struct iwn_softc *sc,
+iwn_collect_noise(struct iwn_softc *sc,
     const struct iwn_rx_general_stats *stats)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_calib_state *calib = &sc->calib;
-	struct iwn_phy_calib_cmd cmd;
-	int i, val;
+	uint32_t val;
+	int i;
 
-	/* accumulate RSSI and noise for all 3 antennas */
+	/* Accumulate RSSI and noise for all 3 antennas. */
 	for (i = 0; i < 3; i++) {
 		calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
 		calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
 	}
-
-	/* we update differential gain only once after 20 beacons */
+	/* NB: We update differential gains only once after 20 beacons. */
 	if (++calib->nbeacons < 20)
 		return;
 
-	/* determine antenna with highest average RSSI */
-	val = max(calib->rssi[0], calib->rssi[1]);
-	val = max(calib->rssi[2], val);
+	/* Determine highest average RSSI. */
+	val = MAX(calib->rssi[0], calib->rssi[1]);
+	val = MAX(calib->rssi[2], val);
 
-	/* determine which antennas are connected */
+	/* Determine which antennas are connected. */
 	sc->antmsk = 0;
 	for (i = 0; i < 3; i++)
 		if (val - calib->rssi[i] <= 15 * 20)
 			sc->antmsk |= 1 << i;
-	/* if neither Ant A and Ant B are connected.. */
-	if ((sc->antmsk & (1 << 0 | 1 << 1)) == 0)
-		sc->antmsk |= 1 << 1;	/* ..mark Ant B as connected! */
+	/* If none of the TX antennas are connected, keep at least one. */
+	if ((sc->antmsk & sc->txantmsk) == 0)
+		sc->antmsk |= IWN_LSB(sc->txantmsk);
 
-	/* get minimal noise among connected antennas */
-	val = INT_MAX;	/* ok, there's at least one */
-	for (i = 0; i < 3; i++)
-		if (sc->antmsk & (1 << i))
-			val = min(calib->noise[i], val);
+	(void)hal->set_gains(sc);
+	calib->state = IWN_CALIB_STATE_RUN;
+
+#ifdef notyet
+	/* XXX Disable RX chains with no antennas connected. */
+	sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->antmsk));
+	(void)iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
+#endif
+
+#if 0
+	/* XXX: not yet */
+	/* Enable power-saving mode if requested by user. */
+	if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
+		(void)iwn_set_pslevel(sc, 0, 3, 1);
+#endif
+}
+
+int
+iwn4965_init_gains(struct iwn_softc *sc)
+{
+	struct iwn_phy_calib_gain cmd;
 
 	memset(&cmd, 0, sizeof cmd);
-	cmd.code = IWN_SET_DIFF_GAIN;
-	/* set differential gains for connected antennas */
+	cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
+	/* Differential gains initially set to 0 for all 3 antennas. */
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+	    "%s: setting initial differential gains\n", __func__);
+	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
+}
+
+int
+iwn5000_init_gains(struct iwn_softc *sc)
+{
+	struct iwn_phy_calib cmd;
+
+	if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
+	    sc->hw_type == IWN_HW_REV_TYPE_6050)
+		return 0;
+
+	memset(&cmd, 0, sizeof cmd);
+	cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
+	cmd.ngroups = 1;
+	cmd.isvalid = 1;
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+	    "%s: setting initial differential gains\n", __func__);
+	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
+}
+
+int
+iwn4965_set_gains(struct iwn_softc *sc)
+{
+	struct iwn_calib_state *calib = &sc->calib;
+	struct iwn_phy_calib_gain cmd;
+	int i, delta, noise;
+
+	/* Get minimal noise among connected antennas. */
+	noise = INT_MAX;	/* NB: There's at least one antennaiwn. */
+	for (i = 0; i < 3; i++)
+		if (sc->antmsk & (1 << i))
+			noise = MIN(calib->noise[i], noise);
+
+	memset(&cmd, 0, sizeof cmd);
+	cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
+	/* Set differential gains for connected antennas. */
 	for (i = 0; i < 3; i++) {
 		if (sc->antmsk & (1 << i)) {
-			cmd.gain[i] = (calib->noise[i] - val) / 30;
-			/* limit differential gain to 3 */
-			cmd.gain[i] = min(cmd.gain[i], 3);
-			cmd.gain[i] |= IWN_GAIN_SET;
+			/* Compute attenuation (in unit of 1.5dB). */
+			delta = (noise - (int32_t)calib->noise[i]) / 30;
+			/* NB: delta <= 0 */
+			/* Limit to [-4.5dB,0]. */
+			cmd.gain[i] = MIN(abs(delta), 3);
+			if (delta < 0)
+				cmd.gain[i] |= 1 << 2;	/* sign bit */
 		}
 	}
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
-	    "%s: set differential gains Ant A/B/C: %x/%x/%x (%x)\n",
-	    __func__,cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk);
-	if (iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1) == 0)
-		calib->state = IWN_CALIB_STATE_RUN;
+	    "setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
+	    cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk);
+	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
+}
+
+int
+iwn5000_set_gains(struct iwn_softc *sc)
+{
+	struct iwn_calib_state *calib = &sc->calib;
+	struct iwn_phy_calib_gain cmd;
+	int i, delta;
+
+	if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
+	    sc->hw_type == IWN_HW_REV_TYPE_6050)
+		return 0;
+
+	memset(&cmd, 0, sizeof cmd);
+	cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
+	cmd.ngroups = 1;
+	cmd.isvalid = 1;
+	/* Set differential gains for antennas B and C. */
+	for (i = 1; i < 3; i++) {
+		if (sc->antmsk & (1 << i)) {
+			/* The delta is relative to antenna A. */
+			delta = ((int32_t)calib->noise[0] -
+			    (int32_t)calib->noise[i]) / 30;
+			/* Limit to [-4.5dB,+4.5dB]. */
+			cmd.gain[i - 1] = MIN(abs(delta), 3);
+			if (delta < 0)
+				cmd.gain[i - 1] |= 1 << 2;	/* sign bit */
+		}
+	}
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+	    "setting differential gains Ant B/C: %x/%x (%x)\n",
+	    cmd.gain[0], cmd.gain[1], sc->antmsk);
+	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
 }
 
 /*
- * Tune RF Rx sensitivity based on the number of false alarms detected
+ * Tune RF RX sensitivity based on the number of false alarms detected
  * during the last beacon period.
  */
 void
 iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 {
-#define inc_clip(val, inc, max)			\
+#define inc(val, inc, max)			\
 	if ((val) < (max)) {			\
 		if ((val) < (max) - (inc))	\
 			(val) += (inc);		\
@@ -3281,7 +3862,7 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 			(val) = (max);		\
 		needs_update = 1;		\
 	}
-#define dec_clip(val, dec, min)			\
+#define dec(val, dec, min)			\
 	if ((val) > (min)) {			\
 		if ((val) > (min) + (dec))	\
 			(val) -= (dec);		\
@@ -3290,215 +3871,524 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 		needs_update = 1;		\
 	}
 
+	const struct iwn_hal *hal = sc->sc_hal;
+	const struct iwn_sensitivity_limits *limits = hal->limits;
 	struct iwn_calib_state *calib = &sc->calib;
 	uint32_t val, rxena, fa;
 	uint32_t energy[3], energy_min;
-	uint8_t noise[3], noise_ref;
 	int i, needs_update = 0;
+	uint8_t noise[3], noise_ref;
 
-	/* check that we've been enabled long enough */
+	/* Check that we've been enabled long enough. */
 	if ((rxena = le32toh(stats->general.load)) == 0)
 		return;
 
-	/* compute number of false alarms since last call for OFDM */
+	/* Compute number of false alarms since last call for OFDM. */
 	fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
 	fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
 	fa *= 200 * 1024;	/* 200TU */
 
-	/* save counters values for next call */
+	/* Save counters values for next call. */
 	calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
 	calib->fa_ofdm = le32toh(stats->ofdm.fa);
 
 	if (fa > 50 * rxena) {
-		/* high false alarm count, decrease sensitivity */
+		/* High false alarm count, decrease sensitivity. */
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 		    "%s: OFDM high false alarm count: %u\n", __func__, fa);
-		inc_clip(calib->corr_ofdm_x1,     1, 140);
-		inc_clip(calib->corr_ofdm_mrc_x1, 1, 270);
-		inc_clip(calib->corr_ofdm_x4,     1, 120);
-		inc_clip(calib->corr_ofdm_mrc_x4, 1, 210);
+		inc(calib->ofdm_x1,     1, limits->max_ofdm_x1);
+		inc(calib->ofdm_mrc_x1, 1, limits->max_ofdm_mrc_x1);
+		inc(calib->ofdm_x4,     1, limits->max_ofdm_x4);
+		inc(calib->ofdm_mrc_x4, 1, limits->max_ofdm_mrc_x4);
 
 	} else if (fa < 5 * rxena) {
-		/* low false alarm count, increase sensitivity */
+		/* Low false alarm count, increase sensitivity. */
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 		    "%s: OFDM low false alarm count: %u\n", __func__, fa);
-		dec_clip(calib->corr_ofdm_x1,     1, 105);
-		dec_clip(calib->corr_ofdm_mrc_x1, 1, 220);
-		dec_clip(calib->corr_ofdm_x4,     1,  85);
-		dec_clip(calib->corr_ofdm_mrc_x4, 1, 170);
+		dec(calib->ofdm_x1,     1, limits->min_ofdm_x1);
+		dec(calib->ofdm_mrc_x1, 1, limits->min_ofdm_mrc_x1);
+		dec(calib->ofdm_x4,     1, limits->min_ofdm_x4);
+		dec(calib->ofdm_mrc_x4, 1, limits->min_ofdm_mrc_x4);
 	}
 
-	/* compute maximum noise among 3 antennas */
+	/* Compute maximum noise among 3 receivers. */
 	for (i = 0; i < 3; i++)
 		noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
-	val = max(noise[0], noise[1]);
-	val = max(noise[2], val);
-	/* insert it into our samples table */
+	val = MAX(noise[0], noise[1]);
+	val = MAX(noise[2], val);
+	/* Insert it into our samples table. */
 	calib->noise_samples[calib->cur_noise_sample] = val;
 	calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
 
-	/* compute maximum noise among last 20 samples */
+	/* Compute maximum noise among last 20 samples. */
 	noise_ref = calib->noise_samples[0];
 	for (i = 1; i < 20; i++)
-		noise_ref = max(noise_ref, calib->noise_samples[i]);
+		noise_ref = MAX(noise_ref, calib->noise_samples[i]);
 
-	/* compute maximum energy among 3 antennas */
+	/* Compute maximum energy among 3 receivers. */
 	for (i = 0; i < 3; i++)
 		energy[i] = le32toh(stats->general.energy[i]);
-	val = min(energy[0], energy[1]);
-	val = min(energy[2], val);
-	/* insert it into our samples table */
+	val = MIN(energy[0], energy[1]);
+	val = MIN(energy[2], val);
+	/* Insert it into our samples table. */
 	calib->energy_samples[calib->cur_energy_sample] = val;
 	calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
 
-	/* compute minimum energy among last 10 samples */
+	/* Compute minimum energy among last 10 samples. */
 	energy_min = calib->energy_samples[0];
 	for (i = 1; i < 10; i++)
-		energy_min = max(energy_min, calib->energy_samples[i]);
+		energy_min = MAX(energy_min, calib->energy_samples[i]);
 	energy_min += 6;
 
-	/* compute number of false alarms since last call for CCK */
+	/* Compute number of false alarms since last call for CCK. */
 	fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
 	fa += le32toh(stats->cck.fa) - calib->fa_cck;
 	fa *= 200 * 1024;	/* 200TU */
 
-	/* save counters values for next call */
+	/* Save counters values for next call. */
 	calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
 	calib->fa_cck = le32toh(stats->cck.fa);
 
 	if (fa > 50 * rxena) {
-		/* high false alarm count, decrease sensitivity */
+		/* High false alarm count, decrease sensitivity. */
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 		    "%s: CCK high false alarm count: %u\n", __func__, fa);
 		calib->cck_state = IWN_CCK_STATE_HIFA;
 		calib->low_fa = 0;
 
-		if (calib->corr_cck_x4 > 160) {
+		if (calib->cck_x4 > 160) {
 			calib->noise_ref = noise_ref;
 			if (calib->energy_cck > 2)
-				dec_clip(calib->energy_cck, 2, energy_min);
+				dec(calib->energy_cck, 2, energy_min);
 		}
-		if (calib->corr_cck_x4 < 160) {
-			calib->corr_cck_x4 = 161;
+		if (calib->cck_x4 < 160) {
+			calib->cck_x4 = 161;
 			needs_update = 1;
 		} else
-			inc_clip(calib->corr_cck_x4, 3, 200);
+			inc(calib->cck_x4, 3, limits->max_cck_x4);
 
-		inc_clip(calib->corr_cck_mrc_x4, 3, 400);
+		inc(calib->cck_mrc_x4, 3, limits->max_cck_mrc_x4);
 
 	} else if (fa < 5 * rxena) {
-		/* low false alarm count, increase sensitivity */
+		/* Low false alarm count, increase sensitivity. */
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 		    "%s: CCK low false alarm count: %u\n", __func__, fa);
 		calib->cck_state = IWN_CCK_STATE_LOFA;
 		calib->low_fa++;
 
-		if (calib->cck_state != 0 &&
-		    ((calib->noise_ref - noise_ref) > 2 ||
+		if (calib->cck_state != IWN_CCK_STATE_INIT &&
+		    (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
 		     calib->low_fa > 100)) {
-			inc_clip(calib->energy_cck,      2,  97);
-			dec_clip(calib->corr_cck_x4,     3, 125);
-			dec_clip(calib->corr_cck_mrc_x4, 3, 200);
+			inc(calib->energy_cck, 2, limits->min_energy_cck);
+			dec(calib->cck_x4,     3, limits->min_cck_x4);
+			dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
 		}
 	} else {
-		/* not worth to increase or decrease sensitivity */
+		/* Not worth to increase or decrease sensitivity. */
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 		    "%s: CCK normal false alarm count: %u\n", __func__, fa);
 		calib->low_fa = 0;
 		calib->noise_ref = noise_ref;
 
 		if (calib->cck_state == IWN_CCK_STATE_HIFA) {
-			/* previous interval had many false alarms */
-			dec_clip(calib->energy_cck, 8, energy_min);
+			/* Previous interval had many false alarms. */
+			dec(calib->energy_cck, 8, energy_min);
 		}
 		calib->cck_state = IWN_CCK_STATE_INIT;
 	}
 
 	if (needs_update)
 		(void)iwn_send_sensitivity(sc);
-#undef dec_clip
-#undef inc_clip
+#undef dec
+#undef inc
 }
 
 int
 iwn_send_sensitivity(struct iwn_softc *sc)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_calib_state *calib = &sc->calib;
 	struct iwn_sensitivity_cmd cmd;
 
 	memset(&cmd, 0, sizeof cmd);
 	cmd.which = IWN_SENSITIVITY_WORKTBL;
-	/* OFDM modulation */
-	cmd.corr_ofdm_x1     = htole16(calib->corr_ofdm_x1);
-	cmd.corr_ofdm_mrc_x1 = htole16(calib->corr_ofdm_mrc_x1);
-	cmd.corr_ofdm_x4     = htole16(calib->corr_ofdm_x4);
-	cmd.corr_ofdm_mrc_x4 = htole16(calib->corr_ofdm_mrc_x4);
-	cmd.energy_ofdm      = htole16(100);
+	/* OFDM modulation. */
+	cmd.corr_ofdm_x1     = htole16(calib->ofdm_x1);
+	cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
+	cmd.corr_ofdm_x4     = htole16(calib->ofdm_x4);
+	cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
+	cmd.energy_ofdm      = htole16(hal->limits->energy_ofdm);
 	cmd.energy_ofdm_th   = htole16(62);
-	/* CCK modulation */
-	cmd.corr_cck_x4      = htole16(calib->corr_cck_x4);
-	cmd.corr_cck_mrc_x4  = htole16(calib->corr_cck_mrc_x4);
+	/* CCK modulation. */
+	cmd.corr_cck_x4      = htole16(calib->cck_x4);
+	cmd.corr_cck_mrc_x4  = htole16(calib->cck_mrc_x4);
 	cmd.energy_cck       = htole16(calib->energy_cck);
-	/* Barker modulation: use default values */
+	/* Barker modulation: use default values. */
 	cmd.corr_barker      = htole16(190);
 	cmd.corr_barker_mrc  = htole16(390);
 
-	DPRINTF(sc, IWN_DEBUG_RESET, 
+	DPRINTF(sc, IWN_DEBUG_RESET,
 	    "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
-	    calib->corr_ofdm_x1, calib->corr_ofdm_mrc_x1, calib->corr_ofdm_x4,
-	    calib->corr_ofdm_mrc_x4, calib->corr_cck_x4,
-	    calib->corr_cck_mrc_x4, calib->energy_cck);
-	return iwn_cmd(sc, IWN_SENSITIVITY, &cmd, sizeof cmd, 1);
+	    calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
+	    calib->ofdm_mrc_x4, calib->cck_x4,
+	    calib->cck_mrc_x4, calib->energy_cck);
+	return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, sizeof cmd, 1);
+}
+
+/*
+ * Set STA mode power saving level (between 0 and 5).
+ * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
+ */
+int
+iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
+{
+	const struct iwn_pmgt *pmgt;
+	struct iwn_pmgt_cmd cmd;
+	uint32_t max, skip_dtim;
+	uint32_t tmp;
+	int i;
+
+	/* Select which PS parameters to use. */
+	if (dtim <= 2)
+		pmgt = &iwn_pmgt[0][level];
+	else if (dtim <= 10)
+		pmgt = &iwn_pmgt[1][level];
+	else
+		pmgt = &iwn_pmgt[2][level];
+
+	memset(&cmd, 0, sizeof cmd);
+	if (level != 0)	/* not CAM */
+		cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
+	if (level == 5)
+		cmd.flags |= htole16(IWN_PS_FAST_PD);
+	tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
+	if (!(tmp & 0x1))	/* L0s Entry disabled. */
+		cmd.flags |= htole16(IWN_PS_PCI_PMGT);
+	cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
+	cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
+
+	if (dtim == 0) {
+		dtim = 1;
+		skip_dtim = 0;
+	} else
+		skip_dtim = pmgt->skip_dtim;
+	if (skip_dtim != 0) {
+		cmd.flags |= htole16(IWN_PS_SLEEP_OVER_DTIM);
+		max = pmgt->intval[4];
+		if (max == (uint32_t)-1)
+			max = dtim * (skip_dtim + 1);
+		else if (max > dtim)
+			max = (max / dtim) * dtim;
+	} else
+		max = dtim;
+	for (i = 0; i < 5; i++)
+		cmd.intval[i] = htole32(MIN(max, pmgt->intval[i]));
+
+	DPRINTF(sc, IWN_DEBUG_RESET, "setting power saving level to %d\n",
+	    level);
+	return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
+}
+
+int
+iwn_config(struct iwn_softc *sc)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct iwn_bluetooth bluetooth;
+	int error;
+	uint16_t rxchain;
+
+	/* Set power saving level to CAM during initialization. */
+	if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not set power saving level, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	/* Configure bluetooth coexistence. */
+	memset(&bluetooth, 0, sizeof bluetooth);
+	bluetooth.flags = 3;
+	bluetooth.lead = 0xaa;
+	bluetooth.kill = 1;
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
+	    __func__);
+	error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not configure bluetooth coexistence, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	/* Configure adapter. */
+	memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
+	IEEE80211_ADDR_COPY(sc->rxon.myaddr, IF_LLADDR(ifp));
+	IEEE80211_ADDR_COPY(sc->rxon.wlap, IF_LLADDR(ifp));
+	/* Set default channel. */
+	sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+	sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
+	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
+		sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
+	switch (ic->ic_opmode) {
+	case IEEE80211_M_STA:
+		sc->rxon.mode = IWN_MODE_STA;
+		sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
+		break;
+	case IEEE80211_M_IBSS:
+	case IEEE80211_M_AHDEMO:
+		sc->rxon.mode = IWN_MODE_IBSS;
+		break;
+	case IEEE80211_M_HOSTAP:
+		sc->rxon.mode = IWN_MODE_HOSTAP;
+		break;
+	case IEEE80211_M_MONITOR:
+		sc->rxon.mode = IWN_MODE_MONITOR;
+		sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
+		    IWN_FILTER_CTL | IWN_FILTER_PROMISC);
+		break;
+	default:
+		/* Should not get there. */
+		break;
+	}
+	sc->rxon.cck_mask  = 0x0f;	/* not yet negotiated */
+	sc->rxon.ofdm_mask = 0xff;	/* not yet negotiated */
+	sc->rxon.ht_single_mask = 0xff;
+	sc->rxon.ht_dual_mask = 0xff;
+	rxchain = IWN_RXCHAIN_VALID(IWN_ANT_ABC) | IWN_RXCHAIN_IDLE_COUNT(2) |
+	    IWN_RXCHAIN_MIMO_COUNT(2);
+	sc->rxon.rxchain = htole16(rxchain);
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
+	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: configure command failed\n", __func__);
+		return error;
+	}
+	sc->sc_curchan = ic->ic_curchan;
+
+	/* Configuration has changed, set TX power accordingly. */
+	error = hal->set_txpower(sc, ic->ic_curchan, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not set TX power\n", __func__);
+		return error;
+	}
+
+	error = iwn_add_broadcast_node(sc, ic->ic_curchan, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not add broadcast node\n", __func__);
+		return error;
+	}
+
+	error = iwn_set_critical_temp(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not set critical temperature\n", __func__);
+		return error;
+	}
+	return 0;
+}
+
+int
+iwn_scan(struct iwn_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211_scan_state *ss = ic->ic_scan;	/*XXX*/
+	struct iwn_scan_hdr *hdr;
+	struct iwn_cmd_data *tx;
+	struct iwn_scan_essid *essid;
+	struct iwn_scan_chan *chan;
+	struct ieee80211_frame *wh;
+	struct ieee80211_rateset *rs;
+	struct ieee80211_channel *c;
+	enum ieee80211_phymode mode;
+	int buflen, error, nrates;
+	uint16_t rxchain;
+	uint8_t *buf, *frm, txant;
+
+	buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (buf == NULL) {
+		device_printf(sc->sc_dev,
+		    "%s: could not allocate buffer for scan command\n",
+		    __func__);
+		return ENOMEM;
+	}
+	hdr = (struct iwn_scan_hdr *)buf;
+
+	/*
+	 * Move to the next channel if no frames are received within 10ms
+	 * after sending the probe request.
+	 */
+	hdr->quiet_time = htole16(10);		/* timeout in milliseconds */
+	hdr->quiet_threshold = htole16(1);	/* min # of packets */
+
+	/* Select antennas for scanning. */
+	rxchain = IWN_RXCHAIN_FORCE | IWN_RXCHAIN_VALID(IWN_ANT_ABC) |
+	    IWN_RXCHAIN_MIMO(IWN_ANT_ABC);
+	if (IEEE80211_IS_CHAN_A(ic->ic_curchan) &&
+	    sc->hw_type == IWN_HW_REV_TYPE_4965) {
+		/* Ant A must be avoided in 5GHz because of an HW bug. */
+		rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_B | IWN_ANT_C);
+	} else	/* Use all available RX antennas. */
+		rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_ABC);
+	hdr->rxchain = htole16(rxchain);
+	hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
+
+	tx = (struct iwn_cmd_data *)(hdr + 1);
+	tx->flags = htole32(IWN_TX_AUTO_SEQ);
+	tx->id = sc->sc_hal->broadcast_id;
+	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
+
+	if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
+		hdr->crc_threshold = htole16(1);
+		/* Send probe requests at 6Mbps. */
+		tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
+	} else {
+		hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
+		/* Send probe requests at 1Mbps. */
+		tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
+		tx->rflags = IWN_RFLAG_CCK;
+	}
+	/* Use the first valid TX antenna. */
+	txant = IWN_LSB(sc->txantmsk);
+	tx->rflags |= IWN_RFLAG_ANT(txant);
+
+	essid = (struct iwn_scan_essid *)(tx + 1);
+	if (ss->ss_ssid[0].len != 0) {
+		essid[0].id = IEEE80211_ELEMID_SSID;
+		essid[0].len = ss->ss_ssid[0].len;
+		memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
+	}
+	/*
+	 * Build a probe request frame.  Most of the following code is a
+	 * copy & paste of what is done in net80211.
+	 */
+	wh = (struct ieee80211_frame *)(essid + 20);
+	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
+	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
+	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
+	IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
+	IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
+	*(uint16_t *)&wh->i_dur[0] = 0;	/* filled by HW */
+	*(uint16_t *)&wh->i_seq[0] = 0;	/* filled by HW */
+
+	frm = (uint8_t *)(wh + 1);
+
+	/* Add SSID IE. */
+	*frm++ = IEEE80211_ELEMID_SSID;
+	*frm++ = ss->ss_ssid[0].len;
+	memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
+	frm += ss->ss_ssid[0].len;
+
+	mode = ieee80211_chan2mode(ic->ic_curchan);
+	rs = &ic->ic_sup_rates[mode];
+
+	/* Add supported rates IE. */
+	*frm++ = IEEE80211_ELEMID_RATES;
+	nrates = rs->rs_nrates;
+	if (nrates > IEEE80211_RATE_SIZE)
+		nrates = IEEE80211_RATE_SIZE;
+	*frm++ = nrates;
+	memcpy(frm, rs->rs_rates, nrates);
+	frm += nrates;
+
+	/* Add supported xrates IE. */
+	if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
+		nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
+		*frm++ = IEEE80211_ELEMID_XRATES;
+		*frm++ = (uint8_t)nrates;
+		memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
+		frm += nrates;
+	}
+
+	/* Set length of probe request. */
+	tx->len = htole16(frm - (uint8_t *)wh);
+
+	c = ic->ic_curchan;
+	chan = (struct iwn_scan_chan *)frm;
+	chan->chan = ieee80211_chan2ieee(ic, c);
+	chan->flags = 0;
+	if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE))
+		chan->flags |= htole32(IWN_CHAN_ACTIVE);
+	if (ss->ss_nssid > 0)
+		chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
+	chan->dsp_gain = 0x6e;
+	if (IEEE80211_IS_CHAN_5GHZ(c)) {
+		chan->rf_gain = 0x3b;
+		chan->active  = htole16(24);
+		chan->passive = htole16(110);
+	} else {
+		chan->rf_gain = 0x28;
+		chan->active  = htole16(36);
+		chan->passive = htole16(120);
+	}
+	hdr->nchan++;
+	chan++;
+
+	DPRINTF(sc, IWN_DEBUG_STATE, "%s: chan %u flags 0x%x rf_gain 0x%x "
+	    "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
+	    chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
+	    chan->active, chan->passive);
+
+	buflen = (uint8_t *)chan - buf;
+	hdr->len = htole16(buflen);
+
+	DPRINTF(sc, IWN_DEBUG_STATE, "sending scan command nchan=%d\n",
+	    hdr->nchan);
+	error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
+	free(buf, M_DEVBUF);
+	return error;
 }
 
 int
 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
 {
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211_node *ni = vap->iv_bss;
-	struct iwn_node_info node;
 	int error;
 
 	sc->calib.state = IWN_CALIB_STATE_INIT;
 
-	/* update adapter's configuration */
-	sc->config.associd = 0;
-	IEEE80211_ADDR_COPY(sc->config.bssid, ni->ni_bssid);
-	sc->config.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
-	sc->config.flags = htole32(IWN_CONFIG_TSF);
+	/* Update adapter's configuration. */
+	IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
+	sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
+	sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
 	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
-		sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
+		sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
+	if (ic->ic_flags & IEEE80211_F_SHSLOT)
+		sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
+	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
+		sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
 	if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
-		sc->config.cck_mask  = 0;
-		sc->config.ofdm_mask = 0x15;
+		sc->rxon.cck_mask  = 0;
+		sc->rxon.ofdm_mask = 0x15;
 	} else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
-		sc->config.cck_mask  = 0x03;
-		sc->config.ofdm_mask = 0;
+		sc->rxon.cck_mask  = 0x03;
+		sc->rxon.ofdm_mask = 0;
 	} else {
 		/* XXX assume 802.11b/g */
-		sc->config.cck_mask  = 0x0f;
-		sc->config.ofdm_mask = 0x15;
+		sc->rxon.cck_mask  = 0x0f;
+		sc->rxon.ofdm_mask = 0x15;
 	}
-	if (ic->ic_flags & IEEE80211_F_SHSLOT)
-		sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
-	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
-		sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
-	sc->config.filter &= ~htole32(IWN_FILTER_BSS);
-
 	DPRINTF(sc, IWN_DEBUG_STATE,
-	   "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
-	   "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
-	   "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
-	   __func__,
-	   le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
-	   sc->config.cck_mask, sc->config.ofdm_mask,
-	   sc->config.ht_single_mask, sc->config.ht_dual_mask,
-	   le16toh(sc->config.rxchain),
-	   sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
-	   le16toh(sc->config.associd), le32toh(sc->config.filter));
-	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
-	    sizeof (struct iwn_config), 1);
+	    "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
+	    "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
+	    "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
+	    __func__,
+	    le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
+	    sc->rxon.cck_mask, sc->rxon.ofdm_mask,
+	    sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
+	    le16toh(sc->rxon.rxchain),
+	    sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
+	    le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
+	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not configure, error %d\n", __func__, error);
@@ -3506,37 +4396,23 @@ iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
 	}
 	sc->sc_curchan = ic->ic_curchan;
 
-	/* configuration has changed, set Tx power accordingly */
-	error = iwn_set_txpower(sc, ni->ni_chan, 1);
-	if (error != 0) {
+	/* Configuration has changed, set TX power accordingly. */
+	if ((error = hal->set_txpower(sc, ni->ni_chan, 1)) != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not set Tx power, error %d\n", __func__, error);
 		return error;
 	}
-
 	/*
-	 * Reconfiguring clears the adapter's nodes table so we must
+	 * Reconfiguring RXON clears the firmware's nodes table so we must
 	 * add the broadcast node again.
 	 */
-	memset(&node, 0, sizeof node);
-	IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
-	node.id = IWN_ID_BROADCAST;
-	DPRINTF(sc, IWN_DEBUG_STATE, "%s: add broadcast node\n", __func__);
-	error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
+	error = iwn_add_broadcast_node(sc, ic->ic_curchan, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not add broadcast node, error %d\n",
+		    "%s: 1 could not add broadcast node, error %d\n",
 		    __func__, error);
 		return error;
 	}
-	error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 1);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not setup MRR for broadcast node, error %d\n",
-		    __func__, error);
-		return error;
-	}
-
 	return 0;
 }
 
@@ -3547,6 +4423,7 @@ int
 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 {
 #define	MS(v,x)	(((v) & x) >> x##_S)
+	const struct iwn_hal *hal = sc->sc_hal;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211_node *ni = vap->iv_bss;
@@ -3560,50 +4437,53 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 		iwn_set_led(sc, IWN_LED_LINK, 5, 5);
 		return 0;
 	}
+	error = iwn_set_timing(sc, ni);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not set timing, error %d\n", __func__, error);
+		return error;
+	}
 
-	iwn_enable_tsf(sc, ni);
-
-	/* update adapter's configuration */
-	sc->config.associd = htole16(IEEE80211_AID(ni->ni_associd));
-	/* short preamble/slot time are negotiated when associating */
-	sc->config.flags &= ~htole32(IWN_CONFIG_SHPREAMBLE | IWN_CONFIG_SHSLOT);
+	/* Update adapter's configuration. */
+	sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
+	/* Short preamble and slot time are negotiated when associating. */
+	sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
 	if (ic->ic_flags & IEEE80211_F_SHSLOT)
-		sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
+		sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
 	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
-		sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
+		sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
 	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
-		sc->config.flags &= ~htole32(IWN_CONFIG_HT);
+		sc->rxon.flags &= ~htole32(IWN_RXON_HT);
 		if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
-			sc->config.flags |= htole32(IWN_CONFIG_HT40U);
+			sc->rxon.flags |= htole32(IWN_RXON_HT40U);
 		else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
-			sc->config.flags |= htole32(IWN_CONFIG_HT40D);
+			sc->rxon.flags |= htole32(IWN_RXON_HT40D);
 		else
-			sc->config.flags |= htole32(IWN_CONFIG_HT20);
-		sc->config.rxchain = htole16(
-			  (3 << IWN_RXCHAIN_VALID_S)
-			| (3 << IWN_RXCHAIN_MIMO_CNT_S)
-			| (1 << IWN_RXCHAIN_CNT_S)
+			sc->rxon.flags |= htole32(IWN_RXON_HT20);
+		sc->rxon.rxchain = htole16(
+			  IWN_RXCHAIN_VALID(3)
+			| IWN_RXCHAIN_MIMO_COUNT(3)
+			| IWN_RXCHAIN_IDLE_COUNT(1)
 			| IWN_RXCHAIN_MIMO_FORCE);
 
 		maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
 		ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
 	} else
 		maxrxampdu = ampdudensity = 0;
-	sc->config.filter |= htole32(IWN_FILTER_BSS);
+	sc->rxon.filter |= htole32(IWN_FILTER_BSS);
 
 	DPRINTF(sc, IWN_DEBUG_STATE,
-	   "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
-	   "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
-	   "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
-	   __func__,
-	   le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
-	   sc->config.cck_mask, sc->config.ofdm_mask,
-	   sc->config.ht_single_mask, sc->config.ht_dual_mask,
-	   le16toh(sc->config.rxchain),
-	   sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
-	   le16toh(sc->config.associd), le32toh(sc->config.filter));
-	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
-	    sizeof (struct iwn_config), 1);
+	    "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
+	    "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
+	    "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
+	    __func__,
+	    le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
+	    sc->rxon.cck_mask, sc->rxon.ofdm_mask,
+	    sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
+	    le16toh(sc->rxon.rxchain),
+	    sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
+	    le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
+	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not update configuration, error %d\n",
@@ -3612,26 +4492,25 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 	}
 	sc->sc_curchan = ni->ni_chan;
 
-	/* configuration has changed, set Tx power accordingly */
-	error = iwn_set_txpower(sc, ni->ni_chan, 1);
+	/* Configuration has changed, set TX power accordingly. */
+	error = hal->set_txpower(sc, ni->ni_chan, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not set Tx power, error %d\n", __func__, error);
 		return error;
 	}
 
-	/* add BSS node */
+	/* Add BSS node. */
 	memset(&node, 0, sizeof node);
 	IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
 	node.id = IWN_ID_BSS;
-	node.htflags = htole32(
-	    (maxrxampdu << IWN_MAXRXAMPDU_S) |
-	    (ampdudensity << IWN_MPDUDENSITY_S));
+	node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(maxrxampdu)
+	    | IWN_AMDPU_DENSITY(ampdudensity));
 	DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
 	    __func__, node.id, le32toh(node.htflags));
-	error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
+	error = hal->add_node(sc, &node, 1);
 	if (error != 0) {
-		device_printf(sc->sc_dev,"could not add BSS node\n");
+		device_printf(sc->sc_dev, "could not add BSS node\n");
 		return error;
 	}
 	error = iwn_set_link_quality(sc, node.id, ni->ni_chan, 1);
@@ -3650,11 +4529,11 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 		return error;
 	}
 
-	/* start/restart periodic calibration timer */
+	/* Start periodic calibration timer. */
 	sc->calib.state = IWN_CALIB_STATE_ASSOC;
 	iwn_calib_reset(sc);
 
-	/* link LED always on while associated */
+	/* Link LED always on while associated. */
 	iwn_set_led(sc, IWN_LED_LINK, 0, 1);
 
 	return 0;
@@ -3662,582 +4541,901 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 }
 
 /*
- * Send a scan request to the firmware.  Since this command is huge, we map it
- * into a mbuf instead of using the pre-allocated set of commands.
+ * Query calibration tables from the initialization firmware.  We do this
+ * only once at first boot.  Called from a process context.
  */
 int
-iwn_scan(struct iwn_softc *sc)
+iwn5000_query_calibration(struct iwn_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct ieee80211_scan_state *ss = ic->ic_scan;	/*XXX*/
-	struct iwn_tx_ring *ring = &sc->txq[4];
-	struct iwn_tx_desc *desc;
-	struct iwn_tx_data *data;
-	struct iwn_tx_cmd *cmd;
-	struct iwn_cmd_data *tx;
-	struct iwn_scan_hdr *hdr;
-	struct iwn_scan_essid *essid;
-	struct iwn_scan_chan *chan;
-	struct ieee80211_frame *wh;
-	struct ieee80211_rateset *rs;
-	struct ieee80211_channel *c;
-	enum ieee80211_phymode mode;
-	uint8_t *frm;
-	int pktlen, error, nrates;
-	bus_addr_t physaddr;
-
-	desc = &ring->desc[ring->cur];
-	data = &ring->data[ring->cur];
-
-	/* XXX malloc */
-	data->m = m_getcl(M_DONTWAIT, MT_DATA, 0);
-	if (data->m == NULL) {
-		device_printf(sc->sc_dev,
-		    "%s: could not allocate mbuf for scan command\n", __func__);
-		return ENOMEM;
-	}
-
-	cmd = mtod(data->m, struct iwn_tx_cmd *);
-	cmd->code = IWN_CMD_SCAN;
-	cmd->flags = 0;
-	cmd->qid = ring->qid;
-	cmd->idx = ring->cur;
-
-	hdr = (struct iwn_scan_hdr *)cmd->data;
-	memset(hdr, 0, sizeof (struct iwn_scan_hdr));
-
-	/* XXX use scan state */
-	/*
-	 * Move to the next channel if no packets are received within 5 msecs
-	 * after sending the probe request (this helps to reduce the duration
-	 * of active scans).
-	 */
-	hdr->quiet = htole16(5);	/* timeout in milliseconds */
-	hdr->plcp_threshold = htole16(1);	/* min # of packets */
-
-	/* select Ant B and Ant C for scanning */
-	hdr->rxchain = htole16(0x3e1 | (7 << IWN_RXCHAIN_VALID_S));
-
-	tx = (struct iwn_cmd_data *)(hdr + 1);
-	memset(tx, 0, sizeof (struct iwn_cmd_data));
-	tx->flags = htole32(IWN_TX_AUTO_SEQ | 0x200);	/* XXX */
-	tx->id = IWN_ID_BROADCAST;
-	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
-	tx->rflags = IWN_RFLAG_ANT_B;
-
-	if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
-		hdr->crc_threshold = htole16(1);
-		/* send probe requests at 6Mbps */
-		tx->rate = iwn_ridx_to_plcp[IWN_RATE_OFDM6];
-	} else {
-		hdr->flags = htole32(IWN_CONFIG_24GHZ | IWN_CONFIG_AUTO);
-		/* send probe requests at 1Mbps */
-		tx->rate = iwn_ridx_to_plcp[IWN_RATE_CCK1];
-		tx->rflags |= IWN_RFLAG_CCK;
-	}
-
-	essid = (struct iwn_scan_essid *)(tx + 1);
-	memset(essid, 0, 4 * sizeof (struct iwn_scan_essid));
-	essid[0].id  = IEEE80211_ELEMID_SSID;
-	essid[0].len = ss->ss_ssid[0].len;
-	memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
-
-	/*
-	 * Build a probe request frame.  Most of the following code is a
-	 * copy & paste of what is done in net80211.
-	 */
-	wh = (struct ieee80211_frame *)&essid[4];
-	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
-	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
-	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
-	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
-	IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
-	IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
-	*(u_int16_t *)&wh->i_dur[0] = 0;	/* filled by h/w */
-	*(u_int16_t *)&wh->i_seq[0] = 0;	/* filled by h/w */
-
-	frm = (uint8_t *)(wh + 1);
-
-	/* add SSID IE */
-        *frm++ = IEEE80211_ELEMID_SSID;
-        *frm++ = ss->ss_ssid[0].len;
-        memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
-	frm += ss->ss_ssid[0].len;
-
-	mode = ieee80211_chan2mode(ic->ic_curchan);
-	rs = &ic->ic_sup_rates[mode];
-
-	/* add supported rates IE */
-	*frm++ = IEEE80211_ELEMID_RATES;
-	nrates = rs->rs_nrates;
-	if (nrates > IEEE80211_RATE_SIZE)
-		nrates = IEEE80211_RATE_SIZE;
-	*frm++ = nrates;
-	memcpy(frm, rs->rs_rates, nrates);
-	frm += nrates;
-
-	/* add supported xrates IE */
-	if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
-		nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
-		*frm++ = IEEE80211_ELEMID_XRATES;
-		*frm++ = (uint8_t)nrates;
-		memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
-		frm += nrates;
-	}
-
-	/* setup length of probe request */
-	tx->len = htole16(frm - (uint8_t *)wh);
-
-	c = ic->ic_curchan;
-	chan = (struct iwn_scan_chan *)frm;
-	chan->chan = ieee80211_chan2ieee(ic, c);
-	chan->flags = 0;
-	if ((c->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
-		chan->flags |= IWN_CHAN_ACTIVE;
-		if (ss->ss_nssid > 0)
-			chan->flags |= IWN_CHAN_DIRECT;
-	}
-	chan->dsp_gain = 0x6e;
-	if (IEEE80211_IS_CHAN_5GHZ(c)) {
-		chan->rf_gain = 0x3b;
-		chan->active  = htole16(10);
-		chan->passive = htole16(110);
-	} else {
-		chan->rf_gain = 0x28;
-		chan->active  = htole16(20);
-		chan->passive = htole16(120);
-	}
-
-	DPRINTF(sc, IWN_DEBUG_STATE, "%s: chan %u flags 0x%x rf_gain 0x%x "
-	    "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
-	    chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
-	    chan->active, chan->passive);
-	hdr->nchan++;
-	chan++;
-
-	frm += sizeof (struct iwn_scan_chan);
-
-	hdr->len = htole16(frm - (uint8_t *)hdr);
-	pktlen = frm - (uint8_t *)cmd;
-
-	error = bus_dmamap_load(ring->data_dmat, data->map, cmd, pktlen,
-	    iwn_dma_map_addr, &physaddr, BUS_DMA_NOWAIT);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not map scan command, error %d\n",
-		    __func__, error);
-		m_freem(data->m);
-		data->m = NULL;
-		return error;
-	}
-
-	IWN_SET_DESC_NSEGS(desc, 1);
-	IWN_SET_DESC_SEG(desc, 0, physaddr, pktlen);
-	sc->shared->len[ring->qid][ring->cur] = htole16(8);
-	if (ring->cur < IWN_TX_WINDOW)
-		sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
-		    htole16(8);
-
-	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
-	    BUS_DMASYNC_PREWRITE);
-	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
-
-	/* kick cmd ring */
-	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
-
-	return 0;	/* will be notified async. of failure/success */
-}
-
-int
-iwn_config(struct iwn_softc *sc)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_power power;
-	struct iwn_bluetooth bluetooth;
-	struct iwn_node_info node;
+	struct iwn5000_calib_config cmd;
 	int error;
 
-	/* set power mode */
-	memset(&power, 0, sizeof power);
-	power.flags = htole16(IWN_POWER_CAM | 0x8);
-	DPRINTF(sc, IWN_DEBUG_RESET, "%s: set power mode\n", __func__);
-	error = iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &power, sizeof power, 0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not set power mode, error %d\n",
-		    __func__, error);
-		return error;
-	}
-
-	/* configure bluetooth coexistence */
-	memset(&bluetooth, 0, sizeof bluetooth);
-	bluetooth.flags = 3;
-	bluetooth.lead = 0xaa;
-	bluetooth.kill = 1;
-	DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
+	memset(&cmd, 0, sizeof cmd);
+	cmd.ucode.once.enable = 0xffffffff;
+	cmd.ucode.once.start  = 0xffffffff;
+	cmd.ucode.once.send   = 0xffffffff;
+	cmd.ucode.flags       = 0xffffffff;
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n",
 	    __func__);
-	error = iwn_cmd(sc, IWN_CMD_BLUETOOTH, &bluetooth, sizeof bluetooth,
-	    0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not configure bluetooth coexistence, error %d\n",
-		    __func__, error);
+	error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
+	if (error != 0)
 		return error;
-	}
 
-	/* configure adapter */
-	memset(&sc->config, 0, sizeof (struct iwn_config));
-	IEEE80211_ADDR_COPY(sc->config.myaddr, IF_LLADDR(ifp));
-	IEEE80211_ADDR_COPY(sc->config.wlap, IF_LLADDR(ifp));
-	/* set default channel */
-	sc->config.chan = htole16(ieee80211_chan2ieee(ic, ic->ic_curchan));
-	sc->config.flags = htole32(IWN_CONFIG_TSF);
-	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
-		sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
-	sc->config.filter = 0;
-	switch (ic->ic_opmode) {
-	case IEEE80211_M_STA:
-		sc->config.mode = IWN_MODE_STA;
-		sc->config.filter |= htole32(IWN_FILTER_MULTICAST);
-		break;
-	case IEEE80211_M_IBSS:
-	case IEEE80211_M_AHDEMO:
-		sc->config.mode = IWN_MODE_IBSS;
-		break;
-	case IEEE80211_M_HOSTAP:
-		sc->config.mode = IWN_MODE_HOSTAP;
-		break;
-	case IEEE80211_M_MONITOR:
-		sc->config.mode = IWN_MODE_MONITOR;
-		sc->config.filter |= htole32(IWN_FILTER_MULTICAST |
-		    IWN_FILTER_CTL | IWN_FILTER_PROMISC);
-		break;
-	default:
-		device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode);
-		return EINVAL;
-	}
-	sc->config.cck_mask  = 0x0f;	/* not yet negotiated */
-	sc->config.ofdm_mask = 0xff;	/* not yet negotiated */
-	sc->config.ht_single_mask = 0xff;
-	sc->config.ht_dual_mask = 0xff;
-	sc->config.rxchain = htole16(0x2800 | (7 << IWN_RXCHAIN_VALID_S));
+	/* Wait at most two seconds for calibration to complete. */
+	return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
+}
 
-	DPRINTF(sc, IWN_DEBUG_STATE,
-	   "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
-	   "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
-	   "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
-	   __func__,
-	   le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
-	   sc->config.cck_mask, sc->config.ofdm_mask,
-	   sc->config.ht_single_mask, sc->config.ht_dual_mask,
-	   le16toh(sc->config.rxchain),
-	   sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
-	   le16toh(sc->config.associd), le32toh(sc->config.filter));
-	error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
-	    sizeof (struct iwn_config), 0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: configure command failed, error %d\n",
-		    __func__, error);
-		return error;
-	}
-	sc->sc_curchan = ic->ic_curchan;
+/*
+ * Send calibration results to the runtime firmware.  These results were
+ * obtained on first boot from the initialization firmware.
+ */
+int
+iwn5000_send_calibration(struct iwn_softc *sc)
+{
+	int idx, error;
 
-	/* configuration has changed, set Tx power accordingly */
-	error = iwn_set_txpower(sc, ic->ic_curchan, 0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not set Tx power, error %d\n", __func__, error);
-		return error;
-	}
-
-	/* add broadcast node */
-	memset(&node, 0, sizeof node);
-	IEEE80211_ADDR_COPY(node.macaddr, ic->ic_ifp->if_broadcastaddr);
-	node.id = IWN_ID_BROADCAST;
-	node.rate = iwn_plcp_signal(2);
-	DPRINTF(sc, IWN_DEBUG_RESET, "%s: add broadcast node\n", __func__);
-	error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not add broadcast node, error %d\n",
-		    __func__, error);
-		return error;
-	}
-	error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 0);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not setup MRR for node %d, error %d\n",
-		    __func__, node.id, error);
-		return error;
-	}
-
-	error = iwn_set_critical_temp(sc);
-	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not set critical temperature, error %d\n",
-		    __func__, error);
-		return error;
+	for (idx = 0; idx < 5; idx++) {
+		if (sc->calibcmd[idx].buf == NULL)
+			continue;	/* No results available. */
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+		    "send calibration result idx=%d len=%d\n",
+		    idx, sc->calibcmd[idx].len);
+		error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf,
+		    sc->calibcmd[idx].len, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "%s: could not send calibration result, error %d\n",
+			    __func__, error);
+			return error;
+		}
 	}
 	return 0;
 }
 
 /*
- * Do post-alive initialization of the NIC (after firmware upload).
+ * This function is called after the runtime firmware notifies us of its
+ * readiness (called in a process context.)
  */
-void
-iwn_post_alive(struct iwn_softc *sc)
-{
-	uint32_t base;
-	uint16_t offset;
-	int qid;
-
-	iwn_mem_lock(sc);
-
-	/* clear SRAM */
-	base = iwn_mem_read(sc, IWN_SRAM_BASE);
-	for (offset = 0x380; offset < 0x520; offset += 4) {
-		IWN_WRITE(sc, IWN_MEM_WADDR, base + offset);
-		IWN_WRITE(sc, IWN_MEM_WDATA, 0);
-	}
-
-	/* shared area is aligned on a 1K boundary */
-	iwn_mem_write(sc, IWN_SRAM_BASE, sc->shared_dma.paddr >> 10);
-	iwn_mem_write(sc, IWN_SELECT_QCHAIN, 0);
-
-	for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
-		iwn_mem_write(sc, IWN_QUEUE_RIDX(qid), 0);
-		IWN_WRITE(sc, IWN_TX_WIDX, qid << 8 | 0);
-
-		/* set sched. window size */
-		IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid));
-		IWN_WRITE(sc, IWN_MEM_WDATA, 64);
-		/* set sched. frame limit */
-		IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid) + 4);
-		IWN_WRITE(sc, IWN_MEM_WDATA, 10 << 16);
-	}
-
-	/* enable interrupts for all 16 queues */
-	iwn_mem_write(sc, IWN_QUEUE_INTR_MASK, 0xffff);
-
-	/* identify active Tx rings (0-7) */
-	iwn_mem_write(sc, IWN_TX_ACTIVE, 0xff);
-
-	/* mark Tx rings (4 EDCA + cmd + 2 HCCA) as active */
-	for (qid = 0; qid < 7; qid++) {
-		iwn_mem_write(sc, IWN_TXQ_STATUS(qid),
-		    IWN_TXQ_STATUS_ACTIVE | qid << 1);
-	}
-
-	iwn_mem_unlock(sc);
-}
-
-void
-iwn_stop_master(struct iwn_softc *sc)
-{
-	uint32_t tmp;
-	int ntries;
-
-	tmp = IWN_READ(sc, IWN_RESET);
-	IWN_WRITE(sc, IWN_RESET, tmp | IWN_STOP_MASTER);
-
-	tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	if ((tmp & IWN_GPIO_PWR_STATUS) == IWN_GPIO_PWR_SLEEP)
-		return;	/* already asleep */
-
-	for (ntries = 0; ntries < 100; ntries++) {
-		if (IWN_READ(sc, IWN_RESET) & IWN_MASTER_DISABLED)
-			break;
-		DELAY(10);
-	}
-	if (ntries == 100)
-		device_printf(sc->sc_dev,
-		    "%s: timeout waiting for master\n", __func__);
-}
-
 int
-iwn_reset(struct iwn_softc *sc)
+iwn4965_post_alive(struct iwn_softc *sc)
 {
-	uint32_t tmp;
-	int ntries;
+	int error, qid;
 
-	/* clear any pending interrupts */
-	IWN_WRITE(sc, IWN_INTR, 0xffffffff);
+	if ((error = iwn_nic_lock(sc)) != 0)
+		return error;
 
-	tmp = IWN_READ(sc, IWN_CHICKEN);
-	IWN_WRITE(sc, IWN_CHICKEN, tmp | IWN_CHICKEN_DISLOS);
+	/* Clear TX scheduler's state in SRAM. */
+	sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
+	iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
+	    IWN4965_SCHED_CTX_LEN);
 
-	tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_INIT);
+	/* Set physical address of TX scheduler rings (1KB aligned.) */
+	iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
 
-	/* wait for clock stabilization */
+	IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
+
+	/* Disable chain mode for all our 16 queues. */
+	iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);
+
+	for (qid = 0; qid < IWN4965_NTXQUEUES; qid++) {
+		iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), 0);
+		IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
+
+		/* Set scheduler window size. */
+		iwn_mem_write(sc, sc->sched_base +
+		    IWN4965_SCHED_QUEUE_OFFSET(qid), IWN_SCHED_WINSZ);
+		/* Set scheduler frame limit. */
+		iwn_mem_write(sc, sc->sched_base +
+		    IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
+		    IWN_SCHED_LIMIT << 16);
+	}
+
+	/* Enable interrupts for all our 16 queues. */
+	iwn_prph_write(sc, IWN4965_SCHED_INTR_MASK, 0xffff);
+	/* Identify TX FIFO rings (0-7). */
+	iwn_prph_write(sc, IWN4965_SCHED_TXFACT, 0xff);
+
+	/* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
+	for (qid = 0; qid < 7; qid++) {
+		static uint8_t qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 };
+		iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
+		    IWN4965_TXQ_STATUS_ACTIVE | qid2fifo[qid] << 1);
+	}
+	iwn_nic_unlock(sc);
+	return 0;
+}
+
+/*
+ * This function is called after the initialization or runtime firmware
+ * notifies us of its readiness (called in a process context.)
+ */
+int
+iwn5000_post_alive(struct iwn_softc *sc)
+{
+	struct iwn5000_wimax_coex wimax;
+	int error, qid;
+
+	if ((error = iwn_nic_lock(sc)) != 0)
+		return error;
+
+	/* Clear TX scheduler's state in SRAM. */
+	sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
+	iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
+	    IWN5000_SCHED_CTX_LEN);
+
+	/* Set physical address of TX scheduler rings (1KB aligned.) */
+	iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
+
+	IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
+
+	/* Enable chain mode for all our 20 queues. */
+	iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffff);
+	iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
+
+	for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
+		iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
+		IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
+
+		iwn_mem_write(sc, sc->sched_base +
+		    IWN5000_SCHED_QUEUE_OFFSET(qid), 0);
+		/* Set scheduler window size and frame limit. */
+		iwn_mem_write(sc, sc->sched_base +
+		    IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
+		    IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
+	}
+
+	/* Enable interrupts for all our 20 queues. */
+	iwn_prph_write(sc, IWN5000_SCHED_INTR_MASK, 0xfffff);
+	/* Identify TX FIFO rings (0-7). */
+	iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);
+
+	/* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
+	for (qid = 0; qid < 7; qid++) {
+		static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
+		iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
+		    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
+	}
+	iwn_nic_unlock(sc);
+
+	/* Configure WiMAX (IEEE 802.16e) coexistence. */
+	memset(&wimax, 0, sizeof wimax);
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: Configuring WiMAX coexistence\n",
+	    __func__);
+	error = iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not configure WiMAX coexistence, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
+		struct iwn5000_phy_calib_crystal cmd;
+
+		/* Perform crystal calibration. */
+		memset(&cmd, 0, sizeof cmd);
+		cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
+		cmd.ngroups = 1;
+		cmd.isvalid = 1;
+		cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff;
+		cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff;
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+		    "sending crystal calibration %d, %d\n",
+		    cmd.cap_pin[0], cmd.cap_pin[1]);
+		error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "%s: crystal calibration failed, error %d\n",
+			    __func__, error);
+			return error;
+		}
+	}
+	if (sc->sc_flags & IWN_FLAG_FIRST_BOOT) {
+		/* Query calibration from the initialization firmware. */
+		if ((error = iwn5000_query_calibration(sc)) != 0) {
+			device_printf(sc->sc_dev,
+			    "%s: could not query calibration, error %d\n",
+			    __func__, error);
+			return error;
+		}
+		/*
+		 * We have the calibration results now so we can skip
+		 * loading the initialization firmware next time.
+		 */
+		sc->sc_flags &= ~IWN_FLAG_FIRST_BOOT;
+
+		/* Reboot (call ourselves recursively!) */
+		iwn_hw_stop(sc);
+		error = iwn_hw_init(sc);
+	} else {
+		/* Send calibration results to runtime firmware. */
+		error = iwn5000_send_calibration(sc);
+	}
+	return error;
+}
+
+/*
+ * The firmware boot code is small and is intended to be copied directly into
+ * the NIC internal memory (no DMA transfer.)
+ */
+int
+iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
+{
+	int error, ntries;
+
+	size /= sizeof (uint32_t);
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	/* Copy microcode image into NIC memory. */
+	iwn_prph_write_region_4(sc, IWN_BSM_SRAM_BASE,
+	    (const uint32_t *)ucode, size);
+
+	iwn_prph_write(sc, IWN_BSM_WR_MEM_SRC, 0);
+	iwn_prph_write(sc, IWN_BSM_WR_MEM_DST, IWN_FW_TEXT_BASE);
+	iwn_prph_write(sc, IWN_BSM_WR_DWCOUNT, size);
+
+	/* Start boot load now. */
+	iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START);
+
+	/* Wait for transfer to complete. */
 	for (ntries = 0; ntries < 1000; ntries++) {
-		if (IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_CLOCK)
+		if (!(iwn_prph_read(sc, IWN_BSM_WR_CTRL) &
+		    IWN_BSM_WR_CTRL_START))
 			break;
 		DELAY(10);
 	}
 	if (ntries == 1000) {
-		device_printf(sc->sc_dev,
-		    "%s: timeout waiting for clock stabilization\n", __func__);
+		device_printf(sc->sc_dev, "%s: could not load boot firmware\n",
+		    __func__);
+		iwn_nic_unlock(sc);
 		return ETIMEDOUT;
 	}
+
+	/* Enable boot after power up. */
+	iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START_EN);
+
+	iwn_nic_unlock(sc);
+	return 0;
+}
+
+int
+iwn4965_load_firmware(struct iwn_softc *sc)
+{
+	struct iwn_fw_info *fw = &sc->fw;
+	struct iwn_dma_info *dma = &sc->fw_dma;
+	int error;
+
+	/* Copy initialization sections into pre-allocated DMA-safe memory. */
+	memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
+	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
+	    fw->init.text, fw->init.textsz);
+
+	/* Tell adapter where to find initialization sections. */
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+	iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
+	iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz);
+	iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
+	    (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
+	iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE, fw->init.textsz);
+	iwn_nic_unlock(sc);
+
+	/* Load firmware boot code. */
+	error = iwn4965_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "%s: could not load boot firmware\n",
+		    __func__);
+		return error;
+	}
+	/* Now press "execute". */
+	IWN_WRITE(sc, IWN_RESET, 0);
+
+	/* Wait at most one second for first alive notification. */
+	error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
+	if (error) {
+		device_printf(sc->sc_dev,
+		    "%s: timeout waiting for adapter to initialize, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	/* Retrieve current temperature for initial TX power calibration. */
+	sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
+	sc->temp = iwn4965_get_temperature(sc);
+
+	/* Copy runtime sections into pre-allocated DMA-safe memory. */
+	memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
+	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
+	    fw->main.text, fw->main.textsz);
+
+	/* Tell adapter where to find runtime sections. */
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
+	iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz);
+	iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
+	    (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
+	iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE,
+	    IWN_FW_UPDATED | fw->main.textsz);
+	iwn_nic_unlock(sc);
+
+	return 0;
+}
+
+int
+iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
+    const uint8_t *section, int size)
+{
+	struct iwn_dma_info *dma = &sc->fw_dma;
+	int error;
+
+	/* Copy firmware section into pre-allocated DMA-safe memory. */
+	memcpy(dma->vaddr, section, size);
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
+	    IWN_FH_TX_CONFIG_DMA_PAUSE);
+
+	IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_DMACHNL), dst);
+	IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_DMACHNL),
+	    IWN_LOADDR(dma->paddr));
+	IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_DMACHNL),
+	    IWN_HIADDR(dma->paddr) << 28 | size);
+	IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_DMACHNL),
+	    IWN_FH_TXBUF_STATUS_TBNUM(1) |
+	    IWN_FH_TXBUF_STATUS_TBIDX(1) |
+	    IWN_FH_TXBUF_STATUS_TFBD_VALID);
+
+	/* Kick Flow Handler to start DMA transfer. */
+	IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
+	    IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD);
+
+	iwn_nic_unlock(sc);
+
+	/* Wait at most five seconds for FH DMA transfer to complete. */
+	return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
+}
+
+int
+iwn5000_load_firmware(struct iwn_softc *sc)
+{
+	struct iwn_fw_part *fw;
+	int error;
+
+	/* Load the initialization firmware on first boot only. */
+	fw = (sc->sc_flags & IWN_FLAG_FIRST_BOOT) ?
+	    &sc->fw.init : &sc->fw.main;
+
+	error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
+	    fw->text, fw->textsz);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not load firmware %s section, error %d\n",
+		    __func__, ".text", error);
+		return error;
+	}
+	error = iwn5000_load_firmware_section(sc, IWN_FW_DATA_BASE,
+	    fw->data, fw->datasz);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not load firmware %s section, error %d\n",
+		    __func__, ".data", error);
+		return error;
+	}
+
+	/* Now press "execute". */
+	IWN_WRITE(sc, IWN_RESET, 0);
+	return 0;
+}
+
+int
+iwn_read_firmware(struct iwn_softc *sc)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	const struct iwn_firmware_hdr *hdr;
+	struct iwn_fw_info *fw = &sc->fw;
+	size_t size;
+
+	IWN_UNLOCK(sc);
+
+	/* Read firmware image from filesystem. */
+	sc->fw_fp = firmware_get(sc->fwname);
+	if (sc->fw_fp == NULL) {
+		device_printf(sc->sc_dev,
+		    "%s: could not load firmare image \"%s\"\n", __func__,
+		     sc->fwname);
+		IWN_LOCK(sc);
+		return EINVAL;
+	}
+	IWN_LOCK(sc);
+
+	size = sc->fw_fp->datasize;
+	if (size < sizeof (*hdr)) {
+		device_printf(sc->sc_dev,
+		    "%s: truncated firmware header: %zu bytes\n",
+		    __func__, size);
+		return EINVAL;
+	}
+
+	/* Extract firmware header information. */
+	hdr = (const struct iwn_firmware_hdr *)sc->fw_fp->data;
+	fw->main.textsz = le32toh(hdr->main_textsz);
+	fw->main.datasz = le32toh(hdr->main_datasz);
+	fw->init.textsz = le32toh(hdr->init_textsz);
+	fw->init.datasz = le32toh(hdr->init_datasz);
+	fw->boot.textsz = le32toh(hdr->boot_textsz);
+	fw->boot.datasz = 0;
+
+	/* Sanity-check firmware header. */
+	if (fw->main.textsz > hal->fw_text_maxsz ||
+	    fw->main.datasz > hal->fw_data_maxsz ||
+	    fw->init.textsz > hal->fw_text_maxsz ||
+	    fw->init.datasz > hal->fw_data_maxsz ||
+	    fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
+	    (fw->boot.textsz & 3) != 0) {
+		device_printf(sc->sc_dev, "%s: invalid firmware header\n",
+		    __func__);
+		return EINVAL;
+	}
+
+	/* Check that all firmware sections fit. */
+	if (size < sizeof (*hdr) + fw->main.textsz + fw->main.datasz +
+	    fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
+		device_printf(sc->sc_dev,
+		    "%s: firmware file too short: %zu bytes\n",
+		    __func__, size);
+		return EINVAL;
+	}
+
+	/* Get pointers to firmware sections. */
+	fw->main.text = (const uint8_t *)(hdr + 1);
+	fw->main.data = fw->main.text + fw->main.textsz;
+	fw->init.text = fw->main.data + fw->main.datasz;
+	fw->init.data = fw->init.text + fw->init.textsz;
+	fw->boot.text = fw->init.data + fw->init.datasz;
+
 	return 0;
 }
 
 void
-iwn_hw_config(struct iwn_softc *sc)
+iwn_unload_firmware(struct iwn_softc *sc)
 {
-	uint32_t tmp, hw;
+	if (sc->fw_fp != NULL) {
+		firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
+		sc->fw_fp = NULL;
+	}
+}
 
-	/* enable interrupts mitigation */
-	IWN_WRITE(sc, IWN_INTR_MIT, 512 / 32);
+int
+iwn_clock_wait(struct iwn_softc *sc)
+{
+	int ntries;
 
-	/* voodoo from the reference driver */
-	tmp = pci_read_config(sc->sc_dev, PCIR_REVID,1);
-	if ((tmp & 0x80) && (tmp & 0x7f) < 8) {
-		/* enable "no snoop" field */
-		tmp = pci_read_config(sc->sc_dev, 0xe8, 1);
-		tmp &= ~IWN_DIS_NOSNOOP;
-		/* clear device specific PCI configuration register 0x41 */
-		pci_write_config(sc->sc_dev, 0xe8, tmp, 1);
+	/* Set "initialization complete" bit. */
+	IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
+
+	/* Wait for clock stabilization. */
+	for (ntries = 0; ntries < 25000; ntries++) {
+		if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
+			return 0;
+		DELAY(100);
+	}
+	device_printf(sc->sc_dev,
+	    "%s: timeout waiting for clock stabilization\n", __func__);
+	return ETIMEDOUT;
+}
+
+int
+iwn4965_apm_init(struct iwn_softc *sc)
+{
+	int error;
+
+	/* Disable L0s. */
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
+
+	error = iwn_clock_wait(sc);
+	if (error != 0)
+		return error;
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	/* Enable DMA. */
+	iwn_prph_write(sc, IWN_APMG_CLK_CTRL,
+	    IWN_APMG_CLK_CTRL_DMA_CLK_RQT | IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
+	DELAY(20);
+
+	/* Disable L1. */
+	iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
+	iwn_nic_unlock(sc);
+
+	return 0;
+}
+
+int
+iwn5000_apm_init(struct iwn_softc *sc)
+{
+	int error;
+
+	/* Disable L0s. */
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
+
+	/* Set Flow Handler wait threshold to the maximum. */
+	IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
+
+	/* Enable HAP to move adapter from L1a to L0s. */
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
+
+	if (sc->hw_type != IWN_HW_REV_TYPE_6000 &&
+	    sc->hw_type != IWN_HW_REV_TYPE_6050)
+		IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
+
+	error = iwn_clock_wait(sc);
+	if (error != 0)
+		return error;
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	/* Enable DMA. */
+	iwn_prph_write(sc, IWN_APMG_CLK_CTRL, IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
+	DELAY(20);
+
+	/* Disable L1. */
+	iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
+	iwn_nic_unlock(sc);
+
+	return 0;
+}
+
+void
+iwn_apm_stop_master(struct iwn_softc *sc)
+{
+	int ntries;
+
+	IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
+			return;
+		DELAY(10);
+	}
+	device_printf(sc->sc_dev, "%s: timeout waiting for master\n",
+	    __func__);
+}
+
+void
+iwn_apm_stop(struct iwn_softc *sc)
+{
+	iwn_apm_stop_master(sc);
+
+	IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
+	DELAY(10);
+	/* Clear "initialization complete" bit. */
+	IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
+}
+
+int
+iwn4965_nic_config(struct iwn_softc *sc)
+{
+	uint32_t tmp;
+
+	/* Retrieve PCIe Active State Power Management (ASPM). */
+	tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
+	if (tmp & 0x02)		/* L1 Entry enabled. */
+		IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
+	else
+		IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
+
+	if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
+		/*
+		 * I don't believe this to be correct but this is what the
+		 * vendor driver is doing. Probably the bits should not be
+		 * shifted in IWN_RFCFG_*.
+		 */
+		IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
+		    IWN_RFCFG_TYPE(sc->rfcfg) |
+		    IWN_RFCFG_STEP(sc->rfcfg) |
+		    IWN_RFCFG_DASH(sc->rfcfg));
+	}
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
+	    IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
+	return 0;
+}
+
+int
+iwn5000_nic_config(struct iwn_softc *sc)
+{
+	uint32_t tmp;
+	int error;
+
+	/* Retrieve PCIe Active State Power Management (ASPM). */
+	tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
+	if (tmp & 0x02)		/* L1 Entry enabled. */
+		IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
+	else
+		IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
+
+	if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
+		IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
+		    IWN_RFCFG_TYPE(sc->rfcfg) |
+		    IWN_RFCFG_STEP(sc->rfcfg) |
+		    IWN_RFCFG_DASH(sc->rfcfg));
+	}
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
+	    IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+	iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
+	iwn_nic_unlock(sc);
+	return 0;
+}
+
+/*
+ * Take NIC ownership over Intel Active Management Technology (AMT).
+ */
+int
+iwn_hw_prepare(struct iwn_softc *sc)
+{
+	int ntries;
+
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_PREPARE);
+	for (ntries = 0; ntries < 15000; ntries++) {
+		if (!(IWN_READ(sc, IWN_HW_IF_CONFIG) &
+		    IWN_HW_IF_CONFIG_PREPARE_DONE))
+			break;
+		DELAY(10);
+	}
+	if (ntries == 15000)
+		return ETIMEDOUT;
+
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
+	for (ntries = 0; ntries < 5; ntries++) {
+		if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
+		    IWN_HW_IF_CONFIG_NIC_READY)
+			return 0;
+		DELAY(10);
+	}
+	return ETIMEDOUT;
+}
+
+int
+iwn_hw_init(struct iwn_softc *sc)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	int error, chnl, qid;
+
+	/* Clear pending interrupts. */
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+
+	error = hal->apm_init(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not power ON adapter, error %d\n",
+		    __func__, error);
+		return error;
 	}
 
-	/* disable L1 entry to work around a hardware bug */
-	tmp = pci_read_config(sc->sc_dev, 0xf0, 1);
-	tmp &= ~IWN_ENA_L1;
-	pci_write_config(sc->sc_dev, 0xf0, tmp, 1 );
+	/* Select VMAIN power source. */
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+	iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_PWR_SRC_MASK);
+	iwn_nic_unlock(sc);
 
-	hw = IWN_READ(sc, IWN_HWCONFIG);
-	IWN_WRITE(sc, IWN_HWCONFIG, hw | 0x310);
+	/* Perform adapter-specific initialization. */
+	error = hal->nic_config(sc);
+	if (error != 0)
+		return error;
 
-	iwn_mem_lock(sc);
-	tmp = iwn_mem_read(sc, IWN_MEM_POWER);
-	iwn_mem_write(sc, IWN_MEM_POWER, tmp | IWN_POWER_RESET);
+	/* Initialize RX ring. */
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+	IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
+	IWN_WRITE(sc, IWN_FH_RX_WPTR, 0);
+	/* Set physical address of RX ring (256-byte aligned.) */
+	IWN_WRITE(sc, IWN_FH_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
+	/* Set physical address of RX status (16-byte aligned.) */
+	IWN_WRITE(sc, IWN_FH_STATUS_WPTR, sc->rxq.stat_dma.paddr >> 4);
+	/* Enable RX. */
+	IWN_WRITE(sc, IWN_FH_RX_CONFIG,
+	    IWN_FH_RX_CONFIG_ENA           |
+	    IWN_FH_RX_CONFIG_IGN_RXF_EMPTY |	/* HW bug workaround */
+	    IWN_FH_RX_CONFIG_IRQ_DST_HOST  |
+	    IWN_FH_RX_CONFIG_SINGLE_FRAME  |
+	    IWN_FH_RX_CONFIG_RB_TIMEOUT(0) |
+	    IWN_FH_RX_CONFIG_NRBD(IWN_RX_RING_COUNT_LOG));
+	iwn_nic_unlock(sc);
+	IWN_WRITE(sc, IWN_FH_RX_WPTR, (IWN_RX_RING_COUNT - 1) & ~7);
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	/* Initialize TX scheduler. */
+	iwn_prph_write(sc, hal->sched_txfact_addr, 0);
+
+	/* Set physical address of "keep warm" page (16-byte aligned.) */
+	IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4);
+
+	/* Initialize TX rings. */
+	for (qid = 0; qid < hal->ntxqs; qid++) {
+		struct iwn_tx_ring *txq = &sc->txq[qid];
+
+		/* Set physical address of TX ring (256-byte aligned.) */
+		IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid),
+		    txq->desc_dma.paddr >> 8);
+	}
+	iwn_nic_unlock(sc);
+
+	/* Enable DMA channels. */
+	for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
+		IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl),
+		    IWN_FH_TX_CONFIG_DMA_ENA |
+		    IWN_FH_TX_CONFIG_DMA_CREDIT_ENA);
+	}
+
+	/* Clear "radio off" and "commands blocked" bits. */
+	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
+	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CMD_BLOCKED);
+
+	/* Clear pending interrupts. */
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+	/* Enable interrupt coalescing. */
+	IWN_WRITE(sc, IWN_INT_COALESCING, 512 / 8);
+	/* Enable interrupts. */
+	IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
+
+	/* _Really_ make sure "radio off" bit is cleared! */
+	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
+	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
+
+	error = hal->load_firmware(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not load firmware, error %d\n",
+		    __func__, error);
+		return error;
+	}
+	/* Wait at most one second for firmware alive notification. */
+	error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: timeout waiting for adapter to initialize, error %d\n",
+		    __func__, error);
+		return error;
+	}
+	/* Do post-firmware initialization. */
+	return hal->post_alive(sc);
+}
+
+void
+iwn_hw_stop(struct iwn_softc *sc)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	uint32_t tmp;
+	int chnl, qid, ntries;
+
+	IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
+
+	/* Disable interrupts. */
+	IWN_WRITE(sc, IWN_MASK, 0);
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+	IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
+
+	/* Make sure we no longer hold the NIC lock. */
+	iwn_nic_unlock(sc);
+
+	/* Stop TX scheduler. */
+	iwn_prph_write(sc, hal->sched_txfact_addr, 0);
+
+	/* Stop all DMA channels. */
+	if (iwn_nic_lock(sc) == 0) {
+		for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
+			IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0);
+			for (ntries = 0; ntries < 200; ntries++) {
+				tmp = IWN_READ(sc, IWN_FH_TX_STATUS);
+				if ((tmp & IWN_FH_TX_STATUS_IDLE(chnl)) ==
+				    IWN_FH_TX_STATUS_IDLE(chnl))
+					break;
+				DELAY(10);
+			}
+		}
+		iwn_nic_unlock(sc);
+	}
+
+	/* Stop RX ring. */
+	iwn_reset_rx_ring(sc, &sc->rxq);
+
+	/* Reset all TX rings. */
+	for (qid = 0; qid < hal->ntxqs; qid++)
+		iwn_reset_tx_ring(sc, &sc->txq[qid]);
+
+	if (iwn_nic_lock(sc) == 0) {
+		iwn_prph_write(sc, IWN_APMG_CLK_DIS, IWN_APMG_CLK_DMA_RQT);
+		iwn_nic_unlock(sc);
+	}
 	DELAY(5);
-	tmp = iwn_mem_read(sc, IWN_MEM_POWER);
-	iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~IWN_POWER_RESET);
-	iwn_mem_unlock(sc);
+
+	/* Power OFF adapter. */
+	iwn_apm_stop(sc);
 }
 
 void
 iwn_init_locked(struct iwn_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_ifp;
-	uint32_t tmp;
-	int error, qid;
+	int error;
 
 	IWN_LOCK_ASSERT(sc);
 
-	/* load the firmware */
-	if (sc->fw_fp == NULL && (error = iwn_load_firmware(sc)) != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not load firmware, error %d\n", __func__, error);
-		return;
+	iwn_stop_locked(sc);
+
+	error = iwn_hw_prepare(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "%s: hardware not ready, eror %d\n",
+		    __func__, error);
+		goto fail;
 	}
 
-	error = iwn_reset(sc);
+	/* Check that the radio is not disabled by hardware switch. */
+	if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
+		device_printf(sc->sc_dev,
+		    "%s: radio is disabled by hardware switch\n",
+		    __func__);
+		error = EPERM;	/* :-) */
+		goto fail;
+	}
+
+	/* Read firmware images from the filesystem. */
+	error = iwn_read_firmware(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not reset adapter, error %d\n", __func__, error);
-		return;
+		    "%s: could not read firmware, error %d\n",
+		    __func__, error);
+		goto fail;
 	}
 
-	iwn_mem_lock(sc);
-	iwn_mem_read(sc, IWN_CLOCK_CTL);
-	iwn_mem_write(sc, IWN_CLOCK_CTL, 0xa00);
-	iwn_mem_read(sc, IWN_CLOCK_CTL);
-	iwn_mem_unlock(sc);
-
-	DELAY(20);
-
-	iwn_mem_lock(sc);
-	tmp = iwn_mem_read(sc, IWN_MEM_PCIDEV);
-	iwn_mem_write(sc, IWN_MEM_PCIDEV, tmp | 0x800);
-	iwn_mem_unlock(sc);
-
-	iwn_mem_lock(sc);
-	tmp = iwn_mem_read(sc, IWN_MEM_POWER);
-	iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~0x03000000);
-	iwn_mem_unlock(sc);
-
-	iwn_hw_config(sc);
-
-	/* init Rx ring */
-	iwn_mem_lock(sc);
-	IWN_WRITE(sc, IWN_RX_CONFIG, 0);
-	IWN_WRITE(sc, IWN_RX_WIDX, 0);
-	/* Rx ring is aligned on a 256-byte boundary */
-	IWN_WRITE(sc, IWN_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
-	/* shared area is aligned on a 16-byte boundary */
-	IWN_WRITE(sc, IWN_RW_WIDX_PTR, (sc->shared_dma.paddr +
-	    offsetof(struct iwn_shared, closed_count)) >> 4);
-	IWN_WRITE(sc, IWN_RX_CONFIG, 0x80601000);
-	iwn_mem_unlock(sc);
-
-	IWN_WRITE(sc, IWN_RX_WIDX, (IWN_RX_RING_COUNT - 1) & ~7);
-
-	iwn_mem_lock(sc);
-	iwn_mem_write(sc, IWN_TX_ACTIVE, 0);
-
-	/* set physical address of "keep warm" page */
-	IWN_WRITE(sc, IWN_KW_BASE, sc->kw_dma.paddr >> 4);
-
-	/* init Tx rings */
-	for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
-		struct iwn_tx_ring *txq = &sc->txq[qid];
-		IWN_WRITE(sc, IWN_TX_BASE(qid), txq->desc_dma.paddr >> 8);
-		IWN_WRITE(sc, IWN_TX_CONFIG(qid), 0x80000008);
-	}
-	iwn_mem_unlock(sc);
-
-	/* clear "radio off" and "disable command" bits (reversed logic) */
-	IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
-	IWN_WRITE(sc, IWN_UCODE_CLR, IWN_DISABLE_CMD);
-
-	/* clear any pending interrupts */
-	IWN_WRITE(sc, IWN_INTR, 0xffffffff);
-	/* enable interrupts */
-	IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
-
-	/* not sure why/if this is necessary... */
-	IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
-	IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
-
-	/* check that the radio is not disabled by RF switch */
-	if (!(IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_RF_ENABLED)) {
-		device_printf(sc->sc_dev,
-		    "radio is disabled by hardware switch\n");
-		return;
-	}
-
-	error = iwn_transfer_firmware(sc);
+	/* Initialize hardware and upload firmware. */
+	error = iwn_hw_init(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not load firmware, error %d\n", __func__, error);
-		return;
+		    "%s: could not initialize hardware, error %d\n",
+		    __func__, error);
+		goto fail;
 	}
 
-	/* firmware has notified us that it is alive.. */
-	iwn_post_alive(sc);	/* ..do post alive initialization */
-
-	sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
-	sc->temp = iwn_get_temperature(sc);
-	DPRINTF(sc, IWN_DEBUG_RESET, "%s: temperature=%d\n",
-	   __func__, sc->temp);
-
+	/* Configure adapter now that it is ready. */
 	error = iwn_config(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not configure device, error %d\n",
 		    __func__, error);
-		return;
+		goto fail;
 	}
 
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
+	return;
+
+fail:
+	iwn_stop_locked(sc);
 }
 
 void
@@ -4259,40 +5457,20 @@ void
 iwn_stop_locked(struct iwn_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_ifp;
-	uint32_t tmp;
-	int i;
 
 	IWN_LOCK_ASSERT(sc);
 
-	IWN_WRITE(sc, IWN_RESET, IWN_NEVO_RESET);
+	IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
 
 	sc->sc_tx_timer = 0;
 	callout_stop(&sc->sc_timer_to);
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
-	/* disable interrupts */
-	IWN_WRITE(sc, IWN_MASK, 0);
-	IWN_WRITE(sc, IWN_INTR, 0xffffffff);
-	IWN_WRITE(sc, IWN_INTR_STATUS, 0xffffffff);
-
-	/* reset all Tx rings */
-	for (i = 0; i < IWN_NTXQUEUES; i++)
-		iwn_reset_tx_ring(sc, &sc->txq[i]);
-
-	/* reset Rx ring */
-	iwn_reset_rx_ring(sc, &sc->rxq);
-
-	iwn_mem_lock(sc);
-	iwn_mem_write(sc, IWN_MEM_CLOCK2, 0x200);
-	iwn_mem_unlock(sc);
-
-	DELAY(5);
-	iwn_stop_master(sc);
-
-	tmp = IWN_READ(sc, IWN_RESET);
-	IWN_WRITE(sc, IWN_RESET, tmp | IWN_SW_RESET);
+	/* Power OFF hardware. */
+	iwn_hw_stop(sc);
 }
 
+
 void
 iwn_stop(struct iwn_softc *sc)
 {
@@ -4331,10 +5509,10 @@ iwn_scan_end(struct ieee80211com *ic)
 static void
 iwn_set_channel(struct ieee80211com *ic)
 {
+	const struct ieee80211_channel *c = ic->ic_curchan;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct iwn_softc *sc = ifp->if_softc;
 	struct ieee80211vap *vap;
-	const struct ieee80211_channel *c = ic->ic_curchan;
 	int error;
 
 	vap = TAILQ_FIRST(&ic->ic_vaps);	/* XXX */
@@ -4387,7 +5565,7 @@ iwn_scan_mindwell(struct ieee80211_scan_state *ss)
 }
 
 static void
-iwn_hwreset(void *arg0, int pending)
+iwn_hw_reset(void *arg0, int pending)
 {
 	struct iwn_softc *sc = arg0;
 	struct ifnet *ifp = sc->sc_ifp;
@@ -4398,7 +5576,7 @@ iwn_hwreset(void *arg0, int pending)
 }
 
 static void
-iwn_radioon(void *arg0, int pending)
+iwn_radio_on(void *arg0, int pending)
 {
 	struct iwn_softc *sc = arg0;
 
@@ -4406,7 +5584,7 @@ iwn_radioon(void *arg0, int pending)
 }
 
 static void
-iwn_radiooff(void *arg0, int pending)
+iwn_radio_off(void *arg0, int pending)
 {
 	struct iwn_softc *sc = arg0;
 	struct ifnet *ifp = sc->sc_ifp;
@@ -4431,6 +5609,37 @@ iwn_sysctlattach(struct iwn_softc *sc)
 #endif
 }
 
+static int
+iwn_shutdown(device_t dev)
+{
+	struct iwn_softc *sc = device_get_softc(dev);
+
+	iwn_stop(sc);
+	return 0;
+}
+
+static int
+iwn_suspend(device_t dev)
+{
+	struct iwn_softc *sc = device_get_softc(dev);
+
+	iwn_stop(sc);
+	return 0;
+}
+
+static int
+iwn_resume(device_t dev)
+{
+	struct iwn_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp = sc->sc_ifp;
+
+	pci_write_config(dev, 0x41, 0, 1);
+
+	if (ifp->if_flags & IFF_UP)
+		iwn_init(sc);
+	return 0;
+}
+
 #ifdef IWN_DEBUG
 static const char *
 iwn_intr_str(uint8_t cmd)
@@ -4446,47 +5655,50 @@ iwn_intr_str(uint8_t cmd)
 	case IWN_BEACON_STATISTICS:	return "BEACON_STATS";
 	case IWN_STATE_CHANGED:		return "STATE_CHANGED";
 	case IWN_BEACON_MISSED:		return "BEACON_MISSED";
-	case IWN_AMPDU_RX_START:	return "AMPDU_RX_START";
-	case IWN_AMPDU_RX_DONE:		return "AMPDU_RX_DONE";
+	case IWN_RX_PHY:		return "RX_PHY";
+	case IWN_MPDU_RX_DONE:		return "MPDU_RX_DONE";
 	case IWN_RX_DONE:		return "RX_DONE";
 
 	/* Command Notifications */
 	case IWN_CMD_CONFIGURE:		return "IWN_CMD_CONFIGURE";
 	case IWN_CMD_ASSOCIATE:		return "IWN_CMD_ASSOCIATE";
 	case IWN_CMD_EDCA_PARAMS:	return "IWN_CMD_EDCA_PARAMS";
-	case IWN_CMD_TSF:		return "IWN_CMD_TSF";
-	case IWN_CMD_TX_LINK_QUALITY:	return "IWN_CMD_TX_LINK_QUALITY";
+	case IWN_CMD_TIMING:		return "IWN_CMD_TIMING";
+	case IWN_CMD_LINK_QUALITY:	return "IWN_CMD_LINK_QUALITY";
 	case IWN_CMD_SET_LED:		return "IWN_CMD_SET_LED";
+	case IWN5000_CMD_WIMAX_COEX:	return "IWN5000_CMD_WIMAX_COEX";
+	case IWN5000_CMD_CALIB_CONFIG:	return "IWN5000_CMD_CALIB_CONFIG";
 	case IWN_CMD_SET_POWER_MODE:	return "IWN_CMD_SET_POWER_MODE";
 	case IWN_CMD_SCAN:		return "IWN_CMD_SCAN";
 	case IWN_CMD_TXPOWER:		return "IWN_CMD_TXPOWER";
-	case IWN_CMD_BLUETOOTH:		return "IWN_CMD_BLUETOOTH";
+	case IWN_CMD_TXPOWER_DBM:	return "IWN_CMD_TXPOWER_DBM";
+	case IWN_CMD_BT_COEX:		return "IWN_CMD_BT_COEX";
 	case IWN_CMD_SET_CRITICAL_TEMP:	return "IWN_CMD_SET_CRITICAL_TEMP";
-	case IWN_SENSITIVITY:		return "IWN_SENSITIVITY";
-	case IWN_PHY_CALIB:		return "IWN_PHY_CALIB";
+	case IWN_CMD_SET_SENSITIVITY:	return "IWN_CMD_SET_SENSITIVITY";
+	case IWN_CMD_PHY_CALIB:		return "IWN_CMD_PHY_CALIB";
 	}
 	return "UNKNOWN INTR NOTIF/CMD";
 }
 #endif /* IWN_DEBUG */
 
 static device_method_t iwn_methods[] = {
-        /* Device interface */
-        DEVMETHOD(device_probe,         iwn_probe),
-        DEVMETHOD(device_attach,        iwn_attach),
-        DEVMETHOD(device_detach,        iwn_detach),
-        DEVMETHOD(device_shutdown,      iwn_shutdown),
-        DEVMETHOD(device_suspend,       iwn_suspend),
-        DEVMETHOD(device_resume,        iwn_resume),
-
-        { 0, 0 }
+	/* Device interface */
+	DEVMETHOD(device_probe,		iwn_probe),
+	DEVMETHOD(device_attach,	iwn_attach),
+	DEVMETHOD(device_detach,	iwn_detach),
+	DEVMETHOD(device_shutdown,	iwn_shutdown),
+	DEVMETHOD(device_suspend,	iwn_suspend),
+	DEVMETHOD(device_resume,	iwn_resume),
+	{ 0, 0 }
 };
 
 static driver_t iwn_driver = {
-        "iwn",
-        iwn_methods,
-        sizeof (struct iwn_softc)
+	"iwn",
+	iwn_methods,
+	sizeof (struct iwn_softc)
 };
 static devclass_t iwn_devclass;
+
 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
 MODULE_DEPEND(iwn, pci, 1, 1, 1);
 MODULE_DEPEND(iwn, firmware, 1, 1, 1);
diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h
index 96e58672405..ed514afa12c 100644
--- a/sys/dev/iwn/if_iwnreg.h
+++ b/sys/dev/iwn/if_iwnreg.h
@@ -1,8 +1,8 @@
 /*	$FreeBSD$	*/
-/*	$OpenBSD: if_iwnreg.h,v 1.9 2007/11/27 20:59:40 damien Exp $	*/
+/*	$OpenBSD: if_iwnreg.h,v 1.26 2009/05/29 08:25:45 damien Exp $	*/
 
 /*-
- * Copyright (c) 2007
+ * Copyright (c) 2007, 2008
  *	Damien Bergamini 
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -18,177 +18,326 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define	EDCA_NUM_AC  4
+#define EDCA_NUM_AC	4
 
 #define IWN_TX_RING_COUNT	256
-#define IWN_RX_RING_COUNT	64
+#define IWN_TX_RING_LOMARK	192
+#define IWN_TX_RING_HIMARK	224
+#define IWN_RX_RING_COUNT_LOG	6
+#define IWN_RX_RING_COUNT	(1 << IWN_RX_RING_COUNT_LOG)
 
-#define IWN_NTXQUEUES		16
-#define IWN_NTXCHAINS		2
+#define IWN4965_NTXQUEUES	16
+#define IWN5000_NTXQUEUES	20
 
-/*
- * Rings must be aligned on a 256-byte boundary.
- */
-#define IWN_RING_DMA_ALIGN	256
+#define IWN4965_NDMACHNLS	7
+#define IWN5000_NDMACHNLS	8
 
-/* maximum scatter/gather */
+#define IWN_SRVC_DMACHNL	9
+
+/* Maximum number of DMA segments for TX. */
 #define IWN_MAX_SCATTER	20
 
-/* Rx buffers must be large enough to hold a full 4K A-MPDU */
+/* RX buffers must be large enough to hold a full 4K A-MPDU. */
 #define IWN_RBUF_SIZE	(4 * 1024)
 
+#if defined(__LP64__)
+/* HW supports 36-bit DMA addresses. */
+#define IWN_LOADDR(paddr)	((uint32_t)(paddr))
+#define IWN_HIADDR(paddr)	(((paddr) >> 32) & 0xf)
+#else
+#define IWN_LOADDR(paddr)	(paddr)
+#define IWN_HIADDR(paddr)	(0)
+#endif
+
+/* Base Address Register. */
+#define IWN_PCI_BAR0	PCI_MAPREG_START
+
 /*
  * Control and status registers.
  */
-#define IWN_HWCONFIG		0x000
-#define IWN_INTR_MIT		0x004
-#define IWN_INTR		0x008
+#define IWN_HW_IF_CONFIG	0x000
+#define IWN_INT_COALESCING	0x004
+#define IWN_INT			0x008
 #define IWN_MASK		0x00c
-#define IWN_INTR_STATUS		0x010
+#define IWN_FH_INT		0x010
 #define IWN_RESET		0x020
-#define IWN_GPIO_CTL		0x024
-#define IWN_EEPROM_CTL		0x02c
-#define IWN_UCODE_CLR		0x05c
-#define IWN_CHICKEN		0x100
-#define IWN_QUEUE_OFFSET(qid)	(0x380 + (qid) * 8)
+#define IWN_GP_CNTRL		0x024
+#define IWN_HW_REV		0x028
+#define IWN_EEPROM		0x02c
+#define IWN_EEPROM_GP		0x030
+#define IWN_OTP_GP		0x034
+#define IWN_GIO			0x03c
+#define IWN_UCODE_GP1_CLR	0x05c
+#define IWN_LED			0x094
+#define IWN_GIO_CHICKEN		0x100
+#define IWN_ANA_PLL		0x20c
+#define IWN_DBG_HPET_MEM	0x240
+#define IWN_MEM_RADDR		0x40c
 #define IWN_MEM_WADDR		0x410
 #define IWN_MEM_WDATA		0x418
-#define IWN_WRITE_MEM_ADDR  	0x444
-#define IWN_READ_MEM_ADDR   	0x448
-#define IWN_WRITE_MEM_DATA  	0x44c
-#define IWN_READ_MEM_DATA   	0x450
-#define IWN_TX_WIDX		0x460
+#define IWN_MEM_RDATA		0x41c
+#define IWN_PRPH_WADDR  	0x444
+#define IWN_PRPH_RADDR   	0x448
+#define IWN_PRPH_WDATA  	0x44c
+#define IWN_PRPH_RDATA   	0x450
+#define IWN_HBUS_TARG_WRPTR	0x460
 
-#define IWN_KW_BASE		0x197c
-#define IWN_TX_BASE(qid)	(0x19d0 + (qid) * 4)
-#define IWN_RW_WIDX_PTR		0x1bc0
-#define IWN_RX_BASE		0x1bc4
-#define IWN_RX_WIDX		0x1bc8
-#define IWN_RX_CONFIG		0x1c00
-#define IWN_RX_STATUS		0x1c44
-#define IWN_TX_CONFIG(qid)	(0x1d00 + (qid) * 32)
-#define IWN_TX_STATUS		0x1eb0
+/*
+ * Flow-Handler registers.
+ */
+#define IWN_FH_TFBD_CTRL0(qid)		(0x1900 + (qid) * 8)
+#define IWN_FH_TFBD_CTRL1(qid)		(0x1904 + (qid) * 8)
+#define IWN_FH_KW_ADDR			0x197c
+#define IWN_FH_SRAM_ADDR(qid)		(0x19a4 + (qid) * 4)
+#define IWN_FH_CBBC_QUEUE(qid)		(0x19d0 + (qid) * 4)
+#define IWN_FH_STATUS_WPTR		0x1bc0
+#define IWN_FH_RX_BASE			0x1bc4
+#define IWN_FH_RX_WPTR			0x1bc8
+#define IWN_FH_RX_CONFIG		0x1c00
+#define IWN_FH_RX_STATUS		0x1c44
+#define IWN_FH_TX_CONFIG(qid)		(0x1d00 + (qid) * 32)
+#define IWN_FH_TXBUF_STATUS(qid)	(0x1d08 + (qid) * 32)
+#define IWN_FH_TX_CHICKEN		0x1e98
+#define IWN_FH_TX_STATUS		0x1eb0
 
-#define IWN_SRAM_BASE		0xa02c00
-#define IWN_TX_ACTIVE		(IWN_SRAM_BASE + 0x01c)
-#define IWN_QUEUE_RIDX(qid)	(IWN_SRAM_BASE + 0x064 + (qid) * 4)
-#define IWN_SELECT_QCHAIN	(IWN_SRAM_BASE + 0x0d0)
-#define IWN_QUEUE_INTR_MASK	(IWN_SRAM_BASE + 0x0e4)
-#define IWN_TXQ_STATUS(qid)	(IWN_SRAM_BASE + 0x104 + (qid) * 4)
+/*
+ * TX scheduler registers.
+ */
+#define IWN_SCHED_BASE			0xa02c00
+#define IWN_SCHED_SRAM_ADDR		(IWN_SCHED_BASE + 0x000)
+#define IWN5000_SCHED_DRAM_ADDR		(IWN_SCHED_BASE + 0x008)
+#define IWN4965_SCHED_DRAM_ADDR		(IWN_SCHED_BASE + 0x010)
+#define IWN5000_SCHED_TXFACT		(IWN_SCHED_BASE + 0x010)
+#define IWN4965_SCHED_TXFACT		(IWN_SCHED_BASE + 0x01c)
+#define IWN4965_SCHED_QUEUE_RDPTR(qid)	(IWN_SCHED_BASE + 0x064 + (qid) * 4)
+#define IWN5000_SCHED_QUEUE_RDPTR(qid)	(IWN_SCHED_BASE + 0x068 + (qid) * 4)
+#define IWN4965_SCHED_QCHAIN_SEL	(IWN_SCHED_BASE + 0x0d0)
+#define IWN4965_SCHED_INTR_MASK		(IWN_SCHED_BASE + 0x0e4)
+#define IWN5000_SCHED_QCHAIN_SEL	(IWN_SCHED_BASE + 0x0e8)
+#define IWN4965_SCHED_QUEUE_STATUS(qid)	(IWN_SCHED_BASE + 0x104 + (qid) * 4)
+#define IWN5000_SCHED_INTR_MASK		(IWN_SCHED_BASE + 0x108)
+#define IWN5000_SCHED_QUEUE_STATUS(qid)	(IWN_SCHED_BASE + 0x10c + (qid) * 4)
+#define IWN5000_SCHED_AGGR_SEL		(IWN_SCHED_BASE + 0x248)
+
+/*
+ * Offsets in TX scheduler's SRAM.
+ */
+#define IWN4965_SCHED_CTX_OFF		0x380
+#define IWN4965_SCHED_CTX_LEN		416
+#define IWN4965_SCHED_QUEUE_OFFSET(qid)	(0x380 + (qid) * 8)
+#define IWN4965_SCHED_TRANS_TBL(qid)	(0x500 + (qid) * 2)
+#define IWN5000_SCHED_CTX_OFF		0x600
+#define IWN5000_SCHED_CTX_LEN		520
+#define IWN5000_SCHED_QUEUE_OFFSET(qid)	(0x600 + (qid) * 8)
+#define IWN5000_SCHED_TRANS_TBL(qid)	(0x7e0 + (qid) * 2)
 
 /*
  * NIC internal memory offsets.
  */
 #define IWN_CLOCK_CTL		0x3000
-#define IWN_MEM_CLOCK2		0x3008
-#define IWN_MEM_POWER		0x300c
-#define IWN_MEM_PCIDEV		0x3010
-#define IWN_MEM_UCODE_CTL	0x3400
-#define IWN_MEM_UCODE_SRC	0x3404
-#define IWN_MEM_UCODE_DST	0x3408
-#define IWN_MEM_UCODE_SIZE	0x340c
-#define IWN_MEM_TEXT_BASE	0x3490
-#define IWN_MEM_TEXT_SIZE	0x3494
-#define IWN_MEM_DATA_BASE	0x3498
-#define IWN_MEM_DATA_SIZE	0x349c
-#define IWN_MEM_UCODE_BASE	0x3800
+#define IWN_APMG_CLK_CTRL	0x3004
+#define IWN_APMG_CLK_DIS	0x3008
+#define IWN_APMG_PS		0x300c
+#define IWN_APMG_PCI_STT	0x3010
+#define IWN_BSM_WR_CTRL		0x3400
+#define IWN_BSM_WR_MEM_SRC	0x3404
+#define IWN_BSM_WR_MEM_DST	0x3408
+#define IWN_BSM_WR_DWCOUNT	0x340c
+#define IWN_BSM_DRAM_TEXT_ADDR	0x3490
+#define IWN_BSM_DRAM_TEXT_SIZE	0x3494
+#define IWN_BSM_DRAM_DATA_ADDR	0x3498
+#define IWN_BSM_DRAM_DATA_SIZE	0x349c
+#define IWN_BSM_SRAM_BASE	0x3800
 
+/* Possible values for IWN_APMG_CLK_DIS. */
+#define IWN_APMG_CLK_DMA_RQT	(1 << 9)
 
-/* possible flags for register IWN_HWCONFIG */
-#define IWN_HW_EEPROM_LOCKED	(1 << 21)
+/* Possible flags for register IWN_HW_IF_CONFIG. */
+#define IWN_HW_IF_CONFIG_4965_R		(1 <<  4)
+#define IWN_HW_IF_CONFIG_MAC_SI		(1 <<  8)
+#define IWN_HW_IF_CONFIG_RADIO_SI	(1 <<  9)
+#define IWN_HW_IF_CONFIG_EEPROM_LOCKED	(1 << 21)
+#define IWN_HW_IF_CONFIG_NIC_READY	(1 << 22)
+#define IWN_HW_IF_CONFIG_HAP_WAKE_L1A	(1 << 23)
+#define IWN_HW_IF_CONFIG_PREPARE_DONE	(1 << 25)
+#define IWN_HW_IF_CONFIG_PREPARE	(1 << 27)
 
-/* possible flags for registers IWN_READ_MEM_ADDR/IWN_WRITE_MEM_ADDR */
-#define IWN_MEM_4	((sizeof (uint32_t) - 1) << 24)
+/* Possible flags for registers IWN_PRPH_RADDR/IWN_PRPH_WADDR. */
+#define IWN_PRPH_DWORD	((sizeof (uint32_t) - 1) << 24)
 
-/* possible values for IWN_MEM_UCODE_DST */
-#define IWN_FW_TEXT	0x00000000
+/* Possible values for IWN_BSM_WR_MEM_DST. */
+#define IWN_FW_TEXT_BASE	0x00000000
+#define IWN_FW_DATA_BASE	0x00800000
 
-/* possible flags for register IWN_RESET */
-#define IWN_NEVO_RESET		(1 << 0)
-#define IWN_SW_RESET		(1 << 7)
-#define IWN_MASTER_DISABLED	(1 << 8)
-#define IWN_STOP_MASTER		(1 << 9)
+/* Possible flags for register IWN_RESET. */
+#define IWN_RESET_NEVO			(1 << 0)
+#define IWN_RESET_SW			(1 << 7)
+#define IWN_RESET_MASTER_DISABLED	(1 << 8)
+#define IWN_RESET_STOP_MASTER		(1 << 9)
 
-/* possible flags for register IWN_GPIO_CTL */
-#define IWN_GPIO_CLOCK		(1 << 0)
-#define IWN_GPIO_INIT		(1 << 2)
-#define IWN_GPIO_MAC		(1 << 3)
-#define IWN_GPIO_SLEEP		(1 << 4)
-#define IWN_GPIO_PWR_STATUS	0x07000000
-#define IWN_GPIO_PWR_SLEEP	(4 << 24)
-#define IWN_GPIO_RF_ENABLED	(1 << 27)
+/* Possible flags for register IWN_GP_CNTRL. */
+#define IWN_GP_CNTRL_MAC_ACCESS_ENA	(1 << 0)
+#define IWN_GP_CNTRL_MAC_CLOCK_READY	(1 << 0)
+#define IWN_GP_CNTRL_INIT_DONE		(1 << 2)
+#define IWN_GP_CNTRL_MAC_ACCESS_REQ	(1 << 3)
+#define IWN_GP_CNTRL_SLEEP		(1 << 4)
+#define IWN_GP_CNTRL_RFKILL		(1 << 27)
 
-/* possible flags for register IWN_CHICKEN */
-#define IWN_CHICKEN_DISLOS	(1 << 29)
+/* Possible flags for register IWN_HW_REV. */
+#define IWN_HW_REV_TYPE_SHIFT	4
+#define IWN_HW_REV_TYPE_MASK	0x000000f0
+#define IWN_HW_REV_TYPE_4965	0
+#define IWN_HW_REV_TYPE_5300	2
+#define IWN_HW_REV_TYPE_5350	3
+#define IWN_HW_REV_TYPE_5150	4
+#define IWN_HW_REV_TYPE_5100	5
+#define IWN_HW_REV_TYPE_1000	6
+#define IWN_HW_REV_TYPE_6000	7
+#define IWN_HW_REV_TYPE_6050	8
 
-/* possible flags for register IWN_UCODE_CLR */
-#define IWN_RADIO_OFF		(1 << 1)
-#define IWN_DISABLE_CMD		(1 << 2)
-#define IWN_CTEMP_STOP_RF	(1 << 3)
+/* Possible flags for register IWN_GIO_CHICKEN. */
+#define IWN_GIO_CHICKEN_L1A_NO_L0S_RX	(1 << 23)
+#define IWN_GIO_CHICKEN_DIS_L0S_TIMER	(1 << 29)
 
-/* possible flags for IWN_RX_STATUS */
-#define	IWN_RX_IDLE	(1 << 24)
+/* Possible flags for register IWN_GIO. */
+#define IWN_GIO_L0S_ENA		(1 << 1)
 
-/* possible flags for register IWN_UC_CTL */
-#define IWN_UC_ENABLE	(1 << 30)
-#define IWN_UC_RUN	(1 << 31)
+/* Possible flags for register IWN_UCODE_GP1_CLR. */
+#define IWN_UCODE_GP1_RFKILL		(1 << 1)
+#define IWN_UCODE_GP1_CMD_BLOCKED	(1 << 2)
+#define IWN_UCODE_GP1_CTEMP_STOP_RF	(1 << 3)
 
-/* possible flags for register IWN_INTR */
-#define IWN_ALIVE_INTR	(1 <<  0)
-#define IWN_WAKEUP_INTR	(1 <<  1)
-#define IWN_SW_RX_INTR	(1 <<  3)
-#define IWN_CT_REACHED	(1 <<  6)
-#define IWN_RF_TOGGLED	(1 <<  7)
-#define IWN_SW_ERROR	(1 << 25)
-#define IWN_TX_INTR	(1 << 27)
-#define IWN_HW_ERROR	(1 << 29)
-#define IWN_RX_INTR	(1 << 31)
+/* Possible flags/values for register IWN_LED. */
+#define IWN_LED_BSM_CTRL	(1 << 5)
+#define IWN_LED_OFF		0x00000038
+#define IWN_LED_ON		0x00000078
 
-#define	IWN_INTR_BITS	"\20\1ALIVE\2WAKEUP\3SW_RX\6CT_REACHED\7RF_TOGGLED" \
-	"\32SW_ERROR\34TX_INTR\36HW_ERROR\40RX_INTR"
+/* Possible values for register IWN_ANA_PLL. */
+#define IWN_ANA_PLL_INIT	0x00880300
 
-#define IWN_INTR_MASK							\
-	(IWN_SW_ERROR | IWN_HW_ERROR | IWN_TX_INTR | IWN_RX_INTR |	\
-	 IWN_ALIVE_INTR | IWN_WAKEUP_INTR | IWN_SW_RX_INTR |		\
-	 IWN_CT_REACHED | IWN_RF_TOGGLED)
+/* Possible flags for register IWN_FH_RX_STATUS. */
+#define	IWN_FH_RX_STATUS_IDLE	(1 << 24)
 
-/* possible flags for register IWN_INTR_STATUS */
-#define IWN_STATUS_TXQ(x)	(1 << (x))
-#define IWN_STATUS_RXQ(x)	(1 << ((x) + 16))
-#define IWN_STATUS_PRI		(1 << 30)
-/* shortcuts for the above */
-#define IWN_TX_STATUS_INTR						\
-	(IWN_STATUS_TXQ(0) | IWN_STATUS_TXQ(1) | IWN_STATUS_TXQ(6))
-#define IWN_RX_STATUS_INTR						\
-	(IWN_STATUS_RXQ(0) | IWN_STATUS_RXQ(1) | IWN_STATUS_RXQ(2) |	\
-	 IWN_STATUS_PRI)
+/* Possible flags for register IWN_BSM_WR_CTRL. */
+#define IWN_BSM_WR_CTRL_START_EN	(1 << 30)
+#define IWN_BSM_WR_CTRL_START		(1 << 31)
 
-/* possible flags for register IWN_TX_STATUS */
-#define IWN_TX_IDLE(qid)	(1 << ((qid) + 24) | 1 << ((qid) + 16))
+/* Possible flags for register IWN_INT. */
+#define IWN_INT_ALIVE		(1 <<  0)
+#define IWN_INT_WAKEUP		(1 <<  1)
+#define IWN_INT_SW_RX		(1 <<  3)
+#define IWN_INT_CT_REACHED	(1 <<  6)
+#define IWN_INT_RF_TOGGLED	(1 <<  7)
+#define IWN_INT_SW_ERR		(1 << 25)
+#define IWN_INT_FH_TX		(1 << 27)
+#define IWN_INT_HW_ERR		(1 << 29)
+#define IWN_INT_FH_RX		(1 << 31)
 
-/* possible flags/masks for register IWN_EEPROM_CTL */
-#define IWN_EEPROM_READY	(1 << 0)
-#define IWN_EEPROM_MSK		(1 << 1)
+/* Shortcut. */
+#define IWN_INT_MASK							\
+	(IWN_INT_SW_ERR | IWN_INT_HW_ERR | IWN_INT_FH_TX |		\
+	 IWN_INT_FH_RX | IWN_INT_ALIVE | IWN_INT_WAKEUP |		\
+	 IWN_INT_SW_RX | IWN_INT_CT_REACHED | IWN_INT_RF_TOGGLED)
 
-/* possible flags for register IWN_TXQ_STATUS */
-#define IWN_TXQ_STATUS_ACTIVE	0x0007fc01
+/* Possible flags for register IWN_FH_INT. */
+#define IWN_FH_INT_TX_CHNL(x)	(1 << (x))
+#define IWN_FH_INT_RX_CHNL(x)	(1 << ((x) + 16))
+#define IWN_FH_INT_HI_PRIOR	(1 << 30)
+/* Shortcuts for the above. */
+#define IWN_FH_INT_TX							\
+	(IWN_FH_INT_TX_CHNL(0) | IWN_FH_INT_TX_CHNL(1))
+#define IWN_FH_INT_RX							\
+	(IWN_FH_INT_RX_CHNL(0) | IWN_FH_INT_RX_CHNL(1) | IWN_FH_INT_HI_PRIOR)
 
-/* possible flags for register IWN_MEM_POWER */
-#define IWN_POWER_RESET	(1 << 26)
+/* Possible flags/values for register IWN_FH_TX_CONFIG. */
+#define IWN_FH_TX_CONFIG_DMA_PAUSE		0
+#define IWN_FH_TX_CONFIG_DMA_ENA		(1 << 31)
+#define IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD	(1 << 20)
 
-/* possible flags for register IWN_MEM_TEXT_SIZE */
+/* Possible flags/values for register IWN_FH_TXBUF_STATUS. */
+#define IWN_FH_TXBUF_STATUS_TBNUM(x)	((x) << 20)
+#define IWN_FH_TXBUF_STATUS_TBIDX(x)	((x) << 12)
+#define IWN_FH_TXBUF_STATUS_TFBD_VALID	3
+
+/* Possible flags for register IWN_FH_TX_CHICKEN. */
+#define IWN_FH_TX_CHICKEN_SCHED_RETRY	(1 << 1)
+
+/* Possible flags for register IWN_FH_TX_STATUS. */
+#define IWN_FH_TX_STATUS_IDLE(chnl)					\
+	(1 << ((chnl) + 24) | 1 << ((chnl) + 16))
+
+/* Possible flags for register IWN_FH_RX_CONFIG. */
+#define IWN_FH_RX_CONFIG_ENA		(1 << 31)
+#define IWN_FH_RX_CONFIG_NRBD(x)	((x) << 20)
+#define IWN_FH_RX_CONFIG_RB_SIZE_8K	(1 << 16)
+#define IWN_FH_RX_CONFIG_SINGLE_FRAME	(1 << 15)
+#define IWN_FH_RX_CONFIG_IRQ_DST_HOST	(1 << 12)
+#define IWN_FH_RX_CONFIG_RB_TIMEOUT(x)	((x) << 4)
+#define IWN_FH_RX_CONFIG_IGN_RXF_EMPTY	(1 <<  2)
+
+/* Possible flags for register IWN_FH_TX_CONFIG. */
+#define IWN_FH_TX_CONFIG_DMA_ENA	(1 << 31)
+#define IWN_FH_TX_CONFIG_DMA_CREDIT_ENA	(1 <<  3)
+
+/* Possible flags for register IWN_EEPROM. */
+#define IWN_EEPROM_READ_VALID	(1 << 0)
+#define IWN_EEPROM_CMD		(1 << 1)
+
+/* Possible flags for register IWN_EEPROM_GP. */
+#define IWN_EEPROM_GP_IF_OWNER	0x00000180
+
+/* Possible flags for register IWN_OTP_GP. */
+#define IWN_OTP_GP_DEV_SEL_OTP		(1 << 16)
+#define IWN_OTP_GP_RELATIVE_ACCESS	(1 << 17)
+#define IWN_OTP_GP_ECC_CORR_STTS	(1 << 20)
+#define IWN_OTP_GP_ECC_UNCORR_STTS	(1 << 21)
+
+/* Possible flags for register IWN_SCHED_QUEUE_STATUS. */
+#define IWN4965_TXQ_STATUS_ACTIVE	0x0007fc01
+#define IWN4965_TXQ_STATUS_INACTIVE	0x0007fc00
+#define IWN4965_TXQ_STATUS_AGGR_ENA	(1 << 5 | 1 << 8)
+#define IWN4965_TXQ_STATUS_CHGACT	(1 << 10)
+#define IWN5000_TXQ_STATUS_ACTIVE	0x00ff0018
+#define IWN5000_TXQ_STATUS_INACTIVE	0x00ff0010
+#define IWN5000_TXQ_STATUS_CHGACT	(1 << 19)
+
+/* Possible flags for register IWN_APMG_CLK_CTRL. */
+#define IWN_APMG_CLK_CTRL_DMA_CLK_RQT	(1 <<  9)
+#define IWN_APMG_CLK_CTRL_BSM_CLK_RQT	(1 << 11)
+
+/* Possible flags for register IWN_APMG_PS. */
+#define IWN_APMG_PS_EARLY_PWROFF_DIS	(1 << 22)
+#define IWN_APMG_PS_PWR_SRC(x)		((x) << 24)
+#define IWN_APMG_PS_PWR_SRC_VMAIN	0
+#define IWN_APMG_PS_PWR_SRC_VAUX	2
+#define IWN_APMG_PS_PWR_SRC_MASK	IWN_APMG_PS_PWR_SRC(3)
+#define IWN_APMG_PS_RESET_REQ		(1 << 26)
+
+/* Possible flags for IWN_APMG_PCI_STT. */
+#define IWN_APMG_PCI_STT_L1A_DIS	(1 << 11)
+
+/* Possible flags for register IWN_BSM_DRAM_TEXT_SIZE. */
 #define IWN_FW_UPDATED	(1 << 31)
 
-/* possible flags for device-specific PCI register 0xe8 */
-#define IWN_DIS_NOSNOOP	(1 << 11)
+#define IWN_SCHED_WINSZ		64
+#define IWN_SCHED_LIMIT		64
+#define IWN4965_SCHED_COUNT	512
+#define IWN5000_SCHED_COUNT	(IWN_TX_RING_COUNT + IWN_SCHED_WINSZ)
+#define IWN4965_SCHEDSZ		(IWN4965_NTXQUEUES * IWN4965_SCHED_COUNT * 2)
+#define IWN5000_SCHEDSZ		(IWN5000_NTXQUEUES * IWN5000_SCHED_COUNT * 2)
 
-/* possible flags for device-specific PCI register 0xf0 */
-#define IWN_ENA_L1	(1 << 1)
+struct iwn_tx_desc {
+	uint8_t		reserved1[3];
+	uint8_t		nsegs;
+	struct {
+		uint32_t	addr;
+		uint16_t	len;
+	} __packed	segs[IWN_MAX_SCATTER];
+	/* Pad to 128 bytes. */
+	uint32_t	reserved2;
+} __packed;
 
-
-#define IWN_TX_WINDOW	64
-struct iwn_shared {
-	uint16_t	len[IWN_NTXQUEUES][512];	/* 16KB total */
+struct iwn_rx_status {
 	uint16_t	closed_count;
 	uint16_t	closed_rx_count;
 	uint16_t	finished_count;
@@ -196,86 +345,78 @@ struct iwn_shared {
 	uint32_t	reserved[2];
 } __packed;
 
-struct iwn_tx_desc {
-	uint32_t	flags;
-	struct {
-		uint32_t	w1;
-		uint32_t	w2;
-		uint32_t	w3;
-	} __packed	segs[IWN_MAX_SCATTER / 2];
-	/* pad to 128 bytes */
-	uint32_t	reserved;
-} __packed;
-
-#define IWN_SET_DESC_NSEGS(d, x)					\
-	(d)->flags = htole32(((x) & 0x1f) << 24)
-
-/* set a segment physical address and length in a Tx descriptor */
-#define IWN_SET_DESC_SEG(d, n, addr, size) do {				\
-	if ((n) & 1) {							\
-		(d)->segs[(n) / 2].w2 |=				\
-		    htole32(((addr) & 0xffff) << 16);			\
-		(d)->segs[(n) / 2].w3 =					\
-		    htole32((((addr) >> 16) & 0xffff) | (size) << 20);	\
-	} else {							\
-		(d)->segs[(n) / 2].w1 = htole32(addr);			\
-		(d)->segs[(n) / 2].w2 = htole32((size) << 4);		\
-	}								\
-} while (0)
-
 struct iwn_rx_desc {
 	uint32_t	len;
 	uint8_t		type;
-#define IWN_UC_READY		  1
-#define IWN_ADD_NODE_DONE	 24
-#define IWN_TX_DONE		 28
-#define IWN_START_SCAN		130
-#define IWN_STOP_SCAN		132
-#define IWN_RX_STATISTICS	156
-#define IWN_BEACON_STATISTICS	157
-#define IWN_STATE_CHANGED	161
-#define IWN_BEACON_MISSED	162
-#define IWN_AMPDU_RX_START	192
-#define IWN_AMPDU_RX_DONE	193
-#define IWN_RX_DONE		195
+#define IWN_UC_READY			  1
+#define IWN_ADD_NODE_DONE		 24
+#define IWN_TX_DONE			 28
+#define IWN5000_CALIBRATION_RESULT	102
+#define IWN5000_CALIBRATION_DONE	103
+#define IWN_START_SCAN			130
+#define IWN_STOP_SCAN			132
+#define IWN_RX_STATISTICS		156
+#define IWN_BEACON_STATISTICS		157
+#define IWN_STATE_CHANGED		161
+#define IWN_BEACON_MISSED		162
+#define IWN_RX_PHY			192
+#define IWN_MPDU_RX_DONE		193
+#define IWN_RX_DONE			195
 
 	uint8_t		flags;
 	uint8_t		idx;
 	uint8_t		qid;
 } __packed;
 
-/* possible Rx status flags */
-#define IWN_RX_NO_CRC_ERR	(1 << 0)
-#define IWN_RX_NO_OVFL_ERR	(1 << 1)
-/* shortcut for the above */
+/* Possible RX status flags. */
+#define IWN_RX_NO_CRC_ERR	(1 <<  0)
+#define IWN_RX_NO_OVFL_ERR	(1 <<  1)
+/* Shortcut for the above. */
 #define IWN_RX_NOERROR	(IWN_RX_NO_CRC_ERR | IWN_RX_NO_OVFL_ERR)
+#define IWN_RX_MPDU_MIC_OK	(1 <<  6)
+#define IWN_RX_CIPHER_MASK	(7 <<  8)
+#define IWN_RX_CIPHER_CCMP	(2 <<  8)
+#define IWN_RX_MPDU_DEC		(1 << 11)
+#define IWN_RX_DECRYPT_MASK	(3 << 11)
+#define IWN_RX_DECRYPT_OK	(3 << 11)
 
 struct iwn_tx_cmd {
 	uint8_t	code;
-#define IWN_CMD_CONFIGURE		0x10	/* REPLY_RXON */
-#define IWN_CMD_ASSOCIATE		0x11	/* REPLY_RXON_ASSOC */
-#define IWN_CMD_EDCA_PARAMS		0x13	/* REPLY_QOS_PARAM */
-#define IWN_CMD_TSF			0x14	/* REPLY_RXON_TIMING */
-#define IWN_CMD_ADD_NODE		0x18	/* REPLY_ADD_STA */
-#define IWN_CMD_TX_DATA			0x1c	/* REPLY_TX */
-#define IWN_CMD_TX_LINK_QUALITY		0x4e	/* REPLY_TX_LINK_QUALITY_CMD */
-#define IWN_CMD_SET_LED			0x48	/* REPLY_LEDS_CMD */
-#define IWN_CMD_SET_POWER_MODE		0x77	/* POWER_TABLE_CMD */
-#define IWN_CMD_SCAN			0x80	/* REPLY_SCAN_CMD */
-#define IWN_CMD_TXPOWER			0x97	/* REPLY_TX_PWR_TABLE_CMD */
-#define IWN_CMD_BLUETOOTH		0x9b	/* REPLY_BT_CONFIG */
-#define IWN_CMD_GET_STATISTICS		0x9c	/* REPLY_STATISTICS_CMD */
-#define IWN_CMD_SET_CRITICAL_TEMP	0xa4	/* REPLY_CT_KILL_CONFIG_CMD */
-#define IWN_SENSITIVITY			0xa8	/* SENSITIVITY_CMD */
-#define IWN_PHY_CALIB			0xb0	/* REPLY_PHY_CALIBRATION_CMD */
+#define IWN_CMD_CONFIGURE		 16
+#define IWN_CMD_ASSOCIATE		 17
+#define IWN_CMD_EDCA_PARAMS		 19
+#define IWN_CMD_TIMING			 20
+#define IWN_CMD_ADD_NODE		 24
+#define IWN_CMD_TX_DATA			 28
+#define IWN_CMD_LINK_QUALITY		 78
+#define IWN_CMD_SET_LED			 72
+#define IWN5000_CMD_WIMAX_COEX		 90
+#define IWN5000_CMD_CALIB_CONFIG	101
+#define IWN_CMD_SET_POWER_MODE		119
+#define IWN_CMD_SCAN			128
+#define IWN_CMD_TXPOWER			151
+#define IWN_CMD_TXPOWER_DBM		152
+#define IWN_CMD_BT_COEX			155
+#define IWN_CMD_GET_STATISTICS		156
+#define IWN_CMD_SET_CRITICAL_TEMP	164
+#define IWN_CMD_SET_SENSITIVITY		168
+#define IWN_CMD_PHY_CALIB		176
+
 	uint8_t	flags;
 	uint8_t	idx;
 	uint8_t	qid;
 	uint8_t	data[136];
 } __packed;
 
-/* structure for command IWN_CMD_CONFIGURE (aka RXON) */
-struct iwn_config {
+/* Antenna flags, used in various commands. */
+#define IWN_ANT_A	(1 << 0)
+#define IWN_ANT_B	(1 << 1)
+#define IWN_ANT_C	(1 << 2)
+/* Shortcut. */
+#define IWN_ANT_ABC	(IWN_ANT_A | IWN_ANT_B | IWN_ANT_C)
+
+/* Structure for command IWN_CMD_CONFIGURE. */
+struct iwn_rxon {
 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
 	uint16_t	reserved1;
 	uint8_t		bssid[IEEE80211_ADDR_LEN];
@@ -287,54 +428,62 @@ struct iwn_config {
 #define IWN_MODE_STA		3
 #define IWN_MODE_IBSS		4
 #define IWN_MODE_MONITOR	6
-	uint8_t		unused4;	/* air propagation */
+
+	uint8_t		air;
 	uint16_t	rxchain;
-#define	IWN_RXCHAIN_VALID	0x000e	/* which antennae are valid */
-#define IWN_RXCHAIN_VALID_S	1
-#define	IWN_RXCHAIN_FORCE	0x0070
-#define	IWN_RXCHAIN_FORCE_S	4
-#define	IWN_RXCHAIN_FORCE_MIMO	0x0380
-#define	IWN_RXCHAIN_FORCE_MIMO_S	7
-#define	IWN_RXCHAIN_CNT		0x0c00
-#define	IWN_RXCHAIN_CNT_S	10
-#define	IWN_RXCHAIN_MIMO_CNT	0x3000
-#define	IWN_RXCHAIN_MIMO_CNT_S	12
-#define IWN_RXCHAIN_MIMO_FORCE	0x4000
-#define IWN_RXCHAIN_MIMO_FORCE_S	14
-	uint8_t		ofdm_mask;	/* basic rates */
-	uint8_t		cck_mask;	/* basic rates */
+#define IWN_RXCHAIN_FORCE		(1 << 0)
+#define IWN_RXCHAIN_VALID(x)		((x) <<  1)
+#define IWN_RXCHAIN_SEL(x)		((x) <<  4)
+#define IWN_RXCHAIN_MIMO(x)		((x) <<  7)
+#define IWN_RXCHAIN_IDLE_COUNT(x)	((x) << 10)
+#define IWN_RXCHAIN_MIMO_COUNT(x)	((x) << 12)
+#define IWN_RXCHAIN_MIMO_FORCE		(1 << 14)
+
+	uint8_t		ofdm_mask;
+	uint8_t		cck_mask;
 	uint16_t	associd;
 	uint32_t	flags;
-#define	IWN_CONFIG_24GHZ	0x00000001	/* band */
-#define	IWN_CONFIG_CCK		0x00000002	/* modulation */
-#define	IWN_CONFIG_AUTO		0x00000004	/* 2.4-only auto-detect */
-#define	IWN_CONFIG_HTPROT	0x00000008	/* xmit with HT protection */
-#define	IWN_CONFIG_SHSLOT	0x00000010	/* short slot time */
-#define	IWN_CONFIG_SHPREAMBLE	0x00000020	/* short premable */
-#define	IWN_CONFIG_NODIVERSITY	0x00000080	/* disable antenna diversity */
-#define	IWN_CONFIG_ANTENNA_A	0x00000100
-#define	IWN_CONFIG_ANTENNA_B	0x00000200
-#define	IWN_CONFIG_RADAR	0x00001000	/* enable radar detect */
-#define	IWN_CONFIG_NARROW	0x00002000	/* MKK narrow band select */
-#define	IWN_CONFIG_TSF		0x00008000
-#define	IWN_CONFIG_HT		0x06400000
-#define	IWN_CONFIG_HT20		0x02000000
-#define	IWN_CONFIG_HT40U	0x04000000
-#define	IWN_CONFIG_HT40D	0x04400000
+#define IWN_RXON_24GHZ		0x00000001	/* band */
+#define IWN_RXON_CCK		0x00000002	/* modulation */
+#define IWN_RXON_AUTO		0x00000004	/* 2.4-only auto-detect */
+#define IWN_RXON_HTPROT		0x00000008	/* xmit with HT protection */
+#define IWN_RXON_SHSLOT		0x00000010	/* short slot time */
+#define IWN_RXON_SHPREAMBLE	0x00000020	/* short premable */
+#define IWN_RXON_NODIVERSITY	0x00000080	/* disable antenna diversity */
+#define IWN_RXON_ANTENNA_A	0x00000100
+#define IWN_RXON_ANTENNA_B	0x00000200
+#define IWN_RXON_RADAR		0x00001000	/* enable radar detect */
+#define IWN_RXON_NARROW		0x00002000	/* MKK narrow band select */
+#define IWN_RXON_TSF		0x00008000
+#define IWN_RXON_HT		0x06400000
+#define IWN_RXON_HT20		0x02000000
+#define IWN_RXON_HT40U		0x04000000
+#define IWN_RXON_HT40D		0x04400000
+#define IWN_RXON_CTS_TO_SELF	0x40000000
+
 	uint32_t	filter;
-#define IWN_FILTER_PROMISC	(1 << 0)	/* pass all data frames */
-#define IWN_FILTER_CTL		(1 << 1)	/* pass ctl+mgt frames */
-#define IWN_FILTER_MULTICAST	(1 << 2)	/* pass multi-cast frames */
-#define IWN_FILTER_NODECRYPT	(1 << 3)	/* pass unicast undecrypted */
-#define IWN_FILTER_BSS		(1 << 5)	/* station is associated */
-#define IWN_FILTER_ALLBEACONS	(1 << 6)	/* pass overlapping bss beacons
-						   (must be associated) */
-	uint16_t	chan;		/* IEEE channel # of control/primary */
-	uint8_t		ht_single_mask;	/* single-stream basic rates */
-	uint8_t		ht_dual_mask;	/* dual-stream basic rates */
+#define IWN_FILTER_PROMISC	(1 << 0)
+#define IWN_FILTER_CTL		(1 << 1)
+#define IWN_FILTER_MULTICAST	(1 << 2)
+#define IWN_FILTER_NODECRYPT	(1 << 3)
+#define IWN_FILTER_BSS		(1 << 5)
+#define IWN_FILTER_BEACON	(1 << 6)
+
+	uint8_t		chan;
+	uint8_t		reserved4;
+	uint8_t		ht_single_mask;
+	uint8_t		ht_dual_mask;
+	/* The following fields are for 5000 Series only. */
+	uint8_t		ht_triple_mask;
+	uint8_t		reserved5;
+	uint16_t	acquisition;
+	uint16_t	reserved6;
 } __packed;
 
-/* structure for command IWN_CMD_ASSOCIATE */
+#define IWN4965_RXONSZ	(sizeof (struct iwn_rxon) - 6)
+#define IWN5000_RXONSZ	(sizeof (struct iwn_rxon))
+
+/* Structure for command IWN_CMD_ASSOCIATE. */
 struct iwn_assoc {
 	uint32_t	flags;
 	uint32_t	filter;
@@ -343,7 +492,7 @@ struct iwn_assoc {
 	uint16_t	reserved;
 } __packed;
 
-/* structure for command IWN_CMD_EDCA_PARAMS */
+/* Structure for command IWN_CMD_EDCA_PARAMS. */
 struct iwn_edca_params {
 	uint32_t	flags;
 #define IWN_EDCA_UPDATE	(1 << 0)
@@ -358,8 +507,8 @@ struct iwn_edca_params {
 	} __packed	ac[EDCA_NUM_AC];
 } __packed;
 
-/* structure for command IWN_CMD_TSF */
-struct iwn_cmd_tsf {
+/* Structure for command IWN_CMD_TIMING. */
+struct iwn_cmd_timing {
 	uint64_t	tstamp;
 	uint16_t	bintval;
 	uint16_t	atim;
@@ -368,66 +517,115 @@ struct iwn_cmd_tsf {
 	uint16_t	reserved;
 } __packed;
 
-/* structure for command IWN_CMD_ADD_NODE */
+/* Structure for command IWN_CMD_ADD_NODE. */
 struct iwn_node_info {
 	uint8_t		control;
 #define IWN_NODE_UPDATE		(1 << 0)
+
 	uint8_t		reserved1[3];
+
 	uint8_t		macaddr[IEEE80211_ADDR_LEN];
 	uint16_t	reserved2;
 	uint8_t		id;
 #define IWN_ID_BSS		 0
-#define IWN_ID_BROADCAST	31
+#define IWN5000_ID_BROADCAST	15
+#define IWN4965_ID_BROADCAST	31
+
 	uint8_t		flags;
-#define IWN_FLAG_SET_KEY	(1 << 0)
+#define IWN_FLAG_SET_KEY		(1 << 0)
+#define IWN_FLAG_SET_DISABLE_TID	(1 << 1)
+#define IWN_FLAG_SET_TXRATE		(1 << 2)
+#define IWN_FLAG_SET_ADDBA		(1 << 3)
+#define IWN_FLAG_SET_DELBA		(1 << 4)
+
 	uint16_t	reserved3;
-	uint16_t	security;
+	uint16_t	kflags;
+#define IWN_KFLAG_CCMP		(1 <<  1)
+#define IWN_KFLAG_MAP		(1 <<  3)
+#define IWN_KFLAG_KID(kid)	((kid) << 8)
+#define IWN_KFLAG_INVALID	(1 << 11)
+#define IWN_KFLAG_GROUP		(1 << 14)
+
 	uint8_t		tsc2;	/* TKIP TSC2 */
 	uint8_t		reserved4;
 	uint16_t	ttak[5];
-	uint16_t	reserved5;
-	uint8_t		key[IEEE80211_KEYBUF_SIZE];
+	uint8_t		kid;
+	uint8_t		reserved5;
+	uint8_t		key[16];
+	/* The following 3 fields are for 5000 Series only. */
+	uint64_t	tsc;
+	uint8_t		rxmic[8];
+	uint8_t		txmic[8];
+
 	uint32_t	htflags;
-#define IWN_MAXRXAMPDU_S	19
-#define IWN_MPDUDENSITY_S	23
+#define IWN_AMDPU_SIZE_FACTOR(x)	((x) << 19)
+#define IWN_AMDPU_DENSITY(x)		((x) << 23)
+
 	uint32_t	mask;
-	uint16_t	tid;
-	uint8_t		rate;		/* legacy rate/MCS */
-#define	IWN_RATE_MCS	0x08		/* or'd to indicate MCS */
-	uint8_t		rflags;
-#define	IWN_RFLAG_HT	(1 << 0)	/* use HT modulation */
-#define IWN_RFLAG_CCK	(1 << 1)	/* use CCK modulation */
-#define	IWN_RFLAG_HT40	(1 << 3)	/* use dual-stream */
-#define	IWN_RFLAG_SGI	(1 << 5)	/* use short GI */
-#define IWN_RFLAG_ANT_A	(1 << 6)	/* start on antenna port A */
-#define IWN_RFLAG_ANT_B	(1 << 7)	/* start on antenna port B */
-	uint8_t		add_imm;
-	uint8_t		del_imm;
-	uint16_t	add_imm_start;
-	uint32_t	reserved6;
+	uint16_t	disable_tid;
+	uint16_t	reserved6;
+	uint8_t		addba_tid;
+	uint8_t		delba_tid;
+	uint16_t	addba_ssn;
+	uint32_t	reserved7;
 } __packed;
 
-/* structure for command IWN_CMD_TX_DATA */
+struct iwn4965_node_info {
+	uint8_t		control;
+	uint8_t		reserved1[3];
+	uint8_t		macaddr[IEEE80211_ADDR_LEN];
+	uint16_t	reserved2;
+	uint8_t		id;
+	uint8_t		flags;
+	uint16_t	reserved3;
+	uint16_t	kflags;
+	uint8_t		tsc2;	/* TKIP TSC2 */
+	uint8_t		reserved4;
+	uint16_t	ttak[5];
+	uint8_t		kid;
+	uint8_t		reserved5;
+	uint8_t		key[16];
+	uint32_t	htflags;
+	uint32_t	mask;
+	uint16_t	disable_tid;
+	uint16_t	reserved6;
+	uint8_t		addba_tid;
+	uint8_t		delba_tid;
+	uint16_t	addba_ssn;
+	uint32_t	reserved7;
+} __packed;
+
+#define IWN_RFLAG_HT	(1 << 0)	/* use HT modulation */
+#define IWN_RFLAG_CCK	(1 << 1)	/* use CCK modulation */
+#define IWN_RFLAG_HT40	(1 << 3)	/* use dual-stream */
+#define IWN_RFLAG_SGI	(1 << 5)	/* use short GI */
+#define IWN_RFLAG_ANT_A	(1 << 6)	/* start on antenna port A */
+#define IWN_RFLAG_ANT_B	(1 << 7)	/* start on antenna port B */
+#define IWN_RFLAG_ANT(x)	((x) << 6)
+
+/* Structure for command IWN_CMD_TX_DATA. */
 struct iwn_cmd_data {
 	uint16_t	len;
 	uint16_t	lnext;
 	uint32_t	flags;
+#define IWN_TX_NEED_PROTECTION	(1 <<  0)	/* 5000 only */
 #define IWN_TX_NEED_RTS		(1 <<  1)
 #define IWN_TX_NEED_CTS		(1 <<  2)
 #define IWN_TX_NEED_ACK		(1 <<  3)
-#define IWN_TX_USE_NODE_RATE	(1 <<  4)
+#define IWN_TX_LINKQ		(1 <<  4)
+#define IWN_TX_IMM_BA		(1 <<  6)
 #define IWN_TX_FULL_TXOP	(1 <<  7)
 #define IWN_TX_BT_DISABLE	(1 << 12)	/* bluetooth coexistence */
 #define IWN_TX_AUTO_SEQ		(1 << 13)
+#define IWN_TX_MORE_FRAG	(1 << 14)
 #define IWN_TX_INSERT_TSTAMP	(1 << 16)
 #define IWN_TX_NEED_PADDING	(1 << 20)
 
-	uint8_t		ntries;
-	uint8_t		bluetooth;
-	uint16_t	reserved1;
-	uint8_t		rate;
+	uint32_t	scratch;
+	uint8_t		plcp;
 	uint8_t		rflags;
 	uint16_t	xrflags;
+
 	uint8_t		id;
 	uint8_t		security;
 #define IWN_CIPHER_WEP40	1
@@ -435,9 +633,9 @@ struct iwn_cmd_data {
 #define IWN_CIPHER_TKIP		3
 #define IWN_CIPHER_WEP104	9
 
-	uint8_t		ridx;
+	uint8_t		linkq;
 	uint8_t		reserved2;
-	uint8_t		key[IEEE80211_KEYBUF_SIZE];
+	uint8_t		key[16];
 	uint16_t	fnext;
 	uint16_t	reserved3;
 	uint32_t	lifetime;
@@ -452,34 +650,30 @@ struct iwn_cmd_data {
 	uint16_t	txop;
 } __packed;
 
-/* structure for command IWN_CMD_TX_LINK_QUALITY */
+/* Structure for command IWN_CMD_LINK_QUALITY. */
 #define IWN_MAX_TX_RETRIES	16
 struct iwn_cmd_link_quality {
 	uint8_t		id;
 	uint8_t		reserved1;
 	uint16_t	ctl;
 	uint8_t		flags;
-	uint8_t		mimo;		/* MIMO delimiter */
-	uint8_t		ssmask;		/* single stream antenna mask */
-	uint8_t		dsmask;		/* dual stream antenna mask */
-	uint8_t		ridx[EDCA_NUM_AC];/* starting rate index */
-	uint16_t	ampdu_limit;	/* tx aggregation time limit */
-	uint8_t		ampdu_disable;
-	uint8_t		ampdu_max;	/* frame count limit */
+	uint8_t		mimo;
+	uint8_t		antmsk_1stream;
+	uint8_t		antmsk_2stream;
+	uint8_t		ridx[EDCA_NUM_AC];
+	uint16_t	ampdu_limit;
+	uint8_t		ampdu_threshold;
+	uint8_t		ampdu_max;
 	uint32_t	reserved2;
 	struct {
-		uint8_t		rate;
-#define IWN_RATE_CCK1	 0
-#define IWN_RATE_CCK11	 3
-#define IWN_RATE_OFDM6	 4
-#define IWN_RATE_OFDM54	11
+		uint8_t		plcp;
 		uint8_t		rflags;
 		uint16_t	xrflags;
-	} table[IWN_MAX_TX_RETRIES];
+	} __packed	retry[IWN_MAX_TX_RETRIES];
 	uint32_t	reserved3;
 } __packed;
 
-/* structure for command IWN_CMD_SET_LED */
+/* Structure for command IWN_CMD_SET_LED. */
 struct iwn_cmd_led {
 	uint32_t	unit;	/* multiplier (in usecs) */
 	uint8_t		which;
@@ -491,20 +685,56 @@ struct iwn_cmd_led {
 	uint8_t		reserved;
 } __packed;
 
-/* structure for command IWN_CMD_SET_POWER_MODE */
-struct iwn_power {
-	uint16_t	flags;
-#define IWN_POWER_CAM	0	/* constantly awake mode */
+/* Structure for command IWN5000_CMD_WIMAX_COEX. */
+struct iwn5000_wimax_coex {
+	uint32_t	flags;
+	struct {
+		uint8_t	request;
+		uint8_t	window;
+		uint8_t	reserved;
+		uint8_t	flags;
+	} __packed	events[16];
+} __packed;
 
-	uint8_t		alive;
+/* Structures for command IWN5000_CMD_CALIB_CONFIG. */
+struct iwn5000_calib_elem {
+	uint32_t	enable;
+	uint32_t	start;
+	uint32_t	send;
+	uint32_t	apply;
+	uint32_t	reserved;
+} __packed;
+
+struct iwn5000_calib_status {
+	struct iwn5000_calib_elem	once;
+	struct iwn5000_calib_elem	perd;
+	uint32_t			flags;
+} __packed;
+
+struct iwn5000_calib_config {
+	struct iwn5000_calib_status	ucode;
+	struct iwn5000_calib_status	driver;
+	uint32_t			reserved;
+} __packed;
+
+/* Structure for command IWN_CMD_SET_POWER_MODE. */
+struct iwn_pmgt_cmd {
+	uint16_t	flags;
+#define IWN_PS_ALLOW_SLEEP	(1 << 0)
+#define IWN_PS_NOTIFY		(1 << 1)
+#define IWN_PS_SLEEP_OVER_DTIM	(1 << 2)
+#define IWN_PS_PCI_PMGT		(1 << 3)
+#define IWN_PS_FAST_PD		(1 << 4)
+
+	uint8_t		keepalive;
 	uint8_t		debug;
-	uint32_t	rx_timeout;
-	uint32_t	tx_timeout;
-	uint32_t	sleep[5];
+	uint32_t	rxtimeout;
+	uint32_t	txtimeout;
+	uint32_t	intval[5];
 	uint32_t	beacons;
 } __packed;
 
-/* structures for command IWN_CMD_SCAN */
+/* Structures for command IWN_CMD_SCAN. */
 struct iwn_scan_essid {
 	uint8_t	id;
 	uint8_t	len;
@@ -515,8 +745,8 @@ struct iwn_scan_hdr {
 	uint16_t	len;
 	uint8_t		reserved1;
 	uint8_t		nchan;
-	uint16_t	quiet;
-	uint16_t	plcp_threshold;
+	uint16_t	quiet_time;
+	uint16_t	quiet_threshold;
 	uint16_t	crc_threshold;
 	uint16_t	rxchain;
 	uint32_t	max_svc;	/* background scans */
@@ -524,38 +754,54 @@ struct iwn_scan_hdr {
 	uint32_t	flags;
 	uint32_t	filter;
 
-	/* followed by a struct iwn_cmd_data */
-	/* followed by an array of 4x struct iwn_scan_essid */
-	/* followed by probe request body */
-	/* followed by nchan x struct iwn_scan_chan */
+	/* Followed by a struct iwn_cmd_data. */
+	/* Followed by an array of 20 structs iwn_scan_essid. */
+	/* Followed by probe request body. */
+	/* Followed by an array of ``nchan'' structs iwn_scan_chan. */
 } __packed;
 
 struct iwn_scan_chan {
-	uint8_t		flags;
-#define IWN_CHAN_ACTIVE	(1 << 0)
-#define IWN_CHAN_DIRECT	(1 << 1)
+	uint32_t	flags;
+#define IWN_CHAN_ACTIVE		(1 << 0)
+#define IWN_CHAN_NPBREQS(x)	(((1 << (x)) - 1) << 1)
 
-	uint8_t		chan;
+	uint16_t	chan;
 	uint8_t		rf_gain;
 	uint8_t		dsp_gain;
 	uint16_t	active;		/* msecs */
 	uint16_t	passive;	/* msecs */
 } __packed;
 
-/* structure for command IWN_CMD_TXPOWER */
+/* Maximum size of a scan command. */
+#define IWN_SCAN_MAXSZ	(MCLBYTES - 4)
+
+/* Structure for command IWN_CMD_TXPOWER (4965AGN only.) */
 #define IWN_RIDX_MAX	32
-struct iwn_cmd_txpower {
-	uint8_t	band;
-	uint8_t	reserved1;
-	uint8_t	chan;
-	uint8_t	reserved2;
+struct iwn4965_cmd_txpower {
+	uint8_t		band;
+	uint8_t		reserved1;
+	uint8_t		chan;
+	uint8_t		reserved2;
 	struct {
-		uint8_t	rf_gain[IWN_NTXCHAINS];
-		uint8_t	dsp_gain[IWN_NTXCHAINS];
-	}	power[IWN_RIDX_MAX + 1];
+		uint8_t	rf_gain[2];
+		uint8_t	dsp_gain[2];
+	} __packed	power[IWN_RIDX_MAX + 1];
 } __packed;
 
-/* structure for command IWN_CMD_BLUETOOTH */
+/* Structure for command IWN_CMD_TXPOWER_DBM (5000 Series only.) */
+struct iwn5000_cmd_txpower {
+	int8_t	global_limit;	/* in half-dBm */
+#define IWN5000_TXPOWER_AUTO		0x7f
+#define IWN5000_TXPOWER_MAX_DBM		16
+
+	uint8_t	flags;
+#define IWN5000_TXPOWER_NO_CLOSED	(1 << 6)
+
+	int8_t	srv_limit;	/* in half-dBm */
+	uint8_t	reserved;
+} __packed;
+
+/* Structure for command IWN_CMD_BLUETOOTH. */
 struct iwn_bluetooth {
 	uint8_t		flags;
 	uint8_t		lead;
@@ -565,18 +811,18 @@ struct iwn_bluetooth {
 	uint32_t	cts;
 } __packed;
 
-/* structure for command IWN_CMD_SET_CRITICAL_TEMP */
+/* Structure for command IWN_CMD_SET_CRITICAL_TEMP. */
 struct iwn_critical_temp {
 	uint32_t	reserved;
 	uint32_t	tempM;
 	uint32_t	tempR;
-/* degK <-> degC conversion macros */
+/* degK <-> degC conversion macros. */
 #define IWN_CTOK(c)	((c) + 273)
 #define IWN_KTOC(k)	((k) - 273)
 #define IWN_CTOMUK(c)	(((c) * 1000000) + 273150000)
 } __packed;
 
-/* structure for command IWN_SENSITIVITY */
+/* Structure for command IWN_CMD_SET_SENSITIVITY. */
 struct iwn_sensitivity_cmd {
 	uint16_t	which;
 #define IWN_SENSITIVITY_DEFAULTTBL	0
@@ -595,21 +841,74 @@ struct iwn_sensitivity_cmd {
 	uint16_t	energy_ofdm_th;
 } __packed;
 
-/* structure for command IWN_PHY_CALIB */
-struct iwn_phy_calib_cmd {
-	uint8_t		code;
-#define IWN_SET_DIFF_GAIN	7
+/* Structures for command IWN_CMD_PHY_CALIB. */
+struct iwn_phy_calib {
+	uint8_t	code;
+#define IWN4965_PHY_CALIB_DIFF_GAIN		 7
+#define IWN5000_PHY_CALIB_DC			 8
+#define IWN5000_PHY_CALIB_LO			 9
+#define IWN5000_PHY_CALIB_TX_IQ			11
+#define IWN5000_PHY_CALIB_CRYSTAL		15
+#define IWN5000_PHY_CALIB_BASE_BAND		16
+#define IWN5000_PHY_CALIB_TX_IQ_PERD		17
+#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN	18
+#define IWN5000_PHY_CALIB_NOISE_GAIN		19
 
-	uint8_t		flags;
-	uint16_t	reserved1;
-	int8_t		gain[3];
-#define IWN_GAIN_SET	(1 << 2)
-
-	uint8_t		reserved2;
+	uint8_t	group;
+	uint8_t	ngroups;
+	uint8_t	isvalid;
 } __packed;
 
+struct iwn5000_phy_calib_crystal {
+	uint8_t	code;
+	uint8_t	group;
+	uint8_t	ngroups;
+	uint8_t	isvalid;
 
-/* structure for IWN_UC_READY notification */
+	uint8_t	cap_pin[2];
+	uint8_t	reserved[2];
+} __packed;
+
+struct iwn_phy_calib_gain {
+	uint8_t	code;
+	uint8_t	group;
+	uint8_t	ngroups;
+	uint8_t	isvalid;
+
+	int8_t	gain[3];
+	uint8_t	reserved;
+} __packed;
+
+/* Structure for command IWN_CMD_SPECTRUM_MEASUREMENT. */
+struct iwn_spectrum_cmd {
+	uint16_t	len;
+	uint8_t		token;
+	uint8_t		id;
+	uint8_t		origin;
+	uint8_t		periodic;
+	uint16_t	timeout;
+	uint32_t	start;
+	uint32_t	reserved1;
+	uint32_t	flags;
+	uint32_t	filter;
+	uint16_t	nchan;
+	uint16_t	reserved2;
+	struct {
+		uint32_t	duration;
+		uint8_t		chan;
+		uint8_t		type;
+#define IWN_MEASUREMENT_BASIC		(1 << 0)
+#define IWN_MEASUREMENT_CCA		(1 << 1)
+#define IWN_MEASUREMENT_RPI_HISTOGRAM	(1 << 2)
+#define IWN_MEASUREMENT_NOISE_HISTOGRAM	(1 << 3)
+#define IWN_MEASUREMENT_FRAME		(1 << 4)
+#define IWN_MEASUREMENT_IDLE		(1 << 7)
+
+		uint16_t	reserved;
+	} __packed	chan[10];
+} __packed;
+
+/* Structure for IWN_UC_READY notification. */
 #define IWN_NATTEN_GROUPS	5
 struct iwn_ucode_info {
 	uint8_t		minor;
@@ -623,25 +922,33 @@ struct iwn_ucode_info {
 
 	uint16_t	reserved2;
 	uint32_t	logptr;
-	uint32_t	errorptr;
+	uint32_t	errptr;
 	uint32_t	tstamp;
 	uint32_t	valid;
 
-	/* the following fields are for UCODE_INIT only */
+	/* The following fields are for UCODE_INIT only. */
 	int32_t		volt;
 	struct {
 		int32_t	chan20MHz;
 		int32_t	chan40MHz;
 	} __packed	temp[4];
-	int32_t		atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS];
+	int32_t		atten[IWN_NATTEN_GROUPS][2];
 } __packed;
 
-/* structure for IWN_TX_DONE notification */
-struct iwn_tx_stat {
+/* Structures for IWN_TX_DONE notification. */
+#define IWN_TX_SUCCESS			0x00
+#define IWN_TX_FAIL			0x80	/* all failures have 0x80 set */
+#define IWN_TX_FAIL_SHORT_LIMIT		0x82	/* too many RTS retries */
+#define IWN_TX_FAIL_LONG_LIMIT		0x83	/* too many retries */
+#define IWN_TX_FAIL_FIFO_UNDERRRUN	0x84	/* tx fifo not kept running */
+#define IWN_TX_FAIL_DEST_IN_PS		0x88	/* sta found in power save */
+#define IWN_TX_FAIL_TX_LOCKED		0x90	/* waiting to see traffic */
+
+struct iwn4965_tx_stat {
 	uint8_t		nframes;
-	uint8_t		nkill;
-	uint8_t		nrts;
-	uint8_t		ntries;
+	uint8_t		killcnt;
+	uint8_t		rtscnt;
+	uint8_t		retrycnt;
 	uint8_t		rate;
 	uint8_t		rflags;
 	uint16_t	xrflags;
@@ -649,16 +956,28 @@ struct iwn_tx_stat {
 	uint16_t	reserved;
 	uint32_t	power[2];
 	uint32_t	status;
-#define	IWN_TX_SUCCESS			0x00
-#define	IWN_TX_FAIL			0x80	/* all failures have 0x80 set */
-#define	IWN_TX_FAIL_SHORT_LIMIT		0x82	/* too many RTS retries */
-#define	IWN_TX_FAIL_LONG_LIMIT		0x83	/* too many retries */
-#define	IWN_TX_FAIL_FIFO_UNDERRRUN	0x84	/* tx fifo not kept running */
-#define	IWN_TX_FAIL_DEST_IN_PS		0x88	/* sta found in power save */
-#define	IWN_TX_FAIL_TX_LOCKED		0x90	/* waiting to see traffic */
 } __packed;
 
-/* structure for IWN_BEACON_MISSED notification */
+struct iwn5000_tx_stat {
+	uint8_t		nframes;
+	uint8_t		killcnt;
+	uint8_t		rtscnt;
+	uint8_t		retrycnt;
+	uint8_t		rate;
+	uint8_t		rflags;
+	uint16_t	xrflags;
+	uint16_t	duration;
+	uint16_t	reserved;
+	uint32_t	power[2];
+	uint32_t	info;
+	uint16_t	seq;
+	uint16_t	len;
+	uint32_t	tlc;
+	uint16_t	status;
+	uint16_t	sequence;
+} __packed;
+
+/* Structure for IWN_BEACON_MISSED notification. */
 struct iwn_beacon_missed {
 	uint32_t	consecutive;
 	uint32_t	total;
@@ -666,13 +985,25 @@ struct iwn_beacon_missed {
 	uint32_t	received;
 } __packed;
 
-/* structure for IWN_AMPDU_RX_DONE notification */
-struct iwn_rx_ampdu {
+/* Structure for IWN_MPDU_RX_DONE notification. */
+struct iwn_rx_mpdu {
 	uint16_t	len;
 	uint16_t	reserved;
 } __packed;
 
-/* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */
+/* Structures for IWN_RX_DONE and IWN_MPDU_RX_DONE notifications. */
+struct iwn4965_rx_phystat {
+	uint16_t	antenna;
+	uint16_t	agc;
+	uint8_t		rssi[6];
+} __packed;
+
+struct iwn5000_rx_phystat {
+	uint32_t	reserved1;
+	uint32_t	agc;
+	uint16_t	rssi[3];
+} __packed;
+
 struct iwn_rx_stat {
 	uint8_t		phy_len;
 	uint8_t		cfg_phy_len;
@@ -683,13 +1014,10 @@ struct iwn_rx_stat {
 	uint64_t	tstamp;
 	uint32_t	beacon;
 	uint16_t	flags;
-	uint16_t	chan;
-	uint16_t	antenna;
-	uint16_t	agc;
-	uint8_t		rssi[6];
-#define IWN_RSSI_TO_DBM	44
+#define IWN_STAT_FLAG_SHPREAMBLE	(1 << 2)
 
-	uint8_t		reserved2[22];
+	uint16_t	chan;
+	uint8_t		phybuf[32];
 	uint8_t		rate;
 	uint8_t		rflags;
 	uint16_t	xrflags;
@@ -697,7 +1025,9 @@ struct iwn_rx_stat {
 	uint16_t	reserve3;
 } __packed;
 
-/* structure for IWN_START_SCAN notification */
+#define IWN_RSSI_TO_DBM	44
+
+/* Structure for IWN_START_SCAN notification. */
 struct iwn_start_scan {
 	uint64_t	tstamp;
 	uint32_t	tbeacon;
@@ -707,7 +1037,7 @@ struct iwn_start_scan {
 	uint32_t	status;
 } __packed;
 
-/* structure for IWN_STOP_SCAN notification */
+/* Structure for IWN_STOP_SCAN notification. */
 struct iwn_stop_scan {
 	uint8_t		nchan;
 	uint8_t		status;
@@ -716,7 +1046,39 @@ struct iwn_stop_scan {
 	uint64_t	tsf;
 } __packed;
 
-/* structure for IWN_{RX,BEACON}_STATISTICS notification */
+/* Structure for IWN_SPECTRUM_MEASUREMENT notification. */
+struct iwn_spectrum_notif {
+	uint8_t		id;
+	uint8_t		token;
+	uint8_t		idx;
+	uint8_t		state;
+#define IWN_MEASUREMENT_START	0
+#define IWN_MEASUREMENT_STOP	1
+
+	uint32_t	start;
+	uint8_t		band;
+	uint8_t		chan;
+	uint8_t		type;
+	uint8_t		reserved1;
+	uint32_t	cca_ofdm;
+	uint32_t	cca_cck;
+	uint32_t	cca_time;
+	uint8_t		basic;
+	uint8_t		reserved2[3];
+	uint32_t	ofdm[8];
+	uint32_t	cck[8];
+	uint32_t	stop;
+	uint32_t	status;
+#define IWN_MEASUREMENT_OK		0
+#define IWN_MEASUREMENT_CONCURRENT	1
+#define IWN_MEASUREMENT_CSA_CONFLICT	2
+#define IWN_MEASUREMENT_TGH_CONFLICT	3
+#define IWN_MEASUREMENT_STOPPED		6
+#define IWN_MEASUREMENT_TIMEOUT		7
+#define IWN_MEASUREMENT_FAILED		8
+} __packed;
+
+/* Structure for IWN_{RX,BEACON}_STATISTICS notification. */
 struct iwn_rx_phy_stats {
 	uint32_t	ina;
 	uint32_t	fina;
@@ -833,7 +1195,20 @@ struct iwn_stats {
 } __packed;
 
 
-/* firmware image header */
+/* Firmware error dump. */
+struct iwn_fw_dump {
+	uint32_t	valid;
+	uint32_t	id;
+	uint32_t	pc;
+	uint32_t	branch_link[2];
+	uint32_t	interrupt_link[2];
+	uint32_t	error_data[2];
+	uint32_t	src_line;
+	uint32_t	tsf;
+	uint32_t	time[2];
+} __packed;
+
+/* Firmware image file header. */
 struct iwn_firmware_hdr {
 	uint32_t	version;
 	uint32_t	main_textsz;
@@ -843,36 +1218,58 @@ struct iwn_firmware_hdr {
 	uint32_t	boot_textsz;
 } __packed;
 
-#define IWN_FW_MAIN_TEXT_MAXSZ	(96 * 1024)
-#define IWN_FW_MAIN_DATA_MAXSZ	(40 * 1024)
-#define IWN_FW_INIT_TEXT_MAXSZ	(96 * 1024)
-#define IWN_FW_INIT_DATA_MAXSZ	(40 * 1024)
+#define IWN4965_FW_TEXT_MAXSZ	( 96 * 1024)
+#define IWN4965_FW_DATA_MAXSZ	( 40 * 1024)
+#define IWN5000_FW_TEXT_MAXSZ	(256 * 1024)
+#define IWN5000_FW_DATA_MAXSZ	( 80 * 1024)
 #define IWN_FW_BOOT_TEXT_MAXSZ	1024
-
+#define IWN4965_FWSZ		(IWN4965_FW_TEXT_MAXSZ + IWN4965_FW_DATA_MAXSZ)
+#define IWN5000_FWSZ		IWN5000_FW_TEXT_MAXSZ
 
 /*
  * Offsets into EEPROM.
  */
 #define IWN_EEPROM_MAC		0x015
-#define IWN_EEPROM_DOMAIN	0x060
-#define IWN_EEPROM_BAND1	0x063
-#define IWN_EEPROM_BAND2	0x072
-#define IWN_EEPROM_BAND3	0x080
-#define IWN_EEPROM_BAND4	0x08d
-#define IWN_EEPROM_BAND5	0x099
-#define IWN_EEPROM_BAND6	0x0a0
-#define IWN_EEPROM_BAND7	0x0a8
-#define IWN_EEPROM_MAXPOW	0x0e8
-#define IWN_EEPROM_VOLTAGE	0x0e9
-#define IWN_EEPROM_BANDS	0x0ea
+#define IWN_EEPROM_RFCFG	0x048
+#define IWN4965_EEPROM_DOMAIN	0x060
+#define IWN4965_EEPROM_BAND1	0x063
+#define IWN5000_EEPROM_REG	0x066
+#define IWN5000_EEPROM_CAL	0x067
+#define IWN4965_EEPROM_BAND2	0x072
+#define IWN4965_EEPROM_BAND3	0x080
+#define IWN4965_EEPROM_BAND4	0x08d
+#define IWN4965_EEPROM_BAND5	0x099
+#define IWN4965_EEPROM_BAND6	0x0a0
+#define IWN4965_EEPROM_BAND7	0x0a8
+#define IWN4965_EEPROM_MAXPOW	0x0e8
+#define IWN4965_EEPROM_VOLTAGE	0x0e9
+#define IWN4965_EEPROM_BANDS	0x0ea
+/* Indirect offsets. */
+#define IWN5000_EEPROM_DOMAIN	0x001
+#define IWN5000_EEPROM_BAND1	0x004
+#define IWN5000_EEPROM_BAND2	0x013
+#define IWN5000_EEPROM_BAND3	0x021
+#define IWN5000_EEPROM_BAND4	0x02e
+#define IWN5000_EEPROM_BAND5	0x03a
+#define IWN5000_EEPROM_BAND6	0x041
+#define IWN5000_EEPROM_BAND7	0x049
+#define IWN5000_EEPROM_CRYSTAL	0x128
+#define IWN5000_EEPROM_TEMP	0x12a
+#define IWN5000_EEPROM_VOLT	0x12b
+
+/* Possible flags for IWN_EEPROM_RFCFG. */
+#define IWN_RFCFG_TYPE(x)	(((x) >>  0) & 0x3)
+#define IWN_RFCFG_STEP(x)	(((x) >>  2) & 0x3)
+#define IWN_RFCFG_DASH(x)	(((x) >>  4) & 0x3)
+#define IWN_RFCFG_TXANTMSK(x)	(((x) >>  8) & 0xf)
+#define IWN_RFCFG_RXANTMSK(x)	(((x) >> 12) & 0xf)
 
 struct iwn_eeprom_chan {
 	uint8_t	flags;
 #define IWN_EEPROM_CHAN_VALID	(1 << 0)
-#define IWN_EEPROM_CHAN_IBSS	(1 << 1)	/* adhoc permitted */
-/* NB: bit 2 is reserved */
-#define IWN_EEPROM_CHAN_ACTIVE	(1 << 3)	/* active/passive scan */
-#define IWN_EEPROM_CHAN_RADAR	(1 << 4)	/* DFS required */
+#define IWN_EEPROM_CHAN_IBSS	(1 << 1)
+#define IWN_EEPROM_CHAN_ACTIVE	(1 << 3)
+#define IWN_EEPROM_CHAN_RADAR	(1 << 4)
 #define IWN_EEPROM_CHAN_WIDE	(1 << 5)	/* HT40 */
 #define IWN_EEPROM_CHAN_NARROW	(1 << 6)	/* HT20 */
 
@@ -880,30 +1277,100 @@ struct iwn_eeprom_chan {
 } __packed;
 
 #define IWN_NSAMPLES	3
-struct iwn_eeprom_chan_samples {
+struct iwn4965_eeprom_chan_samples {
 	uint8_t	num;
 	struct {
 		uint8_t temp;
 		uint8_t	gain;
 		uint8_t	power;
 		int8_t	pa_det;
-	}	samples[IWN_NTXCHAINS][IWN_NSAMPLES];
+	}	samples[2][IWN_NSAMPLES];
 } __packed;
 
 #define IWN_NBANDS	8
-struct iwn_eeprom_band {
+struct iwn4965_eeprom_band {
 	uint8_t	lo;	/* low channel number */
 	uint8_t	hi;	/* high channel number */
-	struct	iwn_eeprom_chan_samples chans[2];
+	struct	iwn4965_eeprom_chan_samples chans[2];
 } __packed;
 
-#define IWN_MAX_PWR_INDEX	107
+/*
+ * Offsets of channels descriptions in EEPROM.
+ */
+static const uint32_t iwn4965_regulatory_bands[IWN_NBANDS] = {
+	IWN4965_EEPROM_BAND1,
+	IWN4965_EEPROM_BAND2,
+	IWN4965_EEPROM_BAND3,
+	IWN4965_EEPROM_BAND4,
+	IWN4965_EEPROM_BAND5,
+	IWN4965_EEPROM_BAND6,
+	IWN4965_EEPROM_BAND7
+};
+
+static const uint32_t iwn5000_regulatory_bands[IWN_NBANDS] = {
+	IWN5000_EEPROM_BAND1,
+	IWN5000_EEPROM_BAND2,
+	IWN5000_EEPROM_BAND3,
+	IWN5000_EEPROM_BAND4,
+	IWN5000_EEPROM_BAND5,
+	IWN5000_EEPROM_BAND6,
+	IWN5000_EEPROM_BAND7
+};
+
+#define IWN_CHAN_BANDS_COUNT	 7
+#define IWN_MAX_CHAN_PER_BAND	14
+static const struct iwn_chan_band {
+	uint8_t	nchan;
+	uint8_t	chan[IWN_MAX_CHAN_PER_BAND];
+} iwn_bands[] = {
+	/* 20MHz channels, 2GHz band. */
+	{ 14, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
+	/* 20MHz channels, 5GHz band. */
+	{ 13, { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
+	{ 12, { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
+	{ 11, { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
+	{  6, { 145, 149, 153, 157, 161, 165 } },
+	/* 40MHz channels (primary channels), 2GHz band. */
+	{  7, { 1, 2, 3, 4, 5, 6, 7 } },
+	/* 40MHz channels (primary channels), 5GHz band. */
+	{ 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
+};
+
+#define IWN_RIDX_MCS	0x08		/* or'd to indicate MCS */
+
+/* HW rate indices. */
+#define IWN_RIDX_CCK1	 0
+#define IWN_RIDX_CCK11	 3
+#define IWN_RIDX_OFDM6	 4
+#define IWN_RIDX_OFDM54	11
+
+static const struct iwn_rate {
+	uint8_t	rate;
+	uint8_t	plcp;
+	uint8_t	flags;
+} iwn_rates[IWN_RIDX_MAX + 1] = {
+	{   2,  10, IWN_RFLAG_CCK },
+	{   4,  20, IWN_RFLAG_CCK },
+	{  11,  55, IWN_RFLAG_CCK },
+	{  22, 110, IWN_RFLAG_CCK },
+	{  12, 0xd, 0 },
+	{  18, 0xf, 0 },
+	{  24, 0x5, 0 },
+	{  36, 0x7, 0 },
+	{  48, 0x9, 0 },
+	{  72, 0xb, 0 },
+	{  96, 0x1, 0 },
+	{ 108, 0x3, 0 },
+	{ 120, 0x3, 0 }
+};
+
+#define IWN4965_MAX_PWR_INDEX	107
 
 /*
  * RF Tx gain values from highest to lowest power (values obtained from
  * the reference driver.)
  */
-static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
+static const uint8_t iwn4965_rf_gain_2ghz[IWN4965_MAX_PWR_INDEX + 1] = {
 	0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
 	0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38,
 	0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
@@ -916,7 +1383,7 @@ static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
+static const uint8_t iwn4965_rf_gain_5ghz[IWN4965_MAX_PWR_INDEX + 1] = {
 	0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d,
 	0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39,
 	0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35,
@@ -933,7 +1400,7 @@ static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
  * DSP pre-DAC gain values from highest to lowest power (values obtained
  * from the reference driver.)
  */
-static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
+static const uint8_t iwn4965_dsp_gain_2ghz[IWN4965_MAX_PWR_INDEX + 1] = {
 	0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
 	0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
 	0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
@@ -946,7 +1413,7 @@ static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
 	0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b
 };
 
-static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
+static const uint8_t iwn4965_dsp_gain_5ghz[IWN4965_MAX_PWR_INDEX + 1] = {
 	0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
 	0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
 	0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
@@ -959,12 +1426,140 @@ static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
 	0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e
 };
 
+/*
+ * Power saving settings (values obtained from the reference driver.)
+ */
+#define IWN_NDTIMRANGES		3
+#define IWN_NPOWERLEVELS	6
+static const struct iwn_pmgt {
+	uint32_t	rxtimeout;
+	uint32_t	txtimeout;
+	uint32_t	intval[5];
+	int		skip_dtim;
+} iwn_pmgt[IWN_NDTIMRANGES][IWN_NPOWERLEVELS] = {
+	/* DTIM <= 2 */
+	{
+	{   0,   0, {  0,  0,  0,  0,  0 }, 0 },	/* CAM */
+	{ 200, 500, {  1,  2,  2,  2, -1 }, 0 },	/* PS level 1 */
+	{ 200, 300, {  1,  2,  2,  2, -1 }, 0 },	/* PS level 2 */
+	{  50, 100, {  2,  2,  2,  2, -1 }, 0 },	/* PS level 3 */
+	{  50,  25, {  2,  2,  4,  4, -1 }, 1 },	/* PS level 4 */
+	{  25,  25, {  2,  2,  4,  6, -1 }, 2 }		/* PS level 5 */
+	},
+	/* 3 <= DTIM <= 10 */
+	{
+	{   0,   0, {  0,  0,  0,  0,  0 }, 0 },	/* CAM */
+	{ 200, 500, {  1,  2,  3,  4,  4 }, 0 },	/* PS level 1 */
+	{ 200, 300, {  1,  2,  3,  4,  7 }, 0 },	/* PS level 2 */
+	{  50, 100, {  2,  4,  6,  7,  9 }, 0 },	/* PS level 3 */
+	{  50,  25, {  2,  4,  6,  9, 10 }, 1 },	/* PS level 4 */
+	{  25,  25, {  2,  4,  7, 10, 10 }, 2 }		/* PS level 5 */
+	},
+	/* DTIM >= 11 */
+	{
+	{   0,   0, {  0,  0,  0,  0,  0 }, 0 },	/* CAM */
+	{ 200, 500, {  1,  2,  3,  4, -1 }, 0 },	/* PS level 1 */
+	{ 200, 300, {  2,  4,  6,  7, -1 }, 0 },	/* PS level 2 */
+	{  50, 100, {  2,  7,  9,  9, -1 }, 0 },	/* PS level 3 */
+	{  50,  25, {  2,  7,  9,  9, -1 }, 0 },	/* PS level 4 */
+	{  25,  25, {  4,  7, 10, 10, -1 }, 0 }		/* PS level 5 */
+	}
+};
+
+struct iwn_sensitivity_limits {
+	uint32_t	min_ofdm_x1;
+	uint32_t	max_ofdm_x1;
+	uint32_t	min_ofdm_mrc_x1;
+	uint32_t	max_ofdm_mrc_x1;
+	uint32_t	min_ofdm_x4;
+	uint32_t	max_ofdm_x4;
+	uint32_t	min_ofdm_mrc_x4;
+	uint32_t	max_ofdm_mrc_x4;
+	uint32_t	min_cck_x4;
+	uint32_t	max_cck_x4;
+	uint32_t	min_cck_mrc_x4;
+	uint32_t	max_cck_mrc_x4;
+	uint32_t	min_energy_cck;
+	uint32_t	energy_cck;
+	uint32_t	energy_ofdm;
+};
+
+/*
+ * RX sensitivity limits (values obtained from the reference driver.)
+ */
+static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = {
+	105, 140,
+	170, 210,
+	 85, 120,
+	170, 210,
+	125, 200,
+	200, 400,
+	 97,
+	100,
+	100
+};
+
+static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
+	120, 155,
+	240, 290,
+	 90, 120,
+	170, 210,
+	125, 200,
+	170, 400,
+	 95,
+	 95,
+	 95
+};
+
+/* Map TID to TX scheduler's FIFO. */
+static const uint8_t iwn_tid2fifo[] = {
+	1, 0, 0, 1, 2, 2, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 3
+};
+
+/* Firmware errors. */
+static const char * const iwn_fw_errmsg[] = {
+	"OK",
+	"FAIL",
+	"BAD_PARAM",
+	"BAD_CHECKSUM",
+	"NMI_INTERRUPT_WDG",
+	"SYSASSERT",
+	"FATAL_ERROR",
+	"BAD_COMMAND",
+	"HW_ERROR_TUNE_LOCK",
+	"HW_ERROR_TEMPERATURE",
+	"ILLEGAL_CHAN_FREQ",
+	"VCC_NOT_STABLE",
+	"FH_ERROR",
+	"NMI_INTERRUPT_HOST",
+	"NMI_INTERRUPT_ACTION_PT",
+	"NMI_INTERRUPT_UNKNOWN",
+	"UCODE_VERSION_MISMATCH",
+	"HW_ERROR_ABS_LOCK",
+	"HW_ERROR_CAL_LOCK_FAIL",
+	"NMI_INTERRUPT_INST_ACTION_PT",
+	"NMI_INTERRUPT_DATA_ACTION_PT",
+	"NMI_TRM_HW_ER",
+	"NMI_INTERRUPT_TRM",
+	"NMI_INTERRUPT_BREAKPOINT"
+	"DEBUG_0",
+	"DEBUG_1",
+	"DEBUG_2",
+	"DEBUG_3",
+	"UNKNOWN"
+};
+
+/* Find least significant bit that is set. */
+#define IWN_LSB(x)	((((x) - 1) & (x)) ^ (x))
+
 #define IWN_READ(sc, reg)						\
 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
 
 #define IWN_WRITE(sc, reg, val)						\
 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
 
-#define IWN_WRITE_REGION_4(sc, offset, datap, count)			\
-	bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
-	    (datap), (count))
+#define IWN_SETBITS(sc, reg, mask)					\
+	IWN_WRITE(sc, reg, IWN_READ(sc, reg) | (mask))
+
+#define IWN_CLRBITS(sc, reg, mask)					\
+	IWN_WRITE(sc, reg, IWN_READ(sc, reg) & ~(mask))
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 19cc0250b94..a5fb31f1258 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -1,6 +1,8 @@
 /*	$FreeBSD$	*/
+/*	$OpenBSD: if_iwnvar.h,v 1.12 2009/05/29 08:25:45 damien Exp $	*/
+
 /*-
- * Copyright (c) 2007
+ * Copyright (c) 2007, 2008
  *	Damien Bergamini 
  * Copyright (c) 2008 Sam Leffler, Errno Consulting
  *
@@ -60,6 +62,8 @@ struct iwn_dma_info {
 
 struct iwn_tx_data {
 	bus_dmamap_t		map;
+	bus_addr_t		cmd_paddr;
+	bus_addr_t		scratch_paddr;
 	struct mbuf		*m;
 	struct ieee80211_node	*ni;
 };
@@ -70,45 +74,52 @@ struct iwn_tx_ring {
 	struct iwn_tx_desc	*desc;
 	struct iwn_tx_cmd	*cmd;
 	struct iwn_tx_data	data[IWN_TX_RING_COUNT];
-	bus_dma_tag_t		data_dmat;
 	int			qid;
 	int			queued;
 	int			cur;
 };
 
+struct iwn_softc;
+
 struct iwn_rx_data {
-	bus_dmamap_t		map;
-	struct mbuf		*m;
+	struct mbuf	*m;
+	bus_dmamap_t	map;
 };
 
 struct iwn_rx_ring {
 	struct iwn_dma_info	desc_dma;
+	struct iwn_dma_info	stat_dma;
 	uint32_t		*desc;
+	struct iwn_rx_status	*stat;
 	struct iwn_rx_data	data[IWN_RX_RING_COUNT];
-	bus_dma_tag_t		data_dmat;
 	int			cur;
 };
 
 struct iwn_node {
 	struct	ieee80211_node		ni;	/* must be the first */
-	struct	ieee80211_amrr_node	amn;
-};
 #define	IWN_NODE(_ni)	((struct iwn_node *)(_ni))
 
+	struct	ieee80211_amrr_node	amn;
+	uint16_t			disable_tid;
+	uint8_t				id;
+	uint8_t				ridx[IEEE80211_RATE_MAXSIZE];
+};
+
 struct iwn_calib_state {
 	uint8_t		state;
 #define IWN_CALIB_STATE_INIT	0
 #define IWN_CALIB_STATE_ASSOC	1
 #define IWN_CALIB_STATE_RUN	2
+
 	u_int		nbeacons;
 	uint32_t	noise[3];
 	uint32_t	rssi[3];
-	uint32_t	corr_ofdm_x1;
-	uint32_t	corr_ofdm_mrc_x1;
-	uint32_t	corr_ofdm_x4;
-	uint32_t	corr_ofdm_mrc_x4;
-	uint32_t	corr_cck_x4;
-	uint32_t	corr_cck_mrc_x4;
+	uint32_t	ofdm_x1;
+	uint32_t	ofdm_mrc_x1;
+	uint32_t	ofdm_x4;
+	uint32_t	ofdm_mrc_x4;
+	uint32_t	cck_x4;
+	uint32_t	cck_mrc_x4;
 	uint32_t	bad_plcp_ofdm;
 	uint32_t	fa_ofdm;
 	uint32_t	bad_plcp_cck;
@@ -118,6 +129,7 @@ struct iwn_calib_state {
 #define IWN_CCK_STATE_INIT	0
 #define IWN_CCK_STATE_LOFA	1
 #define IWN_CCK_STATE_HIFA	2
+
 	uint8_t		noise_samples[20];
 	u_int		cur_noise_sample;
 	uint8_t		noise_ref;
@@ -126,10 +138,60 @@ struct iwn_calib_state {
 	uint32_t	energy_cck;
 };
 
+struct iwn_calib_info {
+	uint8_t		*buf;
+	u_int		len;
+};
+
+struct iwn_fw_part {
+	const uint8_t	*text;
+	uint32_t	textsz;
+	const uint8_t	*data;
+	uint32_t	datasz;
+};
+
+struct iwn_fw_info {
+	u_char			*data;
+	struct iwn_fw_part	init;
+	struct iwn_fw_part	main;
+	struct iwn_fw_part	boot;
+};
+
+struct iwn_hal {
+	int		(*load_firmware)(struct iwn_softc *);
+	void		(*read_eeprom)(struct iwn_softc *);
+	int		(*post_alive)(struct iwn_softc *);
+	int		(*apm_init)(struct iwn_softc *);
+	int		(*nic_config)(struct iwn_softc *);
+	void		(*update_sched)(struct iwn_softc *, int, int, uint8_t,
+			    uint16_t);
+	int		(*get_temperature)(struct iwn_softc *);
+	int		(*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *);
+	int		(*set_txpower)(struct iwn_softc *,
+			    struct ieee80211_channel *, int);
+	int		(*init_gains)(struct iwn_softc *);
+	int		(*set_gains)(struct iwn_softc *);
+	int		(*add_node)(struct iwn_softc *, struct iwn_node_info *,
+			    int);
+	void		(*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
+			    struct iwn_rx_data *);
+	const struct	iwn_sensitivity_limits *limits;
+	int		ntxqs;
+	int		ndmachnls;
+	uint8_t		broadcast_id;
+	int		rxonsz;
+	int		schedsz;
+	uint32_t	fw_text_maxsz;
+	uint32_t	fw_data_maxsz;
+	uint32_t	fwsz;
+	bus_size_t	sched_txfact_addr;
+};
+
 struct iwn_vap {
 	struct ieee80211vap	iv_vap;
 	struct ieee80211_amrr	iv_amrr;
 	struct callout		iv_amrr_to;
+	uint8_t			iv_ridx;
 
 	int			(*iv_newstate)(struct ieee80211vap *,
 				    enum ieee80211_state, int);
@@ -139,67 +201,94 @@ struct iwn_vap {
 struct iwn_softc {
 	struct ifnet		*sc_ifp;
 	int			sc_debug;
-	struct callout		sc_timer_to;	/* calib+watchdog timer */
-	int			sc_tx_timer;	/* tx watchdog timer/counter */
-	const struct ieee80211_channel *sc_curchan;
-
-        struct iwn_rx_radiotap_header sc_rxtap;
-        struct iwn_tx_radiotap_header sc_txtap;
 
 	/* locks */
 	struct mtx		sc_mtx;
 
-	/* bus */
+	/* Bus */
 	device_t 		sc_dev;
 	int			mem_rid;
 	int			irq_rid;
 	struct resource 	*mem;
 	struct resource		*irq;
 
-	/* shared area */
-	struct iwn_dma_info	shared_dma;
-	struct iwn_shared	*shared;
+	u_int			sc_flags;
+#define IWN_FLAG_HAS_5GHZ	(1 << 0)
+#define IWN_FLAG_HAS_OTPROM	(1 << 1)
+#define IWN_FLAG_FIRST_BOOT	(1 << 2)
 
-	/* "keep warm" page */
+	uint8_t 		hw_type;
+	const struct iwn_hal	*sc_hal;
+	const char		*fwname;
+
+	/* TX scheduler rings. */
+	struct iwn_dma_info	sched_dma;
+	uint16_t		*sched;
+	uint32_t		sched_base;
+
+	/* "Keep Warm" page. */
 	struct iwn_dma_info	kw_dma;
 
-	/* firmware image */
+	/* Firmware image. */
 	const struct firmware	*fw_fp;
 
-	/* firmware DMA transfer */
+	/* Firmware DMA transfer. */
 	struct iwn_dma_info	fw_dma;
 
-	/* rings */
-	struct iwn_tx_ring	txq[IWN_NTXQUEUES];
+	/* TX/RX rings. */
+	struct iwn_tx_ring	txq[IWN5000_NTXQUEUES];
 	struct iwn_rx_ring	rxq;
 
 	bus_space_tag_t		sc_st;
 	bus_space_handle_t	sc_sh;
 	void 			*sc_ih;
 	bus_size_t		sc_sz;
+	int			sc_cap_off;	/* PCIe Capabilities. */
 
 	/* Tasks used by the driver */
 	struct task             sc_reinit_task;
 	struct task		sc_radioon_task;
 	struct task		sc_radiooff_task;
-
-	/* Thermal calibration */
+	
 	int			calib_cnt;
 	struct iwn_calib_state	calib;
 
+	struct iwn_fw_info	fw;
+	struct iwn_calib_info	calibcmd[5];
+	uint32_t		errptr;
+
 	struct iwn_rx_stat	last_rx_stat;
 	int			last_rx_valid;
 	struct iwn_ucode_info	ucode_info;
-	struct iwn_config	config;
+	struct iwn_rxon		rxon;
 	uint32_t		rawtemp;
 	int			temp;
 	int			noise;
-	uint8_t			antmsk;
+	uint32_t		qfullmsk;
 
-	struct iwn_eeprom_band	bands[IWN_NBANDS];
+	struct iwn4965_eeprom_band
+				bands[IWN_NBANDS];
+	uint16_t		rfcfg;
+	char			eeprom_domain[4];
+	uint32_t		eeprom_crystal;
 	int16_t			eeprom_voltage;
 	int8_t			maxpwr2GHz;
 	int8_t			maxpwr5GHz;
+	int8_t			maxpwr[IEEE80211_CHAN_MAX];
+
+	uint32_t		critical_temp;
+	uint8_t			ntxchains;
+	uint8_t			nrxchains;
+	uint8_t			txantmsk;
+	uint8_t			rxantmsk;
+	uint8_t			antmsk;
+
+	struct callout		sc_timer_to;
+	int			sc_tx_timer;
+
+	struct iwn_rx_radiotap_header sc_rxtap;
+	struct iwn_tx_radiotap_header sc_txtap;
+	const struct ieee80211_channel *sc_curchan;
 };
 
 #define IWN_LOCK_INIT(_sc) \
diff --git a/sys/modules/iwnfw/Makefile b/sys/modules/iwnfw/Makefile
index 498afcf19eb..ee5e90faf7b 100644
--- a/sys/modules/iwnfw/Makefile
+++ b/sys/modules/iwnfw/Makefile
@@ -1,13 +1,23 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../../contrib/dev/iwn
+FWDIR=	${.CURDIR}/../../contrib/dev/iwn
+.PATH: ${FWDIR}
 
 KMOD=	iwnfw
-FIRMWS=	iwlwifi-4965-4.44.17.fw:iwnfw:44417
+FIRMWS=	iwlwifi-4965-228.57.2.23.fw:iwnfw-4965:22857223 \
+	iwlwifi-5000-5.4.A.11.fw:iwnfw-5000:54A11 \
+	iwlwifi-5150-8.24.2.2.fw:iwnfw-5150:82422
 
-CLEANFILES=	iwlwifi-4965-4.44.17.fw
+CLEANFILES=	iwlwifi-4965-228.57.2.23.fw iwlwifi-5000-5.4.A.11.fw \
+		iwlwifi-5150-8.24.2.2.fw
 
-iwlwifi-4965-4.44.17.fw: ${.CURDIR}/../../contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu
-	uudecode -p ${.CURDIR}/../../contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu > ${.TARGET}
+iwlwifi-4965-228.57.2.23.fw: ${FWDIR}/iwlwifi-4965-228.57.2.23.fw.uu
+	uudecode -p ${FWDIR}/iwlwifi-4965-228.57.2.23.fw.uu > ${.TARGET}
+
+iwlwifi-5000-5.4.A.11.fw: ${FWDIR}/iwlwifi-5000-5.4.A.11.fw.uu
+	uudecode -p ${FWDIR}/iwlwifi-5000-5.4.A.11.fw.uu > ${.TARGET}
+
+iwlwifi-5150-8.24.2.2.fw: ${FWDIR}/iwlwifi-5150-8.24.2.2.fw.uu
+	uudecode -p ${FWDIR}/iwlwifi-5150-8.24.2.2.fw.uu > ${.TARGET}
 
 .include 

From d6eb44c8b0542c4756eb190fcdcfa0351c5812a3 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Fri, 23 Oct 2009 22:53:01 +0000
Subject: [PATCH 321/646] BIOSes, buggy or otherwise, are i386 or amd64
 specific. Have the early USB takeover enabled for i386 and amd64 by default.
 This also avoids a panic on PowerPC where the resource isn't released
 properly and we find a busy resource when the USB host controller wants to
 allocate it...

---
 sys/dev/pci/pci.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index e60ee234c85..8922aba4018 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -274,7 +274,11 @@ TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist);
 SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD,
     &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI");
 
+#if defined(__i386__) || defined(__amd64__)
 static int pci_usb_takeover = 1;
+#else
+static int pci_usb_takeover = 0;
+#endif
 TUNABLE_INT("hw.pci.usb_early_takeover", &pci_usb_takeover);
 SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RD | CTLFLAG_TUN,
     &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\

From 27be5d5888b739a313c08b45717c82704cb63940 Mon Sep 17 00:00:00 2001
From: Joseph Koshy 
Date: Sat, 24 Oct 2009 01:58:10 +0000
Subject: [PATCH 322/646] Only claim that the PMC_CLASS_IAF PMCs are supported
 by a CPU if there are PMCs on the CPU that belong to the class.

Review and testing by:	fabient
---
 sys/dev/hwpmc/hwpmc_core.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index d4f065b6024..b6de04dfce8 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -1977,11 +1977,21 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu)
 		core_iaf_npmc = cpuid[CORE_CPUID_EDX] & 0x1F;
 		core_iaf_width = (cpuid[CORE_CPUID_EDX] >> 5) & 0xFF;
 
-		iaf_initialize(md, maxcpu, core_iaf_npmc, core_iaf_width);
-
-		core_pmcmask |= ((1ULL << core_iaf_npmc) - 1) <<
-		    IAF_OFFSET;
-
+		if (core_iaf_npmc > 0) {
+			iaf_initialize(md, maxcpu, core_iaf_npmc,
+			    core_iaf_width);
+			core_pmcmask |= ((1ULL << core_iaf_npmc) - 1) <<
+			    IAF_OFFSET;
+		} else {
+			/*
+			 * Adjust the number of classes exported to
+			 * user space.
+			 */
+			md->pmd_nclass--;
+			KASSERT(md->pmd_nclass == 2,
+			    ("[core,%d] unexpected nclass %d", __LINE__,
+				md->pmd_nclass));
+		}
 	}
 
 	PMCDBG(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask,

From 791f5d5ba2e472e3b7b46be7bf917c8574f4c8f6 Mon Sep 17 00:00:00 2001
From: Joseph Koshy 
Date: Sat, 24 Oct 2009 04:11:40 +0000
Subject: [PATCH 323/646] Not all Intel Core (TM) CPUs implement PMC_CLASS_IAF
 fixed-function counters.  For such CPUs, use an alternate mapping of
 convenience names to events supported by PMC_CLASS_IAP programmable counters.

Testing and review by:	fabient
---
 lib/libpmc/libpmc.c | 59 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 47 insertions(+), 12 deletions(-)

diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 76bc89d808a..ecc697da203 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -442,6 +442,10 @@ static struct pmc_event_alias core_aliases[] = {
 /*
  * Intel Core2 (Family 6, Model F), Core2Extreme (Family 6, Model 17H)
  * and Atom (Family 6, model 1CH) PMCs.
+ *
+ * We map aliases to events on the fixed-function counters if these
+ * are present.  Note that not all CPUs in this family contain fixed-function
+ * counters.
  */
 
 static struct pmc_event_alias core2_aliases[] = {
@@ -454,8 +458,22 @@ static struct pmc_event_alias core2_aliases[] = {
 	EV_ALIAS("unhalted-cycles",	"iaf-cpu-clk-unhalted.core"),
 	EV_ALIAS(NULL, NULL)
 };
-#define	atom_aliases	core2_aliases
-#define corei7_aliases	core2_aliases
+
+static struct pmc_event_alias core2_aliases_without_iaf[] = {
+	EV_ALIAS("branches",		"iap-br-inst-retired.any"),
+	EV_ALIAS("branch-mispredicts",	"iap-br-inst-retired.mispred"),
+	EV_ALIAS("cycles",		"tsc-tsc"),
+	EV_ALIAS("ic-misses",		"iap-l1i-misses"),
+	EV_ALIAS("instructions",	"iap-inst-retired.any_p"),
+	EV_ALIAS("interrupts",		"iap-hw-int-rcv"),
+	EV_ALIAS("unhalted-cycles",	"iap-cpu-clk-unhalted.core_p"),
+	EV_ALIAS(NULL, NULL)
+};
+
+#define	atom_aliases			core2_aliases
+#define	atom_aliases_without_iaf	core2_aliases_without_iaf
+#define corei7_aliases			core2_aliases
+#define corei7_aliases_without_iaf	core2_aliases_without_iaf
 
 #define	IAF_KW_OS		"os"
 #define	IAF_KW_USR		"usr"
@@ -2379,6 +2397,10 @@ pmc_init(void)
 	uint32_t abi_version;
 	struct module_stat pmc_modstat;
 	struct pmc_op_getcpuinfo op_cpu_info;
+#if defined(__amd64__) || defined(__i386__)
+	int cpu_has_iaf_counters;
+	unsigned int t;
+#endif
 
 	if (pmc_syscall != -1) /* already inited */
 		return (0);
@@ -2420,6 +2442,8 @@ pmc_init(void)
 	if (pmc_class_table == NULL)
 		return (-1);
 
+	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++)
+		pmc_class_table[n] = NULL;
 
 	/*
 	 * Fill in the class table.
@@ -2427,6 +2451,14 @@ pmc_init(void)
 	n = 0;
 #if defined(__amd64__) || defined(__i386__)
 	pmc_class_table[n++] = &tsc_class_table_descr;
+
+	/*
+ 	 * Check if this CPU has fixed function counters.
+	 */
+	cpu_has_iaf_counters = 0;
+	for (t = 0; t < cpu_info.pm_nclass; t++)
+		if (cpu_info.pm_classes[t].pm_class == PMC_CLASS_IAF)
+			cpu_has_iaf_counters = 1;
 #endif
 
 #define	PMC_MDEP_INIT(C) do {					\
@@ -2436,6 +2468,16 @@ pmc_init(void)
 		    PMC_TABLE_SIZE(C##_pmc_classes);		\
 	} while (0)
 
+#define	PMC_MDEP_INIT_INTEL_V2(C) do {					\
+		PMC_MDEP_INIT(C);					\
+		if (cpu_has_iaf_counters) 				\
+			pmc_class_table[n++] = &iaf_class_table_descr;	\
+		else							\
+			pmc_mdep_event_aliases =			\
+				C##_aliases_without_iaf;		\
+		pmc_class_table[n] = &C##_class_table_descr;		\
+	} while (0)
+
 	/* Configure the event name parser. */
 	switch (cpu_info.pm_cputype) {
 #if defined(__i386__)
@@ -2461,24 +2503,17 @@ pmc_init(void)
 		pmc_class_table[n] = &k8_class_table_descr;
 		break;
 	case PMC_CPU_INTEL_ATOM:
-		PMC_MDEP_INIT(atom);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &atom_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(atom);
 		break;
 	case PMC_CPU_INTEL_CORE:
 		PMC_MDEP_INIT(core);
-		pmc_class_table[n] = &core_class_table_descr;
 		break;
 	case PMC_CPU_INTEL_CORE2:
 	case PMC_CPU_INTEL_CORE2EXTREME:
-		PMC_MDEP_INIT(core2);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &core2_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(core2);
 		break;
 	case PMC_CPU_INTEL_COREI7:
-		PMC_MDEP_INIT(corei7);
-		pmc_class_table[n++] = &iaf_class_table_descr;
-		pmc_class_table[n]   = &corei7_class_table_descr;
+		PMC_MDEP_INIT_INTEL_V2(corei7);
 		break;
 	case PMC_CPU_INTEL_PIV:
 		PMC_MDEP_INIT(p4);

From 99b96cf9341c6302713a1514db5c638d825d07c3 Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Sat, 24 Oct 2009 09:18:26 +0000
Subject: [PATCH 324/646] Correct spelling typo in ip_input comment.

Pointed out by:	N.J. Mann ,
		John Nielsen , julian (!), lstewart
MFC after:	2 days
---
 sys/netinet/ip_input.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 5e87467fe25..8ffa01ab8a2 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -531,7 +531,7 @@ tooshort:
 	if ((dchg = (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL)) != 0) {
 		/*
 		 * Directly ship the packet on.  This allows forwarding
-		 * packets originally destined to us to ome other directly
+		 * packets originally destined to us to some other directly
 		 * connected host.
 		 */
 		ip_forward(m, dchg);

From e7e0fcbea805c8984158b81d32a7990f7dac535f Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sat, 24 Oct 2009 09:55:11 +0000
Subject: [PATCH 325/646] Updates to the iwn driver: * iwnfw has now been split
 into individual modules so autoloading of   firmware module(s) does work
 again. * Changes have been made to RUN -> AUTH transition, this should fix
 the   issue reported by Glen and others. * Brandon reported issues in
 iwn_cmd() with large commands, those have   been fixed to. * DEAUTH is now
 handled correctly.

Submitted by:	Bernhard Schmidt 
---
 sys/dev/iwn/if_iwn.c               | 154 ++++++++++++++++++++---------
 sys/modules/iwnfw/Makefile         |  22 +----
 sys/modules/iwnfw/Makefile.inc     |  13 +++
 sys/modules/iwnfw/iwn4965/Makefile |   6 ++
 sys/modules/iwnfw/iwn5000/Makefile |   6 ++
 sys/modules/iwnfw/iwn5150/Makefile |   6 ++
 6 files changed, 142 insertions(+), 65 deletions(-)
 create mode 100644 sys/modules/iwnfw/Makefile.inc
 create mode 100644 sys/modules/iwnfw/iwn4965/Makefile
 create mode 100644 sys/modules/iwnfw/iwn5000/Makefile
 create mode 100644 sys/modules/iwnfw/iwn5150/Makefile

diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index eb2182eb7c5..9d1376bb352 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -601,7 +601,7 @@ iwn_hal_attach(struct iwn_softc *sc)
 	switch (sc->hw_type) {
 	case IWN_HW_REV_TYPE_4965:
 		sc->sc_hal = &iwn4965_hal;
-		sc->fwname = "iwnfw-4965";
+		sc->fwname = "iwn4965fw";
 		sc->critical_temp = IWN_CTOK(110);
 		sc->txantmsk = IWN_ANT_A | IWN_ANT_B;
 		sc->rxantmsk = IWN_ANT_ABC;
@@ -610,7 +610,7 @@ iwn_hal_attach(struct iwn_softc *sc)
 		break;
 	case IWN_HW_REV_TYPE_5100:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-5000";
+		sc->fwname = "iwn5000fw";
 		sc->critical_temp = 110;
 		sc->txantmsk = IWN_ANT_B;
 		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
@@ -619,7 +619,7 @@ iwn_hal_attach(struct iwn_softc *sc)
 		break;
 	case IWN_HW_REV_TYPE_5150:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-5150";
+		sc->fwname = "iwn5150fw";
 		/* NB: critical temperature will be read from EEPROM. */
 		sc->txantmsk = IWN_ANT_A;
 		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
@@ -629,14 +629,14 @@ iwn_hal_attach(struct iwn_softc *sc)
 	case IWN_HW_REV_TYPE_5300:
 	case IWN_HW_REV_TYPE_5350:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-5000";
+		sc->fwname = "iwn5000fw";
 		sc->critical_temp = 110;
 		sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
 		sc->ntxchains = sc->nrxchains = 3;
 		break;
 	case IWN_HW_REV_TYPE_1000:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-1000";
+		sc->fwname = "iwn1000fw";
 		sc->critical_temp = 110;
 		sc->txantmsk = IWN_ANT_A;
 		sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
@@ -645,7 +645,7 @@ iwn_hal_attach(struct iwn_softc *sc)
 		break;
 	case IWN_HW_REV_TYPE_6000:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-6000";
+		sc->fwname = "iwn6000fw";
 		sc->critical_temp = 110;
 		sc->txantmsk = IWN_ANT_ABC;
 		sc->rxantmsk = IWN_ANT_ABC;
@@ -654,7 +654,7 @@ iwn_hal_attach(struct iwn_softc *sc)
 		break;
 	case IWN_HW_REV_TYPE_6050:
 		sc->sc_hal = &iwn5000_hal;
-		sc->fwname = "iwnfw-6050";
+		sc->fwname = "iwn6050fw";
 		sc->critical_temp = 110;
 		sc->txantmsk = IWN_ANT_ABC;
 		sc->rxantmsk = IWN_ANT_ABC;
@@ -1150,7 +1150,6 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 	 */
 	for (i = 0; i < IWN_RX_RING_COUNT; i++) {
 		struct iwn_rx_data *data = &ring->data[i];
-		struct mbuf *m;
 		bus_addr_t paddr;
 
 		error = bus_dmamap_create(ring->desc_dma.tag, 0, &data->map);
@@ -1161,8 +1160,8 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 			goto fail;
 		}
 
-		m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
-		if (m == NULL) {
+		data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
+		if (data->m == NULL) {
 			device_printf(sc->sc_dev,
 			   "%s: could not allocate rx mbuf\n", __func__);
 			error = ENOMEM;
@@ -1171,20 +1170,16 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 
 		/* Map page. */
 		error = bus_dmamap_load(ring->desc_dma.tag, data->map,
-		    mtod(m, caddr_t), MJUMPAGESIZE,
+		    mtod(data->m, caddr_t), MJUMPAGESIZE,
 		    iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 		if (error != 0 && error != EFBIG) {
 			device_printf(sc->sc_dev,
 			    "%s: bus_dmamap_load failed, error %d\n",
 			    __func__, error);
-			m_freem(m);
+			m_freem(data->m);
 			error = ENOMEM;	/* XXX unique code */
 			goto fail;
 		}
-		bus_dmamap_sync(ring->desc_dma.tag, data->map,
-		    BUS_DMASYNC_PREWRITE);
-
-		data->m = m;
 
 		/* Set physical address of RX buffer (256-byte aligned). */
 		ring->desc[i] = htole32(paddr >> 8);
@@ -1233,6 +1228,8 @@ iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 		struct iwn_rx_data *data = &ring->data[i];
 
 		if (data->m != NULL) {
+			bus_dmamap_sync(ring->desc_dma.tag, data->map,
+			    BUS_DMASYNC_POSTREAD);
 			bus_dmamap_unload(ring->desc_dma.tag, data->map);
 			m_freem(data->m);
 		}
@@ -1304,8 +1301,6 @@ iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
 			    __func__, error);
 			goto fail;
 		}
-		bus_dmamap_sync(ring->desc_dma.tag, data->map,
-		    BUS_DMASYNC_PREWRITE);
 	}
 	return 0;
 fail:
@@ -1322,6 +1317,8 @@ iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 		struct iwn_tx_data *data = &ring->data[i];
 
 		if (data->m != NULL) {
+			bus_dmamap_sync(ring->desc_dma.tag, data->map,
+			    BUS_DMASYNC_POSTWRITE);
 			bus_dmamap_unload(ring->desc_dma.tag, data->map);
 			m_freem(data->m);
 			data->m = NULL;
@@ -1329,6 +1326,8 @@ iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 	}
 	/* Clear TX descriptors. */
 	memset(ring->desc, 0, ring->desc_dma.size);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
 	sc->qfullmsk &= ~(1 << ring->qid);
 	ring->queued = 0;
 	ring->cur = 0;
@@ -1347,7 +1346,10 @@ iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 			struct iwn_tx_data *data = &ring->data[i];
 
 			if (data->m != NULL) {
-				bus_dmamap_unload(ring->desc_dma.tag, data->map);
+				bus_dmamap_sync(ring->desc_dma.tag, data->map,
+				     BUS_DMASYNC_POSTWRITE);
+				bus_dmamap_unload(ring->desc_dma.tag,
+				    data->map);
 				m_freem(data->m);
 			}
 		}
@@ -1709,10 +1711,11 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 
 	if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
 		/* !AUTH -> AUTH requires adapter config */
-		error = 1;
-		while (error) {
-			error = iwn_auth(sc, vap);
-		}
+		/* Reset state to handle reassociations correctly. */
+		sc->rxon.associd = 0;
+		sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
+		iwn_calib_reset(sc);
+		error = iwn_auth(sc, vap);
 	}
 	if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
 		/*
@@ -1832,6 +1835,8 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	} else
 		stat = (struct iwn_rx_stat *)(desc + 1);
 
+	bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_POSTREAD);
+
 	if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
 		device_printf(sc->sc_dev,
 		    "%s: invalid rx statistic header, len %d\n",
@@ -2054,7 +2059,6 @@ iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	    __func__, desc->qid, desc->idx, stat->retrycnt,
 	    stat->killcnt, stat->rate, le16toh(stat->duration),
 	    le32toh(stat->status));
-
 	iwn_tx_done(sc, desc, stat->retrycnt, le32toh(stat->status) & 0xff);
 }
 
@@ -2072,7 +2076,6 @@ iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 
 	/* Reset TX scheduler slot. */
 	iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
-
 	iwn_tx_done(sc, desc, stat->retrycnt, le16toh(stat->status) & 0xff);
 }
 
@@ -2151,11 +2154,13 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 
 	/* If the command was mapped in an mbuf, free it. */
 	if (data->m != NULL) {
+		bus_dmamap_sync(ring->desc_dma.tag, data->map,
+		    BUS_DMASYNC_POSTWRITE);
 		bus_dmamap_unload(ring->desc_dma.tag, data->map);
 		m_freem(data->m);
 		data->m = NULL;
 	}
-	wakeup(&ring->cmd[desc->idx]);
+	wakeup(&ring->desc[desc->idx]);
 }
 
 /*
@@ -2183,7 +2188,7 @@ iwn_notif_intr(struct iwn_softc *sc)
 
 		DPRINTF(sc, IWN_DEBUG_RECV,
 		    "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
-		    __func__, desc->qid /*& 0xf*/, desc->idx, desc->flags,
+		    __func__, desc->qid & 0xf, desc->idx, desc->flags,
 		    desc->type, iwn_intr_str(desc->type),
 		    le16toh(desc->len));
 
@@ -2217,10 +2222,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			    (struct iwn_beacon_missed *)(desc + 1);
 			int misses = le32toh(miss->consecutive);
 
-			/* XXX not sure why we're notified w/ zero */
-			if (misses == 0)
-				break;
-
+			bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+			    BUS_DMASYNC_PREWRITE);
 			DPRINTF(sc, IWN_DEBUG_STATE,
 			    "%s: beacons missed %d/%d\n", __func__,
 			    misses, le32toh(miss->total));
@@ -2241,7 +2244,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			    (struct iwn_ucode_info *)(desc + 1);
 
 			/* The microcontroller is ready. */
-
+			bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+			    BUS_DMASYNC_PREWRITE);
 			DPRINTF(sc, IWN_DEBUG_RESET,
 			    "microcode alive notification version=%d.%d "
 			    "subtype=%x alive=%x\n", uc->major, uc->minor,
@@ -2269,7 +2273,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			 * noted. However, we handle this in iwn_intr as we
 			 * get both the enable/disble intr.
 			 */
-
+			bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+			    BUS_DMASYNC_PREWRITE);
 			DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
 			    le32toh(*status));
 			break;
@@ -2279,6 +2284,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			struct iwn_start_scan *scan =
 			    (struct iwn_start_scan *)(desc + 1);
 
+			bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+			    BUS_DMASYNC_PREWRITE);
 			DPRINTF(sc, IWN_DEBUG_ANY,
 			    "%s: scanning channel %d status %x\n",
 			    __func__, scan->chan, le32toh(scan->status));
@@ -2289,6 +2296,8 @@ iwn_notif_intr(struct iwn_softc *sc)
 			struct iwn_stop_scan *scan =
 			    (struct iwn_stop_scan *)(desc + 1);
 
+			bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
+			    BUS_DMASYNC_PREWRITE);
 			DPRINTF(sc, IWN_DEBUG_STATE,
 			    "scan finished nchan=%d status=%d chan=%d\n",
 			    scan->nchan, scan->status, scan->chan);
@@ -2494,8 +2503,13 @@ iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
 	uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
 
 	*w = htole16(len + 8);
-	if (idx < IWN4965_SCHEDSZ)
+	bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	if (idx < IWN4965_SCHEDSZ) {
 		*(w + IWN_TX_RING_COUNT) = *w;
+		bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+		    BUS_DMASYNC_PREWRITE);
+	}
 }
 
 void
@@ -2505,8 +2519,14 @@ iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
 	uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
 
 	*w = htole16(id << 12 | (len + 8));
-	if (idx < IWN_SCHED_WINSZ)
+
+	bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	if (idx < IWN_SCHED_WINSZ) {
 		*(w + IWN_TX_RING_COUNT) = *w;
+		bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+		    BUS_DMASYNC_PREWRITE);
+	}
 }
 
 void
@@ -2515,8 +2535,13 @@ iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
 	uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
 
 	*w = (*w & htole16(0xf000)) | htole16(1);
-	if (idx < IWN_SCHED_WINSZ)
+	bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	if (idx < IWN_SCHED_WINSZ) {
 		*(w + IWN_TX_RING_COUNT) = *w;
+		bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
+		     BUS_DMASYNC_PREWRITE);
+	}
 }
 
 /* Determine if a given rate is CCK or OFDM. */
@@ -3104,26 +3129,49 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 	struct iwn_tx_desc *desc;
 	struct iwn_tx_data *data;
 	struct iwn_tx_cmd *cmd;
+	struct mbuf *m;
 	bus_addr_t paddr;
-	int totlen;
+	int totlen, error;
 
 	IWN_LOCK_ASSERT(sc);
 
-	KASSERT(size <= sizeof cmd->data, ("Command too big"));
-
 	desc = &ring->desc[ring->cur];
 	data = &ring->data[ring->cur];
-	cmd = &ring->cmd[ring->cur];
 	totlen = 4 + size;
 
+	if (size > sizeof cmd->data) {
+		/* Command is too large to fit in a descriptor. */
+		if (totlen > MCLBYTES)
+			return EINVAL;
+		MGETHDR(m, M_DONTWAIT, MT_DATA);
+		if (m == NULL)
+			return ENOMEM;
+		if (totlen > MHLEN) {
+			MCLGET(m, M_DONTWAIT);
+			if (!(m->m_flags & M_EXT)) {
+				m_freem(m);
+				return ENOMEM;
+			}
+		}
+		cmd = mtod(m, struct iwn_tx_cmd *);
+		error = bus_dmamap_load(ring->cmd_dma.tag, data->map, cmd,
+		    totlen, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
+		if (error != 0) {
+			m_freem(m);
+			return error;
+		}
+		data->m = m;
+	} else {
+		cmd = &ring->cmd[ring->cur];
+		paddr = data->cmd_paddr;
+	}
+
 	cmd->code = code;
 	cmd->flags = 0;
 	cmd->qid = ring->qid;
 	cmd->idx = ring->cur;
 	memcpy(cmd->data, buf, size);
 
-	paddr = data->cmd_paddr;
-
 	desc->nsegs = 1;
 	desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
 	desc->segs[0].len  = htole16(IWN_HIADDR(paddr) | totlen << 4);
@@ -3132,6 +3180,16 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 	    __func__, iwn_intr_str(cmd->code), cmd->code,
 	    cmd->flags, cmd->qid, cmd->idx);
 
+	if (size > sizeof cmd->data) {
+		bus_dmamap_sync(ring->cmd_dma.tag, data->map,
+		    BUS_DMASYNC_PREWRITE);
+	} else {
+		bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
+		    BUS_DMASYNC_PREWRITE);
+	}
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+
 	/* Update TX scheduler. */
 	hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
 
@@ -3139,7 +3197,7 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 
-	return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
+	return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
 }
 
 int
@@ -3876,11 +3934,12 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 	struct iwn_calib_state *calib = &sc->calib;
 	uint32_t val, rxena, fa;
 	uint32_t energy[3], energy_min;
-	int i, needs_update = 0;
 	uint8_t noise[3], noise_ref;
+	int i, needs_update = 0;
 
 	/* Check that we've been enabled long enough. */
-	if ((rxena = le32toh(stats->general.load)) == 0)
+	rxena = le32toh(stats->general.load);
+	if (rxena == 0)
 		return;
 
 	/* Compute number of false alarms since last call for OFDM. */
@@ -4810,8 +4869,10 @@ iwn4965_load_firmware(struct iwn_softc *sc)
 
 	/* Copy initialization sections into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 	    fw->init.text, fw->init.textsz);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	/* Tell adapter where to find initialization sections. */
 	error = iwn_nic_lock(sc);
@@ -4849,8 +4910,10 @@ iwn4965_load_firmware(struct iwn_softc *sc)
 
 	/* Copy runtime sections into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 	    fw->main.text, fw->main.textsz);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	/* Tell adapter where to find runtime sections. */
 	error = iwn_nic_lock(sc);
@@ -4877,6 +4940,7 @@ iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
 
 	/* Copy firmware section into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, section, size);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	error = iwn_nic_lock(sc);
 	if (error != 0)
diff --git a/sys/modules/iwnfw/Makefile b/sys/modules/iwnfw/Makefile
index ee5e90faf7b..8d260b7e64c 100644
--- a/sys/modules/iwnfw/Makefile
+++ b/sys/modules/iwnfw/Makefile
@@ -1,23 +1,5 @@
 # $FreeBSD$
 
-FWDIR=	${.CURDIR}/../../contrib/dev/iwn
-.PATH: ${FWDIR}
+SUBDIR=	iwn4965 iwn5000 iwn5150
 
-KMOD=	iwnfw
-FIRMWS=	iwlwifi-4965-228.57.2.23.fw:iwnfw-4965:22857223 \
-	iwlwifi-5000-5.4.A.11.fw:iwnfw-5000:54A11 \
-	iwlwifi-5150-8.24.2.2.fw:iwnfw-5150:82422
-
-CLEANFILES=	iwlwifi-4965-228.57.2.23.fw iwlwifi-5000-5.4.A.11.fw \
-		iwlwifi-5150-8.24.2.2.fw
-
-iwlwifi-4965-228.57.2.23.fw: ${FWDIR}/iwlwifi-4965-228.57.2.23.fw.uu
-	uudecode -p ${FWDIR}/iwlwifi-4965-228.57.2.23.fw.uu > ${.TARGET}
-
-iwlwifi-5000-5.4.A.11.fw: ${FWDIR}/iwlwifi-5000-5.4.A.11.fw.uu
-	uudecode -p ${FWDIR}/iwlwifi-5000-5.4.A.11.fw.uu > ${.TARGET}
-
-iwlwifi-5150-8.24.2.2.fw: ${FWDIR}/iwlwifi-5150-8.24.2.2.fw.uu
-	uudecode -p ${FWDIR}/iwlwifi-5150-8.24.2.2.fw.uu > ${.TARGET}
-
-.include 
+.include 
diff --git a/sys/modules/iwnfw/Makefile.inc b/sys/modules/iwnfw/Makefile.inc
new file mode 100644
index 00000000000..73fe67e355d
--- /dev/null
+++ b/sys/modules/iwnfw/Makefile.inc
@@ -0,0 +1,13 @@
+# $FreeBSD$
+#
+# Common rules for building firmware.  Note this gets auto-included
+# by the subdir Makefile's as a consequence of included bsd.kmod.mk.
+
+_FIRM=	${IMG}.fw
+
+CLEANFILES+=	${_FIRM}
+
+FIRMWS=	${_FIRM}:${KMOD}
+
+${_FIRM}: ${.CURDIR}/../../../contrib/dev/iwn/${_FIRM}.uu
+	uudecode -p $? > ${.TARGET}
diff --git a/sys/modules/iwnfw/iwn4965/Makefile b/sys/modules/iwnfw/iwn4965/Makefile
new file mode 100644
index 00000000000..6e88f8edf0e
--- /dev/null
+++ b/sys/modules/iwnfw/iwn4965/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn4965fw
+IMG=	iwlwifi-4965-228.57.2.23
+
+.include 
diff --git a/sys/modules/iwnfw/iwn5000/Makefile b/sys/modules/iwnfw/iwn5000/Makefile
new file mode 100644
index 00000000000..88e9e993628
--- /dev/null
+++ b/sys/modules/iwnfw/iwn5000/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn5000fw
+IMG=	iwlwifi-5000-5.4.A.11
+
+.include 
diff --git a/sys/modules/iwnfw/iwn5150/Makefile b/sys/modules/iwnfw/iwn5150/Makefile
new file mode 100644
index 00000000000..5eeea79490b
--- /dev/null
+++ b/sys/modules/iwnfw/iwn5150/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn5150fw
+IMG=	iwlwifi-5150-8.24.2.2
+
+.include 

From 749976613e31bd21c69ad35578df50eed013148a Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sat, 24 Oct 2009 11:32:02 +0000
Subject: [PATCH 326/646] Replace ocurrences of FreeBSD CURRENT by FreeBSD 8.0.

MFC after:	2 days
---
 share/man/man4/acpi_hp.4  | 4 ++--
 share/man/man4/acpi_wmi.4 | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/share/man/man4/acpi_hp.4 b/share/man/man4/acpi_hp.4
index 02a0a8d7f7d..efa9d0b0bd1 100644
--- a/share/man/man4/acpi_hp.4
+++ b/share/man/man4/acpi_hp.4
@@ -256,7 +256,7 @@ sysctl dev.acpi_hp.0.cmi_detail=7
 The
 .Nm
 device driver first appeared in
-.Fx CURRENT .
+.Fx 8.0 .
 .Sh AUTHORS
 .An -nosplit
 The
@@ -279,7 +279,7 @@ http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx
 This manual page was written by
 .An Michael Gmelin Aq freebsd@grem.de
 .Sh BUGS
-This driver is experimental and has only been tested on CURRENT i386 on an
+This driver is experimental and has only been tested on i386 on an
 HP Compaq 8510p which featured all supported wireless devices (WWAN/BT/WLAN).
 Expect undefined results when operating on different hardware.
 .Pp
diff --git a/share/man/man4/acpi_wmi.4 b/share/man/man4/acpi_wmi.4
index d9bcbd4bd8a..c73307c6690 100644
--- a/share/man/man4/acpi_wmi.4
+++ b/share/man/man4/acpi_wmi.4
@@ -79,7 +79,7 @@ GUID                                  INST EXPE METH STR EVENT OID
 The
 .Nm
 device driver first appeared in
-.Fx CURRENT .
+.Fx 8.0 .
 .Sh AUTHORS
 .An -nosplit
 The

From 797b830baf987eecd698514cf9209f18df632035 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 24 Oct 2009 12:59:29 +0000
Subject: [PATCH 327/646] Add more obsolete man pages.

---
 ObsoleteFiles.inc | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index ef00999486d..359e091bad6 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -14,6 +14,9 @@
 # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
 #
 
+# 20091005: fusword.9 and susword.9 removed
+OLD_FILES+=usr/share/man/man9/fusword.9.gz
+OLD_FILES+=usr/share/man/man9/susword.9.gz
 # 20090909: vesa and dpms promoted to be i386/amd64 common
 OLD_FILES+=usr/include/machine/pc/vesa.h
 OLD_FILES+=usr/share/man/man4/i386/dpms.4.gz
@@ -26,6 +29,49 @@ OLD_FILES+=usr/share/man/man8/lukemftpd.8.gz
 OLD_FILES+=etc/mtree/BSD.local.dist
 OLD_FILES+=etc/mtree/BSD.x11.dist
 OLD_FILES+=etc/mtree/BSD.x11-4.dist
+# 20090812: net80211 documentation overhaul
+OLD_FILES+=usr/share/man/man9/ieee80211_add_rates.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_add_xrates.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_alloc_node.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_attach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_begin_scan.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_cfgget.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_cfgset.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_chan2ieee.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_chan2mode.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_create_ibss.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_crypto_attach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_crypto_detach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_decap.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_dump_pkt.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_dup_bss.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_encap.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_end_scan.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_find_node.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_fix_rate.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_free_allnodes.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_ieee2mhz.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_ioctl.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_lookup_node.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_media2rate.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_media_change.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_media_init.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_media_status.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_mhz2ieee.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_next_scan.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_node_attach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_node_detach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_node_lateattach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_print_essid.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_proto_attach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_proto_detach.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_rate2media.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_recv_mgmt.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_send_mgmt.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_setmode.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_timeout_nodes.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_watchdog.9.gz
+OLD_FILES+=usr/share/man/man9/ieee80211_wep_crypt.9.gz
 # 20090801: vimage.h removed in favour of vnet.h
 OLD_FILES+=usr/include/sys/vimage.h
 # 20090719: library version bump for 8.0

From 37a7f59644b287998f37276da6ce454fcf86133e Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 24 Oct 2009 18:31:22 +0000
Subject: [PATCH 328/646] Allow Heathrow-based machines to boot a kernel
 containing option SMP without panicing.

---
 sys/powerpc/powermac/hrowpic.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/powerpc/powermac/hrowpic.c b/sys/powerpc/powermac/hrowpic.c
index 2ed0aa3744a..ce35d465e15 100644
--- a/sys/powerpc/powermac/hrowpic.c
+++ b/sys/powerpc/powermac/hrowpic.c
@@ -182,7 +182,13 @@ hrowpic_toggle_irq(struct hrowpic_softc *sc, int irq, int enable)
 	u_int roffset;
 	u_int rbit;
 
-	KASSERT((irq > 0) && (irq < HROWPIC_IRQMAX), ("en irq out of range"));
+	KASSERT((irq > 0) && (irq <= HROWPIC_IRQMAX), ("en irq out of range"));
+
+	/*
+	 * Humor the SMP layer if it wants to set up an IPI handler.
+	 */
+	if (irq == HROWPIC_IRQMAX)
+		return;
 
 	/*
 	 * Calculate prim/sec register bank for the IRQ, update soft copy,

From 570d2b25a621354a11c14bda6ca61ba9329c9c5b Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 24 Oct 2009 18:33:01 +0000
Subject: [PATCH 329/646] Turn on NAP mode on G5 systems, and refactor the HID0
 setup code a little. This makes my G5 Xserve sound slightly less like it is
 filled with howling banshees.

---
 sys/powerpc/include/hid.h |   7 ++
 sys/powerpc/powerpc/cpu.c | 248 ++++++++++++++++++++++++--------------
 2 files changed, 163 insertions(+), 92 deletions(-)

diff --git a/sys/powerpc/include/hid.h b/sys/powerpc/include/hid.h
index 3ba5b559449..94f996530c5 100644
--- a/sys/powerpc/include/hid.h
+++ b/sys/powerpc/include/hid.h
@@ -41,6 +41,7 @@
 #define HID0_ECLK	0x02000000  /* CLK_OUT clock type selection */
 #define HID0_PAR	0x01000000  /* Disable precharge of ARTRY */
 #define HID0_STEN	0x01000000  /* Software table search enable (7450) */
+#define HID0_DEEPNAP	0x01000000  /* Enable deep nap mode (970) */
 #define HID0_HBATEN	0x00800000  /* High BAT enable (74[45][578])  */
 #define HID0_DOZE	0x00800000  /* Enable doze mode */
 #define HID0_NAP	0x00400000  /* Enable nap mode */
@@ -98,6 +99,12 @@
     "\020b16\017TBEN\016SEL_TBCLK\015b19\014b20\013b21\012b22\011b23"	\
     "\010EN_MAS7_UPDATE\007DCFA\006b26\005b27\004b28\003b29\002b30\001NOPTI"
 
+#define HID0_970_BITMASK						\
+    "\20"								\
+    "\040ONEPPC\037SINGLE\036ISYNCSC\035SERGP\031DEEPNAP\030DOZE"	\
+    "\027NAP\025DPM\023TG\022HANGDETECT\021NHR\020INORDER"		\
+    "\016TBCTRL\015TBEN\012CIABREN\011HDICEEN\001ENATTN"		
+
 /*
  *  HID0 bit definitions per cpu model
  *
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index 9f245e294ae..1325207c574 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -114,16 +114,19 @@ static char model[64];
 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
 
 static void	cpu_print_speed(void);
-static void	cpu_print_cacheinfo(u_int, uint16_t);
+
+static void	cpu_6xx_setup(int cpuid, uint16_t vers);
+static void	cpu_6xx_print_cacheinfo(u_int, uint16_t);
+static void	cpu_e500_setup(int cpuid, uint16_t vers);
+static void	cpu_970_setup(int cpuid, uint16_t vers);
 
 void
 cpu_setup(u_int cpuid)
 {
-	u_int		pvr, maj, min, hid0;
+	u_int		pvr, maj, min;
 	uint16_t	vers, rev, revfmt;
 	const struct	cputab *cp;
 	const char	*name;
-	char		*bitmask;
 
 	pvr = mfpvr();
 	vers = pvr >> 16;
@@ -170,10 +173,8 @@ cpu_setup(u_int cpuid)
 			break;
 	}
 
-	hid0 = mfspr(SPR_HID0);
-
 	/*
-	 * Configure power-saving mode.
+	 * Configure CPU
 	 */
 	switch (vers) {
 		case MPC603:
@@ -184,102 +185,34 @@ cpu_setup(u_int cpuid)
 		case IBM750FX:
 		case MPC7400:
 		case MPC7410:
+		case MPC7447A:
+		case MPC7448:
+		case MPC7450:
+		case MPC7455:
+		case MPC7457:
 		case MPC8240:
 		case MPC8245:
-			/* Select DOZE mode. */
-			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
-			hid0 |= HID0_DOZE | HID0_DPM;
-			powerpc_pow_enabled = 1;
+			cpu_6xx_setup(cpuid, vers);
 			break;
 
-		case MPC7448:
-		case MPC7447A:
-		case MPC7457:
-		case MPC7455:
-		case MPC7450:
-			/* Enable the 7450 branch caches */
-			hid0 |= HID0_SGE | HID0_BTIC;
-			hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
-			/* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
-			if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
-					|| (pvr >> 16) == MPC7457)
-				hid0 &= ~HID0_BTIC;
-			/* Select NAP mode. */
-			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
-			hid0 |= HID0_NAP | HID0_DPM;
-			powerpc_pow_enabled = 1;
-			break;
-
-		default:
-			/* No power-saving mode is available. */ ;
-	}
-
-	switch (vers) {
-		case IBM750FX:
-		case MPC750:
-			hid0 &= ~HID0_DBP;		/* XXX correct? */
-			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
-			break;
-
-		case MPC7400:
-		case MPC7410:
-			hid0 &= ~HID0_SPD;
-			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
-			hid0 |= HID0_EIEC;
-			break;
-
-		case FSL_E500v1:
-		case FSL_E500v2:
-			break;
-	}
-
-	mtspr(SPR_HID0, hid0);
-
-	switch (vers) {
-		case MPC7447A:
-		case MPC7448:
-		case MPC7450:
-		case MPC7455:
-		case MPC7457:
-			bitmask = HID0_7450_BITMASK;
-			break;
-		case FSL_E500v1:
-		case FSL_E500v2:
-			bitmask = HID0_E500_BITMASK;
-			break;
-		default:
-			bitmask = HID0_BITMASK;
-			break;
-	}
-
-	switch (vers) {
-		case MPC7450:
-		case MPC7455:
-		case MPC7457:
-		case MPC750:
-		case IBM750FX:
-		case MPC7400:
-		case MPC7410:
-		case MPC7447A:
-		case MPC7448:
-			cpu_print_speed();
-			printf("\n");
-
-			if (bootverbose)
-				cpu_print_cacheinfo(cpuid, vers);
-			break;
 		case IBM970:
 		case IBM970FX:
+		case IBM970GX:
 		case IBM970MP:
-			cpu_print_speed();
-			printf("\n");
+			cpu_970_setup(cpuid, vers);
 			break;
+
+		case FSL_E500v1:
+		case FSL_E500v2:
+			cpu_e500_setup(cpuid, vers);
+			break;
+
 		default:
-			printf("\n");
+			/* HID setup is unknown */
 			break;
 	}
 
-	printf("cpu%d: HID0 %b\n", cpuid, hid0, bitmask);
+	printf("\n");
 }
 
 void
@@ -346,10 +279,101 @@ cpu_est_clockrate(int cpu_id, uint64_t *cps)
 }
 
 void
-cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
+cpu_6xx_setup(int cpuid, uint16_t vers)
 {
-	uint32_t hid;
+	register_t hid0, pvr;
+	const char *bitmask;
 
+	hid0 = mfspr(SPR_HID0);
+	pvr = mfpvr();
+
+	/*
+	 * Configure power-saving mode.
+	 */
+	switch (vers) {
+		case MPC603:
+		case MPC603e:
+		case MPC603ev:
+		case MPC604ev:
+		case MPC750:
+		case IBM750FX:
+		case MPC7400:
+		case MPC7410:
+		case MPC8240:
+		case MPC8245:
+			/* Select DOZE mode. */
+			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
+			hid0 |= HID0_DOZE | HID0_DPM;
+			powerpc_pow_enabled = 1;
+			break;
+
+		case MPC7448:
+		case MPC7447A:
+		case MPC7457:
+		case MPC7455:
+		case MPC7450:
+			/* Enable the 7450 branch caches */
+			hid0 |= HID0_SGE | HID0_BTIC;
+			hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
+			/* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
+			if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
+					|| (pvr >> 16) == MPC7457)
+				hid0 &= ~HID0_BTIC;
+			/* Select NAP mode. */
+			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
+			hid0 |= HID0_NAP | HID0_DPM;
+			powerpc_pow_enabled = 1;
+			break;
+
+		default:
+			/* No power-saving mode is available. */ ;
+	}
+
+	switch (vers) {
+		case IBM750FX:
+		case MPC750:
+			hid0 &= ~HID0_DBP;		/* XXX correct? */
+			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
+			break;
+
+		case MPC7400:
+		case MPC7410:
+			hid0 &= ~HID0_SPD;
+			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
+			hid0 |= HID0_EIEC;
+			break;
+
+	}
+
+	mtspr(SPR_HID0, hid0);
+
+	cpu_print_speed();
+	printf("\n");
+
+	if (bootverbose)
+		cpu_6xx_print_cacheinfo(cpuid, vers);
+
+	switch (vers) {
+		case MPC7447A:
+		case MPC7448:
+		case MPC7450:
+		case MPC7455:
+		case MPC7457:
+			bitmask = HID0_7450_BITMASK;
+			break;
+		default:
+			bitmask = HID0_BITMASK;
+			break;
+	}
+
+	printf("cpu%d: HID0 %b", cpuid, (int)hid0, bitmask);
+}
+
+
+static void
+cpu_6xx_print_cacheinfo(u_int cpuid, uint16_t vers)
+{
+	register_t hid;
 
 	hid = mfspr(SPR_HID0);
 	printf("cpu%u: ", cpuid);
@@ -395,3 +419,43 @@ cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
 	} else
 		printf("L2 cache disabled\n");
 }
+
+static void
+cpu_e500_setup(int cpuid, uint16_t vers)
+{
+	register_t hid0;
+
+	hid0 = mfspr(SPR_HID0);
+	printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK);
+}
+
+static void
+cpu_970_setup(int cpuid, uint16_t vers)
+{
+	uint32_t hid0_hi, hid0_lo;
+
+	__asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;"
+	    : "=r" (hid0_hi), "=r" (hid0_lo) : "K" (SPR_HID0));
+
+	/* Configure power-saving mode */
+	hid0_hi |= (HID0_NAP | HID0_DPM);
+	hid0_hi &= ~(HID0_DOZE | HID0_DEEPNAP);
+	powerpc_pow_enabled = 1;
+
+	__asm __volatile (" \
+		sync; isync;					\
+		sldi	%0,%0,32; or %0,%0,%1;			\
+		mtspr	%2, %0;					\
+		mfspr   %0, %2; mfspr   %0, %2; mfspr   %0, %2; \
+		mfspr   %0, %2; mfspr   %0, %2; mfspr   %0, %2; \
+		sync; isync"
+	    :: "r" (hid0_hi), "r"(hid0_lo), "K" (SPR_HID0));
+
+	cpu_print_speed();
+	printf("\n");
+
+	__asm __volatile ("mfspr %0,%1; srdi %0,%0,32;"
+	    : "=r" (hid0_hi) : "K" (SPR_HID0));
+	printf("cpu%d: HID0 %b", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
+}
+

From 90147b750690a384e7686263e0d2f38ae87ab4de Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Sat, 24 Oct 2009 18:49:17 +0000
Subject: [PATCH 330/646] Spell DIAGNOSTIC correctly.

---
 sys/fs/smbfs/smbfs_vfsops.c | 2 +-
 sys/netgraph/NOTES          | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c
index b762bde99af..2a328b35a1c 100644
--- a/sys/fs/smbfs/smbfs_vfsops.c
+++ b/sys/fs/smbfs/smbfs_vfsops.c
@@ -259,7 +259,7 @@ smbfs_mount(struct mount *mp)
 	VOP_UNLOCK(vp, 0);
 	SMBVDEBUG("root.v_usecount = %d\n", vrefcnt(vp));
 
-#ifdef DIAGNOSTICS
+#ifdef DIAGNOSTIC
 	SMBERROR("mp=%p\n", mp);
 #endif
 	return error;
diff --git a/sys/netgraph/NOTES b/sys/netgraph/NOTES
index 0ddc02f5a66..eb3a54c5614 100644
--- a/sys/netgraph/NOTES
+++ b/sys/netgraph/NOTES
@@ -76,10 +76,10 @@ Archie's suggestions... :-)
      be careful with things like #ifdef INET.
    - All nodes assume that all data mbufs have the M_PKTHDR flag set!
      The ng_send_data() and related functions should have an
-     #ifdef DIAGNOSTICS check to check this assumption for every mbuf.
+     #ifdef DIAGNOSTIC check to check this assumption for every mbuf.
      -DONE with INVARIANTS. Framework should test this more.
    - More generally, netgraph code should make liberal use of the
-     #ifdef DIAGNOSTICS definition.
+     #ifdef DIAGNOSTIC definition.
      -INVARIANTS.
    - Since data and messages are sent functionally, programmers need
      to watch out for infinite feedback loops. Should ng_base.c detect

From 4d9d1e823c5735be5fe9f21e22b8bf1efaf717ca Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Sat, 24 Oct 2009 19:00:58 +0000
Subject: [PATCH 331/646] - Rename tunable kern.ipc.shmmaxpgs to
 kern.ipc.shmall. - Explain the fuss when initializing shmmax.

PR:	75542 (mistakenly closed instead of PR 75541)
---
 sys/kern/sysv_shm.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 4e62211ebca..a16c8afc770 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -821,12 +821,19 @@ shminit()
 {
 	int i;
 
-	TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall);
+#ifndef BURN_BRIDGES
+	if (TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall) != 0)
+		printf("kern.ipc.shmmaxpgs is now called kern.ipc.shmall!\n");
+#endif
+	TUNABLE_ULONG_FETCH("kern.ipc.shmall", &shminfo.shmall);
+
+	/* Initialize shmmax dealing with possible overflow. */
 	for (i = PAGE_SIZE; i > 0; i--) {
 		shminfo.shmmax = shminfo.shmall * i;
 		if (shminfo.shmmax >= shminfo.shmall)
 			break;
 	}
+
 	TUNABLE_ULONG_FETCH("kern.ipc.shmmin", &shminfo.shmmin);
 	TUNABLE_ULONG_FETCH("kern.ipc.shmmni", &shminfo.shmmni);
 	TUNABLE_ULONG_FETCH("kern.ipc.shmseg", &shminfo.shmseg);

From 3b43a26b509dd42d2f7e692cedd8ea05c703eaa4 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 24 Oct 2009 20:07:17 +0000
Subject: [PATCH 332/646] Implement _umtx_op_err() for ia64.

---
 lib/libthr/arch/ia64/Makefile.inc         |  2 +-
 lib/libthr/arch/ia64/ia64/_umtx_op_err.S  | 35 +++++++++++++++++++++++
 lib/libthr/arch/ia64/include/pthread_md.h |  2 ++
 3 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 lib/libthr/arch/ia64/ia64/_umtx_op_err.S

diff --git a/lib/libthr/arch/ia64/Makefile.inc b/lib/libthr/arch/ia64/Makefile.inc
index 1c0ce94c512..160cdf64577 100644
--- a/lib/libthr/arch/ia64/Makefile.inc
+++ b/lib/libthr/arch/ia64/Makefile.inc
@@ -2,4 +2,4 @@
 
 .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
 
-SRCS+= pthread_md.c
+SRCS+= _umtx_op_err.S pthread_md.c
diff --git a/lib/libthr/arch/ia64/ia64/_umtx_op_err.S b/lib/libthr/arch/ia64/ia64/_umtx_op_err.S
new file mode 100644
index 00000000000..a71221096e6
--- /dev/null
+++ b/lib/libthr/arch/ia64/ia64/_umtx_op_err.S
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2009 Marcel Moolenaar
+ * 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.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+
+ENTRY(_umtx_op_err, 5)
+	CALLSYS_NOERROR(_umtx_op)
+	br.ret.sptk.few rp
+END(_umtx_op_err)
diff --git a/lib/libthr/arch/ia64/include/pthread_md.h b/lib/libthr/arch/ia64/include/pthread_md.h
index 0cff7c9c966..69b3eece409 100644
--- a/lib/libthr/arch/ia64/include/pthread_md.h
+++ b/lib/libthr/arch/ia64/include/pthread_md.h
@@ -33,6 +33,8 @@
 
 #define	CPU_SPINWAIT
 
+#define	HAS__UMTX_OP_ERR	1
+
 #define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
 
 /*

From b475d22d678f5ebe81962d2571901f452252430b Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 24 Oct 2009 20:28:42 +0000
Subject: [PATCH 333/646] A 32KB kernel stack is not quite enough. The new USB
 stack is a bit more stack hungry as compared to the old one that my RX2660
 gets a machine check and spontaneously reboots at the time the USB DVD drive
 is found and attached to CAM as a mass storage device. This doesn't happen
 always, but definitely varies per kernel build. Likewise when using a
 128-byte printf buffer. The additional 128 bytes that printf needs seems to
 be enough to have the memory stack and register stack collide and causing a
 machine check.

Thus: Bump KSTACK_PAGES from 4 to 5.
---
 sys/ia64/include/param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/ia64/include/param.h b/sys/ia64/include/param.h
index 331af7aacf4..4c8e8b9cee0 100644
--- a/sys/ia64/include/param.h
+++ b/sys/ia64/include/param.h
@@ -92,7 +92,7 @@
 #define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
 
 #ifndef	KSTACK_PAGES
-#define	KSTACK_PAGES	4		/* pages of kernel stack */
+#define	KSTACK_PAGES	5		/* pages of kernel stack */
 #endif
 #define	KSTACK_GUARD_PAGES 0		/* pages of kstack guard; 0 disables */
 

From 59085a35e8f3cb8712a9da5ff5e8a24beacff0db Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 24 Oct 2009 20:35:34 +0000
Subject: [PATCH 334/646] Add PRINTF_BUFR_SIZE=128, since we have SMP by
 default. While here, fix tabulation.

---
 sys/ia64/conf/GENERIC | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index b143868870b..f9250075acf 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -40,13 +40,14 @@ options 	INVARIANTS	# Enable calls of extra sanity checking
 options 	INVARIANT_SUPPORT # required by INVARIANTS
 options 	KDB		# Enable kernel debugger support
 options 	KTRACE		# ktrace(1) syscall trace support
-options 	MAC			# TrustedBSD MAC Framework
+options 	MAC		# TrustedBSD MAC Framework
 options 	MD_ROOT		# MD usable as root device
 options 	MSDOSFS		# MSDOS Filesystem
 options 	NFSCLIENT	# Network Filesystem Client
 options 	NFSSERVER	# Network Filesystem Server
 options 	NFSLOCKD	# Network Lock Manager
 options 	NFS_ROOT	# NFS usable as root device
+options 	PRINTF_BUFR_SIZE=128  # Printf buffering to limit interspersion
 options 	PROCFS		# Process filesystem (/proc)
 options 	PSEUDOFS	# Pseudo-filesystem framework
 options 	SCHED_ULE	# ULE scheduler
@@ -65,7 +66,7 @@ options 	UFS_GJOURNAL	# Enable gjournal-based UFS journaling
 options 	WITNESS		# Enable checks to detect deadlocks and cycles
 options 	WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
 options 	_KPOSIX_PRIORITY_SCHEDULING	# Posix P1003_1B RT extensions
-options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
+options 	HWPMC_HOOKS	# Necessary kernel hooks for hwpmc(4)
 
 # Various "busses"
 device		firewire	# FireWire bus code

From 941538c0f4f62f835e7185ac228bf8dae702fab1 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Sat, 24 Oct 2009 20:57:11 +0000
Subject: [PATCH 335/646] Add some tests for ${var?} and set -u.

---
 tools/regression/bin/sh/expansion/question1.0 | 22 ++++++++++++++
 tools/regression/bin/sh/expansion/set-u1.0    | 29 +++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 tools/regression/bin/sh/expansion/question1.0
 create mode 100644 tools/regression/bin/sh/expansion/set-u1.0

diff --git a/tools/regression/bin/sh/expansion/question1.0 b/tools/regression/bin/sh/expansion/question1.0
new file mode 100644
index 00000000000..355af624aa6
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/question1.0
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+x=a\ b
+[ "$x" = "${x?}" ] || exit 1
+set -- ${x?}
+{ [ "$#" = 2 ] && [ "$1" = a ] && [ "$2" = b ]; } || exit 1
+unset x
+(echo ${x?abcdefg}) 2>&1 | grep -q abcdefg || exit 1
+sh -c 'unset foo; echo ${foo?}' 2>/dev/null && exit 1
+sh -c 'foo=; echo ${foo:?}' 2>/dev/null && exit 1
+sh -c 'foo=; echo ${foo?}' >/dev/null || exit 1
+sh -c 'foo=1; echo ${foo:?}' >/dev/null || exit 1
+sh -c 'echo ${!?}' 2>/dev/null && exit 1
+sh -c ':& echo ${!?}' >/dev/null || exit 1
+sh -c 'echo ${#?}' >/dev/null || exit 1
+sh -c 'echo ${*?}' 2>/dev/null && exit 1
+sh -c 'echo ${*?}' sh x >/dev/null || exit 1
+sh -c 'echo ${1?}' 2>/dev/null && exit 1
+sh -c 'echo ${1?}' sh x >/dev/null || exit 1
+sh -c 'echo ${2?}' sh x 2>/dev/null && exit 1
+sh -c 'echo ${2?}' sh x y >/dev/null || exit 1
+exit 0
diff --git a/tools/regression/bin/sh/expansion/set-u1.0 b/tools/regression/bin/sh/expansion/set-u1.0
new file mode 100644
index 00000000000..a66bfc9dc99
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/set-u1.0
@@ -0,0 +1,29 @@
+# $FreeBSD$
+
+sh -uc 'unset foo; echo $foo' 2>/dev/null && exit 1
+sh -uc 'foo=; echo $foo' >/dev/null || exit 1
+sh -uc 'foo=1; echo $foo' >/dev/null || exit 1
+# -/+/= are unaffected by set -u
+sh -uc 'unset foo; echo ${foo-}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo+}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo=}' >/dev/null || exit 1
+# length/trimming are affected
+sh -uc 'unset foo; echo ${#foo}' 2>/dev/null && exit 1
+sh -uc 'foo=; echo ${#foo}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo#?}' 2>/dev/null && exit 1
+sh -uc 'foo=1; echo ${foo#?}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo##?}' 2>/dev/null && exit 1
+sh -uc 'foo=1; echo ${foo##?}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo%?}' 2>/dev/null && exit 1
+sh -uc 'foo=1; echo ${foo%?}' >/dev/null || exit 1
+sh -uc 'unset foo; echo ${foo%%?}' 2>/dev/null && exit 1
+sh -uc 'foo=1; echo ${foo%%?}' >/dev/null || exit 1
+
+sh -uc 'echo $!' 2>/dev/null && exit 1
+sh -uc ':& echo $!' >/dev/null || exit 1
+sh -uc 'echo $#' >/dev/null || exit 1
+sh -uc 'echo $1' 2>/dev/null && exit 1
+sh -uc 'echo $1' sh x >/dev/null || exit 1
+sh -uc 'echo $2' sh x 2>/dev/null && exit 1
+sh -uc 'echo $2' sh x y >/dev/null || exit 1
+exit 0

From 64254a667a6ba4b553b12369cee2190e5ee0daf8 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Sat, 24 Oct 2009 21:20:04 +0000
Subject: [PATCH 336/646] sh: Exempt $@ and $* from set -u

This seems more useful and will likely be in the next POSIX standard.

Also document more precisely in the man page what set -u does (note that
$@, $* and $! are the only special parameters that can ever be unset, all
the others are always set, although they may be empty).
---
 bin/sh/expand.c                            |  2 +-
 bin/sh/sh.1                                |  7 +++++--
 tools/regression/bin/sh/expansion/set-u2.0 | 12 ++++++++++++
 3 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 tools/regression/bin/sh/expansion/set-u2.0

diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 700fa0a9f91..af79e8cad0d 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -657,7 +657,7 @@ again: /* jump here after setting a variable with ${var=text} */
 	}
 	varlen = 0;
 	startloc = expdest - stackblock();
-	if (!set && uflag) {
+	if (!set && uflag && *var != '@' && *var != '*') {
 		switch (subtype) {
 		case VSNORMAL:
 		case VSTRIMLEFT:
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 937fda75434..db872fd03ea 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
 .\"	from: @(#)sh.1	8.6 (Berkeley) 5/4/95
 .\" $FreeBSD$
 .\"
-.Dd May 31, 2009
+.Dd October 24, 2009
 .Dt SH 1
 .Os
 .Sh NAME
@@ -296,7 +296,10 @@ sh -T -c "trap 'exit 1' 2 ; some-blocking-program"
 .Ed
 .It Fl u Li nounset
 Write a message to standard error when attempting
-to expand a variable that is not set, and if the
+to expand a variable, a positional parameter or
+the special parameter
+.Va \&!
+that is not set, and if the
 shell is not interactive, exit immediately.
 .It Fl V Li vi
 Enable the built-in
diff --git a/tools/regression/bin/sh/expansion/set-u2.0 b/tools/regression/bin/sh/expansion/set-u2.0
new file mode 100644
index 00000000000..f81aa62cb6b
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/set-u2.0
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+set -u
+: $* $@ "$@" "$*"
+set -- x
+: $* $@ "$@" "$*"
+shift $#
+: $* $@ "$@" "$*"
+set -- y
+set --
+: $* $@ "$@" "$*"
+exit 0

From a0c703bf21c16cb6fb8d8b50f2488c68f31e49fd Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sun, 25 Oct 2009 02:48:29 +0000
Subject: [PATCH 337/646] Update a comment to reflect the previous change.

---
 sys/kern/sys_process.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 88a5b89f8a0..1aa6995a4af 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -279,7 +279,7 @@ proc_rwmem(struct proc *p, struct uio *uio)
 		}
 
 		/*
-		 * Now we need to get the page.  out_entry, out_prot, wired,
+		 * Now we need to get the page.  out_entry, wired,
 		 * and single_use aren't used.  One would think the vm code
 		 * would be a *bit* nicer...  We use tmap because
 		 * vm_map_lookup() can change the map argument.

From 16d95d4f92d26f59208d6ddae1ca337c7a5e44a2 Mon Sep 17 00:00:00 2001
From: Joseph Koshy 
Date: Sun, 25 Oct 2009 04:34:47 +0000
Subject: [PATCH 338/646] Inform hwpmc(4) of a thread's impending demise prior
 to invoking sched_throw().

Debugging help:		fabient
Review and testing by:	fabient
---
 sys/kern/kern_thread.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 4f3b32cdd0a..9be4c2f3eb3 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -27,6 +27,7 @@
  */
 
 #include "opt_witness.h"
+#include "opt_hwpmc_hooks.h"
 
 #include 
 __FBSDID("$FreeBSD$");
@@ -47,6 +48,9 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#ifdef	HWPMC_HOOKS
+#include 
+#endif
 
 #include 
 
@@ -417,6 +421,14 @@ thread_exit(void)
 			panic ("thread_exit: Last thread exiting on its own");
 		}
 	} 
+#ifdef	HWPMC_HOOKS
+	/*
+	 * If this thread is part of a process that is being tracked by hwpmc(4),
+	 * inform the module of the thread's impending exit.
+	 */
+	if (PMC_PROC_IS_USING_PMCS(td->td_proc))
+		PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_OUT);
+#endif
 	PROC_UNLOCK(p);
 	thread_lock(td);
 	/* Save our tick information with both the thread and proc locked */

From f91c218bf8c55ac87e0467a2227101d8edff8cf8 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sun, 25 Oct 2009 09:48:21 +0000
Subject: [PATCH 339/646] Output a comment on top of each generated file
 explaining where it came from.

---
 sys/tools/fw_stub.awk | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/tools/fw_stub.awk b/sys/tools/fw_stub.awk
index 5f6fe452148..05e2f32ec97 100644
--- a/sys/tools/fw_stub.awk
+++ b/sys/tools/fw_stub.awk
@@ -121,7 +121,11 @@ ctmpfilename = cfilename ".tmp";
 modname = opt_m;
 gsub(/[-\.]/, "_", modname);
 
-printc("#include \
+printc("/*\
+ * Automatically generated by:\
+ * $FreeBSD$\
+ */\
+#include \
 #include \
 #include \
 #include \

From d97bee3e7e9249f7dcd9cce9feca6b8a6e24ad33 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 25 Oct 2009 09:58:56 +0000
Subject: [PATCH 340/646] Unconditionally call the setsockopt for IPV6_V6ONLY
 for v6 linux sockets no matter whether we are compiled as module or if our
 default of the net.inet6.ip6.v6only sysctl already matches what we would set.

This avoids unnecessary complications with modules, VIMAGES, INET6 and
the sysctl value, especially considering that most users will use
linux compat as a module.

Discussed with:	kib, rwatson (weeks ago)
Reviewed by:	rwatson
MFC after:	6 weeks
---
 sys/compat/linux/linux_socket.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index d3860b0b2b2..396a71e8495 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -639,19 +639,12 @@ linux_socket(struct thread *td, struct linux_socket_args *args)
 	}
 #ifdef INET6
 	/*
-	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
-	 * default and some apps depend on this. So, set V6ONLY to 0
-	 * for Linux apps if the sysctl value is set to 1.
+	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default
+	 * and some apps depend on this. So, set V6ONLY to 0 for Linux apps.
+	 * For simplicity we do this unconditionally of the net.inet6.ip6.v6only
+	 * sysctl value.
 	 */
-	if (bsd_args.domain == PF_INET6
-#ifndef KLD_MODULE
-	    /*
-	     * XXX: Avoid undefined symbol error with an IPv4 only
-	     * kernel.
-	     */
-	    && V_ip6_v6only
-#endif
-	    ) {
+	if (bsd_args.domain == PF_INET6) {
 		int v6only;
 
 		v6only = 0;

From 78e360f8e5bdef54d297797984dfc8a28089f28d Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sun, 25 Oct 2009 10:23:11 +0000
Subject: [PATCH 341/646] Update firmware images according to the latest iwn
 updated. "device iwnfw" includes all firmware images, but you can pick just
 one by using the model number, e.g.: "device iwn4965fw".

---
 sys/conf/files | 48 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 9e99f2cd934..8c9b9549547 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1082,20 +1082,48 @@ iwi_monitor.fw			optional iwimonitorfw | iwifw		\
 	no-obj no-implicit-rule						\
 	clean		"iwi_monitor.fw"
 dev/iwn/if_iwn.c		optional iwn
-iwnfw.c			optional iwnfw					\
-	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn.fw:iwnfw:44417 -lintel_iwn -miwn -c${.TARGET}" \
+iwn4965fw.c			optional iwn4965fw | iwnfw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn4965.fw:iwn4965fw -miwn4965fw -c${.TARGET}" \
 	no-implicit-rule before-depend local				\
-	clean		"iwnfw.c"
-iwnfw.fwo			optional iwnfw				\
-	dependency	"iwn.fw"					\
-	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn.fw" \
+	clean		"iwn4965fw.c"
+iwn4965fw.fwo			optional iwn4965fw | iwnfw		\
+	dependency	"iwn4965.fw"					\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn4965.fw" \
 	no-implicit-rule						\
-	clean		"iwnfw.fwo"
-iwn.fw			optional iwnfw					\
+	clean		"iwn4965fw.fwo"
+iwn4965.fw			optional iwn4965fw | iwnfw		\
 	dependency	".PHONY"					\
-	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-4965-4.44.17.fw.uu"	\
+	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu" \
 	no-obj no-implicit-rule						\
-	clean		"iwn.fw"
+	clean		"iwn4965.fw"
+iwn5000fw.c			optional iwn5000fw | iwnfw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn5000.fw:iwn5000fw -miwn5000fw -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"iwn5000fw.c"
+iwn5000fw.fwo		optional iwn5000fw | iwnfw			\
+	dependency	"iwn5000.fw"					\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn5000.fw" \
+	no-implicit-rule						\
+	clean		"iwn5000fw.fwo"
+iwn5000.fw			optional iwn5000fw | iwnfw		\
+	dependency	".PHONY"					\
+	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu"	\
+	no-obj no-implicit-rule						\
+	clean		"iwn5000.fw"
+iwn5150fw.c			optional iwn5150fw | iwnfw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn5150.fw:iwn5150fw -miwn5150fw -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"iwn5150fw.c"
+iwn5150fw.fwo			optional iwn5150fw | iwnfw		\
+	dependency	"iwn5150.fw"					\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn5150.fw" \
+	no-implicit-rule						\
+	clean		"iwn5150fw.fwo"
+iwn5150.fw			optional iwn5150fw | iwnfw		\
+	dependency	".PHONY"					\
+	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu" \
+	no-obj no-implicit-rule						\
+	clean		"iwn5150.fw"
 dev/ixgb/if_ixgb.c		optional ixgb
 dev/ixgb/ixgb_ee.c		optional ixgb
 dev/ixgb/ixgb_hw.c		optional ixgb

From 63b49c2b8a7f318f6337068bbba8b0b25b701fef Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sun, 25 Oct 2009 10:29:37 +0000
Subject: [PATCH 342/646] Explain that iwn was updated and the firmware images
 are now split.

---
 UPDATING | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/UPDATING b/UPDATING
index 16a9185956c..f22aa536d6a 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
 	machines to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20091025:
+	The iwn(4) driver has been updated to support the 5000 and 5150 series.
+	There's one kernel module for each firmware. Adding "device iwnfw"
+	to the kernel configuration file means including all three firmware
+	images inside the kernel. If you want to include just the one for
+	your wireless card, use the the devices iwn4965fw, iwn5000fw or
+	iwn5150fw.
+
 20090926:
 	The rc.d/network_ipv6, IPv6 configuration script has been integrated
 	into rc.d/netif.  The changes are the following:

From 2267cb3d7f2c379925f7951c117b7520e88f3440 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sun, 25 Oct 2009 11:01:53 +0000
Subject: [PATCH 343/646] Update according to the latest iwn(4) driver import.

---
 share/man/man4/iwn.4   | 24 ++++++++++++++++++++----
 share/man/man4/iwnfw.4 | 17 ++++++++++++++---
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4
index 7ddded24fab..0f0a97eadfe 100644
--- a/share/man/man4/iwn.4
+++ b/share/man/man4/iwn.4
@@ -25,36 +25,52 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 13, 2008
+.Dd October 25, 2009
 .Os
 .Dt IWN 4
 .Sh NAME
 .Nm iwn
-.Nd "Intel Wireless WiFi Link 4965AGN IEEE 802.11n driver"
+.Nd "Intel Wireless WiFi Link 4965/5000 IEEE 802.11n driver"
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 include the following lines in your
 kernel configuration file:
 .Bd -ragged -offset indent
 .Cd "device iwn"
-.Cd "device iwnfw"
 .Cd "device pci"
 .Cd "device wlan"
 .Cd "device firmware"
 .Ed
 .Pp
+You also need to select a firmware for your device. Chose one from:
+.Bd -ragged -offset indent
+.Cd "device iwn4965fw"
+.Cd "device iwn5000fw"
+.Cd "device iwn5100fw"
+.Ed
+.Pp
+Or you can use
+.Bd -ragged -offset indent
+.Cd "device iwnfw"
+.Ed
+.Pp
+to include them all.
+.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_iwn_load="YES"
+iwn4965fw_load="YES"
+iwn5000fw_load="YES"
+iwn5100fw_load="YES"
 .Ed
 .Sh DESCRIPTION
 The
 .Nm
 driver provides support for
 .Tn Intel
-Wireless WiFi Link 4965AGN PCI-Express network adapters.
+Wireless WiFi Link 4965 and 5000 series of PCI-Express network adapters.
 .Nm
 supports
 .Cm station ,
diff --git a/share/man/man4/iwnfw.4 b/share/man/man4/iwnfw.4
index 1f9faa9c89c..c7ff0666ce9 100644
--- a/share/man/man4/iwnfw.4
+++ b/share/man/man4/iwnfw.4
@@ -22,7 +22,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 9, 2009
+.Dd October 25, 2009
 .Dt IWNFW 4
 .Os
 .Sh NAME
@@ -36,15 +36,26 @@ kernel configuration file:
 .Cd "device iwnfw"
 .Ed
 .Pp
+This will include three firmware images inside the kernel.
+If you want to pick only the firmware image for your network adapter choose one
+of the following:
+.Bd -ragged -offset indent
+.Cd "device iwn4965fw"
+.Cd "device iwn5000fw"
+.Cd "device iwn5100fw"
+.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
-iwnfw_load="YES"
+iwn4965fw_load="YES"
+iwn5000fw_load="YES"
+iwn5100fw_load="YES"
 .Ed
 .Sh DESCRIPTION
 This module provides access to firmware sets for the
-Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapters.
+Intel Wireless WiFi Link 4965 and 5000 series of IEEE 802.11n adapters.
 It may be
 statically linked into the kernel, or loaded as a module.
 .Sh SEE ALSO

From 573cb89b8dfef3d67713112f08adf5aace18ac35 Mon Sep 17 00:00:00 2001
From: Alexander Kabaev 
Date: Sun, 25 Oct 2009 15:52:31 +0000
Subject: [PATCH 344/646] Compile libgcov without stack protection. It can be
 linked into both static and dynamic binaries compiled with or without stack
 protection and should not depend on libssp_nonshared.a symbols.

Discussed with: kib
PR:		bin/139052
---
 gnu/lib/libgcov/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/lib/libgcov/Makefile b/gnu/lib/libgcov/Makefile
index 36be1ea21a1..680cdbff30a 100644
--- a/gnu/lib/libgcov/Makefile
+++ b/gnu/lib/libgcov/Makefile
@@ -2,6 +2,7 @@
 
 NO_PROFILE=
 .include 
+MK_SSP=		no
 .include "${.CURDIR}/../../usr.bin/cc/Makefile.tgt"
 
 GCCDIR=	${.CURDIR}/../../../contrib/gcc

From 36930fc947da5c21ba39e4a37bb770f7f7ffef4a Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sun, 25 Oct 2009 17:30:50 +0000
Subject: [PATCH 345/646] Eliminate an unnecessary check from
 vm_fault_prefault().

---
 sys/vm/vm_fault.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 98b6b099b1e..4314fdadfa4 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1011,8 +1011,8 @@ vm_fault_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
 		while ((m = vm_page_lookup(lobject, pindex)) == NULL &&
 		    lobject->type == OBJT_DEFAULT &&
 		    (backing_object = lobject->backing_object) != NULL) {
-			if (lobject->backing_object_offset & PAGE_MASK)
-				break;
+			KASSERT((lobject->backing_object_offset & PAGE_MASK) ==
+			    0, ("vm_fault_prefault: unaligned object offset"));
 			pindex += lobject->backing_object_offset >> PAGE_SHIFT;
 			VM_OBJECT_LOCK(backing_object);
 			VM_OBJECT_UNLOCK(lobject);

From dade5b4d4c4ff24e8986587ad86acdb69a9cacd1 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 25 Oct 2009 17:47:52 +0000
Subject: [PATCH 346/646] Spell out the name of the month.

---
 share/man/man4/bge.4 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4
index 10dd0dbdb82..45c7156cbc6 100644
--- a/share/man/man4/bge.4
+++ b/share/man/man4/bge.4
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Oct 7, 2009
+.Dd October 7, 2009
 .Dt BGE 4
 .Os
 .Sh NAME

From 0e0ed74fccbe5a0f390ed3f9433e1920f28acc8a Mon Sep 17 00:00:00 2001
From: Ulf Lilleengen 
Date: Sun, 25 Oct 2009 21:46:38 +0000
Subject: [PATCH 347/646] - Add support for Marvell Yukon 88E8042 device.

Submitted by:	Mario Lobo 
Approved by:	yongari
---
 share/man/man4/msk.4    | 2 ++
 sys/dev/msk/if_msk.c    | 2 ++
 sys/dev/msk/if_mskreg.h | 1 +
 3 files changed, 5 insertions(+)

diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4
index 7e8e5b305f5..e6200478afe 100644
--- a/share/man/man4/msk.4
+++ b/share/man/man4/msk.4
@@ -190,6 +190,8 @@ Marvell Yukon 88E8040 Fast Ethernet
 .It
 Marvell Yukon 88E8040T Fast Ethernet
 .It
+Marvell Yukon 88E8042 Fast Ethernet
+.It
 Marvell Yukon 88E8048 Fast Ethernet
 .It
 Marvell Yukon 88E8050 Gigabit Ethernet
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 7c6191b8683..912eaeb498c 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -201,6 +201,8 @@ static struct msk_product {
 	    "Marvell Yukon 88E8040 Fast Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_8040T,
 	    "Marvell Yukon 88E8040T Fast Ethernet" },
+	{ VENDORID_MARVELL, DEVICEID_MRVL_8042,
+	    "Marvell Yukon 88E8042 Fast Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_8048,
 	    "Marvell Yukon 88E8048 Fast Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_4361,
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index 575b59f7d69..b42a01fe1a5 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -133,6 +133,7 @@
 #define DEVICEID_MRVL_8039	0x4353
 #define DEVICEID_MRVL_8040	0x4354
 #define DEVICEID_MRVL_8040T	0x4355
+#define DEVICEID_MRVL_8042	0x4357
 #define DEVICEID_MRVL_8048	0x435A
 #define DEVICEID_MRVL_4360	0x4360
 #define DEVICEID_MRVL_4361	0x4361

From 7afab86c3db3f12115274bfb4861239e60380fe0 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Mon, 26 Oct 2009 00:01:52 +0000
Subject: [PATCH 348/646] Simplify the inner loop of vm_fault_copy_entry().

Reviewed by:	kib
---
 sys/vm/vm_fault.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 4314fdadfa4..508d617fc6b 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1133,20 +1133,20 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 {
 	vm_object_t backing_object, dst_object, object;
 	vm_object_t src_object;
-	vm_ooffset_t dst_offset;
-	vm_ooffset_t src_offset;
-	vm_pindex_t pindex;
+	vm_pindex_t dst_pindex, pindex, src_pindex;
 	vm_prot_t prot;
 	vm_offset_t vaddr;
 	vm_page_t dst_m;
 	vm_page_t src_m;
+	boolean_t src_readonly;
 
 #ifdef	lint
 	src_map++;
 #endif	/* lint */
 
 	src_object = src_entry->object.vm_object;
-	src_offset = src_entry->offset;
+	src_pindex = OFF_TO_IDX(src_entry->offset);
+	src_readonly = (src_entry->protection & VM_PROT_WRITE) == 0;
 
 	/*
 	 * Create the top-level object for the destination entry. (Doesn't
@@ -1177,16 +1177,16 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 	 * one from the source object (it should be there) to the destination
 	 * object.
 	 */
-	for (vaddr = dst_entry->start, dst_offset = 0;
+	for (vaddr = dst_entry->start, dst_pindex = 0;
 	    vaddr < dst_entry->end;
-	    vaddr += PAGE_SIZE, dst_offset += PAGE_SIZE) {
+	    vaddr += PAGE_SIZE, dst_pindex++) {
 
 		/*
-		 * Allocate a page in the destination object
+		 * Allocate a page in the destination object.
 		 */
 		do {
-			dst_m = vm_page_alloc(dst_object,
-				OFF_TO_IDX(dst_offset), VM_ALLOC_NORMAL);
+			dst_m = vm_page_alloc(dst_object, dst_pindex,
+			    VM_ALLOC_NORMAL);
 			if (dst_m == NULL) {
 				VM_OBJECT_UNLOCK(dst_object);
 				VM_WAIT;
@@ -1201,10 +1201,9 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 		 */
 		VM_OBJECT_LOCK(src_object);
 		object = src_object;
-		pindex = 0;
-		while ((src_m = vm_page_lookup(object, pindex +
-		    OFF_TO_IDX(dst_offset + src_offset))) == NULL &&
-		    (src_entry->protection & VM_PROT_WRITE) == 0 &&
+		pindex = src_pindex + dst_pindex;
+		while ((src_m = vm_page_lookup(object, pindex)) == NULL &&
+		    src_readonly &&
 		    (backing_object = object->backing_object) != NULL) {
 			/*
 			 * Allow fallback to backing objects if we are reading.

From dddeaa47e49edef5972d3a07554321009a5d702e Mon Sep 17 00:00:00 2001
From: Colin Percival 
Date: Mon, 26 Oct 2009 06:51:20 +0000
Subject: [PATCH 349/646] Eject CDROM after installation if used as source
 media.

Submitted by:	randi
MFC after:	1 month
---
 usr.sbin/sysinstall/cdrom.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/usr.sbin/sysinstall/cdrom.c b/usr.sbin/sysinstall/cdrom.c
index a5029ecb9a2..07a372237a3 100644
--- a/usr.sbin/sysinstall/cdrom.c
+++ b/usr.sbin/sysinstall/cdrom.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,6 +59,8 @@ static Boolean previouslyMounted; /* Was the disc already mounted? */
 static char mountpoint[MAXPATHLEN] = "/dist";
 int CDROMInitQuiet;
 
+static void mediaEjectCDROM(Device *dev);
+
 static properties
 read_props(char *name)
 {
@@ -218,4 +221,23 @@ mediaShutdownCDROM(Device *dev)
 	msgConfirm("Could not unmount the CDROM/DVD from %s: %s", mountpoint, strerror(errno));
     else
 	cdromMounted = FALSE;
+
+    mediaEjectCDROM(dev);
+}
+
+static void
+mediaEjectCDROM(Device *dev)
+{
+	int fd = -1;
+
+	msgDebug("Ejecting CDROM/DVD at %s", dev->devname);
+
+	fd = open(dev->devname, O_RDONLY);
+	
+	if (fd < 0)
+		msgDebug("Could not eject the CDROM/DVD from %s: %s", dev->devname, strerror(errno));
+	else {
+		ioctl(fd, CDIOCALLOW);
+		ioctl(fd, CDIOCEJECT);
+	}
 }

From 0fdcb6f05507fc45eb2caa46728856cf27362e8d Mon Sep 17 00:00:00 2001
From: Ulf Lilleengen 
Date: Mon, 26 Oct 2009 07:43:41 +0000
Subject: [PATCH 350/646] - Initialize variable in order to avoid GCC warning
 and enable WARNS=6.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

PR:		bin/139970
Submitted by:	Ulrich Spテカrlein 
---
 sbin/geom/class/part/Makefile    | 2 --
 sbin/geom/class/part/geom_part.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/sbin/geom/class/part/Makefile b/sbin/geom/class/part/Makefile
index 36227162a1f..8e7d0ffdb4e 100644
--- a/sbin/geom/class/part/Makefile
+++ b/sbin/geom/class/part/Makefile
@@ -6,6 +6,4 @@ CLASS=	part
 
 LDADD=	-lutil
 
-WARNS?=	4
-
 .include 
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c
index db3c5e9515e..e2a045e3cfa 100644
--- a/sbin/geom/class/part/geom_part.c
+++ b/sbin/geom/class/part/geom_part.c
@@ -192,6 +192,7 @@ find_provider(struct ggeom *gp, unsigned long long minsector)
 	unsigned long long sector, bestsector;
 
 	bestpp = NULL;
+	bestsector = 0;
 	LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
 		s = find_provcfg(pp, "start");
 		if (s == NULL) {

From 55944f2a7572b4393284dbd555ef43ddb2a9b599 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 08:41:10 +0000
Subject: [PATCH 351/646] Fix SATA on nVidia MCP55 chipset. It needs some short
 time to allow BAR(5) memory access.

PR:		amd64/128686, amd64/132372, amd64/139156
MFC after:	3 days
---
 sys/dev/ata/chipsets/ata-nvidia.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index 95be37c3082..bb763161d5b 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -165,7 +165,8 @@ ata_nvidia_chipinit(device_t dev)
 
 	    /* enable control access */
 	    pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) | 0x04,1);
-
+	    /* MCP55 seems to need some time to allow r_res2 read. */
+	    DELAY(10);
 	    if (ctlr->chip->cfg1 & NVQ) {
 		/* clear interrupt status */
 		ATA_OUTL(ctlr->r_res2, offset, 0x00ff00ff);

From b868265d82287a018dae551b60090cd73c5d7bb3 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 09:16:08 +0000
Subject: [PATCH 352/646] Document atapci kernel module split.

PR:		amd64/139859
MFC after:	3 days
---
 UPDATING | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/UPDATING b/UPDATING
index f22aa536d6a..009edae3f3c 100644
--- a/UPDATING
+++ b/UPDATING
@@ -632,6 +632,15 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
 	userland (libpmc(3)) and the kernel module (hwpmc(4)) in
 	sync.
 
+20081009:
+	atapci kernel module now includes only generic PCI ATA
+	driver. AHCI driver moved to ataahci kernel module.
+	All vendor-specific code moved into separate kernel modules:
+	ataacard, ataacerlabs, ataadaptec, ataamd, ataati, atacenatek,
+	atacypress, atacyrix, atahighpoint, ataintel, ataite, atajmicron,
+	atamarvell, atamicron, atanational, atanetcell, atanvidia,
+	atapromise, ataserverworks, atasiliconimage, atasis, atavia
+
 20080820:
 	The TTY subsystem of the kernel has been replaced by a new
 	implementation, which provides better scalability and an

From 6d3af67b2397542a0dbf402a020a30605173c5a6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 10:00:59 +0000
Subject: [PATCH 353/646] Add two more VIA SATA chip IDs.

PR:		kern/135057
---
 sys/dev/ata/ata-pci.h          | 2 ++
 sys/dev/ata/chipsets/ata-via.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 788adaf193c..e3ab0253d75 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -415,6 +415,8 @@ struct ata_pci_controller {
 #define ATA_VIA8237             0x32271106
 #define ATA_VIA8237A            0x05911106
 #define ATA_VIA8237S		0x53371106
+#define ATA_VIA8237_5372	0x53721106
+#define ATA_VIA8237_7372	0x73721106
 #define ATA_VIA8251             0x33491106
 #define ATA_VIA8361             0x31121106
 #define ATA_VIA8363             0x03051106
diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index daed0db13af..f5b5f9bc9b3 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -103,6 +103,8 @@ ata_via_probe(device_t dev)
      { ATA_VIA6421,   0x00, 6,      VIABAR,  ATA_SA150, "6421" },
      { ATA_VIA8237A,  0x00, 7,      0x00,    ATA_SA150, "8237A" },
      { ATA_VIA8237S,  0x00, 7,      0x00,    ATA_SA150, "8237S" },
+     { ATA_VIA8237_5372, 0x00, 7,   0x00,    ATA_SA300, "8237" },
+     { ATA_VIA8237_7372, 0x00, 7,   0x00,    ATA_SA300, "8237" },
      { ATA_VIA8251,   0x00, 0,      VIAAHCI, ATA_SA300, "8251" },
      { 0, 0, 0, 0, 0, 0 }};
 

From 3663f8041b8f740501afdc5032649c2467771c5d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 10:07:52 +0000
Subject: [PATCH 354/646] Add IDs for PATA part also.

---
 sys/dev/ata/chipsets/ata-via.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index f5b5f9bc9b3..47ebd0a15d8 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -95,6 +95,8 @@ ata_via_probe(device_t dev)
      { ATA_VIA8237,   0x00, VIA133, 0x00,    ATA_UDMA6, "8237" },
      { ATA_VIA8237A,  0x00, VIA133, 0x00,    ATA_UDMA6, "8237A" },
      { ATA_VIA8237S,  0x00, VIA133, 0x00,    ATA_UDMA6, "8237S" },
+     { ATA_VIA8237_5372, 0x00, VIA133, 0x00, ATA_UDMA6, "8237" },
+     { ATA_VIA8237_7372, 0x00, VIA133, 0x00, ATA_UDMA6, "8237" },
      { ATA_VIA8251,   0x00, VIA133, 0x00,    ATA_UDMA6, "8251" },
      { 0, 0, 0, 0, 0, 0 }};
     static struct ata_chip_id new_ids[] =

From c4bda3c6a398eaee3890e0b69f418ffcd4537d34 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 10:35:16 +0000
Subject: [PATCH 355/646] Document new modularised ATA kernel options.

PR:		kern/133162
MFC after:	3 days
---
 sys/conf/NOTES | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index deab220b445..55e0f90c76e 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1657,6 +1657,10 @@ device		siis
 # The 'ATA' driver supports all ATA and ATAPI devices, including PC Card
 # devices. You only need one "device ata" for it to find all
 # PCI and PC Card ATA/ATAPI devices on modern machines.
+# Alternatively, individual bus and chipset drivers may be chosen by using
+# the 'atacore' driver then selecting the drivers on a per vendor basis.
+# For example to build a system which only supports a VIA chipset,
+# omit 'ata' and include the 'atacore', 'atapci' and 'atavia' drivers.
 device		ata
 device		atadisk		# ATA disk drives
 device		ataraid		# ATA RAID drives
@@ -1665,6 +1669,39 @@ device		atapifd		# ATAPI floppy drives
 device		atapist		# ATAPI tape drives
 device		atapicam	# emulate ATAPI devices as SCSI ditto via CAM
 				# needs CAM to be present (scbus & pass)
+
+# Modular ATA
+#device		atacore		# Core ATA functionality
+#device		atacard		# CARDBUS support
+#device		atabus		# PC98 cbus support
+#device		ataisa		# ISA bus support
+#device		atapci		# PCI bus support; only generic chipset support
+
+# PCI ATA chipsets
+#device		ataahci		# AHCI SATA
+#device		ataacard	# ACARD
+#device		ataacerlabs	# Acer Labs Inc. (ALI)
+#device		ataadaptec	# Adaptec
+#device		ataamd		# American Micro Devices (AMD)
+#device		ataati		# ATI
+#device		atacenatek	# Cenatek
+#device		atacypress	# Cypress
+#device		atacyrix	# Cyrix
+#device		atahighpoint	# HighPoint
+#device		ataintel	# Intel
+#device		ataite		# Integrated Technology Inc. (ITE)
+#device		atajmicron	# JMicron
+#device		atamarvell	# Marvell
+#device		atamicron	# Micron
+#device		atanational	# National
+#device		atanetcell	# NetCell
+#device		atanvidia	# nVidia
+#device		atapromise	# Promise
+#device		ataserverworks	# ServerWorks
+#device		atasiliconimage	# Silicon Image Inc. (SiI) (formerly CMD)
+#device		atasis		# Silicon Integrated Systems Corp.(SiS)
+#device		atavia		# VIA Technologies Inc.
+
 #
 # For older non-PCI, non-PnPBIOS systems, these are the hints lines to add:
 hint.ata.0.at="isa"

From cc0daebb537d9e2282962126730450b90648aea6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 11:20:14 +0000
Subject: [PATCH 356/646] Increase ATA command timeouts. Some drives need more
 then 5s to spin-up.

PR:		kern/111023
---
 sys/dev/ata/ata-disk.c  | 8 ++++----
 sys/dev/ata/ata-queue.c | 4 ++--
 sys/dev/ata/ata-raid.c  | 4 ++--
 sys/dev/ata/atapi-cd.c  | 2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index c699a05f52e..58f2245aa0b 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -230,7 +230,7 @@ ad_spindown(void *priv)
     }
     request->dev = dev;
     request->flags = ATA_R_CONTROL;
-    request->timeout = 5;
+    request->timeout = 10;
     request->retries = 1;
     request->callback = ad_power_callback;
     request->u.ata.command = ATA_STANDBY_IMMEDIATE;
@@ -265,7 +265,7 @@ ad_strategy(struct bio *bp)
 	request->timeout = 31;
     }
     else {
-	request->timeout = 5;
+	request->timeout = 10;
     }
     request->retries = 2;
     request->data = bp->bio_data;
@@ -468,7 +468,7 @@ ad_set_geometry(device_t dev)
     request->u.ata.count = 0;
     request->u.ata.feature = 0;
     request->flags = ATA_R_CONTROL | ATA_R_QUIET;
-    request->timeout = 5;
+    request->timeout = 10;
     request->retries = 0;
     ata_queue_request(request);
     if (request->status & ATA_S_ERROR)
@@ -487,7 +487,7 @@ ad_set_geometry(device_t dev)
     request->u.ata.count = 1;
     request->u.ata.feature = 0;
     request->flags = ATA_R_CONTROL;
-    request->timeout = 5;
+    request->timeout = 10;
     request->retries = 0;
     ata_queue_request(request);
     if (request->status & ATA_S_ERROR)
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 88568842246..c0eb558e717 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -135,7 +135,7 @@ ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature,
 	    atadev->spindown_state = 0;
 	    request->timeout = 31;
 	} else {
-	    request->timeout = 5;
+	    request->timeout = 10;
 	}
 	request->retries = 0;
 	ata_queue_request(request);
@@ -389,7 +389,7 @@ ata_completed(void *context, int dummy)
 	    request->bytecount = sizeof(struct atapi_sense);
 	    request->donecount = 0;
 	    request->transfersize = sizeof(struct atapi_sense);
-	    request->timeout = 5;
+	    request->timeout = 10;
 	    request->flags &= (ATA_R_ATAPI | ATA_R_QUIET | ATA_R_DEBUG);
 	    request->flags |= (ATA_R_READ | ATA_R_AT_HEAD | ATA_R_REQUEUE);
 	    ATA_DEBUG_RQ(request, "autoissue request sense");
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index fc6a23c0461..a88284bc3ec 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -273,7 +273,7 @@ ata_raid_flush(struct bio *bp)
 	request->u.ata.lba = 0;
 	request->u.ata.count = 0;
 	request->u.ata.feature = 0;
-	request->timeout = 1;
+	request->timeout = 10;
 	request->retries = 0;
 	request->flags |= ATA_R_ORDERED | ATA_R_DIRECT;
 	ata_queue_request(request);
@@ -4371,7 +4371,7 @@ ata_raid_init_request(device_t dev, struct ar_softc *rdp, struct bio *bio)
 	return NULL;
     }
     request->dev = dev;
-    request->timeout = 5;
+    request->timeout = 10;
     request->retries = 2;
     request->callback = ata_raid_done;
     request->driver = rdp;
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 941c1018547..2791826eb98 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -700,7 +700,7 @@ acd_geom_access(struct g_provider *pp, int dr, int dw, int de)
 	request->dev = dev;
 	bcopy(ccb, request->u.atapi.ccb, 16);
 	request->flags = ATA_R_ATAPI;
-	request->timeout = 5;
+	request->timeout = 10;
 	ata_queue_request(request);
 	if (!request->error &&
 	    (request->u.atapi.sense.key == 2 ||

From e8579543e8e23c8a412120f16aacbefe3baa8413 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 11:23:41 +0000
Subject: [PATCH 357/646] Round timeout up when converting CAM milliseconds to
 ATA seconds.

---
 sys/dev/ata/atapi-cam.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c
index cf90c49f7c3..c9af63291dc 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -629,7 +629,7 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
 	request->data = buf;
 	request->bytecount = len;
 	request->transfersize = min(request->bytecount, 65534);
-	request->timeout = ccb_h->timeout / 1000; /* XXX lost granularity */
+	request->timeout = (ccb_h->timeout + 999) / 1000;
 	request->callback = &atapi_cb;
 	request->flags = request_flags;
 
@@ -732,7 +732,7 @@ atapi_cb(struct ata_request *request)
 		request->data = (caddr_t)&csio->sense_data;
 		request->bytecount = sizeof(struct atapi_sense);
 		request->transfersize = min(request->bytecount, 65534);
-		request->timeout = csio->ccb_h.timeout / 1000;
+		request->timeout = (csio->ccb_h.timeout + 999) / 1000;
 		request->retries = 2;
 		request->flags = ATA_R_QUIET|ATA_R_ATAPI|ATA_R_IMMEDIATE;
 		hcb->flags |= AUTOSENSE;

From 84f620d3e2c6019cf66dfb89dd5c9cb1a980fac3 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 26 Oct 2009 11:26:49 +0000
Subject: [PATCH 358/646] Report SATA speeds to CAM, to not confuse users with
 low numbers logged.

---
 sys/dev/ata/atapi-cam.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c
index c9af63291dc..84b44c56399 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -414,6 +414,12 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
 	    case ATA_UDMA6:
 		cpi->base_transfer_speed = 133000;
 		break;
+	    case ATA_SA150:
+		cpi->base_transfer_speed = 150000;
+		break;
+	    case ATA_SA300:
+		cpi->base_transfer_speed = 300000;
+		break;
 	    default:
 		break;
 	    }

From 90f241383ea9bf3c9fb230e79e49f6602ddcb113 Mon Sep 17 00:00:00 2001
From: Rong-En Fan 
Date: Mon, 26 Oct 2009 13:01:29 +0000
Subject: [PATCH 359/646] Pull upstream patch to fix ee(1) crash when received
 SIGWINCH:

  modify _nc_wgetch() to check for a -1 in the fifo, e.g., after a
  SIGWINCH, and discard that value, to avoid confusing application
  (patch by Eygene Ryabinkin, FreeBSD bin/136223).

PR:		136223
Submitted by:	Eygene Ryabinkin
Obtained from:	ncurses-5.7-20091024 snapshot
MFC after:	3 days
---
 ncurses/base/lib_getch.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c
index a3812bee76e..e7ba0b210e3 100644
--- a/ncurses/base/lib_getch.c
+++ b/ncurses/base/lib_getch.c
@@ -476,6 +476,12 @@ _nc_wgetch(WINDOW *win,
 	    /* resizeterm can push KEY_RESIZE */
 	    if (cooked_key_in_fifo()) {
 		*result = fifo_pull(sp);
+		/*
+		 * Get the ERR from queue -- it is from WINCH,
+		 * so we should take it out, the "error" is handled.
+		 */
+		if (fifo_peek(sp) == -1)
+		    fifo_pull(sp);
 		returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK);
 	    }
 	}

From bdb403798c3bc94e5afc271ea6d80d681d768107 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Mon, 26 Oct 2009 14:57:33 +0000
Subject: [PATCH 360/646] Fix parsing of mount options specified with -o in
 case an option with value is preceded by an option without value (for example
 -o option1,option2=value). Options must be separated before searching for
 '='. Also compare pnextopt explicitly against NULL.

PR:		bin/134069
Approved by:	trasz (mentor)
---
 sbin/mount_nfs/mount_nfs.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index 7d4f3f65e1c..229da147255 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -232,16 +232,16 @@ main(int argc, char *argv[])
 				char *pnextopt = NULL;
 				char *val = "";
 				pass_flag_to_nmount = 1;
-				pval = strchr(opt, '=');
 				pnextopt = strchr(opt, ',');
+				if (pnextopt != NULL) {
+					*pnextopt = '\0';
+					pnextopt++;
+				}
+				pval = strchr(opt, '=');
 				if (pval != NULL) {
 					*pval = '\0';
 					val = pval + 1;
 				}
-				if (pnextopt) {
-					*pnextopt = '\0';
-					pnextopt++;
-				}
 				if (strcmp(opt, "bg") == 0) {
 					opflags |= BGRND;
 					pass_flag_to_nmount=0;

From 808de0ae26bcb3b90cac6676d63f18906284711d Mon Sep 17 00:00:00 2001
From: Maksim Yevmenkin 
Date: Mon, 26 Oct 2009 17:27:30 +0000
Subject: [PATCH 361/646] Fix typo in bluetooth.3 Do not use reserved C++
 keyword "new"

MFC after:	1 month
---
 lib/libbluetooth/bluetooth.3 | 2 +-
 lib/libbluetooth/bluetooth.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/libbluetooth/bluetooth.3 b/lib/libbluetooth/bluetooth.3
index c4eab90fbaa..40ea20c45c5 100644
--- a/lib/libbluetooth/bluetooth.3
+++ b/lib/libbluetooth/bluetooth.3
@@ -272,7 +272,7 @@ otherwise 0.
 .Pp
 The
 .Fn bt_devinfo
-function populates prodivded
+function populates provided
 .Vt bt_devinfo
 structure with the information about given Bluetooth device.
 The caller is expected to pass Bluetooth device name in the
diff --git a/lib/libbluetooth/bluetooth.h b/lib/libbluetooth/bluetooth.h
index 5ad3c3c553b..a73dbe915bc 100644
--- a/lib/libbluetooth/bluetooth.h
+++ b/lib/libbluetooth/bluetooth.h
@@ -163,8 +163,8 @@ int		bt_devclose(int s);
 int		bt_devsend (int s, uint16_t opcode, void *param, size_t plen);
 ssize_t		bt_devrecv (int s, void *buf, size_t size, time_t to);
 int		bt_devreq  (int s, struct bt_devreq *r, time_t to);
-int		bt_devfilter(int s, struct bt_devfilter const *new,
-			     struct bt_devfilter *old);
+int		bt_devfilter(int s, struct bt_devfilter const *newp,
+			     struct bt_devfilter *oldp);
 void		bt_devfilter_pkt_set(struct bt_devfilter *filter, uint8_t type);
 void		bt_devfilter_pkt_clr(struct bt_devfilter *filter, uint8_t type);
 int		bt_devfilter_pkt_tst(struct bt_devfilter const *filter, uint8_t type);

From 93902625760d9365f14ad97b0cd705de8a71a43a Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 26 Oct 2009 17:42:03 +0000
Subject: [PATCH 362/646] Fix some spelling nits.

---
 sys/kern/kern_cpuset.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 91269e4aab3..7f57bae3caa 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
  * not.  This means that anonymous sets are immutable because they may be
  * shared.  To modify an anonymous set a new set is created with the desired
  * mask and the same parent as the existing anonymous set.  This gives the
- * illusion of each thread having a private mask.A
+ * illusion of each thread having a private mask.
  *
  * Via the syscall apis a user may ask to retrieve or modify the root, base,
  * or mask that is discovered via a pid, tid, or setid.  Modifying a set
@@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$");
  * Modifying a pid or tid's mask applies only to that tid but must still
  * exist within the assigned parent set.
  *
- * A thread may not be assigned to a a group seperate from other threads in
+ * A thread may not be assigned to a a group separate from other threads in
  * the process.  This is to remove ambiguity when the setid is queried with
  * a pid argument.  There is no other technical limitation.
  *
@@ -98,7 +98,7 @@ __FBSDID("$FreeBSD$");
  *
  * A simple application should not concern itself with sets at all and
  * rather apply masks to its own threads via CPU_WHICH_TID and a -1 id
- * meaning 'curthread'.  It may query availble cpus for that tid with a
+ * meaning 'curthread'.  It may query available cpus for that tid with a
  * getaffinity call using (CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, ...).
  */
 static uma_zone_t cpuset_zone;
@@ -153,7 +153,7 @@ cpuset_refbase(struct cpuset *set)
 }
 
 /*
- * Release a reference in a context where it is safe to allocte.
+ * Release a reference in a context where it is safe to allocate.
  */
 void
 cpuset_rel(struct cpuset *set)
@@ -752,7 +752,7 @@ cpuset_setproc_update_set(struct proc *p, struct cpuset *set)
 
 /*
  * This is called once the final set of system cpus is known.  Modifies
- * the root set and all children and mark the root readonly.  
+ * the root set and all children and mark the root read-only.  
  */
 static void
 cpuset_init(void *arg)

From 4afcae9ba3366d5f4c2ab5e2f8676cd8236eacb1 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Mon, 26 Oct 2009 18:02:05 +0000
Subject: [PATCH 363/646] There is no need to "busy" a page when the object is
 locked for the duration of the operation.

---
 sys/fs/tmpfs/tmpfs_subr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 8dc833816f9..5b13e640948 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -906,10 +906,9 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize)
 
 		if (zerolen > 0) {
 			m = vm_page_grab(uobj, OFF_TO_IDX(newsize),
-					VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+			    VM_ALLOC_NOBUSY | VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 			pmap_zero_page_area(m, PAGE_SIZE - zerolen,
 				zerolen);
-			vm_page_wakeup(m);
 		}
 		VM_OBJECT_UNLOCK(uobj);
 

From 86855bf54935f7c2e0431cb40d1f1aa2813b40a7 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 26 Oct 2009 18:32:06 +0000
Subject: [PATCH 364/646] Another nit that both I and ispell missed.

Submitted by:	Ben Kaduk  minimarmot of gmail
---
 sys/kern/kern_cpuset.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 7f57bae3caa..3bdb45e3bf7 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$");
  * Modifying a pid or tid's mask applies only to that tid but must still
  * exist within the assigned parent set.
  *
- * A thread may not be assigned to a a group separate from other threads in
+ * A thread may not be assigned to a group separate from other threads in
  * the process.  This is to remove ambiguity when the setid is queried with
  * a pid argument.  There is no other technical limitation.
  *

From ac9bce0f3bfa07a188c5ebecb755a268080944cc Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Mon, 26 Oct 2009 19:23:34 +0000
Subject: [PATCH 366/646] Improve the round robin stream scheduler.

Approved by: rrs (mentor)
MFC after: 3 days
---
 sys/netinet/sctp_output.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index a99fc691230..02bca9044c8 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -7169,20 +7169,14 @@ sctp_select_a_stream(struct sctp_tcb *stcb, struct sctp_association *asoc)
 
 	/* Find the next stream to use */
 	if (asoc->last_out_stream == NULL) {
-		strq = asoc->last_out_stream = TAILQ_FIRST(&asoc->out_wheel);
-		if (asoc->last_out_stream == NULL) {
-			/* huh nothing on the wheel, TSNH */
-			return (NULL);
+		strq = TAILQ_FIRST(&asoc->out_wheel);
+	} else {
+		strq = TAILQ_NEXT(asoc->last_out_stream, next_spoke);
+		if (strq == NULL) {
+			strq = TAILQ_FIRST(&asoc->out_wheel);
 		}
-		goto done_it;
-	}
-	strq = TAILQ_NEXT(asoc->last_out_stream, next_spoke);
-done_it:
-	if (strq == NULL) {
-		strq = asoc->last_out_stream = TAILQ_FIRST(&asoc->out_wheel);
 	}
 	return (strq);
-
 }
 
 

From 77cbe30ea95e622c99b9e518406e24c231d89b72 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Mon, 26 Oct 2009 20:23:15 +0000
Subject: [PATCH 367/646] Remove usb controller takeover code now that it is
 handled by the pci code.

Reminded by:	jhb
Reviewed by:	HPS
---
 sys/dev/usb/controller/ehci_pci.c | 49 -------------------------------
 sys/dev/usb/controller/ohci.c     | 24 ---------------
 sys/dev/usb/controller/uhci_pci.c | 15 ----------
 3 files changed, 88 deletions(-)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index fc2035bd297..5931c51b82b 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -102,8 +102,6 @@ __FBSDID("$FreeBSD$");
 
 #define	PCI_EHCI_BASE_REG	0x10
 
-static void ehci_pci_takecontroller(device_t self);
-
 static device_probe_t ehci_pci_probe;
 static device_attach_t ehci_pci_attach;
 static device_detach_t ehci_pci_detach;
@@ -129,7 +127,6 @@ ehci_pci_resume(device_t self)
 {
 	ehci_softc_t *sc = device_get_softc(self);
 
-	ehci_pci_takecontroller(self);
 	ehci_resume(sc);
 
 	bus_generic_resume(self);
@@ -414,7 +411,6 @@ ehci_pci_attach(device_t self)
 		sc->sc_intr_hdl = NULL;
 		goto error;
 	}
-	ehci_pci_takecontroller(self);
 
 	/* Undocumented quirks taken from Linux */
 
@@ -506,51 +502,6 @@ ehci_pci_detach(device_t self)
 	return (0);
 }
 
-static void
-ehci_pci_takecontroller(device_t self)
-{
-	ehci_softc_t *sc = device_get_softc(self);
-	uint32_t cparams;
-	uint32_t eec;
-	uint16_t to;
-	uint8_t eecp;
-	uint8_t bios_sem;
-
-	cparams = EREAD4(sc, EHCI_HCCPARAMS);
-
-	/* Synchronise with the BIOS if it owns the controller. */
-	for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
-	    eecp = EHCI_EECP_NEXT(eec)) {
-		eec = pci_read_config(self, eecp, 4);
-		if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP) {
-			continue;
-		}
-		bios_sem = pci_read_config(self, eecp +
-		    EHCI_LEGSUP_BIOS_SEM, 1);
-		if (bios_sem == 0) {
-			continue;
-		}
-		device_printf(sc->sc_bus.bdev, "waiting for BIOS "
-		    "to give up control\n");
-		pci_write_config(self, eecp +
-		    EHCI_LEGSUP_OS_SEM, 1, 1);
-		to = 500;
-		while (1) {
-			bios_sem = pci_read_config(self, eecp +
-			    EHCI_LEGSUP_BIOS_SEM, 1);
-			if (bios_sem == 0)
-				break;
-
-			if (--to == 0) {
-				device_printf(sc->sc_bus.bdev,
-				    "timed out waiting for BIOS\n");
-				break;
-			}
-			usb_pause_mtx(NULL, hz / 100);	/* wait 10ms */
-		}
-	}
-}
-
 static driver_t ehci_driver =
 {
 	.name = "ehci",
diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c
index 637b639e3f6..2ced6765dad 100644
--- a/sys/dev/usb/controller/ohci.c
+++ b/sys/dev/usb/controller/ohci.c
@@ -175,30 +175,6 @@ ohci_controller_init(ohci_softc_t *sc)
 	uint32_t per;
 	uint32_t desca;
 
-	/* Determine in what context we are running. */
-	ctl = OREAD4(sc, OHCI_CONTROL);
-	if (ctl & OHCI_IR) {
-		/* SMM active, request change */
-		DPRINTF("SMM active, request owner change\n");
-		OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
-		for (i = 0; (i < 100) && (ctl & OHCI_IR); i++) {
-			usb_pause_mtx(NULL, hz / 1000);
-			ctl = OREAD4(sc, OHCI_CONTROL);
-		}
-		if (ctl & OHCI_IR) {
-			device_printf(sc->sc_bus.bdev,
-			    "SMM does not respond, resetting\n");
-			OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-			goto reset;
-		}
-	} else {
-		DPRINTF("cold started\n");
-reset:
-		/* controller was cold started */
-		usb_pause_mtx(NULL,
-		    USB_MS_TO_TICKS(USB_BUS_RESET_DELAY));
-	}
-
 	/*
 	 * This reset should not be necessary according to the OHCI spec, but
 	 * without it some controllers do not start.
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 3956eada423..e367b23597a 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -115,8 +115,6 @@ uhci_pci_resume(device_t self)
 {
 	uhci_softc_t *sc = device_get_softc(self);
 
-	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
-
 	uhci_resume(sc);
 
 	bus_generic_resume(self);
@@ -363,19 +361,6 @@ uhci_pci_attach(device_t self)
 		sc->sc_intr_hdl = NULL;
 		goto error;
 	}
-	/*
-	 * Set the PIRQD enable bit and switch off all the others. We don't
-	 * want legacy support to interfere with us XXX Does this also mean
-	 * that the BIOS won't touch the keyboard anymore if it is connected
-	 * to the ports of the root hub?
-	 */
-#ifdef USB_DEBUG
-	if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN) {
-		device_printf(self, "LegSup = 0x%04x\n",
-		    pci_read_config(self, PCI_LEGSUP, 2));
-	}
-#endif
-	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
 
 	err = uhci_init(sc);
 	if (!err) {

From c2e8b89ce458171e34c25abdb5def43d334f53e6 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Mon, 26 Oct 2009 21:47:16 +0000
Subject: [PATCH 368/646] Revert r198500 for now, this will break situations
 when hw.pci.usb_early_takeover is set to zero and the SMM release is never
 done.

Pointed out by:	marcel
---
 sys/dev/usb/controller/ehci_pci.c | 49 +++++++++++++++++++++++++++++++
 sys/dev/usb/controller/ohci.c     | 24 +++++++++++++++
 sys/dev/usb/controller/uhci_pci.c | 15 ++++++++++
 3 files changed, 88 insertions(+)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index 5931c51b82b..fc2035bd297 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -102,6 +102,8 @@ __FBSDID("$FreeBSD$");
 
 #define	PCI_EHCI_BASE_REG	0x10
 
+static void ehci_pci_takecontroller(device_t self);
+
 static device_probe_t ehci_pci_probe;
 static device_attach_t ehci_pci_attach;
 static device_detach_t ehci_pci_detach;
@@ -127,6 +129,7 @@ ehci_pci_resume(device_t self)
 {
 	ehci_softc_t *sc = device_get_softc(self);
 
+	ehci_pci_takecontroller(self);
 	ehci_resume(sc);
 
 	bus_generic_resume(self);
@@ -411,6 +414,7 @@ ehci_pci_attach(device_t self)
 		sc->sc_intr_hdl = NULL;
 		goto error;
 	}
+	ehci_pci_takecontroller(self);
 
 	/* Undocumented quirks taken from Linux */
 
@@ -502,6 +506,51 @@ ehci_pci_detach(device_t self)
 	return (0);
 }
 
+static void
+ehci_pci_takecontroller(device_t self)
+{
+	ehci_softc_t *sc = device_get_softc(self);
+	uint32_t cparams;
+	uint32_t eec;
+	uint16_t to;
+	uint8_t eecp;
+	uint8_t bios_sem;
+
+	cparams = EREAD4(sc, EHCI_HCCPARAMS);
+
+	/* Synchronise with the BIOS if it owns the controller. */
+	for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
+	    eecp = EHCI_EECP_NEXT(eec)) {
+		eec = pci_read_config(self, eecp, 4);
+		if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP) {
+			continue;
+		}
+		bios_sem = pci_read_config(self, eecp +
+		    EHCI_LEGSUP_BIOS_SEM, 1);
+		if (bios_sem == 0) {
+			continue;
+		}
+		device_printf(sc->sc_bus.bdev, "waiting for BIOS "
+		    "to give up control\n");
+		pci_write_config(self, eecp +
+		    EHCI_LEGSUP_OS_SEM, 1, 1);
+		to = 500;
+		while (1) {
+			bios_sem = pci_read_config(self, eecp +
+			    EHCI_LEGSUP_BIOS_SEM, 1);
+			if (bios_sem == 0)
+				break;
+
+			if (--to == 0) {
+				device_printf(sc->sc_bus.bdev,
+				    "timed out waiting for BIOS\n");
+				break;
+			}
+			usb_pause_mtx(NULL, hz / 100);	/* wait 10ms */
+		}
+	}
+}
+
 static driver_t ehci_driver =
 {
 	.name = "ehci",
diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c
index 2ced6765dad..637b639e3f6 100644
--- a/sys/dev/usb/controller/ohci.c
+++ b/sys/dev/usb/controller/ohci.c
@@ -175,6 +175,30 @@ ohci_controller_init(ohci_softc_t *sc)
 	uint32_t per;
 	uint32_t desca;
 
+	/* Determine in what context we are running. */
+	ctl = OREAD4(sc, OHCI_CONTROL);
+	if (ctl & OHCI_IR) {
+		/* SMM active, request change */
+		DPRINTF("SMM active, request owner change\n");
+		OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
+		for (i = 0; (i < 100) && (ctl & OHCI_IR); i++) {
+			usb_pause_mtx(NULL, hz / 1000);
+			ctl = OREAD4(sc, OHCI_CONTROL);
+		}
+		if (ctl & OHCI_IR) {
+			device_printf(sc->sc_bus.bdev,
+			    "SMM does not respond, resetting\n");
+			OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
+			goto reset;
+		}
+	} else {
+		DPRINTF("cold started\n");
+reset:
+		/* controller was cold started */
+		usb_pause_mtx(NULL,
+		    USB_MS_TO_TICKS(USB_BUS_RESET_DELAY));
+	}
+
 	/*
 	 * This reset should not be necessary according to the OHCI spec, but
 	 * without it some controllers do not start.
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index e367b23597a..3956eada423 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -115,6 +115,8 @@ uhci_pci_resume(device_t self)
 {
 	uhci_softc_t *sc = device_get_softc(self);
 
+	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
+
 	uhci_resume(sc);
 
 	bus_generic_resume(self);
@@ -361,6 +363,19 @@ uhci_pci_attach(device_t self)
 		sc->sc_intr_hdl = NULL;
 		goto error;
 	}
+	/*
+	 * Set the PIRQD enable bit and switch off all the others. We don't
+	 * want legacy support to interfere with us XXX Does this also mean
+	 * that the BIOS won't touch the keyboard anymore if it is connected
+	 * to the ports of the root hub?
+	 */
+#ifdef USB_DEBUG
+	if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN) {
+		device_printf(self, "LegSup = 0x%04x\n",
+		    pci_read_config(self, PCI_LEGSUP, 2));
+	}
+#endif
+	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
 
 	err = uhci_init(sc);
 	if (!err) {

From bed992dc265053215b2f958ff2b387d459f30694 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Mon, 26 Oct 2009 22:00:26 +0000
Subject: [PATCH 369/646] Sync with the other archs and wrapper the prototype
 of in_cksum_skip(9) in #ifdef _KERNEL.

Submitted by:	Ulrich Spoerlein
MFC after:	1 month
---
 sys/sparc64/include/in_cksum.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/sparc64/include/in_cksum.h b/sys/sparc64/include/in_cksum.h
index c754d8b1b01..ae06a4cb997 100644
--- a/sys/sparc64/include/in_cksum.h
+++ b/sys/sparc64/include/in_cksum.h
@@ -164,6 +164,8 @@ in_cksum_hdr(struct ip *ip)
 	return (__ret);
 }
 
+#ifdef _KERNEL
 u_short	in_cksum_skip(struct mbuf *m, int len, int skip);
+#endif
 
 #endif /* _MACHINE_IN_CKSUM_H_ */

From 207ec3a836dcb63be61bbbc607a8cda3ffe0206d Mon Sep 17 00:00:00 2001
From: Colin Percival 
Date: Mon, 26 Oct 2009 23:24:59 +0000
Subject: [PATCH 370/646] Don't leak a file descriptor when ejecting a CDROM.

Submitted by:	Ronald Klop, trhodes
Note to self:	don't do commits while half-asleep
---
 usr.sbin/sysinstall/cdrom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/usr.sbin/sysinstall/cdrom.c b/usr.sbin/sysinstall/cdrom.c
index 07a372237a3..6bc72d863ef 100644
--- a/usr.sbin/sysinstall/cdrom.c
+++ b/usr.sbin/sysinstall/cdrom.c
@@ -239,5 +239,6 @@ mediaEjectCDROM(Device *dev)
 	else {
 		ioctl(fd, CDIOCALLOW);
 		ioctl(fd, CDIOCEJECT);
+		close(fd);
 	}
 }

From 210a688642f7e851e453853f45cdc90e016df1ff Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 10:15:58 +0000
Subject: [PATCH 371/646] When protection of wired read-only mapping is changed
 to read-write, install new shadow object behind the map entry and copy the
 pages from the underlying objects to it. This makes the mprotect(2) call to
 actually perform the requested operation instead of silently do nothing and
 return success, that causes SIGSEGV on later write access to the mapping.

Reuse vm_fault_copy_entry() to do the copying, modifying it to behave
correctly when src_entry == dst_entry.

Reviewed by:	alc
MFC after:	3 weeks
---
 sys/vm/vm_fault.c | 62 +++++++++++++++++++++++++++++++++++------------
 sys/vm/vm_map.c   | 14 ++++++++---
 2 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 508d617fc6b..68057fb4f3f 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1119,7 +1119,10 @@ vm_fault_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
  *	Routine:
  *		vm_fault_copy_entry
  *	Function:
- *		Copy all of the pages from a wired-down map entry to another.
+ *		Create new shadow object backing dst_entry with private copy of
+ *		all underlying pages. When src_entry is equal to dst_entry,
+ *		function implements COW for wired-down map entry. Otherwise,
+ *		it forks wired entry into dst_map.
  *
  *	In/out conditions:
  *		The source and destination maps must be locked for write.
@@ -1131,19 +1134,20 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
     vm_map_entry_t dst_entry, vm_map_entry_t src_entry,
     vm_ooffset_t *fork_charge)
 {
-	vm_object_t backing_object, dst_object, object;
-	vm_object_t src_object;
+	vm_object_t backing_object, dst_object, object, src_object;
 	vm_pindex_t dst_pindex, pindex, src_pindex;
-	vm_prot_t prot;
+	vm_prot_t access, prot;
 	vm_offset_t vaddr;
 	vm_page_t dst_m;
 	vm_page_t src_m;
-	boolean_t src_readonly;
+	boolean_t src_readonly, upgrade;
 
 #ifdef	lint
 	src_map++;
 #endif	/* lint */
 
+	upgrade = src_entry == dst_entry;
+
 	src_object = src_entry->object.vm_object;
 	src_pindex = OFF_TO_IDX(src_entry->offset);
 	src_readonly = (src_entry->protection & VM_PROT_WRITE) == 0;
@@ -1160,17 +1164,34 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 #endif
 
 	VM_OBJECT_LOCK(dst_object);
-	KASSERT(dst_entry->object.vm_object == NULL,
+	KASSERT(upgrade || dst_entry->object.vm_object == NULL,
 	    ("vm_fault_copy_entry: vm_object not NULL"));
 	dst_entry->object.vm_object = dst_object;
 	dst_entry->offset = 0;
-	dst_object->uip = curthread->td_ucred->cr_ruidinfo;
-	uihold(dst_object->uip);
 	dst_object->charge = dst_entry->end - dst_entry->start;
-	KASSERT(dst_entry->uip == NULL,
-	    ("vm_fault_copy_entry: leaked swp charge"));
-	*fork_charge += dst_object->charge;
-	prot = dst_entry->max_protection;
+	if (fork_charge != NULL) {
+		KASSERT(dst_entry->uip == NULL,
+		    ("vm_fault_copy_entry: leaked swp charge"));
+		dst_object->uip = curthread->td_ucred->cr_ruidinfo;
+		uihold(dst_object->uip);
+		*fork_charge += dst_object->charge;
+	} else {
+		dst_object->uip = dst_entry->uip;
+		dst_entry->uip = NULL;
+	}
+	access = prot = dst_entry->max_protection;
+	/*
+	 * If not an upgrade, then enter the mappings in the pmap as
+	 * read and/or execute accesses.  Otherwise, enter them as
+	 * write accesses.
+	 *
+	 * A writeable large page mapping is only created if all of
+	 * the constituent small page mappings are modified. Marking
+	 * PTEs as modified on inception allows promotion to happen
+	 * without taking potentially large number of soft faults.
+	 */
+	if (!upgrade)
+		access &= ~VM_PROT_WRITE;
 
 	/*
 	 * Loop through all of the pages in the entry's range, copying each
@@ -1221,21 +1242,30 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 		VM_OBJECT_UNLOCK(dst_object);
 
 		/*
-		 * Enter it in the pmap as a read and/or execute access.
+		 * Enter it in the pmap. If a wired, copy-on-write
+		 * mapping is being replaced by a write-enabled
+		 * mapping, then wire that new mapping.
 		 */
-		pmap_enter(dst_map->pmap, vaddr, prot & ~VM_PROT_WRITE, dst_m,
-		    prot, FALSE);
+		pmap_enter(dst_map->pmap, vaddr, access, dst_m, prot, upgrade);
 
 		/*
 		 * Mark it no longer busy, and put it on the active list.
 		 */
 		VM_OBJECT_LOCK(dst_object);
 		vm_page_lock_queues();
-		vm_page_activate(dst_m);
+		if (upgrade) {
+			vm_page_unwire(src_m, 0);
+			vm_page_wire(dst_m);
+		} else
+			vm_page_activate(dst_m);
 		vm_page_unlock_queues();
 		vm_page_wakeup(dst_m);
 	}
 	VM_OBJECT_UNLOCK(dst_object);
+	if (upgrade) {
+		dst_entry->eflags &= ~(MAP_ENTRY_COW | MAP_ENTRY_NEEDS_COPY);
+		vm_object_deallocate(src_object);
+	}
 }
 
 
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 116671294c4..06ae63e622b 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1805,10 +1805,10 @@ int
 vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
 	       vm_prot_t new_prot, boolean_t set_max)
 {
-	vm_map_entry_t current;
-	vm_map_entry_t entry;
+	vm_map_entry_t current, entry;
 	vm_object_t obj;
 	struct uidinfo *uip;
+	vm_prot_t old_prot;
 
 	vm_map_lock(map);
 
@@ -1897,9 +1897,8 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
 	 */
 	current = entry;
 	while ((current != &map->header) && (current->start < end)) {
-		vm_prot_t old_prot;
-
 		old_prot = current->protection;
+
 		if (set_max)
 			current->protection =
 			    (current->max_protection = new_prot) &
@@ -1907,6 +1906,13 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
 		else
 			current->protection = new_prot;
 
+		if ((current->eflags & (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED))
+		     == (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED) &&
+		    (current->protection & VM_PROT_WRITE) != 0 &&
+		    (old_prot & VM_PROT_WRITE) == 0) {
+			vm_fault_copy_entry(map, map, current, current, NULL);
+		}
+
 		/*
 		 * Update physical map if necessary. Worry about copy-on-write
 		 * here.

From 84440afb54cdee80c5515edf360a4c60d526d0ff Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 10:42:24 +0000
Subject: [PATCH 372/646] In kern_sigsuspend(), better manipulate thread signal
 mask using kern_sigprocmask() to properly notify other possible candidate
 threads for signal delivery.

Since sigsuspend() shall only return to usermode after a signal was
delivered, do cursig/postsig loop immediately after waiting for
signal, repeating the wait if wakeup was spurious due to race with
other thread fetching signal from the process queue before us. Add
thread_suspend_check() call to allow the thread to be stopped or killed
while in loop.

Modify last argument of kern_sigprocmask() from boolean to flags,
allowing the function to be called with locked proc. Convertion of the
callers that supplied 1 to the old argument will be done in the next
commit, and due to SIGPROCMASK_OLD value equial to 1, code is formally
correct in between.

Reviewed by:	davidxu
Tested by:	pho
MFC after:	1 month
---
 sys/compat/freebsd32/freebsd32_misc.c | 13 +------
 sys/kern/kern_sig.c                   | 51 +++++++++++++++------------
 sys/sys/signalvar.h                   |  7 +++-
 sys/sys/syscallsubr.h                 |  2 --
 4 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 71b22aa11c2..9f6b16defad 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2579,21 +2579,10 @@ int
 ofreebsd32_sigsuspend(struct thread *td,
 			      struct ofreebsd32_sigsuspend_args *uap)
 {
-	struct proc *p = td->td_proc;
 	sigset_t mask;
 
-	PROC_LOCK(p);
-	td->td_oldsigmask = td->td_sigmask;
-	td->td_pflags |= TDP_OLDMASK;
 	OSIG2SIG(uap->mask, mask);
-	SIG_CANTMASK(mask);
-	SIGSETLO(td->td_sigmask, mask);
-	signotify(td);
-	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
-		/* void */;
-	PROC_UNLOCK(p);
-	/* always return EINTR rather than ERESTART... */
-	return (EINTR);
+	return (kern_sigsuspend(td, mask));
 }
 
 struct sigstack32 {
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index bc09686bcf1..a453b555a76 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -970,14 +970,15 @@ execsigs(struct proc *p)
  */
 int
 kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
-    int old)
+    int flags)
 {
 	sigset_t new_block, oset1;
 	struct proc *p;
 	int error;
 
 	p = td->td_proc;
-	PROC_LOCK(p);
+	if (!(flags & SIGPROCMASK_PROC_LOCKED))
+		PROC_LOCK(p);
 	if (oset != NULL)
 		*oset = td->td_sigmask;
 
@@ -999,7 +1000,7 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
 		case SIG_SETMASK:
 			SIG_CANTMASK(*set);
 			oset1 = td->td_sigmask;
-			if (old)
+			if (flags & SIGPROCMASK_OLD)
 				SIGSETLO(td->td_sigmask, *set);
 			else
 				td->td_sigmask = *set;
@@ -1025,7 +1026,8 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
 	if (p->p_numthreads != 1)
 		reschedule_signals(p, new_block);
 
-	PROC_UNLOCK(p);
+	if (!(flags & SIGPROCMASK_PROC_LOCKED))
+		PROC_UNLOCK(p);
 	return (error);
 }
 
@@ -1458,6 +1460,7 @@ int
 kern_sigsuspend(struct thread *td, sigset_t mask)
 {
 	struct proc *p = td->td_proc;
+	int has_sig, sig;
 
 	/*
 	 * When returning from sigsuspend, we want
@@ -1467,13 +1470,28 @@ kern_sigsuspend(struct thread *td, sigset_t mask)
 	 * to indicate this.
 	 */
 	PROC_LOCK(p);
-	td->td_oldsigmask = td->td_sigmask;
+	kern_sigprocmask(td, SIG_SETMASK, &mask, &td->td_oldsigmask,
+	    SIGPROCMASK_PROC_LOCKED);
 	td->td_pflags |= TDP_OLDMASK;
-	SIG_CANTMASK(mask);
-	td->td_sigmask = mask;
-	signotify(td);
-	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause", 0) == 0)
-		/* void */;
+
+	/*
+	 * Process signals now. Otherwise, we can get spurious wakeup
+	 * due to signal entered process queue, but delivered to other
+	 * thread. But sigsuspend should return only on signal
+	 * delivery.
+	 */
+	for (has_sig = 0; !has_sig;) {
+		while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause",
+			0) == 0)
+			/* void */;
+		thread_suspend_check(0);
+		mtx_lock(&p->p_sigacts->ps_mtx);
+		while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0) {
+			postsig(sig);
+			has_sig = 1;
+		}
+		mtx_unlock(&p->p_sigacts->ps_mtx);
+	}
 	PROC_UNLOCK(p);
 	/* always return EINTR rather than ERESTART... */
 	return (EINTR);
@@ -1495,21 +1513,10 @@ osigsuspend(td, uap)
 	struct thread *td;
 	struct osigsuspend_args *uap;
 {
-	struct proc *p = td->td_proc;
 	sigset_t mask;
 
-	PROC_LOCK(p);
-	td->td_oldsigmask = td->td_sigmask;
-	td->td_pflags |= TDP_OLDMASK;
 	OSIG2SIG(uap->mask, mask);
-	SIG_CANTMASK(mask);
-	SIGSETLO(td->td_sigmask, mask);
-	signotify(td);
-	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
-		/* void */;
-	PROC_UNLOCK(p);
-	/* always return EINTR rather than ERESTART... */
-	return (EINTR);
+	return (kern_sigsuspend(td, mask));
 }
 #endif /* COMPAT_43 */
 
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index b39f2bfd4c4..b9a54f030d0 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -316,6 +316,10 @@ extern int kern_logsigexit;	/* Sysctl variable kern.logsigexit */
 #define	SIG_STOP_ALLOWED	100
 #define	SIG_STOP_NOT_ALLOWED	101
 
+/* flags for kern_sigprocmask */
+#define	SIGPROCMASK_OLD		0x0001
+#define	SIGPROCMASK_PROC_LOCKED	0x0002
+
 /*
  * Machine-independent functions:
  */
@@ -359,7 +363,8 @@ void	sigqueue_delete_stopmask_proc(struct proc *);
 void	sigqueue_take(ksiginfo_t *ksi);
 int	kern_sigtimedwait(struct thread *, sigset_t,
 		ksiginfo_t *, struct timespec *);
-
+int	kern_sigprocmask(struct thread *td, int how,
+	    sigset_t *set, sigset_t *oset, int flags);
 /*
  * Machine-dependent functions:
  */
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index e1c83ccebb2..c3898733533 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -190,8 +190,6 @@ int	kern_shmctl(struct thread *td, int shmid, int cmd, void *buf,
 int	kern_sigaction(struct thread *td, int sig, struct sigaction *act,
 	    struct sigaction *oact, int flags);
 int	kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);
-int	kern_sigprocmask(struct thread *td, int how,
-	    sigset_t *set, sigset_t *oset, int old);
 int	kern_sigsuspend(struct thread *td, sigset_t mask);
 int	kern_stat(struct thread *td, char *path, enum uio_seg pathseg,
 	    struct stat *sbp);

From d6e029adbef6c202441fc41b455610b4cc906ca5 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 10:47:58 +0000
Subject: [PATCH 373/646] In r197963, a race with thread being selected for
 signal delivery while in kernel mode, and later changing signal mask to block
 the signal, was fixed for sigprocmask(2) and ptread_exit(3). The same race
 exists for sigreturn(2), setcontext(2) and swapcontext(2) syscalls.

Use kern_sigprocmask() instead of direct manipulation of td_sigmask to
reschedule newly blocked signals, closing the race.

Reviewed by:	davidxu
Tested by:	pho
MFC after:	1 month
---
 sys/amd64/amd64/machdep.c             |  8 ++---
 sys/amd64/ia32/ia32_signal.c          | 30 +++++--------------
 sys/amd64/linux32/linux32_sysvec.c    | 18 ++++-------
 sys/arm/arm/machdep.c                 |  7 +----
 sys/compat/freebsd32/freebsd32_misc.c | 23 +++++---------
 sys/i386/i386/machdep.c               | 27 ++++-------------
 sys/i386/linux/linux_sysvec.c         | 18 ++++-------
 sys/ia64/ia64/machdep.c               |  8 +----
 sys/kern/kern_context.c               | 12 +++-----
 sys/kern/kern_sig.c                   | 43 ++++++++++++++-------------
 sys/mips/mips/pm_machdep.c            | 13 +++-----
 sys/pc98/pc98/machdep.c               | 27 ++++-------------
 sys/powerpc/aim/machdep.c             |  8 +----
 sys/powerpc/booke/machdep.c           |  8 +----
 sys/sparc64/sparc64/machdep.c         |  6 +---
 sys/sun4v/sun4v/machdep.c             |  6 +---
 16 files changed, 77 insertions(+), 185 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 95db5d2d605..ebb7805b337 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -415,7 +415,7 @@ sigreturn(td, uap)
 	ucontext_t uc;
 	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const ucontext_t *ucp;
+	ucontext_t *ucp;
 	long rflags;
 	int cs, error, ret;
 	ksiginfo_t ksi;
@@ -478,7 +478,6 @@ sigreturn(td, uap)
 	td->td_pcb->pcb_fsbase = ucp->uc_mcontext.mc_fsbase;
 	td->td_pcb->pcb_gsbase = ucp->uc_mcontext.mc_gsbase;
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (ucp->uc_mcontext.mc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
@@ -486,10 +485,7 @@ sigreturn(td, uap)
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
 
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	td->td_pcb->pcb_flags |= PCB_FULLCTX;
 	td->td_pcb->pcb_full_iret = 1;
 	return (EJUSTRETURN);
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index d7c1dd5c6f9..10ec641bc61 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -244,10 +244,8 @@ freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
 		if (ret == 0) {
 			ret = ia32_set_mcontext(td, &uc.uc_mcontext);
 			if (ret == 0) {
-				SIG_CANTMASK(uc.uc_sigmask);
-				PROC_LOCK(td->td_proc);
-				td->td_sigmask = uc.uc_sigmask;
-				PROC_UNLOCK(td->td_proc);
+				kern_sigprocmask(td, SIG_SETMASK,
+				    &uc.uc_sigmask, NULL, 0);
 			}
 		}
 	}
@@ -273,10 +271,8 @@ freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
 			if (ret == 0) {
 				ret = ia32_set_mcontext(td, &uc.uc_mcontext);
 				if (ret == 0) {
-					SIG_CANTMASK(uc.uc_sigmask);
-					PROC_LOCK(td->td_proc);
-					td->td_sigmask = uc.uc_sigmask;
-					PROC_UNLOCK(td->td_proc);
+					kern_sigprocmask(td, SIG_SETMASK,
+					    &uc.uc_sigmask, NULL, 0);
 				}
 			}
 		}
@@ -544,9 +540,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
 	} */ *uap;
 {
 	struct ia32_ucontext4 uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const struct ia32_ucontext4 *ucp;
+	struct ia32_ucontext4 *ucp;
 	int cs, eflags, error;
 	ksiginfo_t ksi;
 
@@ -610,11 +605,7 @@ freebsd4_freebsd32_sigreturn(td, uap)
 	regs->tf_fs = ucp->uc_mcontext.mc_fs;
 	regs->tf_gs = ucp->uc_mcontext.mc_gs;
 
-	PROC_LOCK(p);
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	td->td_pcb->pcb_full_iret = 1;
 	return (EJUSTRETURN);
 }
@@ -631,9 +622,8 @@ freebsd32_sigreturn(td, uap)
 	} */ *uap;
 {
 	struct ia32_ucontext uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const struct ia32_ucontext *ucp;
+	struct ia32_ucontext *ucp;
 	int cs, eflags, error, ret;
 	ksiginfo_t ksi;
 
@@ -702,11 +692,7 @@ freebsd32_sigreturn(td, uap)
 	regs->tf_gs = ucp->uc_mcontext.mc_gs;
 	regs->tf_flags = TF_HASSEGS;
 
-	PROC_LOCK(p);
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	td->td_pcb->pcb_full_iret = 1;
 	return (EJUSTRETURN);
 }
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index 54a04eea581..6e3e32622bf 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -565,9 +565,9 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 int
 linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 {
-	struct proc *p = td->td_proc;
 	struct l_sigframe frame;
 	struct trapframe *regs;
+	sigset_t bmask;
 	l_sigset_t lmask;
 	int eflags, i;
 	ksiginfo_t ksi;
@@ -623,11 +623,8 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 	lmask.__bits[0] = frame.sf_sc.sc_mask;
 	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
 		lmask.__bits[i+1] = frame.sf_extramask[i];
-	PROC_LOCK(p);
-	linux_to_bsd_sigset(&lmask, &td->td_sigmask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	linux_to_bsd_sigset(&lmask, &bmask);
+	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
 
 	/*
 	 * Restore signal context.
@@ -666,9 +663,9 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 int
 linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
 {
-	struct proc *p = td->td_proc;
 	struct l_ucontext uc;
 	struct l_sigcontext *context;
+	sigset_t bmask;
 	l_stack_t *lss;
 	stack_t ss;
 	struct trapframe *regs;
@@ -725,11 +722,8 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
 		return(EINVAL);
 	}
 
-	PROC_LOCK(p);
-	linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	linux_to_bsd_sigset(&uc.uc_sigmask, &bmask);
+	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
 
 	/*
 	 * Restore signal context
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 597cdf54106..f49319e50b9 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -605,7 +605,6 @@ sigreturn(td, uap)
 		const struct __ucontext *sigcntxp;
 	} */ *uap;
 {
-	struct proc *p = td->td_proc;
 	struct sigframe sf;
 	struct trapframe *tf;
 	int spsr;
@@ -627,11 +626,7 @@ sigreturn(td, uap)
 	set_mcontext(td, &sf.sf_uc.uc_mcontext);
 
 	/* Restore signal mask. */
-	PROC_LOCK(p);
-	td->td_sigmask = sf.sf_uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &sf.sf_uc.uc_sigmask, NULL, 0);
 
 	return (EJUSTRETURN);
 }
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 9f6b16defad..37fa07964e4 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2482,7 +2482,7 @@ ofreebsd32_sigprocmask(struct thread *td,
 	int error;
 
 	OSIG2SIG(uap->mask, set);
-	error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
+	error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD);
 	SIG2OSIG(oset, td->td_retval[0]);
 	return (error);
 }
@@ -2546,15 +2546,11 @@ int
 ofreebsd32_sigblock(struct thread *td,
 			    struct ofreebsd32_sigblock_args *uap)
 {
-	struct proc *p = td->td_proc;
-	sigset_t set;
+	sigset_t set, oset;
 
 	OSIG2SIG(uap->mask, set);
-	SIG_CANTMASK(set);
-	PROC_LOCK(p);
-	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
-	SIGSETOR(td->td_sigmask, set);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
+	SIG2OSIG(oset, td->td_retval[0]);
 	return (0);
 }
 
@@ -2562,16 +2558,11 @@ int
 ofreebsd32_sigsetmask(struct thread *td,
 			      struct ofreebsd32_sigsetmask_args *uap)
 {
-	struct proc *p = td->td_proc;
-	sigset_t set;
+	sigset_t set, oset;
 
 	OSIG2SIG(uap->mask, set);
-	SIG_CANTMASK(set);
-	PROC_LOCK(p);
-	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
-	SIGSETLO(td->td_sigmask, set);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
+	SIG2OSIG(oset, td->td_retval[0]);
 	return (0);
 }
 
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 96c8f25704e..5c294eb35c1 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -756,7 +756,6 @@ osigreturn(td, uap)
 	struct osigcontext sc;
 	struct trapframe *regs;
 	struct osigcontext *scp;
-	struct proc *p = td->td_proc;
 	int eflags, error;
 	ksiginfo_t ksi;
 
@@ -856,17 +855,14 @@ osigreturn(td, uap)
 	regs->tf_eip = scp->sc_pc;
 	regs->tf_eflags = eflags;
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (scp->sc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
-	SIGSETOLD(td->td_sigmask, scp->sc_mask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, (sigset_t *)&scp->sc_mask, NULL,
+	    SIGPROCMASK_OLD);
 	return (EJUSTRETURN);
 }
 #endif /* COMPAT_43 */
@@ -883,9 +879,8 @@ freebsd4_sigreturn(td, uap)
 	} */ *uap;
 {
 	struct ucontext4 uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const struct ucontext4 *ucp;
+	struct ucontext4 *ucp;
 	int cs, eflags, error;
 	ksiginfo_t ksi;
 
@@ -973,18 +968,13 @@ freebsd4_sigreturn(td, uap)
 		bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
 	}
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (ucp->uc_mcontext.mc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
-
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	return (EJUSTRETURN);
 }
 #endif	/* COMPAT_FREEBSD4 */
@@ -1000,9 +990,8 @@ sigreturn(td, uap)
 	} */ *uap;
 {
 	ucontext_t uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const ucontext_t *ucp;
+	ucontext_t *ucp;
 	int cs, eflags, error, ret;
 	ksiginfo_t ksi;
 
@@ -1094,7 +1083,6 @@ sigreturn(td, uap)
 		bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
 	}
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (ucp->uc_mcontext.mc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
@@ -1102,10 +1090,7 @@ sigreturn(td, uap)
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
 
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	return (EJUSTRETURN);
 }
 
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index d07f65563d3..069b5bb8572 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -667,10 +667,10 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 int
 linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 {
-	struct proc *p = td->td_proc;
 	struct l_sigframe frame;
 	struct trapframe *regs;
 	l_sigset_t lmask;
+	sigset_t bmask;
 	int eflags, i;
 	ksiginfo_t ksi;
 
@@ -725,11 +725,8 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 	lmask.__bits[0] = frame.sf_sc.sc_mask;
 	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
 		lmask.__bits[i+1] = frame.sf_extramask[i];
-	PROC_LOCK(p);
-	linux_to_bsd_sigset(&lmask, &td->td_sigmask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	linux_to_bsd_sigset(&lmask, &bmask);
+	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
 
 	/*
 	 * Restore signal context.
@@ -767,9 +764,9 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
 int
 linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
 {
-	struct proc *p = td->td_proc;
 	struct l_ucontext uc;
 	struct l_sigcontext *context;
+	sigset_t bmask;
 	l_stack_t *lss;
 	stack_t ss;
 	struct trapframe *regs;
@@ -826,11 +823,8 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
 		return(EINVAL);
 	}
 
-	PROC_LOCK(p);
-	linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	linux_to_bsd_sigset(&uc.uc_sigmask, &bmask);
+	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
 
 	/*
 	 * Restore signal context
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 67ca3c28c49..299c9ec8253 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1056,11 +1056,9 @@ sigreturn(struct thread *td,
 {
 	ucontext_t uc;
 	struct trapframe *tf;
-	struct proc *p;
 	struct pcb *pcb;
 
 	tf = td->td_frame;
-	p = td->td_proc;
 	pcb = td->td_pcb;
 
 	/*
@@ -1072,17 +1070,13 @@ sigreturn(struct thread *td,
 
 	set_mcontext(td, &uc.uc_mcontext);
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (sigonstack(tf->tf_special.sp))
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
-	td->td_sigmask = uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
 
 	return (EJUSTRETURN);
 }
diff --git a/sys/kern/kern_context.c b/sys/kern/kern_context.c
index f951fca4da9..6628eb6b81d 100644
--- a/sys/kern/kern_context.c
+++ b/sys/kern/kern_context.c
@@ -89,10 +89,8 @@ setcontext(struct thread *td, struct setcontext_args *uap)
 		if (ret == 0) {
 			ret = set_mcontext(td, &uc.uc_mcontext);
 			if (ret == 0) {
-				SIG_CANTMASK(uc.uc_sigmask);
-				PROC_LOCK(td->td_proc);
-				td->td_sigmask = uc.uc_sigmask;
-				PROC_UNLOCK(td->td_proc);
+				kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask,
+				    NULL, 0);
 			}
 		}
 	}
@@ -118,10 +116,8 @@ swapcontext(struct thread *td, struct swapcontext_args *uap)
 			if (ret == 0) {
 				ret = set_mcontext(td, &uc.uc_mcontext);
 				if (ret == 0) {
-					SIG_CANTMASK(uc.uc_sigmask);
-					PROC_LOCK(td->td_proc);
-					td->td_sigmask = uc.uc_sigmask;
-					PROC_UNLOCK(td->td_proc);
+					kern_sigprocmask(td, SIG_SETMASK,
+					    &uc.uc_sigmask, NULL, 0);
 				}
 			}
 		}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index a453b555a76..d0249f517db 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1396,15 +1396,11 @@ osigblock(td, uap)
 	register struct thread *td;
 	struct osigblock_args *uap;
 {
-	struct proc *p = td->td_proc;
-	sigset_t set;
+	sigset_t set, oset;
 
 	OSIG2SIG(uap->mask, set);
-	SIG_CANTMASK(set);
-	PROC_LOCK(p);
-	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
-	SIGSETOR(td->td_sigmask, set);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
+	SIG2OSIG(oset, td->td_retval[0]);
 	return (0);
 }
 
@@ -1418,16 +1414,11 @@ osigsetmask(td, uap)
 	struct thread *td;
 	struct osigsetmask_args *uap;
 {
-	struct proc *p = td->td_proc;
-	sigset_t set;
+	sigset_t set, oset;
 
 	OSIG2SIG(uap->mask, set);
-	SIG_CANTMASK(set);
-	PROC_LOCK(p);
-	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
-	SIGSETLO(td->td_sigmask, set);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
+	SIG2OSIG(oset, td->td_retval[0]);
 	return (0);
 }
 #endif /* COMPAT_43 */
@@ -1845,6 +1836,7 @@ void
 trapsignal(struct thread *td, ksiginfo_t *ksi)
 {
 	struct sigacts *ps;
+	sigset_t mask;
 	struct proc *p;
 	int sig;
 	int code;
@@ -1868,8 +1860,11 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
 		(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], 
 				ksi, &td->td_sigmask);
 		SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
-		if (!SIGISMEMBER(ps->ps_signodefer, sig))
-			SIGADDSET(td->td_sigmask, sig);
+		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
+			SIGEMPTYSET(mask);
+			SIGADDSET(mask, sig);
+			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, 0);
+		}
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*
 			 * See kern_sigaction() for origin of this code.
@@ -2683,7 +2678,7 @@ postsig(sig)
 	struct sigacts *ps;
 	sig_t action;
 	ksiginfo_t ksi;
-	sigset_t returnmask;
+	sigset_t returnmask, mask;
 
 	KASSERT(sig != 0, ("postsig"));
 
@@ -2738,9 +2733,15 @@ postsig(sig)
 		} else
 			returnmask = td->td_sigmask;
 
-		SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
-		if (!SIGISMEMBER(ps->ps_signodefer, sig))
-			SIGADDSET(td->td_sigmask, sig);
+		kern_sigprocmask(td, SIG_BLOCK,
+		    &ps->ps_catchmask[_SIG_IDX(sig)], NULL,
+		    SIGPROCMASK_PROC_LOCKED);
+		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
+			SIGEMPTYSET(mask);
+			SIGADDSET(mask, sig);
+			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
+			    SIGPROCMASK_PROC_LOCKED);
+		}
 
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*
diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c
index 9fb1feca3fb..dc30f4cacb7 100644
--- a/sys/mips/mips/pm_machdep.c
+++ b/sys/mips/mips/pm_machdep.c
@@ -213,13 +213,11 @@ int
 sigreturn(struct thread *td, struct sigreturn_args *uap)
 {
 	struct trapframe *regs;
-	const ucontext_t *ucp;
-	struct proc *p;
+	ucontext_t *ucp;
 	ucontext_t uc;
 	int error;
 
 	ucp = &uc;
-	p = td->td_proc;
 
 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
 	if (error != 0)
@@ -229,7 +227,7 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 
 /* #ifdef DEBUG */
 	if (ucp->uc_mcontext.mc_regs[ZERO] != UCONTEXT_MAGIC) {
-		printf("sigreturn: pid %d, ucp %p\n", p->p_pid, ucp);
+		printf("sigreturn: pid %d, ucp %p\n", td->td_proc->p_pid, ucp);
 		printf("  old sp %x ra %x pc %x\n",
 		    regs->sp, regs->ra, regs->pc);
 		printf("  new sp %x ra %x pc %x z %x\n",
@@ -253,11 +251,8 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	regs->mullo = ucp->uc_mcontext.mullo;
 	regs->mulhi = ucp->uc_mcontext.mulhi;
 
-	PROC_LOCK(p);
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
+
 	return(EJUSTRETURN);
 }
 
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index f052ceecb23..f07eb6b95e4 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -686,7 +686,6 @@ osigreturn(td, uap)
 	struct osigcontext sc;
 	struct trapframe *regs;
 	struct osigcontext *scp;
-	struct proc *p = td->td_proc;
 	int eflags, error;
 	ksiginfo_t ksi;
 
@@ -786,17 +785,14 @@ osigreturn(td, uap)
 	regs->tf_eip = scp->sc_pc;
 	regs->tf_eflags = eflags;
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (scp->sc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
-	SIGSETOLD(td->td_sigmask, scp->sc_mask);
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, (sigset_t *)&scp->sc_mask, NULL,
+	    SIGPROCMASK_OLD);
 	return (EJUSTRETURN);
 }
 #endif /* COMPAT_43 */
@@ -813,9 +809,8 @@ freebsd4_sigreturn(td, uap)
 	} */ *uap;
 {
 	struct ucontext4 uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const struct ucontext4 *ucp;
+	struct ucontext4 *ucp;
 	int cs, eflags, error;
 	ksiginfo_t ksi;
 
@@ -903,18 +898,13 @@ freebsd4_sigreturn(td, uap)
 		bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
 	}
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (ucp->uc_mcontext.mc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
-
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 	return (EJUSTRETURN);
 }
 #endif	/* COMPAT_FREEBSD4 */
@@ -930,9 +920,8 @@ sigreturn(td, uap)
 	} */ *uap;
 {
 	ucontext_t uc;
-	struct proc *p = td->td_proc;
 	struct trapframe *regs;
-	const ucontext_t *ucp;
+	ucontext_t *ucp;
 	int cs, eflags, error, ret;
 	ksiginfo_t ksi;
 
@@ -1024,18 +1013,14 @@ sigreturn(td, uap)
 		bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
 	}
 
-	PROC_LOCK(p);
 #if defined(COMPAT_43)
 	if (ucp->uc_mcontext.mc_onstack & 1)
 		td->td_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		td->td_sigstk.ss_flags &= ~SS_ONSTACK;
 #endif
+	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
 
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
 	return (EJUSTRETURN);
 }
 
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index da73dfab3ff..713402e98f1 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -692,7 +692,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 int
 sigreturn(struct thread *td, struct sigreturn_args *uap)
 {
-	struct proc *p;
 	ucontext_t uc;
 	int error;
 
@@ -707,12 +706,7 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	if (error != 0)
 		return (error);
 
-	p = td->td_proc;
-	PROC_LOCK(p);
-	td->td_sigmask = uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
 
 	CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
 	     td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 87870985ac8..1eace0e8e60 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -665,7 +665,6 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
 int
 sigreturn(struct thread *td, struct sigreturn_args *uap)
 {
-	struct proc *p;
 	ucontext_t uc;
 	int error;
 
@@ -680,12 +679,7 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	if (error != 0)
 		return (error);
 
-	p = td->td_proc;
-	PROC_LOCK(p);
-	td->td_sigmask = uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
 
 	CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
 	    td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 49a2bb1c94f..4b55c0ef380 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -653,11 +653,7 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	if (error != 0)
 		return (error);
 
-	PROC_LOCK(p);
-	td->td_sigmask = uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
 
 	CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx",
 	    td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate);
diff --git a/sys/sun4v/sun4v/machdep.c b/sys/sun4v/sun4v/machdep.c
index 5430460ccc7..3913d35ca02 100644
--- a/sys/sun4v/sun4v/machdep.c
+++ b/sys/sun4v/sun4v/machdep.c
@@ -667,11 +667,7 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	if (error != 0)
 		return (error);
 
-	PROC_LOCK(p);
-	td->td_sigmask = uc.uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
 
 	CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx",
 	    td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate);

From 066d836b022fdd90780ba4757bbe8f7b3ffbb5e2 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 10:55:34 +0000
Subject: [PATCH 374/646] Current pselect(3) is implemented in usermode and
 thus vulnerable to well-known race condition, which elimination was the
 reason for the function appearance in first place. If sigmask supplied as
 argument to pselect() enables a signal, the signal might be delivered before
 thread called select(2), causing lost wakeup. Reimplement pselect() in
 kernel, making change of sigmask and sleep atomic.

Since signal shall be delivered to the usermode, but sigmask restored,
set TDP_OLDMASK and save old mask in td_oldsigmask. The TDP_OLDMASK
should be cleared by ast() in case signal was not gelivered during
syscall execution.

Reviewed by:	davidxu
Tested by:	pho
MFC after:	1 month
---
 lib/libc/gen/pselect.c                | 78 ---------------------------
 lib/libc/sys/Symbol.map               |  3 ++
 lib/libthr/thread/thr_syscalls.c      |  4 +-
 sys/compat/freebsd32/freebsd32_misc.c | 35 ++++++++++++
 sys/compat/freebsd32/syscalls.master  |  4 ++
 sys/kern/subr_trap.c                  |  5 ++
 sys/kern/sys_generic.c                | 56 +++++++++++++++++--
 sys/kern/syscalls.master              |  4 ++
 sys/sys/syscallsubr.h                 |  2 +
 9 files changed, 109 insertions(+), 82 deletions(-)
 delete mode 100644 lib/libc/gen/pselect.c

diff --git a/lib/libc/gen/pselect.c b/lib/libc/gen/pselect.c
deleted file mode 100644
index 28066a204aa..00000000000
--- a/lib/libc/gen/pselect.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2000 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that both the above copyright notice and this
- * permission notice appear in all copies, that both the above
- * copyright notice and this permission notice appear in all
- * supporting documentation, and that the name of M.I.T. not be used
- * in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.  M.I.T. makes
- * no representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied
- * warranty.
- *
- * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
- * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
- * SHALL M.I.T. 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.
- */
-
-#include 
-__FBSDID("$FreeBSD$");
-
-#include "namespace.h"
-#include 
-#include 
-
-#include 
-#include 
-#include "un-namespace.h"
-
-__weak_reference(__pselect, pselect);
-
-/*
- * Emulate the POSIX 1003.1g-2000 `pselect' interface.  This is the
- * same as the traditional BSD `select' function, except that it uses
- * a timespec rather than a timeval, doesn't modify the timeout argument,
- * and allows the user to specify a signal mask to apply during the select.
- */
-int
-__pselect(int count, fd_set * __restrict rfds, fd_set * __restrict wfds, 
-	fd_set * __restrict efds, const struct timespec * __restrict timo, 
-	const sigset_t * __restrict mask)
-{
-	sigset_t omask;
-	struct timeval tvtimo, *tvp;
-	int rv, sverrno;
-
-	if (timo) {
-		TIMESPEC_TO_TIMEVAL(&tvtimo, timo);
-		tvp = &tvtimo;
-	} else
-		tvp = 0;
-
-	if (mask != 0) {
-		rv = _sigprocmask(SIG_SETMASK, mask, &omask);
-		if (rv != 0)
-			return rv;
-	}
-
-	rv = _select(count, rfds, wfds, efds, tvp);
-	if (mask != 0) {
-		sverrno = errno;
-		_sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
-		errno = sverrno;
-	}
-
-	return rv;
-}
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index c834a25e948..ce6f32a675c 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -211,6 +211,7 @@ FBSD_1.0 {
 	posix_openpt;
 	preadv;
 	profil;
+	pselect;
 	ptrace;
 	pwritev;
 	quotactl;
@@ -781,6 +782,8 @@ FBSDprivate_1.0 {
 	__sys_preadv;
 	_profil;
 	__sys_profil;
+	_pselect;
+	__sys_pselect;
 	_ptrace;
 	__sys_ptrace;
 	_pwritev;
diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c
index d05d68b2e3b..92670a9a77a 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -104,6 +104,8 @@ extern int	__sys_accept(int, struct sockaddr *, socklen_t *);
 extern int	__sys_connect(int, const struct sockaddr *, socklen_t);
 extern int	__sys_fsync(int);
 extern int	__sys_msync(void *, size_t, int);
+extern int	__sys_pselect(int, fd_set *, fd_set *, fd_set *,
+			const struct timespec *, const sigset_t *);
 extern int	__sys_poll(struct pollfd *, unsigned, int);
 extern ssize_t	__sys_recv(int, void *, size_t, int);
 extern ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
@@ -394,7 +396,7 @@ ___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
 	int ret;
 
 	_thr_cancel_enter(curthread);
-	ret = __pselect(count, rfds, wfds, efds, timo, mask);
+	ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
 	_thr_cancel_leave(curthread);
 
 	return (ret);
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 37fa07964e4..75b290b365f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -593,6 +593,41 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
 	    sizeof(int32_t) * 8));
 }
 
+int
+freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
+{
+	struct timespec32 ts32;
+	struct timespec ts;
+	struct timeval tv, *tvp;
+	sigset_t set, *uset;
+	int error;
+
+	if (uap->ts != NULL) {
+		error = copyin(uap->ts, &ts32, sizeof(ts32));
+		if (error != 0)
+			return (error);
+		CP(ts32, ts, tv_sec);
+		CP(ts32, ts, tv_nsec);
+		TIMESPEC_TO_TIMEVAL(&tv, &ts);
+		tvp = &tv;
+	} else
+		tvp = NULL;
+	if (uap->sm != NULL) {
+		error = copyin(uap->sm, &set, sizeof(set));
+		if (error != 0)
+			return (error);
+		uset = &set;
+	} else
+		uset = NULL;
+	/*
+	 * XXX big-endian needs to convert the fd_sets too.
+	 * XXX Do pointers need PTRIN()?
+	 */
+	error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
+	    uset, sizeof(int32_t) * 8);
+	return (error);
+}
+
 /*
  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  */
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 833b1e5272d..865f0c1ea1c 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -909,3 +909,7 @@
 519	AUE_PDKILL	UNIMPL	pdkill
 520	AUE_PDGETPID	UNIMPL	pdgetpid
 521	AUE_PDWAIT	UNIMPL	pdwait
+522	AUE_SELECT	STD	{ int freebsd32_pselect(int nd, fd_set *in, \
+				    fd_set *ou, fd_set *ex, \
+				    const struct timespec32 *ts, \
+				    const sigset_t *sm); }
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index ccf64791e15..4d20ebdc1ce 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -245,6 +245,11 @@ ast(struct trapframe *framep)
 		PROC_UNLOCK(p);
 	}
 
+	if (td->td_pflags & TDP_OLDMASK) {
+		td->td_pflags &= ~TDP_OLDMASK;
+		kern_sigprocmask(td, SIG_SETMASK, &td->td_oldsigmask, NULL, 0);
+	}
+
 	userret(td, framep);
 	mtx_assert(&Giant, MA_NOTOWNED);
 }
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 6831fe8d8ca..b34af613237 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -751,6 +751,58 @@ poll_no_poll(int events)
 	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
 }
 
+int
+pselect(struct thread *td, struct pselect_args *uap)
+{
+	struct timespec ts;
+	struct timeval tv, *tvp;
+	sigset_t set, *uset;
+	int error;
+
+	if (uap->ts != NULL) {
+		error = copyin(uap->ts, &ts, sizeof(ts));
+		if (error != 0)
+		    return (error);
+		TIMESPEC_TO_TIMEVAL(&tv, &ts);
+		tvp = &tv;
+	} else
+		tvp = NULL;
+	if (uap->sm != NULL) {
+		error = copyin(uap->sm, &set, sizeof(set));
+		if (error != 0)
+			return (error);
+		uset = &set;
+	} else
+		uset = NULL;
+	return (kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
+	    uset, NFDBITS));
+}
+
+int
+kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, fd_set *ex,
+    struct timeval *tvp, sigset_t *uset, int abi_nfdbits)
+{
+	int error;
+
+	if (uset != NULL) {
+		error = kern_sigprocmask(td, SIG_SETMASK, uset,
+		    &td->td_oldsigmask, 0);
+		if (error != 0)
+			return (error);
+		td->td_pflags |= TDP_OLDMASK;
+		/*
+		 * Make sure that ast() is called on return to
+		 * usermode and TDP_OLDMASK is cleared, restoring old
+		 * sigmask.
+		 */
+		thread_lock(td);
+		td->td_flags |= TDF_ASTPENDING;
+		thread_unlock(td);
+	}
+	error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
+	return (error);
+}
+
 #ifndef _SYS_SYSPROTO_H_
 struct select_args {
 	int	nd;
@@ -759,9 +811,7 @@ struct select_args {
 };
 #endif
 int
-select(td, uap)
-	register struct thread *td;
-	register struct select_args *uap;
+select(struct thread *td, struct select_args *uap)
 {
 	struct timeval tv, *tvp;
 	int error;
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index f96ed790afb..ac64a75c5f8 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -919,5 +919,9 @@
 519	AUE_PDKILL	UNIMPL	pdkill
 520	AUE_PDGETPID	UNIMPL	pdgetpid
 521	AUE_PDWAIT	UNIMPL	pdwait
+522	AUE_SELECT	STD	{ int pselect(int nd, fd_set *in, \
+				    fd_set *ou, fd_set *ex, \
+				    const struct timespec *ts, \
+				    const sigset_t *sm); }
 ; Please copy any additions and changes to the following compatability tables:
 ; sys/compat/freebsd32/syscalls.master
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index c3898733533..2813a58d26e 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -148,6 +148,8 @@ int	kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
 	    int name, u_long flags);
 int	kern_pipe(struct thread *td, int fildes[2]);
 int	kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset);
+int	kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou,
+	    fd_set *ex, struct timeval *tvp, sigset_t *uset, int abi_nfdbits);
 int	kern_ptrace(struct thread *td, int req, pid_t pid, void *addr,
 	    int data);
 int	kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset);

From 6de630f92520dda64a78f69c1600cdd595d5cb05 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 10:57:53 +0000
Subject: [PATCH 375/646] Commit libc files missed in r198508

---
 lib/libc/gen/Makefile.inc | 2 +-
 lib/libc/gen/Symbol.map   | 2 --
 lib/libc/gen/pselect.3    | 5 -----
 3 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index dd9af85c637..e5ca3fac8b5 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -21,7 +21,7 @@ SRCS+=  __getosreldate.c __xuname.c \
 	initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
 	lockf.c lrand48.c mrand48.c nftw.c nice.c \
 	nlist.c nrand48.c opendir.c \
-	pause.c pmadvise.c popen.c posix_spawn.c pselect.c \
+	pause.c pmadvise.c popen.c posix_spawn.c \
 	psignal.c pw_scan.c pwcache.c \
 	raise.c readdir.c readpassphrase.c rewinddir.c \
 	scandir.c seed48.c seekdir.c sem.c semctl.c \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 6fb61b18baf..a3ea75b0b01 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -223,7 +223,6 @@ FBSD_1.0 {
 	posix_madvise;
 	popen;
 	pclose;
-	pselect;
 	psignal;
 	raise;
 	readdir;
@@ -454,7 +453,6 @@ FBSDprivate_1.0 {
 	__opendir2;
 	__pause;
 	_pause;
-	__pselect;
 	__pw_scan;	/* Used by (at least) libutil */
 	__raise;
 	_raise;
diff --git a/lib/libc/gen/pselect.3 b/lib/libc/gen/pselect.3
index a56a0a80a88..8e306d6c245 100644
--- a/lib/libc/gen/pselect.3
+++ b/lib/libc/gen/pselect.3
@@ -88,11 +88,6 @@ for a more detailed discussion of the semantics of this interface, and
 for macros used to manipulate the
 .Vt "fd_set"
 data type.
-.Sh IMPLEMENTATION NOTES
-The
-.Fn pselect
-function is implemented in the C library as a wrapper around
-.Fn select .
 .Sh RETURN VALUES
 The
 .Fn pselect

From 17c974499c14beef374279dbc0a8c9741480aaa2 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 11:01:15 +0000
Subject: [PATCH 376/646] Regenerate

---
 sys/kern/init_sysent.c   |  3 ++-
 sys/kern/syscalls.c      |  3 ++-
 sys/kern/systrace_args.c | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 2e329a8d822..1463aede612 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/kern/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #include "opt_compat.h"
@@ -556,4 +556,5 @@ struct sysent sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 519 = pdkill */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 520 = pdgetpid */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 521 = pdwait */
+	{ AS(pselect_args), (sy_call_t *)pselect, AUE_SELECT, NULL, 0, 0, 0 },	/* 522 = pselect */
 };
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 1017c744b10..39211997a0b 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/kern/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 const char *syscallnames[] = {
@@ -529,4 +529,5 @@ const char *syscallnames[] = {
 	"#519",			/* 519 = pdkill */
 	"#520",			/* 520 = pdgetpid */
 	"#521",			/* 521 = pdwait */
+	"pselect",			/* 522 = pselect */
 };
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
index e8d6bc34acb..9cbb4b1bb9c 100644
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -3072,6 +3072,18 @@ systrace_args(int sysnum, void *params, u_int64_t *uarg, int *n_args)
 		*n_args = 2;
 		break;
 	}
+	/* pselect */
+	case 522: {
+		struct pselect_args *p = params;
+		iarg[0] = p->nd; /* int */
+		uarg[1] = (intptr_t) p->in; /* fd_set * */
+		uarg[2] = (intptr_t) p->ou; /* fd_set * */
+		uarg[3] = (intptr_t) p->ex; /* fd_set * */
+		uarg[4] = (intptr_t) p->ts; /* const struct timespec * */
+		uarg[5] = (intptr_t) p->sm; /* const sigset_t * */
+		*n_args = 6;
+		break;
+	}
 	default:
 		*n_args = 0;
 		break;
@@ -8154,6 +8166,31 @@ systrace_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
 			break;
 		};
 		break;
+	/* pselect */
+	case 522:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "fd_set *";
+			break;
+		case 2:
+			p = "fd_set *";
+			break;
+		case 3:
+			p = "fd_set *";
+			break;
+		case 4:
+			p = "const struct timespec *";
+			break;
+		case 5:
+			p = "const sigset_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	default:
 		break;
 	};

From 550ca2a8a3ce6d5f96644e1082d2f0c2ec680815 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 11:01:40 +0000
Subject: [PATCH 377/646] Regenerate

---
 sys/sys/syscall.h  |  5 +++--
 sys/sys/syscall.mk |  5 +++--
 sys/sys/sysproto.h | 12 +++++++++++-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index c14a6433205..865107a560d 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/kern/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #define	SYS_syscall	0
@@ -428,4 +428,5 @@
 #define	SYS_msgctl	511
 #define	SYS_shmctl	512
 #define	SYS_lpathconf	513
-#define	SYS_MAXSYSCALL	522
+#define	SYS_pselect	522
+#define	SYS_MAXSYSCALL	523
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index 3d4fb5f386e..4953adc11d7 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -1,7 +1,7 @@
 # FreeBSD system call names.
 # DO NOT EDIT-- this file is automatically generated.
 # $FreeBSD$
-# created from FreeBSD: head/sys/kern/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+# created from FreeBSD: head/sys/kern/syscalls.master 198508 2009-10-27 10:55:34Z kib 
 MIASM =  \
 	syscall.o \
 	exit.o \
@@ -376,4 +376,5 @@ MIASM =  \
 	__semctl.o \
 	msgctl.o \
 	shmctl.o \
-	lpathconf.o
+	lpathconf.o \
+	pselect.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 52e342d0d4b..a97a0aee6f2 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/kern/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #ifndef _SYS_SYSPROTO_H_
@@ -1641,6 +1641,14 @@ struct lpathconf_args {
 	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
 	char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)];
 };
+struct pselect_args {
+	char nd_l_[PADL_(int)]; int nd; char nd_r_[PADR_(int)];
+	char in_l_[PADL_(fd_set *)]; fd_set * in; char in_r_[PADR_(fd_set *)];
+	char ou_l_[PADL_(fd_set *)]; fd_set * ou; char ou_r_[PADR_(fd_set *)];
+	char ex_l_[PADL_(fd_set *)]; fd_set * ex; char ex_r_[PADR_(fd_set *)];
+	char ts_l_[PADL_(const struct timespec *)]; const struct timespec * ts; char ts_r_[PADR_(const struct timespec *)];
+	char sm_l_[PADL_(const sigset_t *)]; const sigset_t * sm; char sm_r_[PADR_(const sigset_t *)];
+};
 int	nosys(struct thread *, struct nosys_args *);
 void	sys_exit(struct thread *, struct sys_exit_args *);
 int	fork(struct thread *, struct fork_args *);
@@ -1999,6 +2007,7 @@ int	__semctl(struct thread *, struct __semctl_args *);
 int	msgctl(struct thread *, struct msgctl_args *);
 int	shmctl(struct thread *, struct shmctl_args *);
 int	lpathconf(struct thread *, struct lpathconf_args *);
+int	pselect(struct thread *, struct pselect_args *);
 
 #ifdef COMPAT_43
 
@@ -2671,6 +2680,7 @@ int	freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
 #define	SYS_AUE_msgctl	AUE_MSGCTL
 #define	SYS_AUE_shmctl	AUE_SHMCTL
 #define	SYS_AUE_lpathconf	AUE_LPATHCONF
+#define	SYS_AUE_pselect	AUE_SELECT
 
 #undef PAD_
 #undef PADL_

From 063e9958a6f1708542780495c1b08d9e95622ac6 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 27 Oct 2009 11:02:04 +0000
Subject: [PATCH 378/646] Regenerate

---
 sys/compat/freebsd32/freebsd32_proto.h    | 12 +++++++++++-
 sys/compat/freebsd32/freebsd32_syscall.h  |  5 +++--
 sys/compat/freebsd32/freebsd32_syscalls.c |  3 ++-
 sys/compat/freebsd32/freebsd32_sysent.c   |  3 ++-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h
index 53c35661bf0..6960d6709d6 100644
--- a/sys/compat/freebsd32/freebsd32_proto.h
+++ b/sys/compat/freebsd32/freebsd32_proto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #ifndef _FREEBSD32_SYSPROTO_H_
@@ -453,6 +453,14 @@ struct freebsd32_shmctl_args {
 	char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
 	char buf_l_[PADL_(struct shmid_ds32 *)]; struct shmid_ds32 * buf; char buf_r_[PADR_(struct shmid_ds32 *)];
 };
+struct freebsd32_pselect_args {
+	char nd_l_[PADL_(int)]; int nd; char nd_r_[PADR_(int)];
+	char in_l_[PADL_(fd_set *)]; fd_set * in; char in_r_[PADR_(fd_set *)];
+	char ou_l_[PADL_(fd_set *)]; fd_set * ou; char ou_r_[PADR_(fd_set *)];
+	char ex_l_[PADL_(fd_set *)]; fd_set * ex; char ex_r_[PADR_(fd_set *)];
+	char ts_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * ts; char ts_r_[PADR_(const struct timespec32 *)];
+	char sm_l_[PADL_(const sigset_t *)]; const sigset_t * sm; char sm_r_[PADR_(const sigset_t *)];
+};
 int	freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *);
 int	freebsd32_recvmsg(struct thread *, struct freebsd32_recvmsg_args *);
 int	freebsd32_sendmsg(struct thread *, struct freebsd32_sendmsg_args *);
@@ -536,6 +544,7 @@ int	freebsd32_jail_set(struct thread *, struct freebsd32_jail_set_args *);
 int	freebsd32_semctl(struct thread *, struct freebsd32_semctl_args *);
 int	freebsd32_msgctl(struct thread *, struct freebsd32_msgctl_args *);
 int	freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *);
+int	freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *);
 
 #ifdef COMPAT_43
 
@@ -814,6 +823,7 @@ int	freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
 #define	FREEBSD32_SYS_AUE_freebsd32_semctl	AUE_SEMCTL
 #define	FREEBSD32_SYS_AUE_freebsd32_msgctl	AUE_MSGCTL
 #define	FREEBSD32_SYS_AUE_freebsd32_shmctl	AUE_SHMCTL
+#define	FREEBSD32_SYS_AUE_freebsd32_pselect	AUE_SELECT
 
 #undef PAD_
 #undef PADL_
diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
index d40842b29c8..49006ef78e6 100644
--- a/sys/compat/freebsd32/freebsd32_syscall.h
+++ b/sys/compat/freebsd32/freebsd32_syscall.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #define	FREEBSD32_SYS_syscall	0
@@ -382,4 +382,5 @@
 #define	FREEBSD32_SYS_freebsd32_msgctl	511
 #define	FREEBSD32_SYS_freebsd32_shmctl	512
 #define	FREEBSD32_SYS_lpathconf	513
-#define	FREEBSD32_SYS_MAXSYSCALL	522
+#define	FREEBSD32_SYS_freebsd32_pselect	522
+#define	FREEBSD32_SYS_MAXSYSCALL	523
diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
index aff77356737..76196eb340c 100644
--- a/sys/compat/freebsd32/freebsd32_syscalls.c
+++ b/sys/compat/freebsd32/freebsd32_syscalls.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 const char *freebsd32_syscallnames[] = {
@@ -529,4 +529,5 @@ const char *freebsd32_syscallnames[] = {
 	"#519",			/* 519 = pdkill */
 	"#520",			/* 520 = pdgetpid */
 	"#521",			/* 521 = pdwait */
+	"freebsd32_pselect",			/* 522 = freebsd32_pselect */
 };
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
index cc0dfe353df..bd99e91dd39 100644
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 197636 2009-09-30 08:46:01Z rwatson 
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 198508 2009-10-27 10:55:34Z kib 
  */
 
 #include "opt_compat.h"
@@ -566,4 +566,5 @@ struct sysent freebsd32_sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 519 = pdkill */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 520 = pdgetpid */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 521 = pdwait */
+	{ AS(freebsd32_pselect_args), (sy_call_t *)freebsd32_pselect, AUE_SELECT, NULL, 0, 0, 0 },	/* 522 = freebsd32_pselect */
 };

From 4413fcc65aadb77d7922e45a40659217b3f5537e Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Tue, 27 Oct 2009 11:08:24 +0000
Subject: [PATCH 379/646] Vendor import of tzdata2009p

- Argentina will not go in DST this year.

Obtained from:	ftp://elsie.nci.nih.gov/pub/
---
 southamerica | 90 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 51 insertions(+), 39 deletions(-)

diff --git a/southamerica b/southamerica
index 562dfdf2c69..9c4edcb7ceb 100644
--- a/southamerica
+++ b/southamerica
@@ -1,5 +1,5 @@
 # 
-# @(#)southamerica	8.37
+# @(#)southamerica	8.40
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -215,9 +215,23 @@ Rule	Arg	2000	only	-	Mar	3	0:00	0	-
 # http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
 # 
 
+# From fullinet (2009-10-18):
+# As announced in
+# 
+# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
+# 
+# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
+#
+# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
+# oficial, decision que estaba en estudio para su implementacion el
+# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
+# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
+# la modificacion del huso horario, ya que 2009 nos encuentra con
+# crecimiento en la produccion y distribucion energetica."
+
 Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
-Rule	Arg	2008	max	-	Mar	Sun>=15	0:00	0	-
-Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
+Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
  
 # From Mariano Absatz (2004-05-21):
 # Today it was officially published that the Province of Mendoza is changing
@@ -389,44 +403,39 @@ Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
 # during 2009, this timezone change will run from 00:00 the third Sunday
 # in March until 24:00 of the second Saturday in October.
 
-# From Arthur David Olson (2009-03-16):
-# The unofficial claim at
-# 
-# http://www.timeanddate.com/news/time/san-luis-new-time-zone.html
-# 
-# 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 Ros) are opposing to the
-# Daylight Saving Time for the 2009-2010 season.
+# From Mariano Absatz (2009-10-16):
+# ...the Province of San Luis is a case in itself.
 #
-# (Spanish)
-# "El cambio de huso horario en Entre Ros deber ser aprobado por la
-# Legislatura":
-# 
-# http://www.analisisdigital.com.ar/noticias.php?ed=1&di=0&no=110168
+# The Law at
+# 
-# English translation - "The time zone change in Entre Rios must be approved by
-# the Legislature."
+# is ambiguous because establishes a calendar from the 2nd Sunday in
+# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
+# complement of that starting on the 2nd Sunday of March at 0:00 and
+# ending on the 2nd Saturday of March at 24:00.
 #
-# (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"
+# This clearly breaks every time the 1st of March or October is a Sunday.
 #
-# 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").
+# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
+# Sunday of October and March.
+#
+# The problem is that the changes in the rest of the Provinces that did
+# change in 2007/2008, were made according to the Federal Law and Decrees
+# that did so on the 3rd Sunday of October and March.
+#
+# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
+# (October 11th) at 0:00.
+#
+# So I guess a new set of rules, besides "Arg", must be made and the last
+# America/Argentina/San_Luis entries should change to use these...
+#
+# I'm enclosing a patch that does what I say... regretfully, the San Luis
+# timezone must be called "WART/WARST" even when most of the time (like,
+# right now) WARST == ART... that is, since last Sunday, all the country
+# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
+# of the country calls it "ART".
+# ...
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
@@ -560,6 +569,10 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
 			-3:00	-	ART
 #
 # San Luis (SL)
+
+Rule	SanLuis	2008	max	-	Mar	Sun>=8	0:00	0	-
+Rule	SanLuis	2007	max	-	Oct	Sun>=8	0:00	1:00	S
+
 Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-4:16:48 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
@@ -574,8 +587,7 @@ Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-3:00	-	ART	2004 May 31
 			-4:00	-	WART	2004 Jul 25
 			-3:00	Arg	AR%sT	2008 Jan 21
-			-3:00	-	ART	2009 Mar 15
-			-4:00	Arg	WAR%sT
+			-4:00	SanLuis	WAR%sT
 #
 # Santa Cruz (SC)
 Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31

From e04cb6afe4efbc9dd4cce620fd946c8fb1dfc04f Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Tue, 27 Oct 2009 14:37:25 +0000
Subject: [PATCH 380/646] Add link for callout_schedule(9).

---
 share/man/man9/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 072827a2e0f..09df65b649e 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1222,6 +1222,7 @@ MLINKS+=timeout.9 callout.9 \
 	timeout.9 callout_init_rw.9 \
 	timeout.9 callout_pending.9 \
 	timeout.9 callout_reset.9 \
+	timeout.9 callout_schedule.9 \
 	timeout.9 callout_stop.9 \
 	timeout.9 untimeout.9
 MLINKS+=ucred.9 crcopy.9 \

From e4bd91445e49f19ef93ac2a79bb7b88f7c80e056 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Tue, 27 Oct 2009 17:12:59 +0000
Subject: [PATCH 381/646] Don't ignore the return value of g_modevent() in
 acd_modevent().

Approved by:	trasz (mentor)
---
 sys/dev/ata/atapi-cd.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 2791826eb98..7e23db6956e 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -1905,8 +1905,7 @@ static devclass_t acd_devclass;
 static int
 acd_modevent(module_t mod, int what, void *arg)  
 {
-    g_modevent(0, what, &acd_class);
-    return 0;
+    return g_modevent(0, what, &acd_class);
 }
  
 DRIVER_MODULE(acd, ata, acd_driver, acd_devclass, acd_modevent, NULL);

From 0c73f68bb6188deba447936149400142812cfb24 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Tue, 27 Oct 2009 17:14:22 +0000
Subject: [PATCH 382/646] Don't ignore the return value of g_modevent() in
 fdc_modevent().

Approved by:	trasz (mentor)
---
 sys/dev/fdc/fdc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index b2145cd0074..3ff31fd7c3b 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -2068,8 +2068,7 @@ static int
 fdc_modevent(module_t mod, int type, void *data)
 {
 
-	g_modevent(NULL, type, &g_fd_class);
-	return (0);
+	return (g_modevent(NULL, type, &g_fd_class));
 }
 
 DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, fdc_modevent, 0);

From 613628c4d80c6211fed873bf7ddba089285eb59f Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Tue, 27 Oct 2009 17:22:03 +0000
Subject: [PATCH 383/646] Fix typos and mdoc style.

---
 share/man/man4/iwn.4 | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4
index 0f0a97eadfe..1edb425c696 100644
--- a/share/man/man4/iwn.4
+++ b/share/man/man4/iwn.4
@@ -42,7 +42,8 @@ kernel configuration file:
 .Cd "device firmware"
 .Ed
 .Pp
-You also need to select a firmware for your device. Chose one from:
+You also need to select a firmware for your device.
+Choose one from:
 .Bd -ragged -offset indent
 .Cd "device iwn4965fw"
 .Cd "device iwn5000fw"
@@ -57,7 +58,7 @@ Or you can use
 to include them all.
 .Pp
 Alternatively, to load the driver as a
-module at boot time, place the following line in
+module at boot time, place the following lines in
 .Xr loader.conf 5 :
 .Bd -literal -offset indent
 if_iwn_load="YES"

From d18f7e0a983947323ba60c2815ec92db0059e9e0 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Tue, 27 Oct 2009 18:17:07 +0000
Subject: [PATCH 384/646] Bugfix: Use formula from section 7.2.3 of RFC 4960.
 Reported by Martin Becke.

Approved by: rrs (mentor)
MFC after: 3 days
---
 sys/netinet/sctp_cc_functions.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet/sctp_cc_functions.c b/sys/netinet/sctp_cc_functions.c
index 02fb1a9a907..8beff191628 100644
--- a/sys/netinet/sctp_cc_functions.c
+++ b/sys/netinet/sctp_cc_functions.c
@@ -348,7 +348,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
 	int old_cwnd = net->cwnd;
 
-	net->ssthresh = max(net->cwnd / 2, 2 * net->mtu);
+	net->ssthresh = max(net->cwnd / 2, 4 * net->mtu);
 	net->cwnd = net->mtu;
 	net->partial_bytes_acked = 0;
 

From b69a64e9c8672255ef79d957158723bb4e8923db Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Tue, 27 Oct 2009 19:37:37 +0000
Subject: [PATCH 385/646] Whitespace fixup: 8 spaces -> tab

---
 sys/dev/aac/aac.c     | 4 ++--
 sys/dev/aac/aac_cam.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 5c3180b8395..d8dec97a1aa 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -229,7 +229,7 @@ static int		aac_query_disk(struct aac_softc *sc, caddr_t uptr);
 static int		aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
 static int		aac_supported_features(struct aac_softc *sc, caddr_t uptr);
 static void		aac_ioctl_event(struct aac_softc *sc,
-				        struct aac_event *event, void *arg);
+					struct aac_event *event, void *arg);
 static struct aac_mntinforesp *
 	aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
 
@@ -3618,7 +3618,7 @@ aac_query_disk(struct aac_softc *sc, caddr_t uptr)
 		query_disk.Lun = 0;
 		query_disk.UnMapped = 0;
 		sprintf(&query_disk.diskDeviceName[0], "%s%d",
-		        disk->ad_disk->d_name, disk->ad_disk->d_unit);
+			disk->ad_disk->d_name, disk->ad_disk->d_unit);
 	}
 	mtx_unlock(&sc->aac_container_lock);
 
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index e38b0ab410b..ddf19f335b8 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -272,10 +272,10 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 		strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 		cpi->unit_number = cam_sim_unit(sim);
-                cpi->transport = XPORT_SPI;
-                cpi->transport_version = 2;
-                cpi->protocol = PROTO_SCSI;
-                cpi->protocol_version = SCSI_REV_2;
+		cpi->transport = XPORT_SPI;
+		cpi->transport_version = 2;
+		cpi->protocol = PROTO_SCSI;
+		cpi->protocol_version = SCSI_REV_2;
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		return;

From 8d5ed6e7174935c6fd7bc25a6e9a58291b75945b Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Wed, 28 Oct 2009 07:05:32 +0000
Subject: [PATCH 386/646] Now that the zoneinfo data is automatically updated
 when a new world is installed, we should at least have the tzsetup tool
 available!

Suggested by:	Andriy Gapon 
Noticed by:	Ben Kaduk 
MFC after:	1 week
---
 Makefile.inc1 | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 3dcba1edb00..591d79f7a09 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -599,11 +599,14 @@ installcheck_UGID:
 .if ${MK_INFO} != "no"
 _install-info=	install-info
 .endif
+.if ${MK_ZONEINFO} != "no"
+_zoneinfo=	zic tzsetup
+.endif
 
 ITOOLS=	[ awk cap_mkdb cat chflags chmod chown \
 	date echo egrep find grep ${_install-info} \
 	ln lockf make mkdir mtree mv pwd_mkdb rm sed sh sysctl \
-	test true uname wc zic
+	test true uname wc ${_zoneinfo}
 
 #
 # distributeworld

From b3fb748ccf0b6fb8da145de78f4cab7bc642bea5 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 10:06:27 +0000
Subject: [PATCH 387/646] Close a file descriptor leak in an error case.

PR:		138374
Submitted by:	Patroklos Argyroudis 
MFC after:	1 week
---
 sys/boot/common/commands.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c
index 0559d1558c4..7fba019153b 100644
--- a/sys/boot/common/commands.c
+++ b/sys/boot/common/commands.c
@@ -150,6 +150,7 @@ command_help(int argc, char *argv[])
 	break;
     default:
 	command_errmsg = "usage is 'help  []";
+	close(hfd);
 	return(CMD_ERROR);
     }
 

From 9a714660ef2d7d0f25d8dbf6d3e38a4ab33b64c4 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 28 Oct 2009 11:14:32 +0000
Subject: [PATCH 388/646] Move pselect(3) man page to section 2.

Noted by:	jhb
MFC after:	1 month
---
 ObsoleteFiles.inc                         | 2 ++
 lib/libc/gen/Makefile.inc                 | 2 +-
 lib/libc/sys/Makefile.inc                 | 3 ++-
 lib/libc/{gen/pselect.3 => sys/pselect.2} | 6 +++---
 4 files changed, 8 insertions(+), 5 deletions(-)
 rename lib/libc/{gen/pselect.3 => sys/pselect.2} (98%)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 359e091bad6..cc4f5f40c9d 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -14,6 +14,8 @@
 # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
 #
 
+# 20091027: pselect.3 implemented as syscall
+OLD_FILES+=usr/share/man/man3/pselect.3.gz
 # 20091005: fusword.9 and susword.9 removed
 OLD_FILES+=usr/share/man/man9/fusword.9.gz
 OLD_FILES+=usr/share/man/man9/susword.9.gz
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index e5ca3fac8b5..0bdee9ddd84 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -62,7 +62,7 @@ MAN+=	alarm.3 arc4random.3 \
 	posix_spawnattr_getpgroup.3 posix_spawnattr_getschedparam.3 \
 	posix_spawnattr_getschedpolicy.3 posix_spawnattr_init.3 \
 	posix_spawnattr_getsigdefault.3 posix_spawnattr_getsigmask.3 \
-	pselect.3 psignal.3 pwcache.3 \
+	psignal.3 pwcache.3 \
 	raise.3 rand48.3 readpassphrase.3 rfork_thread.3 \
 	scandir.3 sem_destroy.3 sem_getvalue.3 sem_init.3 \
 	sem_open.3 sem_post.3 sem_timedwait.3 sem_wait.3 \
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 1e6059da218..1915c550eba 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -83,7 +83,8 @@ MAN+=	abort2.2 accept.2 access.2 acct.2 adjtime.2 \
 	mq_setattr.2 \
 	msgctl.2 msgget.2 msgrcv.2 msgsnd.2 \
 	msync.2 munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 \
-	pathconf.2 pipe.2 poll.2 posix_openpt.2 profil.2 ptrace.2 quotactl.2 \
+	pathconf.2 pipe.2 poll.2 posix_openpt.2 profil.2 \
+	pselect.2 ptrace.2 quotactl.2 \
 	read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \
 	rtprio.2
 .if !defined(NO_P1003_1B)
diff --git a/lib/libc/gen/pselect.3 b/lib/libc/sys/pselect.2
similarity index 98%
rename from lib/libc/gen/pselect.3
rename to lib/libc/sys/pselect.2
index 8e306d6c245..cf784a5dcd7 100644
--- a/lib/libc/gen/pselect.3
+++ b/lib/libc/sys/pselect.2
@@ -28,8 +28,8 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 16, 2002
-.Dt PSELECT 3
+.Dd October 27, 2009
+.Dt PSELECT 2
 .Os
 .Sh NAME
 .Nm pselect
@@ -116,7 +116,7 @@ The
 function first appeared in
 .Fx 5.0 .
 .Sh AUTHORS
-The
+The first implementation of
 .Fn pselect
 function and this manual page were written by
 .An Garrett Wollman Aq wollman@FreeBSD.org .

From 621882f0bc2663510bd7b8375c2f70b859b22256 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 12:10:29 +0000
Subject: [PATCH 389/646] Close a stream file descriptor leak.

PR:		138130
Submitted by:	Patroklos Argyroudis 
MFC after:	1 week
---
 sys/netinet/libalias/alias.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c
index 2e469d7e49a..226965d208e 100644
--- a/sys/netinet/libalias/alias.c
+++ b/sys/netinet/libalias/alias.c
@@ -1669,6 +1669,7 @@ LibAliasRefreshModules(void)
 			LibAliasLoadModule(buf);
 		}
 	}
+	fclose(fd);
 	return (0);
 }
 

From 867b1d3431b4b7502abc23c03fda8c4891b8d55e Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Wed, 28 Oct 2009 13:50:28 +0000
Subject: [PATCH 390/646] Do first controller time sync after 1 minute, as in
 Adaptec's vendor driver.

---
 sys/dev/aac/aac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index d8dec97a1aa..ded47cede87 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -354,7 +354,7 @@ aac_attach(struct aac_softc *sc)
 	}
 
 	mtx_lock(&sc->aac_io_lock);
-	callout_reset(&sc->aac_daemontime, 30 * 60 * hz, aac_daemon, sc);
+	callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
 	mtx_unlock(&sc->aac_io_lock);
 
 	return(0);

From a79d48f537f63d8b8794c30c09795319d27443c7 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 14:13:45 +0000
Subject: [PATCH 391/646] Initialize f_rabuf in the raw device case. A
 subsequent close() later on would try to free it, leading to a crash.

PR:		93998
Submitted by:	neel
MFC after:	1 week
---
 lib/libstand/open.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/libstand/open.c b/lib/libstand/open.c
index acbda1c9ed3..49dc6608ff4 100644
--- a/lib/libstand/open.c
+++ b/lib/libstand/open.c
@@ -113,6 +113,7 @@ open(const char *fname, int mode)
     /* see if we opened a raw device; otherwise, 'file' is the file name. */
     if (file == (char *)0 || *file == '\0') {
 	f->f_flags |= F_RAW;
+	f->f_rabuf = NULL;
 	return (fd);
     }
 

From 3d93e0e9ec8422de3be5b8c3c62c4b70a08d2f27 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 14:39:27 +0000
Subject: [PATCH 392/646] Fix date (1) and SEE ALSO section.

Submitted by:	Ulrich Spoerlein (1)
MFC after:	1 week
---
 share/man/man5/regdomain.5 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/share/man/man5/regdomain.5 b/share/man/man5/regdomain.5
index f46a4afe835..495f4b70f1f 100644
--- a/share/man/man5/regdomain.5
+++ b/share/man/man5/regdomain.5
@@ -23,7 +23,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
-.Dd Apri 13, 2008
+.Dd April 13, 2008
 .Dt REGDOMAIN 5
 .Os
 .Sh NAME
@@ -44,5 +44,5 @@ This file should be changed only to reflect changes in regulations.
 XML database of 802.11 regulatory constraints
 .El
 .Sh SEE ALSO
-.Xr wlan 4
-.Xr ifconfig 8 ,
+.Xr wlan 4 ,
+.Xr ifconfig 8

From af578835691ce9a4e0dbd3dbc6e4100aab86fb82 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 15:22:58 +0000
Subject: [PATCH 393/646] Remove spurious `)`

PR:		137758
Submitted by:	Henning Petersen 
MFC after:	1 week
---
 sys/dev/amr/amr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index 2061fcc801f..955c87947fe 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -225,7 +225,7 @@ amr_attach(struct amr_softc *sc)
     }
 
 #ifdef AMR_BOARD_INIT
-    if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc))))
+    if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc)))
 	return(ENXIO);
 #endif
 

From f12c03487461c0d1004e5a8ab7d7796a3ec91e4e Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 28 Oct 2009 20:17:54 +0000
Subject: [PATCH 394/646] Fix some problems with effective mmap() offsets > 32
 bits.  This was partially fixed on amd64 earlier.  Rather than forcing
 linux_mmap_common() to use a 32-bit offset, have it accept a 64-bit file
 offset.  This offset is then passed to the real mmap() call.  Rather than
 inventing a structure to hold the normal linux_mmap args that has a 64-bit
 offset, just pass each of the arguments individually to linux_mmap_common()
 since that more closes matches the existing style of various kern_foo()
 functions.

Submitted by:	Christian Zander @ Nvidia
MFC after:	1 week
---
 sys/amd64/linux32/linux32_machdep.c | 66 +++++++++++++----------------
 sys/i386/linux/linux_machdep.c      | 65 ++++++++++++++--------------
 2 files changed, 61 insertions(+), 70 deletions(-)

diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 42ea0700f8b..46119b67df6 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -91,6 +91,10 @@ linux_to_bsd_sigaltstack(int lsa)
 	return (bsa);
 }
 
+static int	linux_mmap_common(struct thread *td, l_uintptr_t addr,
+		    l_size_t len, l_int prot, l_int flags, l_int fd,
+		    l_loff_t pos);
+
 int
 bsd_to_linux_sigaltstack(int bsa)
 {
@@ -759,12 +763,9 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
 #define STACK_SIZE  (2 * 1024 * 1024)
 #define GUARD_SIZE  (4 * PAGE_SIZE)
 
-static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
-
 int
 linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
 {
-	struct l_mmap_argv linux_args;
 
 #ifdef DEBUG
 	if (ldebug(mmap2))
@@ -773,14 +774,9 @@ linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
 		    args->flags, args->fd, args->pgoff);
 #endif
 
-	linux_args.addr = PTROUT(args->addr);
-	linux_args.len = args->len;
-	linux_args.prot = args->prot;
-	linux_args.flags = args->flags;
-	linux_args.fd = args->fd;
-	linux_args.pgoff = args->pgoff;
-
-	return (linux_mmap_common(td, &linux_args));
+	return (linux_mmap_common(td, PTROUT(args->addr), args->len, args->prot,
+		args->flags, args->fd, (uint64_t)(uint32_t)args->pgoff *
+		PAGE_SIZE));
 }
 
 int
@@ -799,15 +795,15 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
 		    linux_args.addr, linux_args.len, linux_args.prot,
 		    linux_args.flags, linux_args.fd, linux_args.pgoff);
 #endif
-	if ((linux_args.pgoff % PAGE_SIZE) != 0)
-		return (EINVAL);
-	linux_args.pgoff /= PAGE_SIZE;
 
-	return (linux_mmap_common(td, &linux_args));
+	return (linux_mmap_common(td, linux_args.addr, linux_args.len,
+	    linux_args.prot, linux_args.flags, linux_args.fd,
+	    (uint32_t)linux_args.pgoff));
 }
 
 static int
-linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
+linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
+    l_int flags, l_int fd, l_loff_t pos)
 {
 	struct proc *p = td->td_proc;
 	struct mmap_args /* {
@@ -830,21 +826,20 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 	 * Linux mmap(2):
 	 * You must specify exactly one of MAP_SHARED and MAP_PRIVATE
 	 */
-	if (! ((linux_args->flags & LINUX_MAP_SHARED) ^
-	    (linux_args->flags & LINUX_MAP_PRIVATE)))
+	if (!((flags & LINUX_MAP_SHARED) ^ (flags & LINUX_MAP_PRIVATE)))
 		return (EINVAL);
 
-	if (linux_args->flags & LINUX_MAP_SHARED)
+	if (flags & LINUX_MAP_SHARED)
 		bsd_args.flags |= MAP_SHARED;
-	if (linux_args->flags & LINUX_MAP_PRIVATE)
+	if (flags & LINUX_MAP_PRIVATE)
 		bsd_args.flags |= MAP_PRIVATE;
-	if (linux_args->flags & LINUX_MAP_FIXED)
+	if (flags & LINUX_MAP_FIXED)
 		bsd_args.flags |= MAP_FIXED;
-	if (linux_args->flags & LINUX_MAP_ANON)
+	if (flags & LINUX_MAP_ANON)
 		bsd_args.flags |= MAP_ANON;
 	else
 		bsd_args.flags |= MAP_NOSYNC;
-	if (linux_args->flags & LINUX_MAP_GROWSDOWN)
+	if (flags & LINUX_MAP_GROWSDOWN)
 		bsd_args.flags |= MAP_STACK;
 
 	/*
@@ -852,12 +847,12 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 	 * on Linux/i386. We do this to ensure maximum compatibility.
 	 * Linux/ia64 does the same in i386 emulation mode.
 	 */
-	bsd_args.prot = linux_args->prot;
+	bsd_args.prot = prot;
 	if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
 		bsd_args.prot |= PROT_READ | PROT_EXEC;
 
 	/* Linux does not check file descriptor when MAP_ANONYMOUS is set. */
-	bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd;
+	bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : fd;
 	if (bsd_args.fd != -1) {
 		/*
 		 * Linux follows Solaris mmap(2) description:
@@ -882,7 +877,7 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		fdrop(fp, td);
 	}
 
-	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
+	if (flags & LINUX_MAP_GROWSDOWN) {
 		/*
 		 * The Linux MAP_GROWSDOWN option does not limit auto
 		 * growth of the region.  Linux mmap with this option
@@ -905,8 +900,7 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		 * fixed size of (STACK_SIZE - GUARD_SIZE).
 		 */
 
-		if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len >
-		    p->p_vmspace->vm_maxsaddr) {
+		if ((caddr_t)PTRIN(addr) + len > p->p_vmspace->vm_maxsaddr) {
 			/*
 			 * Some Linux apps will attempt to mmap
 			 * thread stacks near the top of their
@@ -937,19 +931,19 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		 * we map the full stack, since we don't have a way
 		 * to autogrow it.
 		 */
-		if (linux_args->len > STACK_SIZE - GUARD_SIZE) {
-			bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
-			bsd_args.len = linux_args->len;
+		if (len > STACK_SIZE - GUARD_SIZE) {
+			bsd_args.addr = (caddr_t)PTRIN(addr);
+			bsd_args.len = len;
 		} else {
-			bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) -
-			    (STACK_SIZE - GUARD_SIZE - linux_args->len);
+			bsd_args.addr = (caddr_t)PTRIN(addr) -
+			    (STACK_SIZE - GUARD_SIZE - len);
 			bsd_args.len = STACK_SIZE - GUARD_SIZE;
 		}
 	} else {
-		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
-		bsd_args.len  = linux_args->len;
+		bsd_args.addr = (caddr_t)PTRIN(addr);
+		bsd_args.len  = len;
 	}
-	bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
+	bsd_args.pos = pos;
 
 #ifdef DEBUG
 	if (ldebug(mmap))
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index cd3cf79d558..4e119d87fcc 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -93,6 +93,10 @@ struct l_old_select_argv {
 	struct l_timeval	*timeout;
 };
 
+static int	linux_mmap_common(struct thread *td, l_uintptr_t addr,
+		    l_size_t len, l_int prot, l_int flags, l_int fd,
+		    l_loff_t pos);
+
 int
 linux_to_bsd_sigaltstack(int lsa)
 {
@@ -591,12 +595,9 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
 #define STACK_SIZE  (2 * 1024 * 1024)
 #define GUARD_SIZE  (4 * PAGE_SIZE)
 
-static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
-
 int
 linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
 {
-	struct l_mmap_argv linux_args;
 
 #ifdef DEBUG
 	if (ldebug(mmap2))
@@ -605,14 +606,9 @@ linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
 		    args->flags, args->fd, args->pgoff);
 #endif
 
-	linux_args.addr = args->addr;
-	linux_args.len = args->len;
-	linux_args.prot = args->prot;
-	linux_args.flags = args->flags;
-	linux_args.fd = args->fd;
-	linux_args.pgoff = args->pgoff * PAGE_SIZE;
-
-	return (linux_mmap_common(td, &linux_args));
+	return (linux_mmap_common(td, args->addr, args->len, args->prot,
+		args->flags, args->fd, (uint64_t)(uint32_t)args->pgoff *
+		PAGE_SIZE));
 }
 
 int
@@ -632,11 +628,14 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
 		    linux_args.flags, linux_args.fd, linux_args.pgoff);
 #endif
 
-	return (linux_mmap_common(td, &linux_args));
+	return (linux_mmap_common(td, linux_args.addr, linux_args.len,
+	    linux_args.prot, linux_args.flags, linux_args.fd,
+	    (uint32_t)linux_args.pgoff));
 }
 
 static int
-linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
+linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
+    l_int flags, l_int fd, l_loff_t pos)
 {
 	struct proc *p = td->td_proc;
 	struct mmap_args /* {
@@ -659,21 +658,20 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 	 * Linux mmap(2):
 	 * You must specify exactly one of MAP_SHARED and MAP_PRIVATE
 	 */
-	if (! ((linux_args->flags & LINUX_MAP_SHARED) ^
-	    (linux_args->flags & LINUX_MAP_PRIVATE)))
+	if (!((flags & LINUX_MAP_SHARED) ^ (flags & LINUX_MAP_PRIVATE)))
 		return (EINVAL);
 
-	if (linux_args->flags & LINUX_MAP_SHARED)
+	if (flags & LINUX_MAP_SHARED)
 		bsd_args.flags |= MAP_SHARED;
-	if (linux_args->flags & LINUX_MAP_PRIVATE)
+	if (flags & LINUX_MAP_PRIVATE)
 		bsd_args.flags |= MAP_PRIVATE;
-	if (linux_args->flags & LINUX_MAP_FIXED)
+	if (flags & LINUX_MAP_FIXED)
 		bsd_args.flags |= MAP_FIXED;
-	if (linux_args->flags & LINUX_MAP_ANON)
+	if (flags & LINUX_MAP_ANON)
 		bsd_args.flags |= MAP_ANON;
 	else
 		bsd_args.flags |= MAP_NOSYNC;
-	if (linux_args->flags & LINUX_MAP_GROWSDOWN)
+	if (flags & LINUX_MAP_GROWSDOWN)
 		bsd_args.flags |= MAP_STACK;
 
 	/*
@@ -681,12 +679,12 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 	 * on Linux/i386. We do this to ensure maximum compatibility.
 	 * Linux/ia64 does the same in i386 emulation mode.
 	 */
-	bsd_args.prot = linux_args->prot;
+	bsd_args.prot = prot;
 	if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
 		bsd_args.prot |= PROT_READ | PROT_EXEC;
 
 	/* Linux does not check file descriptor when MAP_ANONYMOUS is set. */
-	bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd;
+	bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : fd;
 	if (bsd_args.fd != -1) {
 		/*
 		 * Linux follows Solaris mmap(2) description:
@@ -711,9 +709,9 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		fdrop(fp, td);
 	}
 
-	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
+	if (flags & LINUX_MAP_GROWSDOWN) {
 		/* 
-		 * The linux MAP_GROWSDOWN option does not limit auto
+		 * The Linux MAP_GROWSDOWN option does not limit auto
 		 * growth of the region.  Linux mmap with this option
 		 * takes as addr the inital BOS, and as len, the initial
 		 * region size.  It can then grow down from addr without
@@ -734,8 +732,7 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		 * fixed size of (STACK_SIZE - GUARD_SIZE).
 		 */
 
-		if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len >
-		    p->p_vmspace->vm_maxsaddr) {
+		if ((caddr_t)PTRIN(addr) + len > p->p_vmspace->vm_maxsaddr) {
 			/* 
 			 * Some linux apps will attempt to mmap
 			 * thread stacks near the top of their
@@ -766,19 +763,19 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
 		 * we map the full stack, since we don't have a way
 		 * to autogrow it.
 		 */
-		if (linux_args->len > STACK_SIZE - GUARD_SIZE) {
-			bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
-			bsd_args.len = linux_args->len;
+		if (len > STACK_SIZE - GUARD_SIZE) {
+			bsd_args.addr = (caddr_t)PTRIN(addr);
+			bsd_args.len = len;
 		} else {
-			bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) -
-			    (STACK_SIZE - GUARD_SIZE - linux_args->len);
+			bsd_args.addr = (caddr_t)PTRIN(addr) -
+			    (STACK_SIZE - GUARD_SIZE - len);
 			bsd_args.len = STACK_SIZE - GUARD_SIZE;
 		}
 	} else {
-		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
-		bsd_args.len  = linux_args->len;
+		bsd_args.addr = (caddr_t)PTRIN(addr);
+		bsd_args.len  = len;
 	}
-	bsd_args.pos = linux_args->pgoff;
+	bsd_args.pos = pos;
 
 #ifdef DEBUG
 	if (ldebug(mmap))

From 052e971d25564d202da551441cf7a477b43034ad Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Thu, 29 Oct 2009 09:27:09 +0000
Subject: [PATCH 395/646] HZ is now 1000 on most platforms, update a comment.

Reviewed by:	phk, markm
---
 sys/sys/time.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/sys/time.h b/sys/sys/time.h
index 0185c31b772..c2ed337e52d 100644
--- a/sys/sys/time.h
+++ b/sys/sys/time.h
@@ -283,7 +283,7 @@ extern struct timeval boottime;
  *
  * Functions with the "get" prefix returns a less precise result
  * much faster than the functions without "get" prefix and should
- * be used where a precision of 10 msec is acceptable or where
+ * be used where a precision of 1/hz seconds is acceptable or where
  * performance is priority. (NB: "precision", _not_ "resolution" !) 
  * 
  */

From 9589412053ed517fc2613104a22166fe5847ba01 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Thu, 29 Oct 2009 09:45:05 +0000
Subject: [PATCH 396/646] Back in 2003, get_cyclecount() was changed to use
 binuptime() instead of nanotime().  Reflect this change in a manpage.

Reviewed by:	phk, markm
---
 share/man/man9/get_cyclecount.9 | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/share/man/man9/get_cyclecount.9 b/share/man/man9/get_cyclecount.9
index c6731117313..e3be78e59d2 100644
--- a/share/man/man9/get_cyclecount.9
+++ b/share/man/man9/get_cyclecount.9
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 20, 2000
+.Dd October 24, 2009
 .Dt GET_CYCLECOUNT 9
 .Os
 .Sh NAME
@@ -65,10 +65,10 @@ do not have such a register,
 so
 .Fn get_cyclecount
 on these platforms
-returns the number of nanoseconds
+returns a (non-monotonic) combination of numbers
 represented by the
 structure returned by
-.Xr nanotime 9 .
+.Xr binuptime 9 .
 .Pp
 The
 .Tn Pentium
@@ -77,18 +77,12 @@ processors all use the
 register.
 .Pp
 The
-.Tn Alpha
-processors use the
-.Li PCC
-register.
-.Pp
-The
 .Tn IA64
 processors use the
 .Li AR.ITC
 register.
 .Sh SEE ALSO
-.Xr nanotime 9
+.Xr binuptime 9
 .Sh HISTORY
 The
 .Fn get_cyclecount

From f7e95633c6bc05da6eb6229588541c6d7b50f826 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Thu, 29 Oct 2009 09:51:13 +0000
Subject: [PATCH 397/646] Update some comments regarding ktr(4).

---
 sys/conf/NOTES | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 55e0f90c76e..71115808ccf 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -402,8 +402,7 @@ options 	KTRACE			#kernel tracing
 options 	KTRACE_REQUEST_POOL=101
 
 #
-# KTR is a kernel tracing mechanism imported from BSD/OS.  Currently
-# it has no userland interface aside from a few sysctl's.  It is
+# KTR is a kernel tracing facility imported from BSD/OS.  It is
 # enabled with the KTR option.  KTR_ENTRIES defines the number of
 # entries in the circular trace buffer; it must be a power of two.
 # KTR_COMPILE defines the mask of events to compile into the kernel as
@@ -413,7 +412,7 @@ options 	KTRACE_REQUEST_POOL=101
 # events, with bit X corresponding to CPU X.  KTR_VERBOSE enables
 # dumping of KTR events to the console by default.  This functionality
 # can be toggled via the debug.ktr_verbose sysctl and defaults to off
-# if KTR_VERBOSE is not defined.
+# if KTR_VERBOSE is not defined.  See ktr(4) and ktrdump(8) for details.
 #
 options 	KTR
 options 	KTR_ENTRIES=1024
@@ -424,7 +423,7 @@ options 	KTR_VERBOSE
 
 #
 # ALQ(9) is a facility for the asynchronous queuing of records from the kernel
-# to a vnode, and is employed by services such as KTR(4) to produce trace
+# to a vnode, and is employed by services such as ktr(4) to produce trace
 # files based on a kernel event stream.  Records are written asynchronously
 # in a worker thread.
 #
@@ -618,9 +617,9 @@ options 	SCTP_WITH_NO_CSUM
 # I have not yet commited the tools to get and print
 # the logs, I will do that eventually .. before then
 # if you want them send me an email rrs@freebsd.org
-# You basically must have KTR enabled for these
+# You basically must have ktr(4) enabled for these
 # and you then set the sysctl to turn on/off various
-# logging bits. Use ktrdump to pull the log and run
+# logging bits. Use ktrdump(8) to pull the log and run
 # it through a dispaly program.. and graphs and other
 # things too.
 #

From 7415a41f4aaed49fc878768ff17eabcbe676c336 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 10:03:08 +0000
Subject: [PATCH 398/646] Fix style issue.

---
 sys/kern/uipc_syscalls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 475a2deb06d..708cefcb6df 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2016,7 +2016,7 @@ retry_space:
 		 * Loop and construct maximum sized mbuf chain to be bulk
 		 * dumped into socket buffer.
 		 */
-		while(space > loopbytes) {
+		while (space > loopbytes) {
 			vm_pindex_t pindex;
 			vm_offset_t pgoff;
 			struct mbuf *m0;

From 71a7750434f52d32e0b726cd219829c004df5e74 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Thu, 29 Oct 2009 12:19:10 +0000
Subject: [PATCH 399/646] Update the route's sequence number upon receiving a
 RANN.

MFC after:	3 days
---
 sys/net80211/ieee80211_hwmp.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index ea06b0e3a9d..66055d71255 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -1239,15 +1239,18 @@ hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni,
 		return;
 	}
 	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
-	if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq) && rann->rann_ttl > 1 &&
-	    rann->rann_hopcount < hs->hs_maxhops &&
-	    (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
-		memcpy(&prann, rann, sizeof(prann));
-		prann.rann_hopcount += 1;
-		prann.rann_ttl -= 1;
-		prann.rann_metric += ms->ms_pmetric->mpm_metric(ni);
-		hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
-		    &prann);
+	if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq)) {
+		hr->hr_seq = rann->rann_seq;
+		if (rann->rann_ttl > 1 &&
+		    rann->rann_hopcount < hs->hs_maxhops &&
+		    (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
+			memcpy(&prann, rann, sizeof(prann));
+			prann.rann_hopcount += 1;
+			prann.rann_ttl -= 1;
+			prann.rann_metric += ms->ms_pmetric->mpm_metric(ni);
+			hwmp_send_rann(vap->iv_bss, vap->iv_myaddr,
+			    broadcastaddr, &prann);
+		}
 	}
 }
 

From f3755df16d9941e13e11376925cd08eef7607eb8 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Thu, 29 Oct 2009 13:27:14 +0000
Subject: [PATCH 400/646] Turn off use of ATA_A_4BIT on modern hardware. This
 flag was already obsoleted in 1996 by ATA-2, and crashes some modern hardware
 like some revisions of the Serverworks K2 SATA controller. Even very ancient
 hardware seems not to require it. In the unlikely event this causes problems,
 the previous behavior can be re-enabled by defining ATA_LEGACY_SUPPORT at the
 top of this file.

Reviewed by:	Alexander Motin 
---
 sys/dev/ata/ata-all.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 4bb45e48f64..adee8f58127 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -26,6 +26,11 @@
  * $FreeBSD$
  */
 
+#if 0
+#define	ATA_LEGACY_SUPPORT		/* Enable obsolete features that break
+					 * some modern devices */
+#endif
+
 /* ATA register defines */
 #define ATA_DATA                        0       /* (RW) data */
 
@@ -81,7 +86,11 @@
 #define ATA_PC98_CTLOFFSET              0x10c   /* do for PC98 devices */
 #define         ATA_A_IDS               0x02    /* disable interrupts */
 #define         ATA_A_RESET             0x04    /* RESET controller */
-#define         ATA_A_4BIT              0x08    /* 4 head bits */
+#ifdef	ATA_LEGACY_SUPPORT			
+#define         ATA_A_4BIT              0x08    /* 4 head bits: obsolete 1996 */
+#else
+#define         ATA_A_4BIT              0x00 
+#endif
 #define         ATA_A_HOB               0x80    /* High Order Byte enable */
 
 /* SATA register defines */

From e5310f3310f45ec0b5067b66fdcf57d365eb86ee Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Thu, 29 Oct 2009 13:28:37 +0000
Subject: [PATCH 401/646] Add some magic taken from OS X and Linux to support
 early revision K2 SATA controllers, like those found on the G5 Xserve.

Reviewed by:	mav
---
 sys/dev/ata/chipsets/ata-serverworks.c | 31 ++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c
index eca72d47780..dfa01f5f80c 100644
--- a/sys/dev/ata/chipsets/ata-serverworks.c
+++ b/sys/dev/ata/chipsets/ata-serverworks.c
@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#ifdef __powerpc__
+#include 
+#endif
 #include 
 #include 
 #include 
@@ -106,6 +109,13 @@ static int
 ata_serverworks_status(device_t dev)
 {
     struct ata_channel *ch = device_get_softc(dev);
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+
+    /*
+     * Check if this interrupt belongs to our channel.
+     */
+    if (!(ATA_INL(ctlr->r_res2, 0x1f80) & (1 << ch->unit)))
+	return (0);
 
     /*
      * We need to do a 4-byte read on the status reg before the values
@@ -208,8 +218,29 @@ ata_serverworks_ch_attach(device_t dev)
     ch->hw.tf_write = ata_serverworks_tf_write;
 #ifdef __powerpc__
     ch->hw.status = ata_serverworks_status;
+
+    /* Make sure that our interrupt is edge triggered */
+    powerpc_config_intr(bus_get_resource_start(device_get_parent(dev),
+	SYS_RES_IRQ, 0), INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
 #endif
 
+    if (ctlr->chip->chipid == ATA_K2) {
+	/*
+	 * The revision 1 K2 SATA controller has interesting bugs. Patch them.
+	 * These magic numbers regulate interrupt delivery in the first few
+	 * cases and are pure magic in the last case.
+	 *
+	 * Values obtained from the Darwin driver.
+	 */
+
+	ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, 0x04);
+	ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff);
+	ATA_IDX_OUTL(ch, ATA_SCONTROL, 0x00000300);
+	ATA_OUTL(ctlr->r_res2, ch_offset + 0x88, 0);
+	ATA_OUTL(ctlr->r_res2, ch_offset + 0x80,
+	    ATA_INL(ctlr->r_res2, ch_offset + 0x80) & ~0x00040000);
+    }
+
     /* chip does not reliably do 64K DMA transfers */
     ch->dma.max_iosize = 64 * DEV_BSIZE;
 

From 742765c971d5e82f122dcae4a6ad36d8e9993b40 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 13:44:58 +0000
Subject: [PATCH 402/646] When extracting the capture buffer from a crashdump,
 only read the valid portion of the capture buffer (db_capture_bufoff vs
 db_capture_bufsize). This could result in outputting garbage (e.g. lots of
 'p' characters if DIAGNOSTIC is enabled) after the end of the capture buffer.
  While here, fix a spelling nit.

Reported by:	Mikolaj Golub  to my trociny of gmail
MFC after:	3 days
---
 sbin/ddb/ddb_capture.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/sbin/ddb/ddb_capture.c b/sbin/ddb/ddb_capture.c
index 9f83acbb03a..ffc9b91552d 100644
--- a/sbin/ddb/ddb_capture.c
+++ b/sbin/ddb/ddb_capture.c
@@ -95,24 +95,24 @@ kread_symbol(kvm_t *kvm, int index, void *address, size_t size,
 static void
 ddb_capture_print_kvm(kvm_t *kvm)
 {
-	u_int db_capture_bufsize;
+	u_int db_capture_bufoff;
 	char *buffer, *db_capture_buf;
 
 	if (kread_symbol(kvm, X_DB_CAPTURE_BUF, &db_capture_buf,
 	    sizeof(db_capture_buf), 0) < 0)
 		errx(-1, "kvm: unable to read db_capture_buf");
 
-	if (kread_symbol(kvm, X_DB_CAPTURE_BUFSIZE, &db_capture_bufsize,
-	    sizeof(db_capture_bufsize), 0) < 0)
-		errx(-1, "kvm: unable to read db_capture_bufsize");
+	if (kread_symbol(kvm, X_DB_CAPTURE_BUFOFF, &db_capture_bufoff,
+	    sizeof(db_capture_bufoff), 0) < 0)
+		errx(-1, "kvm: unable to read db_capture_bufoff");
 
-	buffer = malloc(db_capture_bufsize + 1);
+	buffer = malloc(db_capture_bufoff + 1);
 	if (buffer == NULL)
-		err(-1, "malloc: db_capture_bufsize (%u)",
-		    db_capture_bufsize);
-	bzero(buffer, db_capture_bufsize + 1);
+		err(-1, "malloc: db_capture_bufoff (%u)",
+		    db_capture_bufoff);
+	bzero(buffer, db_capture_bufoff + 1);
 
-	if (kread(kvm, db_capture_buf, buffer, db_capture_bufsize, 0) < 0)
+	if (kread(kvm, db_capture_buf, buffer, db_capture_bufoff, 0) < 0)
 		errx(-1, "kvm: unable to read buffer");
 
 	printf("%s\n", buffer);
@@ -161,7 +161,7 @@ ddb_capture_status_kvm(kvm_t *kvm)
 		errx(-1, "kvm: unable to read db_capture_bufsize");
 	if (kread_symbol(kvm, X_DB_CAPTURE_INPROGRESS,
 	    &db_capture_inprogress, sizeof(db_capture_inprogress), 0) < 0)
-		err(-1, "kvm: unable to read db_capture_inpgoress");
+		err(-1, "kvm: unable to read db_capture_inprogress");
 	printf("%u/%u bytes used\n", db_capture_bufoff, db_capture_bufsize);
 	if (db_capture_inprogress)
 		printf("capture is on\n");

From c5229b9d2b414b9a1aac40d8f8bee48d85bea6a2 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 13:45:33 +0000
Subject: [PATCH 403/646] Include the output of the ddb(4) capture buffer.

Submitted by:	Mikolaj Golub  to my trociny of gmail
MFC after:	3 days
---
 usr.sbin/crashinfo/crashinfo.sh | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/usr.sbin/crashinfo/crashinfo.sh b/usr.sbin/crashinfo/crashinfo.sh
index cd410094189..886affd6f0e 100755
--- a/usr.sbin/crashinfo/crashinfo.sh
+++ b/usr.sbin/crashinfo/crashinfo.sh
@@ -304,3 +304,10 @@ echo "------------------------------------------------------------------------"
 echo "kernel config"
 echo
 config -x $KERNEL
+
+echo
+echo "------------------------------------------------------------------------"
+echo "ddb capture buffer"
+echo
+
+ddb capture -M $VMCORE -N $KERNEL print

From 21a2ac1953c77a18a75988dc2c4324704f7c7608 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 13:52:34 +0000
Subject: [PATCH 404/646] Define identify fields described in CF specification.

---
 sys/sys/ata.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index e3cb0cefa19..fa91e3bdc98 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -226,7 +226,11 @@ struct ata_params {
 /*128*/ u_int16_t       security_status;
 	u_int16_t       reserved129[31];
 /*160*/ u_int16_t       cfa_powermode1;
-	u_int16_t       reserved161[15];
+	u_int16_t       reserved161;
+/*162*/ u_int16_t       cfa_kms_support;
+/*163*/ u_int16_t       cfa_trueide_modes;
+/*164*/ u_int16_t       cfa_memory_modes;
+	u_int16_t       reserved165[11];
 /*176*/ u_int8_t        media_serial[60];
 /*206*/ u_int16_t       sct;
 	u_int16_t       reserved206[2];

From d8cd25d022ec27f585b607eb20e03f8788c67689 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Thu, 29 Oct 2009 14:22:09 +0000
Subject: [PATCH 405/646] Turn off Altivec data-stream prefetching before going
 into power-save mode on those CPUs that need it.

---
 sys/powerpc/aim/machdep.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index 713402e98f1..01272b45b6c 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -897,8 +897,10 @@ void
 cpu_idle(int busy)
 {
 	uint32_t msr;
+	uint16_t vers;
 
 	msr = mfmsr();
+	vers = mfpvr() >> 16;
 
 #ifdef INVARIANTS
 	if ((msr & PSL_EE) != PSL_EE) {
@@ -908,9 +910,25 @@ cpu_idle(int busy)
 	}
 #endif
 	if (powerpc_pow_enabled) {
-		powerpc_sync();
-		mtmsr(msr | PSL_POW);
-		isync();
+		switch (vers) {
+		case IBM970:
+		case IBM970FX:
+		case IBM970MP:
+		case MPC7447A:
+		case MPC7448:
+		case MPC7450:
+		case MPC7455:
+		case MPC7457:
+			__asm __volatile("\
+			    dssall; sync; mtmsr %0; isync"
+			    :: "r"(msr | PSL_POW));
+			break;
+		default:
+			powerpc_sync();
+			mtmsr(msr | PSL_POW);
+			isync();
+			break;
+		}
 	}
 }
 

From 8084540253f5ddbef26a080561df2b6f8c24292f Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 14:34:24 +0000
Subject: [PATCH 406/646] Trapsignal() calls kern_sigprocmask() when delivering
 catched signal with proc lock held.

Reported and tested by:	Mykola Dzham  freebsd at levsha org ua
MFC after:	1 month
---
 sys/kern/kern_sig.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index d0249f517db..7f5cfa32ad8 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1863,7 +1863,8 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
 		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
 			SIGEMPTYSET(mask);
 			SIGADDSET(mask, sig);
-			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, 0);
+			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
+			    SIGPROCMASK_PROC_LOCKED);
 		}
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*

From e46b9eeadae7eadf4f4ad7e023fc3657370e14b4 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 29 Oct 2009 14:53:45 +0000
Subject: [PATCH 407/646] Rename aac_fast_intr to aac_filter to reflect its
 current use.  Eliminate the fallback of using the filter as an interrupt
 handler, as it is no longer needed.

Discussed with:	scottl, jhb
---
 sys/dev/aac/aac.c    | 18 +++++++-----------
 sys/dev/aac/aacvar.h |  2 +-
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index ded47cede87..0bfb3f89997 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -909,8 +909,11 @@ aac_new_intr(void *arg)
 	mtx_unlock(&sc->aac_io_lock);
 }
 
+/*
+ * Interrupt filter for !NEW_COMM interface.
+ */
 int
-aac_fast_intr(void *arg)
+aac_filter(void *arg)
 {
 	struct aac_softc *sc;
 	u_int16_t reason;
@@ -2032,18 +2035,11 @@ aac_setup_intr(struct aac_softc *sc)
 		}
 	} else {
 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-				   INTR_TYPE_BIO, aac_fast_intr, NULL,
+				   INTR_TYPE_BIO, aac_filter, NULL,
 				   sc, &sc->aac_intr)) {
 			device_printf(sc->aac_dev,
-				      "can't set up FAST interrupt\n");
-			if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-					   INTR_MPSAFE|INTR_TYPE_BIO,
-					   NULL, (driver_intr_t *)aac_fast_intr,
-					   sc, &sc->aac_intr)) {
-				device_printf(sc->aac_dev,
-					     "can't set up MPSAFE interrupt\n");
-				return (EINVAL);
-			}
+				      "can't set up interrupt filter\n");
+			return (EINVAL);
 		}
 	}
 	return (0);
diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index 7f64371ef86..18b8501cf61 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -448,7 +448,7 @@ extern int		aac_shutdown(device_t dev);
 extern int		aac_suspend(device_t dev); 
 extern int		aac_resume(device_t dev);
 extern void		aac_new_intr(void *arg);
-extern int		aac_fast_intr(void *arg);
+extern int		aac_filter(void *arg);
 extern void		aac_submit_bio(struct bio *bp);
 extern void		aac_biodone(struct bio *bp);
 extern void		aac_startio(struct aac_softc *sc);

From 6652a11014aa7c4238fdf0fdf358ddb053afa510 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 29 Oct 2009 15:59:27 +0000
Subject: [PATCH 408/646] Revert part of r198363, there is no "device cam", it
 is included in "device scbus".

MFC after:	3 days
---
 share/man/man4/atapicam.4 | 1 -
 share/man/man4/umass.4    | 1 -
 2 files changed, 2 deletions(-)

diff --git a/share/man/man4/atapicam.4 b/share/man/man4/atapicam.4
index 81442074cc6..5f083d017e7 100644
--- a/share/man/man4/atapicam.4
+++ b/share/man/man4/atapicam.4
@@ -39,7 +39,6 @@ place the following lines in your
 kernel configuration file:
 .Bd -ragged -offset indent
 .Cd "device scbus"
-.Cd "device cam"
 .Cd "device ata"
 .Cd "device atapicam"
 .Ed
diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4
index ffa1ac31073..56094cd57e0 100644
--- a/share/man/man4/umass.4
+++ b/share/man/man4/umass.4
@@ -39,7 +39,6 @@ place the following line in your
 kernel configuration file:
 .Bd -ragged -offset indent
 .Cd "device scbus"
-.Cd "device cam"
 .Cd "device usb"
 .Cd "device umass"
 .Ed

From c89d07b9f5394a001c4fe38f992ab9464f49b956 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 29 Oct 2009 17:14:18 +0000
Subject: [PATCH 409/646] Rename aac_srb32 to aac_srb, to match Adaptec's
 vendor driver.

---
 sys/dev/aac/aac_cam.c | 6 +++---
 sys/dev/aac/aacreg.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index ddf19f335b8..5755f0d611a 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -211,7 +211,7 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 {
 	struct	aac_cam *camsc;
 	struct	aac_softc *sc;
-	struct	aac_srb32 *srb;
+	struct	aac_srb *srb;
 	struct	aac_fib *fib;
 	struct	aac_command *cm;
 
@@ -351,7 +351,7 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 	}
 
 	fib = cm->cm_fib;
-	srb = (struct aac_srb32 *)&fib->data[0];
+	srb = (struct aac_srb *)&fib->data[0];
 	cm->cm_datalen = 0;
 
 	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
@@ -459,7 +459,7 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 	    AAC_FIBSTATE_REXPECTED	|
 	    AAC_FIBSTATE_NORM;
 	fib->Header.Size = sizeof(struct aac_fib_header) +
-	    sizeof(struct aac_srb32);
+	    sizeof(struct aac_srb);
 
 	aac_enqueue_ready(cm);
 	aac_startio(cm->cm_sc);
diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h
index db96ff206d9..d45634a9cb5 100644
--- a/sys/dev/aac/aacreg.h
+++ b/sys/dev/aac/aacreg.h
@@ -1363,7 +1363,7 @@ struct aac_close_command {
 /*
  * SCSI Passthrough structures
  */
-struct aac_srb32 {
+struct aac_srb {
 	u_int32_t		function;
 	u_int32_t		bus;
 	u_int32_t		target;

From 8e43cc231b504e402d008e13679cde85bb1c38a7 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 29 Oct 2009 17:21:41 +0000
Subject: [PATCH 410/646] Add additional featuresState.fBits entries to
 simplify compiling and testing Adaptec's vendor driver.

Submitted by:	Adaptec, driver 17517
---
 sys/sys/aac_ioctl.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/sys/sys/aac_ioctl.h b/sys/sys/aac_ioctl.h
index ef16a429e04..69af10e73a7 100644
--- a/sys/sys/aac_ioctl.h
+++ b/sys/sys/aac_ioctl.h
@@ -192,7 +192,10 @@ struct aac_query_disk {
 typedef union {
 	struct {
 		u_int32_t largeLBA  : 1;	/* disk support greater 2TB */
-		u_int32_t fReserved : 31;
+		u_int32_t IoctlBuf  : 1;	/* ARCIOCTL call support */
+		u_int32_t AIFSupport: 1;	/* AIF support */
+		u_int32_t JBODSupport:1;	/* fw + driver support JBOD */
+		u_int32_t fReserved : 28;
 	} fBits;
 	u_int32_t fValue;
 } featuresState;

From f786e2f82e91ee0b3a62cf25a5bc7daf8d2ff109 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 17:34:02 +0000
Subject: [PATCH 411/646] When fetching sum stats (vmstat -s) from a crash
 dump, fetch per-CPU counts and sum them to form the total counts.

PR:		bin/135893
Submitted by:	Mikolaj Golub  to my trociny of gmail
MFC after:	1 week
---
 usr.bin/vmstat/vmstat.c | 81 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c
index aa1d13bb47a..cf4b73a07c2 100644
--- a/usr.bin/vmstat/vmstat.c
+++ b/usr.bin/vmstat/vmstat.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -417,11 +418,91 @@ getuptime(void)
 	return(uptime);
 }
 
+static void
+fill_pcpu(struct pcpu ***pcpup, int* maxcpup)
+{
+	struct pcpu **pcpu;
+	
+	int maxcpu, size, i;
+
+	*pcpup = NULL;
+	
+	if (kd == NULL)
+		return;
+
+	maxcpu = kvm_getmaxcpu(kd);
+	if (maxcpu < 0)
+		errx(1, "kvm_getmaxcpu: %s", kvm_geterr(kd));
+
+	pcpu = calloc(maxcpu, sizeof(struct pcpu *));
+	if (pcpu == NULL)
+		err(1, "calloc");
+
+	for (i = 0; i < maxcpu; i++) {
+		pcpu[i] = kvm_getpcpu(kd, i);
+		if (pcpu[i] == (struct pcpu *)-1)
+			errx(1, "kvm_getpcpu: %s", kvm_geterr(kd));
+	}
+
+	*maxcpup = maxcpu;
+	*pcpup = pcpu;
+}
+
+static void
+free_pcpu(struct pcpu **pcpu, int maxcpu)
+{
+	int i;
+
+	for (i = 0; i < maxcpu; i++)
+		free(pcpu[i]);
+	free(pcpu);
+}
+
 static void
 fill_vmmeter(struct vmmeter *vmmp)
 {
+	struct pcpu **pcpu;
+	int maxcpu, i;
+
 	if (kd != NULL) {
 		kread(X_SUM, vmmp, sizeof(*vmmp));
+		fill_pcpu(&pcpu, &maxcpu);
+		for (i = 0; i < maxcpu; i++) {
+			if (pcpu[i] == NULL)
+				continue;
+#define ADD_FROM_PCPU(i, name) \
+			vmmp->name += pcpu[i]->pc_cnt.name
+			ADD_FROM_PCPU(i, v_swtch);
+			ADD_FROM_PCPU(i, v_trap);
+			ADD_FROM_PCPU(i, v_syscall);
+			ADD_FROM_PCPU(i, v_intr);
+			ADD_FROM_PCPU(i, v_soft);
+			ADD_FROM_PCPU(i, v_vm_faults);
+			ADD_FROM_PCPU(i, v_cow_faults);
+			ADD_FROM_PCPU(i, v_cow_optim);
+			ADD_FROM_PCPU(i, v_zfod);
+			ADD_FROM_PCPU(i, v_ozfod);
+			ADD_FROM_PCPU(i, v_swapin);
+			ADD_FROM_PCPU(i, v_swapout);
+			ADD_FROM_PCPU(i, v_swappgsin);
+			ADD_FROM_PCPU(i, v_swappgsout);
+			ADD_FROM_PCPU(i, v_vnodein);
+			ADD_FROM_PCPU(i, v_vnodeout);
+			ADD_FROM_PCPU(i, v_vnodepgsin);
+			ADD_FROM_PCPU(i, v_vnodepgsout);
+			ADD_FROM_PCPU(i, v_intrans);
+			ADD_FROM_PCPU(i, v_tfree);
+			ADD_FROM_PCPU(i, v_forks);
+			ADD_FROM_PCPU(i, v_vforks);
+			ADD_FROM_PCPU(i, v_rforks);
+			ADD_FROM_PCPU(i, v_kthreads);
+			ADD_FROM_PCPU(i, v_forkpages);
+			ADD_FROM_PCPU(i, v_vforkpages);
+			ADD_FROM_PCPU(i, v_rforkpages);
+			ADD_FROM_PCPU(i, v_kthreadpages);
+#undef ADD_FROM_PCPU
+		}
+		free_pcpu(pcpu, maxcpu);
 	} else {
 		size_t size = sizeof(unsigned int);
 #define GET_VM_STATS(cat, name) \

From 08abf6399a2d9dfdc5bf437ae218230056cc3537 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Thu, 29 Oct 2009 17:40:33 +0000
Subject: [PATCH 412/646] Improve round robin stream scheduler and cleanup some
 code.

Approved by: rrs (mentor)
MFC after: 3 days
---
 sys/netinet/sctp_output.c | 45 +++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 02bca9044c8..8c29f70b7c4 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5605,13 +5605,10 @@ sctp_insert_on_wheel(struct sctp_tcb *stcb,
 	if (holds_lock == 0) {
 		SCTP_TCB_SEND_LOCK(stcb);
 	}
-	if ((strq->next_spoke.tqe_next) ||
-	    (strq->next_spoke.tqe_prev)) {
-		/* already on wheel */
-		goto outof_here;
+	if ((strq->next_spoke.tqe_next == NULL) &&
+	    (strq->next_spoke.tqe_prev == NULL)) {
+		TAILQ_INSERT_TAIL(&asoc->out_wheel, strq, next_spoke);
 	}
-	TAILQ_INSERT_TAIL(&asoc->out_wheel, strq, next_spoke);
-outof_here:
 	if (holds_lock == 0) {
 		SCTP_TCB_SEND_UNLOCK(stcb);
 	}
@@ -5624,19 +5621,26 @@ sctp_remove_from_wheel(struct sctp_tcb *stcb,
     int holds_lock)
 {
 	/* take off and then setup so we know it is not on the wheel */
-	if (holds_lock == 0)
+	if (holds_lock == 0) {
 		SCTP_TCB_SEND_LOCK(stcb);
-	if (TAILQ_FIRST(&strq->outqueue)) {
-		/* more was added */
-		if (holds_lock == 0)
-			SCTP_TCB_SEND_UNLOCK(stcb);
-		return;
 	}
-	TAILQ_REMOVE(&asoc->out_wheel, strq, next_spoke);
-	strq->next_spoke.tqe_next = NULL;
-	strq->next_spoke.tqe_prev = NULL;
-	if (holds_lock == 0)
+	if (TAILQ_EMPTY(&strq->outqueue)) {
+		if (asoc->last_out_stream == strq) {
+			asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, sctpwheel_listhead, next_spoke);
+			if (asoc->last_out_stream == NULL) {
+				asoc->last_out_stream = TAILQ_LAST(&asoc->out_wheel, sctpwheel_listhead);
+			}
+			if (asoc->last_out_stream == strq) {
+				asoc->last_out_stream = NULL;
+			}
+		}
+		TAILQ_REMOVE(&asoc->out_wheel, strq, next_spoke);
+		strq->next_spoke.tqe_next = NULL;
+		strq->next_spoke.tqe_prev = NULL;
+	}
+	if (holds_lock == 0) {
 		SCTP_TCB_SEND_UNLOCK(stcb);
+	}
 }
 
 static void
@@ -7185,7 +7189,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
     struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now)
 {
 	struct sctp_association *asoc;
-	struct sctp_stream_out *strq, *strqn, *strqt;
+	struct sctp_stream_out *strq, *strqn;
 	int goal_mtu, moved_how_much, total_moved = 0, bail = 0;
 	int locked, giveup;
 	struct sctp_stream_queue_pending *sp;
@@ -7261,11 +7265,10 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
 				break;
 		} else {
 			asoc->locked_on_sending = NULL;
-			strqt = sctp_select_a_stream(stcb, asoc);
-			if (TAILQ_FIRST(&strq->outqueue) == NULL) {
+			if (TAILQ_EMPTY(&strq->outqueue)) {
 				if (strq == strqn) {
 					/* Must move start to next one */
-					strqn = TAILQ_NEXT(asoc->last_out_stream, next_spoke);
+					strqn = TAILQ_NEXT(strq, next_spoke);
 					if (strqn == NULL) {
 						strqn = TAILQ_FIRST(&asoc->out_wheel);
 						if (strqn == NULL) {
@@ -7278,7 +7281,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
 			if ((giveup) || bail) {
 				break;
 			}
-			strq = strqt;
+			strq = sctp_select_a_stream(stcb, asoc);
 			if (strq == NULL) {
 				break;
 			}

From 62ec4c19c4d8ba7a5434c1522b0d502b61d5f14b Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 18:03:16 +0000
Subject: [PATCH 413/646] - Numerous whitespace and style fixes. - More
 descriptive error messages when failing to parse components during   attach.

---
 sys/dev/acpi_support/acpi_aiboost.c | 279 +++++++++++++++-------------
 1 file changed, 145 insertions(+), 134 deletions(-)

diff --git a/sys/dev/acpi_support/acpi_aiboost.c b/sys/dev/acpi_support/acpi_aiboost.c
index a8fe9cc4a45..ab7433b5448 100644
--- a/sys/dev/acpi_support/acpi_aiboost.c
+++ b/sys/dev/acpi_support/acpi_aiboost.c
@@ -41,23 +41,25 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-#define _COMPONENT	ACPI_OEM
+#define	_COMPONENT	ACPI_OEM
 ACPI_MODULE_NAME("AIBOOST")
 
-#define DESCSTRLEN 32
-struct acpi_aiboost_element{
+#define	DESCSTRLEN	32
+
+struct acpi_aiboost_element {
 	uint32_t id;
-	char desc[DESCSTRLEN];
+	char	desc[DESCSTRLEN];
 };
+
 ACPI_SERIAL_DECL(aiboost, "ACPI AIBOOST");
-/**/
-struct acpi_aiboost_component{
-	unsigned int num;
-	struct acpi_aiboost_element elem[1];
+
+struct acpi_aiboost_component {
+	u_int	num;
+	struct acpi_aiboost_element elem[0];
 };
 
 struct acpi_aiboost_softc {
-	int pid;
+	int	pid;
 	struct acpi_aiboost_component *temp;
 	struct acpi_aiboost_component *volt;
 	struct acpi_aiboost_component *fan;
@@ -65,7 +67,7 @@ struct acpi_aiboost_softc {
 
 static int	acpi_aiboost_probe(device_t dev);
 static int	acpi_aiboost_attach(device_t dev);
-static int 	acpi_aiboost_detach(device_t dev);
+static int	acpi_aiboost_detach(device_t dev);
 
 static device_method_t acpi_aiboost_methods[] = {
 	/* Device interface */
@@ -85,46 +87,56 @@ static driver_t	acpi_aiboost_driver = {
 static devclass_t acpi_aiboost_devclass;
 
 DRIVER_MODULE(acpi_aiboost, acpi, acpi_aiboost_driver, acpi_aiboost_devclass,
-	      0, 0);
+    0, 0);
 MODULE_DEPEND(acpi_aiboost, acpi, 1, 1, 1);
+
 static char    *abs_id[] = {"ATK0110", NULL};
 
-/*VSIF, RVLT, SVLT,  TSIF, RTMP, STMP FSIF, RFAN, SFAN */
+/* VSIF, RVLT, SVLT, TSIF, RTMP, STMP, FSIF, RFAN, SFAN */
 
-static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct  acpi_aiboost_component **comp)
+static ACPI_STATUS
+acpi_aiboost_getcomponent(device_t dev, char *name,
+    struct acpi_aiboost_component **comp)
 {
-	ACPI_BUFFER		buf, buf2;
-	ACPI_OBJECT            *o,*elem,*subobj;
+	ACPI_BUFFER buf, buf2;
+	ACPI_OBJECT *elem, *o, *subobj;
 	ACPI_STATUS status;
-	struct acpi_aiboost_component *c = NULL;
-
+	struct acpi_aiboost_component *c;
 	int i;
 
+	c = NULL;
 	buf.Pointer = NULL;
 	buf.Length = ACPI_ALLOCATE_BUFFER;
 	buf2.Pointer = NULL;
-
 	status = AcpiEvaluateObject(acpi_get_handle(dev), name, NULL, &buf);
-	
-	if(ACPI_FAILURE(status))
-		return status;
-	
-	o = buf.Pointer;
-	if(o->Type != ACPI_TYPE_PACKAGE)
-		goto error;
-	
-	elem = o->Package.Elements;
-	if(elem->Type != ACPI_TYPE_INTEGER)
-		goto error;
 
-	c = malloc(sizeof(struct acpi_aiboost_component)
-		   + sizeof(struct acpi_aiboost_element)
-		   * (elem->Integer.Value -1),
-		   M_DEVBUF, M_ZERO|M_WAITOK);
+	if (ACPI_FAILURE(status))
+		return (status);
+
+	o = buf.Pointer;
+	if (o->Type != ACPI_TYPE_PACKAGE) {
+		device_printf(dev, "%s is not a package\n", name);
+		goto error;
+	}
+
+	elem = o->Package.Elements;
+	if (elem->Type != ACPI_TYPE_INTEGER) {
+		device_printf(dev, "First item in %s is not a count\n", name);
+		goto error;
+	}
+
+	if (elem->Integer.Value != o->Package.Count - 1) {
+		device_printf(dev, "Device count mismatch in %s\n", name);
+		goto error;
+	}
+
+	c = malloc(sizeof(struct acpi_aiboost_component) +
+	    sizeof(struct acpi_aiboost_element) * elem->Integer.Value, M_DEVBUF,
+	    M_WAITOK | M_ZERO);
 	*comp = c;
 	c->num = elem->Integer.Value;
-	
-	for(i = 1 ; i < o->Package.Count; i++){
+
+	for (i = 1; i < o->Package.Count; i++) {
 		elem = &o->Package.Elements[i];
 		if (elem->Type == ACPI_TYPE_ANY) {
 			buf2.Pointer = NULL;
@@ -132,196 +144,195 @@ static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct  a
 
 			status = AcpiEvaluateObject(elem->Reference.Handle,
 			    NULL, NULL, &buf2);
-			if (ACPI_FAILURE(status)){
-				printf("FETCH OBJECT\n");
+			if (ACPI_FAILURE(status)) {
+				device_printf(dev,
+				    "Failed to fetch object for %s\n", name);
 				goto error;
 			}
 			subobj = buf2.Pointer;
 		} else if (elem->Type == ACPI_TYPE_PACKAGE)
 			subobj = elem;
 		else {
-			printf("NO PACKAGE\n");
+			device_printf(dev,
+			    "Subitem %d was not a package for %s\n", i, name);
 			goto error;
 		}
-		if(ACPI_FAILURE(acpi_PkgInt32(subobj,0, &c->elem[i -1].id))){
-			printf("ID FAILED\n");
+		status = acpi_PkgInt32(subobj, 0, &c->elem[i - 1].id);
+		if (ACPI_FAILURE(status)) {
+			device_printf(dev,
+			    "Failed to fetch ID for subobject %d in %s\n", i,
+			    name);
 			goto error;
 		}
-		status = acpi_PkgStr(subobj, 1, c->elem[i - 1].desc, 
-				     sizeof(c->elem[i - 1].desc));
-		if(ACPI_FAILURE(status)){
-			if(status == E2BIG){
+		status = acpi_PkgStr(subobj, 1, c->elem[i - 1].desc,
+		    sizeof(c->elem[i - 1].desc));
+		if (ACPI_FAILURE(status)){
+			if (status == E2BIG) {
 				c->elem[i - 1].desc[DESCSTRLEN-1] = 0;
-			}else{
-				printf("DESC FAILED %d\n", i-1);
+			} else {
+				device_printf(dev,
+		    "Failed to fetch description for subobject %d in %s\n",
+				    i, name);
 				goto error;
 			}
 		}
-		
+
 		if (buf2.Pointer) {
 			AcpiOsFree(buf2.Pointer);
 			buf2.Pointer = NULL;
 		}
 	}
 
-	if(buf.Pointer)
+	if (buf.Pointer)
 		AcpiOsFree(buf.Pointer);
 
-	return 0;
+	return (0);
 
- error:
-	printf("BAD DATA\n");
-	if(buf.Pointer)
+error:
+	if (buf.Pointer)
 		AcpiOsFree(buf.Pointer);
-	if(buf2.Pointer)
+	if (buf2.Pointer)
 		AcpiOsFree(buf2.Pointer);
-	if(c)
+	if (c)
 		free(c, M_DEVBUF);
-	return AE_BAD_DATA;
+	return (AE_BAD_DATA);
 }
 
-static int 
+static int
 acpi_aiboost_get_value(ACPI_HANDLE handle, char *path, UINT32 number)
 {
 	ACPI_OBJECT arg1, *ret;
 	ACPI_OBJECT_LIST args;
 	ACPI_BUFFER buf;
-	buf.Length = ACPI_ALLOCATE_BUFFER;
-	buf.Pointer = 0;
 	int val;
 
 	arg1.Type = ACPI_TYPE_INTEGER;
 	arg1.Integer.Value = number;
 	args.Count = 1;
 	args.Pointer = &arg1;
-
-	if(ACPI_FAILURE(AcpiEvaluateObject(handle, path, &args, &buf))){
-		return -1;
-	}
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	buf.Pointer = NULL;
+	if (ACPI_FAILURE(AcpiEvaluateObject(handle, path, &args, &buf)))
+		return (-1);
 
 	ret = buf.Pointer;
-	val = (ret->Type == ACPI_TYPE_INTEGER)? ret->Integer.Value : -1;
+	if (ret->Type == ACPI_TYPE_INTEGER)
+		val = ret->Integer.Value;
+	else
+		val = -1;
 
 	AcpiOsFree(buf.Pointer);
-	return val;
+	return (val);
 }
 
 
-static int acpi_aiboost_temp_sysctl(SYSCTL_HANDLER_ARGS)
+static int
+acpi_aiboost_temp_sysctl(SYSCTL_HANDLER_ARGS)
 {
-	device_t dev = arg1;
-	int function = oidp->oid_arg2;
-	int error = 0, val;
+	device_t dev;
+	int error, val;
+
+	dev = arg1;
 	ACPI_SERIAL_BEGIN(aiboost);
-	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RTMP",function );
-	error = sysctl_handle_int(oidp, &val, 0 , req);
+	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RTMP", arg2);
+	error = sysctl_handle_int(oidp, &val, 0, req);
 	ACPI_SERIAL_END(aiboost);
-	
-	return 0;
+	return (error);
 }
 
-static int acpi_aiboost_volt_sysctl(SYSCTL_HANDLER_ARGS)
+static int
+acpi_aiboost_volt_sysctl(SYSCTL_HANDLER_ARGS)
 {
-	device_t dev = arg1;
-	int function = oidp->oid_arg2;
-	int error = 0, val;
+	device_t dev;
+	int error, val;
+
+	dev = arg1;
 	ACPI_SERIAL_BEGIN(aiboost);
-	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RVLT", function);
-	error = sysctl_handle_int(oidp, &val, 0 , req);
+	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RVLT", arg2);
+	error = sysctl_handle_int(oidp, &val, 0, req);
 	ACPI_SERIAL_END(aiboost);
-	
-	return 0;
+	return (error);
 }
 
-static int acpi_aiboost_fan_sysctl(SYSCTL_HANDLER_ARGS)
+static int
+acpi_aiboost_fan_sysctl(SYSCTL_HANDLER_ARGS)
 {
-	device_t dev = arg1;
-	int function = oidp->oid_arg2;
-	int error = 0, val;
+	device_t dev;
+	int error, val;
+
+	dev = arg1;
 	ACPI_SERIAL_BEGIN(aiboost);
-	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RFAN", function);
-	error = sysctl_handle_int(oidp, &val, 0 , req);
+	val = acpi_aiboost_get_value(acpi_get_handle(dev), "RFAN", arg2);
+	error = sysctl_handle_int(oidp, &val, 0, req);
 	ACPI_SERIAL_END(aiboost);
-	
-	return 0;
+	return (error);
 }
 
 static int
 acpi_aiboost_probe(device_t dev)
 {
-	int		ret = ENXIO;
 
-	if (ACPI_ID_PROBE(device_get_parent(dev), dev, abs_id)) {
-		device_set_desc(dev, "ASUStek AIBOOSTER");
-		ret = 0;
-	}
-	return (ret);
+	if (ACPI_ID_PROBE(device_get_parent(dev), dev, abs_id) == NULL)
+		return (ENXIO);
+
+	device_set_desc(dev, "ASUStek AIBOOSTER");
+	return (0);
 }
 
 static int
 acpi_aiboost_attach(device_t dev)
 {
 	struct acpi_aiboost_softc *sc;
-	char nambuf[]="tempXXX";
+	char nambuf[16];
 	int i;
 
 	sc = device_get_softc(dev);
-	if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "TSIF", &sc->temp)))
+	if (ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "TSIF", &sc->temp)))
 		goto error;
-	for(i= 0; i < sc->temp->num; i++){
-		sprintf(nambuf,"temp%d", i);
+	for (i = 0; i < sc->temp->num; i++) {
+		snprintf(nambuf, sizeof(nambuf), "temp%d", i);
 		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-				SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-				OID_AUTO, nambuf,
-				CTLTYPE_INT|CTLFLAG_RD, dev, 
-				sc->temp->elem[i].id,
-				acpi_aiboost_temp_sysctl,
-				"I", sc->temp->elem[i].desc);
-	}
-	if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "VSIF", &sc->volt)))
-		goto error;
-
-	for(i= 0; i < sc->volt->num; i++){
-		sprintf(nambuf,"volt%d", i);
-		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-				SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-				OID_AUTO, nambuf,
-				CTLTYPE_INT|CTLFLAG_RD, dev, 
-				sc->volt->elem[i].id,
-				acpi_aiboost_volt_sysctl,
-				"I", sc->volt->elem[i].desc);
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		    nambuf, CTLTYPE_INT | CTLFLAG_RD, dev, sc->temp->elem[i].id,
+		    acpi_aiboost_temp_sysctl, "I", sc->temp->elem[i].desc);
 	}
 
-	if(ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "FSIF", &sc->fan)))
+	if (ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "VSIF", &sc->volt)))
 		goto error;
-
-	for(i= 0; i < sc->fan->num; i++){
-		sprintf(nambuf,"fan%d", i);
+	for (i = 0; i < sc->volt->num; i++) {
+		snprintf(nambuf, sizeof(nambuf), "volt%d", i);
 		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-				SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-				OID_AUTO, nambuf,
-				CTLTYPE_INT|CTLFLAG_RD, dev, 
-				sc->fan->elem[i].id,
-				acpi_aiboost_fan_sysctl,
-				"I", sc->fan->elem[i].desc);
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		    nambuf, CTLTYPE_INT | CTLFLAG_RD, dev, sc->volt->elem[i].id,
+		    acpi_aiboost_volt_sysctl, "I", sc->volt->elem[i].desc);
+	}
+
+	if (ACPI_FAILURE(acpi_aiboost_getcomponent(dev, "FSIF", &sc->fan)))
+		goto error;
+	for (i = 0; i < sc->fan->num; i++) {
+		snprintf(nambuf, sizeof(nambuf), "fan%d", i);
+		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		    nambuf, CTLTYPE_INT | CTLFLAG_RD, dev, sc->fan->elem[i].id,
+		    acpi_aiboost_fan_sysctl, "I", sc->fan->elem[i].desc);
 	}
 
-	
 	return (0);
  error:
-	return EINVAL;
+	return (EINVAL);
 }
 
-static int 
+static int
 acpi_aiboost_detach(device_t dev)
 {
-	struct acpi_aiboost_softc *sc = device_get_softc(dev);
+	struct acpi_aiboost_softc *sc;
 
-	if(sc->temp)
+	sc = device_get_softc(dev);
+	if (sc->temp)
 		free(sc->temp, M_DEVBUF);
-	if(sc->volt)
+	if (sc->volt)
 		free(sc->volt, M_DEVBUF);
-	if(sc->fan)
+	if (sc->fan)
 		free(sc->fan, M_DEVBUF);
 	return (0);
 }

From 6bd41d5bc2341f1fc2dd25a3cdcd903bee9cf5c2 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 20:53:26 +0000
Subject: [PATCH 414/646] Add missing ATA kernel options dependencies.

MFC after:	3 days
---
 sys/conf/files | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 8c9b9549547..b8dee582038 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -520,14 +520,14 @@ dev/ata/chipsets/ata-highpoint.c	optional ata pci | atahighpoint
 dev/ata/chipsets/ata-intel.c	optional ata pci | ataintel
 dev/ata/chipsets/ata-ite.c	optional ata pci | ataite
 dev/ata/chipsets/ata-jmicron.c	optional ata pci | atajmicron
-dev/ata/chipsets/ata-marvell.c	optional ata pci | atamarvell
+dev/ata/chipsets/ata-marvell.c	optional ata pci | atamarvell | ataadaptec
 dev/ata/chipsets/ata-micron.c	optional ata pci | atamicron
 dev/ata/chipsets/ata-national.c	optional ata pci | atanational
 dev/ata/chipsets/ata-netcell.c	optional ata pci | atanetcell
 dev/ata/chipsets/ata-nvidia.c	optional ata pci | atanvidia
 dev/ata/chipsets/ata-promise.c	optional ata pci | atapromise
 dev/ata/chipsets/ata-serverworks.c	optional ata pci | ataserverworks
-dev/ata/chipsets/ata-siliconimage.c	optional ata pci | atasiliconimage
+dev/ata/chipsets/ata-siliconimage.c	optional ata pci | atasiliconimage | ataati
 dev/ata/chipsets/ata-sis.c	optional ata pci | atasis
 dev/ata/chipsets/ata-via.c	optional ata pci | atavia
 dev/ata/ata-disk.c		optional atadisk

From 80a8b0f3bff89773974cc7e109c340a3c195070c Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 30 Oct 2009 10:10:39 +0000
Subject: [PATCH 415/646] Trapsignal() and postsig() call kern_sigprocmask()
 with both process lock and curproc->p_sigacts->ps_mtx. Reschedule_signals may
 need to have ps_mtx locked to decide and wakeup a thread, causing recursion
 on the mutex.

Inform kern_sigprocmask() and reschedule_signals() about lock state
of the ps_mtx by new flag SIGPROCMASK_PS_LOCKED to avoid recursion.

Reported and tested by:	keramida
MFC after:	1 month
---
 sys/kern/kern_sig.c | 36 ++++++++++++++++--------------------
 sys/sys/signalvar.h |  1 +
 2 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 7f5cfa32ad8..e174df1e42d 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -220,7 +220,7 @@ static int sigproptbl[NSIG] = {
         SA_KILL|SA_PROC,		/* SIGUSR2 */
 };
 
-static void reschedule_signals(struct proc *p, sigset_t block);
+static void reschedule_signals(struct proc *p, sigset_t block, int flags);
 
 static void
 sigqueue_start(void)
@@ -1024,7 +1024,7 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
 	 * possibly waking it up.
 	 */
 	if (p->p_numthreads != 1)
-		reschedule_signals(p, new_block);
+		reschedule_signals(p, new_block, flags);
 
 	if (!(flags & SIGPROCMASK_PROC_LOCKED))
 		PROC_UNLOCK(p);
@@ -1859,13 +1859,11 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
 #endif
 		(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], 
 				ksi, &td->td_sigmask);
-		SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
-		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
-			SIGEMPTYSET(mask);
+		mask = ps->ps_catchmask[_SIG_IDX(sig)];
+		if (!SIGISMEMBER(ps->ps_signodefer, sig))
 			SIGADDSET(mask, sig);
-			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
-			    SIGPROCMASK_PROC_LOCKED);
-		}
+		kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
+		    SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*
 			 * See kern_sigaction() for origin of this code.
@@ -2401,7 +2399,7 @@ stopme:
 }
 
 static void
-reschedule_signals(struct proc *p, sigset_t block)
+reschedule_signals(struct proc *p, sigset_t block, int flags)
 {
 	struct sigacts *ps;
 	struct thread *td;
@@ -2419,12 +2417,14 @@ reschedule_signals(struct proc *p, sigset_t block)
 
 		td = sigtd(p, i, 0);
 		signotify(td);
-		mtx_lock(&ps->ps_mtx);
+		if (!(flags & SIGPROCMASK_PS_LOCKED))
+			mtx_lock(&ps->ps_mtx);
 		if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, i))
 			tdsigwakeup(td, i, SIG_CATCH,
 			    (SIGISMEMBER(ps->ps_sigintr, i) ? EINTR :
 			     ERESTART));
-		mtx_unlock(&ps->ps_mtx);
+		if (!(flags & SIGPROCMASK_PS_LOCKED))
+			mtx_unlock(&ps->ps_mtx);
 	}
 }
 
@@ -2452,7 +2452,7 @@ tdsigcleanup(struct thread *td)
 	SIGFILLSET(unblocked);
 	SIGSETNAND(unblocked, td->td_sigmask);
 	SIGFILLSET(td->td_sigmask);
-	reschedule_signals(p, unblocked);
+	reschedule_signals(p, unblocked, 0);
 
 }
 
@@ -2734,15 +2734,11 @@ postsig(sig)
 		} else
 			returnmask = td->td_sigmask;
 
-		kern_sigprocmask(td, SIG_BLOCK,
-		    &ps->ps_catchmask[_SIG_IDX(sig)], NULL,
-		    SIGPROCMASK_PROC_LOCKED);
-		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
-			SIGEMPTYSET(mask);
+		mask = ps->ps_catchmask[_SIG_IDX(sig)];
+		if (!SIGISMEMBER(ps->ps_signodefer, sig))
 			SIGADDSET(mask, sig);
-			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
-			    SIGPROCMASK_PROC_LOCKED);
-		}
+		kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
+		    SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
 
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index b9a54f030d0..c27a1280801 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -319,6 +319,7 @@ extern int kern_logsigexit;	/* Sysctl variable kern.logsigexit */
 /* flags for kern_sigprocmask */
 #define	SIGPROCMASK_OLD		0x0001
 #define	SIGPROCMASK_PROC_LOCKED	0x0002
+#define	SIGPROCMASK_PS_LOCKED	0x0004
 
 /*
  * Machine-independent functions:

From 2bc706c6482adb2f598386e3cb86b3fb2da90b29 Mon Sep 17 00:00:00 2001
From: Colin Percival 
Date: Fri, 30 Oct 2009 11:13:00 +0000
Subject: [PATCH 416/646] Add notes pointing out that bsdiff does not store
 file hashes and bspatch thus does not verify file hashes, and that
 consequently it is recommended that users store hashes separately and verify
 files before and after running bspatch.

Requested by:	BugMagnet
MFC after:	1 week
---
 usr.bin/bsdiff/bsdiff/bsdiff.1   | 19 +++++++++++++++++++
 usr.bin/bsdiff/bspatch/bspatch.1 | 21 +++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/usr.bin/bsdiff/bsdiff/bsdiff.1 b/usr.bin/bsdiff/bsdiff/bsdiff.1
index 5c608b44c42..4ceb9ed5bb0 100644
--- a/usr.bin/bsdiff/bsdiff/bsdiff.1
+++ b/usr.bin/bsdiff/bsdiff/bsdiff.1
@@ -65,5 +65,24 @@ an absolute minimum working set size of 8 times the size of
 .Ar oldfile .
 .Sh SEE ALSO
 .Xr bspatch 1
+.Sh BUGS
+The
+.Nm
+utility does not store the hashes of
+.Ar oldfile
+or 
+.Ar newfile
+in
+.Ar patchfile .
+As a result, it is possible to apply a patch to the wrong file; this
+will usually produce garbage.
+It is recommended that users of
+.Nm
+store the hashes of
+.Ar oldfile
+and
+.Ar newfile
+and compare against them before and after applying
+.Ar patchfile .
 .Sh AUTHORS
 .An Colin Percival Aq cperciva@FreeBSD.org
diff --git a/usr.bin/bsdiff/bspatch/bspatch.1 b/usr.bin/bsdiff/bspatch/bspatch.1
index 894bc507522..29b8db3c81e 100644
--- a/usr.bin/bsdiff/bspatch/bspatch.1
+++ b/usr.bin/bsdiff/bspatch/bspatch.1
@@ -61,5 +61,26 @@ but can tolerate a very small working set without a dramatic loss
 of performance.
 .Sh SEE ALSO
 .Xr bsdiff 1
+.Sh BUGS
+The
+.Nm
+utility does not verify that
+.Ar oldfile
+is the correct source file for
+.Ar patchfile .
+Attempting to apply a patch to the wrong file will usually produce
+garbage; consequently it is strongly recommended that users of
+.Nm
+verify that
+.Ar oldfile
+matches the source file from which
+.Ar patchfile
+was built, by comparing cryptographic hashes, for example.
+Users may also wish to verify after running
+.Nm
+that
+.Ar newfile
+matches the target file from which
+.Ar was built.
 .Sh AUTHORS
 .An Colin Percival Aq cperciva@FreeBSD.org

From ff301ae2afe7184255a8e551c9eb8cb291ccb6dc Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Fri, 30 Oct 2009 16:00:34 +0000
Subject: [PATCH 417/646] Make procstat -k work on PowerPC by avoiding
 mistakenly using signed compares with a low address (0x1000) and a high
 address (the KVA kernel stack).

---
 sys/powerpc/powerpc/stack_machdep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/powerpc/powerpc/stack_machdep.c b/sys/powerpc/powerpc/stack_machdep.c
index 7bc6fd45ca7..b3519c39d74 100644
--- a/sys/powerpc/powerpc/stack_machdep.c
+++ b/sys/powerpc/powerpc/stack_machdep.c
@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 static void
-stack_capture(struct stack *st, register_t frame)
+stack_capture(struct stack *st, vm_offset_t frame)
 {
 	vm_offset_t callpc;
 
@@ -76,7 +76,7 @@ stack_capture(struct stack *st, register_t frame)
 void
 stack_save_td(struct stack *st, struct thread *td)
 {
-	register_t frame;
+	vm_offset_t frame;
 
 	if (TD_IS_SWAPPED(td))
 		panic("stack_save_td: swapped");

From a4522488149b82d73f120919b29b78ec7bc1192d Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 30 Oct 2009 16:23:56 +0000
Subject: [PATCH 418/646] Add support for Adaptec 39320LPE adapters.

PR:		124202
Submitted by:	Andre Albsmeier 
Reviewed by:	gibbs
MFC after:	1 week
---
 sys/dev/aic7xxx/aic79xx_pci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c
index d19313a96a7..928012e0475 100644
--- a/sys/dev/aic7xxx/aic79xx_pci.c
+++ b/sys/dev/aic7xxx/aic79xx_pci.c
@@ -89,6 +89,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
 #define ID_AHA_39320D_B			0x801C900500419005ull
 #define ID_AHA_39320D_HP		0x8011900500AC0E11ull
 #define ID_AHA_39320D_B_HP		0x801C900500AC0E11ull
+#define ID_AHA_39320LPE 		0x8017900500459005ull
 #define ID_AIC7902_PCI_REV_A4		0x3
 #define ID_AIC7902_PCI_REV_B0		0x10
 #define SUBID_HP			0x0E11
@@ -204,6 +205,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
 		"Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
 		ahd_aic7902_setup
 	},
+	{
+		ID_AHA_39320LPE,
+		ID_ALL_MASK,
+		"Adaptec 39320LPE Ultra320 SCSI adapter",
+		ahd_aic7902_setup
+	},
 	/* Generic chip probes for devices we don't know 'exactly' */
 	{
 		ID_AIC7901 & ID_9005_GENERIC_MASK,

From 883759335fc6b0e480f7d19b57c7066759a0f356 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:55:31 +0000
Subject: [PATCH 419/646] Fix blitter support for RS880 chips

MFC after:	3 days
---
 sys/dev/drm/r600_blit.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c
index 6443d843f98..3e64e42b357 100644
--- a/sys/dev/drm/r600_blit.c
+++ b/sys/dev/drm/r600_blit.c
@@ -1367,7 +1367,7 @@ set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
-	    /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
 		cp_set_surface_sync(dev_priv,
 				    R600_TC_ACTION_ENA, 48, gpu_addr);
@@ -1509,7 +1509,7 @@ set_default_state(drm_radeon_private_t *dev_priv)
 	case CHIP_RV610:
 	case CHIP_RV620:
 	case CHIP_RS780:
-	/*case CHIP_RS880:*/
+	case CHIP_RS880:
 	default:
 		num_ps_gprs = 84;
 		num_vs_gprs = 36;
@@ -1591,7 +1591,7 @@ set_default_state(drm_radeon_private_t *dev_priv)
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
-	    /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
 		sq_config = 0;
 	else

From 6d68455174d85948edc5e1728204c3c3e3a888e1 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:59:58 +0000
Subject: [PATCH 420/646] Use system specified memory barriers rather than
 rolling our own.

---
 sys/dev/drm/drmP.h | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index cad2cee623a..25e272e927b 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -223,23 +223,9 @@ typedef u_int8_t u8;
  * DRM_WRITEMEMORYBARRIER() prevents reordering of writes.
  * DRM_MEMORYBARRIER() prevents reordering of reads and writes.
  */
-#if defined(__i386__)
-#define DRM_READMEMORYBARRIER()		__asm __volatile( \
-					"lock; addl $0,0(%%esp)" : : : "memory");
-#define DRM_WRITEMEMORYBARRIER()	__asm __volatile("" : : : "memory");
-#define DRM_MEMORYBARRIER()		__asm __volatile( \
-					"lock; addl $0,0(%%esp)" : : : "memory");
-#elif defined(__alpha__)
-#define DRM_READMEMORYBARRIER()		alpha_mb();
-#define DRM_WRITEMEMORYBARRIER()	alpha_wmb();
-#define DRM_MEMORYBARRIER()		alpha_mb();
-#elif defined(__amd64__)
-#define DRM_READMEMORYBARRIER()		__asm __volatile( \
-					"lock; addl $0,0(%%rsp)" : : : "memory");
-#define DRM_WRITEMEMORYBARRIER()	__asm __volatile("" : : : "memory");
-#define DRM_MEMORYBARRIER()		__asm __volatile( \
-					"lock; addl $0,0(%%rsp)" : : : "memory");
-#endif
+#define DRM_READMEMORYBARRIER()		rmb()
+#define DRM_WRITEMEMORYBARRIER()	wmb()
+#define DRM_MEMORYBARRIER()		mb()
 
 #define DRM_READ8(map, offset)						\
 	*(volatile u_int8_t *)(((vm_offset_t)(map)->handle) +		\

From 615fb6e9bcb4bd27ff6de0af0eb5d886402d71dc Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 18:02:10 +0000
Subject: [PATCH 421/646] Some general cleanup of scatter/gather memory
 allocation

 - We don't need to check malloc return values with M_WAITOK
 - remove variables that we don't really need
 - cleanup the error paths by just calling drm_sg_cleanup()
 - fix drm_sg_cleanup() to be safe to call at any time

MFC after:	2 weeks
---
 sys/dev/drm/drm_scatter.c | 69 ++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 44 deletions(-)

diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c
index 5f8b29b001b..7fbf37182e4 100644
--- a/sys/dev/drm/drm_scatter.c
+++ b/sys/dev/drm/drm_scatter.c
@@ -47,35 +47,20 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request)
 {
 	struct drm_sg_mem *entry;
 	struct drm_dma_handle *dmah;
-	unsigned long pages;
 	int ret;
 
 	if (dev->sg)
 		return EINVAL;
 
 	entry = malloc(sizeof(*entry), DRM_MEM_SGLISTS, M_WAITOK | M_ZERO);
-	if (!entry)
-		return ENOMEM;
-
-	pages = round_page(request->size) / PAGE_SIZE;
-	DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages);
-
-	entry->pages = pages;
-
-	entry->busaddr = malloc(pages * sizeof(*entry->busaddr), DRM_MEM_PAGES,
-	    M_WAITOK | M_ZERO);
-	if (!entry->busaddr) {
-		free(entry, DRM_MEM_SGLISTS);
-		return ENOMEM;
-	}
+	entry->pages = round_page(request->size) / PAGE_SIZE;
+	DRM_DEBUG("sg size=%ld pages=%d\n", request->size, entry->pages);
 
+	entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr),
+	    DRM_MEM_PAGES, M_WAITOK | M_ZERO);
 	dmah = malloc(sizeof(struct drm_dma_handle), DRM_MEM_DMA,
-	    M_ZERO | M_NOWAIT);
-	if (dmah == NULL) {
-		free(entry->busaddr, DRM_MEM_PAGES);
-		free(entry, DRM_MEM_SGLISTS);
-		return ENOMEM;
-	}
+	    M_WAITOK | M_ZERO);
+	entry->dmah = dmah;
 
 	ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */
@@ -85,41 +70,27 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request)
 	    NULL, NULL, /* lockfunc, lockfuncargs */
 	    &dmah->tag);
 	if (ret != 0) {
-		free(dmah, DRM_MEM_DMA);
-		free(entry->busaddr, DRM_MEM_PAGES);
-		free(entry, DRM_MEM_SGLISTS);
+		drm_sg_cleanup(entry);
 		return ENOMEM;
 	}
 
 	ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr,
 	    BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map);
 	if (ret != 0) {
-		bus_dma_tag_destroy(dmah->tag);
-		free(dmah, DRM_MEM_DMA);
-		free(entry->busaddr, DRM_MEM_PAGES);
-		free(entry, DRM_MEM_SGLISTS);
+		drm_sg_cleanup(entry);
 		return ENOMEM;
 	}
 
+	entry->handle = (unsigned long)dmah->vaddr;
+	entry->virtual = dmah->vaddr;
+
 	ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr,
 	    request->size, drm_sg_alloc_cb, entry, BUS_DMA_NOWAIT);
 	if (ret != 0) {
-		bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
-		bus_dma_tag_destroy(dmah->tag);
-		free(dmah, DRM_MEM_DMA);
-		free(entry->busaddr, DRM_MEM_PAGES);
-		free(entry, DRM_MEM_SGLISTS);
+		drm_sg_cleanup(entry);
 		return ENOMEM;
 	}
 
-	entry->dmah = dmah;
-	entry->handle = (unsigned long)dmah->vaddr;
-	
-	DRM_DEBUG("sg alloc handle  = %08lx\n", entry->handle);
-
-	entry->virtual = (void *)entry->handle;
-	request->handle = entry->handle;
-
 	DRM_LOCK();
 	if (dev->sg) {
 		DRM_UNLOCK();
@@ -129,6 +100,11 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request)
 	dev->sg = entry;
 	DRM_UNLOCK();
 
+	DRM_DEBUG("handle=%08lx, kva=%p, contents=%08lx\n", entry->handle,
+	    entry->virtual, *(unsigned long *)entry->virtual);
+
+	request->handle = entry->handle;
+
 	return 0;
 }
 
@@ -143,6 +119,8 @@ drm_sg_alloc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 
 	for(i = 0 ; i < nsegs ; i++) {
 		entry->busaddr[i] = segs[i].ds_addr;
+		DRM_DEBUG("segment %d @ 0x%016lx\n", i,
+		    (unsigned long)segs[i].ds_addr);
 	}
 }
 
@@ -162,9 +140,12 @@ drm_sg_cleanup(struct drm_sg_mem *entry)
 {
 	struct drm_dma_handle *dmah = entry->dmah;
 
-	bus_dmamap_unload(dmah->tag, dmah->map);
-	bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
-	bus_dma_tag_destroy(dmah->tag);
+	if (dmah->map != NULL)
+		bus_dmamap_unload(dmah->tag, dmah->map);
+	if (dmah->vaddr != NULL)
+		bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
+	if (dmah->tag != NULL)
+		bus_dma_tag_destroy(dmah->tag);
 	free(dmah, DRM_MEM_DMA);
 	free(entry->busaddr, DRM_MEM_PAGES);
 	free(entry, DRM_MEM_SGLISTS);

From 29e3ffd4f5309dcdcea7f9246b77620068e6a05d Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 18:07:22 +0000
Subject: [PATCH 422/646] A bit of cleanup work on radeon_freelist_get()

  * Fix the main loop to search all buffers before sleeping.
  * Remove dead code

MFC after:	3 days
---
 sys/dev/drm/radeon_cp.c | 45 ++++-------------------------------------
 1 file changed, 4 insertions(+), 41 deletions(-)

diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c
index 734fafa445f..2e85f115a6d 100644
--- a/sys/dev/drm/radeon_cp.c
+++ b/sys/dev/drm/radeon_cp.c
@@ -1860,8 +1860,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
 	for (t = 0; t < dev_priv->usec_timeout; t++) {
 		u32 done_age = GET_SCRATCH(dev_priv, 1);
 		DRM_DEBUG("done_age = %d\n", done_age);
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
+		for (i = 0; i < dma->buf_count; i++) {
+			buf = dma->buflist[start];
 			buf_priv = buf->dev_private;
 			if (buf->file_priv == NULL || (buf->pending &&
 						       buf_priv->age <=
@@ -1870,7 +1870,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
 				buf->pending = 0;
 				return buf;
 			}
-			start = 0;
+			if (++start >= dma->buf_count)
+				start = 0;
 		}
 
 		if (t) {
@@ -1879,47 +1880,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
 		}
 	}
 
-	DRM_DEBUG("returning NULL!\n");
 	return NULL;
 }
 
-#if 0
-struct drm_buf *radeon_freelist_get(struct drm_device * dev)
-{
-	struct drm_device_dma *dma = dev->dma;
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	drm_radeon_buf_priv_t *buf_priv;
-	struct drm_buf *buf;
-	int i, t;
-	int start;
-	u32 done_age;
-
-	done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
-	if (++dev_priv->last_buf >= dma->buf_count)
-		dev_priv->last_buf = 0;
-
-	start = dev_priv->last_buf;
-	dev_priv->stats.freelist_loops++;
-
-	for (t = 0; t < 2; t++) {
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
-			buf_priv = buf->dev_private;
-			if (buf->file_priv == 0 || (buf->pending &&
-						    buf_priv->age <=
-						    done_age)) {
-				dev_priv->stats.requested_bufs++;
-				buf->pending = 0;
-				return buf;
-			}
-		}
-		start = 0;
-	}
-
-	return NULL;
-}
-#endif
-
 void radeon_freelist_reset(struct drm_device * dev)
 {
 	struct drm_device_dma *dma = dev->dma;

From 11de9e8c790c64c557d28ab082328fc73ea42dae Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 18:08:46 +0000
Subject: [PATCH 423/646] Cleanup in r600_blit

 - Don't bother to assign vb until we know we have enough space
 - Add variables for sx2, sy2, dx2, dy2 so that these aren't
   calculated over and over, also reduce chance of errors.
 - Use switch to assign color/format

MFC after:	3 days
---
 sys/dev/drm/r600_blit.c | 68 +++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 29 deletions(-)

diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c
index 3e64e42b357..a26f2c445b9 100644
--- a/sys/dev/drm/r600_blit.c
+++ b/sys/dev/drm/r600_blit.c
@@ -1719,7 +1719,10 @@ r600_blit_copy(struct drm_device *dev,
 	u32 *vb;
 
 	vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
-		      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
+	    dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
+	DRM_DEBUG("src=0x%016llx, dst=0x%016llx, size=%d\n",
+	    (unsigned long long)src_gpu_addr,
+	    (unsigned long long)dst_gpu_addr, size_bytes);
 
 	if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
 		max_bytes = 8192;
@@ -1757,7 +1760,7 @@ r600_blit_copy(struct drm_device *dev,
 					return;
 				set_shaders(dev);
 				vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
-					      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
+				    dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
 			}
 
 			vb[0] = i2f(dst_x);
@@ -1847,7 +1850,7 @@ r600_blit_copy(struct drm_device *dev,
 					return;
 				set_shaders(dev);
 				vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
-					      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
+				    dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
 			}
 
 			vb[0] = i2f(dst_x / 4);
@@ -1913,12 +1916,10 @@ r600_blit_swap(struct drm_device *dev,
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	int cb_format, tex_format;
+	int sx2, sy2, dx2, dy2;
 	u64 vb_addr;
 	u32 *vb;
 
-	vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
-		      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
-
 	if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
 		dev_priv->blit_vb->used = 0;
 		radeon_cp_discard_buffer(dev, dev_priv->blit_vb);
@@ -1926,20 +1927,14 @@ r600_blit_swap(struct drm_device *dev,
 		if (!dev_priv->blit_vb)
 			return;
 		set_shaders(dev);
-		vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
-			      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
 	}
+	vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+	    dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
 
-	if (cpp == 4) {
-		cb_format = COLOR_8_8_8_8;
-		tex_format = FMT_8_8_8_8;
-	} else if (cpp == 2) {
-		cb_format = COLOR_5_6_5;
-		tex_format = FMT_5_6_5;
-	} else {
-		cb_format = COLOR_8;
-		tex_format = FMT_8;
-	}
+	sx2 = sx + w;
+	sy2 = sy + h;
+	dx2 = dx + w;
+	dy2 = dy + h;
 
 	vb[0] = i2f(dx);
 	vb[1] = i2f(dy);
@@ -1947,31 +1942,46 @@ r600_blit_swap(struct drm_device *dev,
 	vb[3] = i2f(sy);
 
 	vb[4] = i2f(dx);
-	vb[5] = i2f(dy + h);
+	vb[5] = i2f(dy2);
 	vb[6] = i2f(sx);
-	vb[7] = i2f(sy + h);
+	vb[7] = i2f(sy2);
 
-	vb[8] = i2f(dx + w);
-	vb[9] = i2f(dy + h);
-	vb[10] = i2f(sx + w);
-	vb[11] = i2f(sy + h);
+	vb[8] = i2f(dx2);
+	vb[9] = i2f(dy2);
+	vb[10] = i2f(sx2);
+	vb[11] = i2f(sy2);
+
+	switch(cpp) {
+	case 4:
+		cb_format = COLOR_8_8_8_8;
+		tex_format = FMT_8_8_8_8;
+		break;
+	case 2:
+		cb_format = COLOR_5_6_5;
+		tex_format = FMT_5_6_5;
+		break;
+	default:
+		cb_format = COLOR_8;
+		tex_format = FMT_8;
+		break;
+	}
 
 	/* src */
 	set_tex_resource(dev_priv, tex_format,
 			 src_pitch / cpp,
-			 sy + h, src_pitch / cpp,
+			 sy2, src_pitch / cpp,
 			 src_gpu_addr);
 
 	cp_set_surface_sync(dev_priv,
-			    R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
+			    R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr);
 
 	/* dst */
 	set_render_target(dev_priv, cb_format,
-			  dst_pitch / cpp, dy + h,
+			  dst_pitch / cpp, dy2,
 			  dst_gpu_addr);
 
 	/* scissors */
-	set_scissors(dev_priv, dx, dy, dx + w, dy + h);
+	set_scissors(dev_priv, dx, dy, dx2, dy2);
 
 	/* Vertex buffer setup */
 	vb_addr = dev_priv->gart_buffers_offset +
@@ -1984,7 +1994,7 @@ r600_blit_swap(struct drm_device *dev,
 
 	cp_set_surface_sync(dev_priv,
 			    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
-			    dst_pitch * (dy + h), dst_gpu_addr);
+			    dst_pitch * dy2, dst_gpu_addr);
 
 	dev_priv->blit_vb->used += 12 * 4;
 }

From d2217702c1895f642ecae137e95318ec62214d2a Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 18:30:13 +0000
Subject: [PATCH 424/646] Fix botched git -> svn merge.

MFC after:	2 weeks
---
 sys/dev/drm/drm_scatter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c
index 7fbf37182e4..b3ab63b630c 100644
--- a/sys/dev/drm/drm_scatter.c
+++ b/sys/dev/drm/drm_scatter.c
@@ -65,7 +65,7 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request)
 	ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */
 	    NULL, NULL, /* filtfunc, filtfuncargs */
-	    request->size, pages, /* maxsize, nsegs */
+	    request->size, entry->pages, /* maxsize, nsegs */
 	    PAGE_SIZE, 0, /* maxsegsize, flags */
 	    NULL, NULL, /* lockfunc, lockfuncargs */
 	    &dmah->tag);

From 6aca3a5d0ba42c3cdfab104430c7640fce61a7f4 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 30 Oct 2009 20:28:49 +0000
Subject: [PATCH 425/646] Add support for different request block format used
 by Gen-IIe Marvell SATA. This adds support for Marvell 6042/7042 chips and
 Adaptec 1430SA controller.

---
 sys/dev/ata/ata-pci.h              |  3 ++
 sys/dev/ata/chipsets/ata-adaptec.c |  2 +
 sys/dev/ata/chipsets/ata-marvell.c | 83 +++++++++++++++++++++---------
 3 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index e3ab0253d75..7a6ed42f0c9 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -97,6 +97,7 @@ struct ata_pci_controller {
 
 #define ATA_ADAPTEC_ID          0x9005
 #define ATA_ADAPTEC_1420        0x02419005
+#define ATA_ADAPTEC_1430        0x02439005
 
 #define ATA_ATI_ID              0x1002
 #define ATA_ATI_IXP200          0x43491002
@@ -216,7 +217,9 @@ struct ata_pci_controller {
 #define ATA_M88SX5080           0x508011ab
 #define ATA_M88SX5081           0x508111ab
 #define ATA_M88SX6041           0x604111ab
+#define ATA_M88SX6042           0x604211ab
 #define ATA_M88SX6081           0x608111ab
+#define ATA_M88SX7042           0x704211ab
 #define ATA_M88SX6101           0x610111ab
 #define ATA_M88SX6121           0x612111ab
 #define ATA_M88SX6145           0x614511ab
diff --git a/sys/dev/ata/chipsets/ata-adaptec.c b/sys/dev/ata/chipsets/ata-adaptec.c
index 6b92ee4a67a..26c11f20690 100644
--- a/sys/dev/ata/chipsets/ata-adaptec.c
+++ b/sys/dev/ata/chipsets/ata-adaptec.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 
 /* misc defines */
 #define MV_60XX		60		//must match ata_marvell.c's definition
+#define MV_7042		72		//must match ata_marvell.c's definition
 
 
 /*
@@ -64,6 +65,7 @@ ata_adaptec_probe(device_t dev)
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     static struct ata_chip_id ids[] =
     {{ ATA_ADAPTEC_1420, 0, 4, MV_60XX, ATA_SA300, "1420SA" },
+     { ATA_ADAPTEC_1430, 0, 4, MV_7042, ATA_SA300, "1430SA" },
      { 0, 0, 0, 0, 0, 0}};
 
     if (pci_get_vendor(dev) != ATA_ADAPTEC_ID)
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index dd6b96fcbf3..adf4d9893d5 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -67,6 +67,8 @@ static void ata_marvell_edma_dmainit(device_t dev);
 /* misc defines */
 #define MV_50XX		50
 #define MV_60XX		60
+#define MV_6042		62
+#define MV_7042		72
 #define MV_61XX		61
 
 
@@ -102,7 +104,9 @@ ata_marvell_probe(device_t dev)
      { ATA_M88SX5080, 0, 8, MV_50XX, ATA_SA150, "88SX5080" },
      { ATA_M88SX5081, 0, 8, MV_50XX, ATA_SA150, "88SX5081" },
      { ATA_M88SX6041, 0, 4, MV_60XX, ATA_SA300, "88SX6041" },
+     { ATA_M88SX6042, 0, 4, MV_6042, ATA_SA300, "88SX6042" },
      { ATA_M88SX6081, 0, 8, MV_60XX, ATA_SA300, "88SX6081" },
+     { ATA_M88SX7042, 0, 4, MV_7042, ATA_SA300, "88SX7042" },
      { ATA_M88SX6101, 0, 1, MV_61XX, ATA_UDMA6, "88SX6101" },
      { ATA_M88SX6121, 0, 1, MV_61XX, ATA_UDMA6, "88SX6121" },
      { ATA_M88SX6145, 0, 2, MV_61XX, ATA_UDMA6, "88SX6145" },
@@ -119,6 +123,8 @@ ata_marvell_probe(device_t dev)
     switch (ctlr->chip->cfg2) {
     case MV_50XX:
     case MV_60XX:
+    case MV_6042:
+    case MV_7042:
 	ctlr->chipinit = ata_marvell_edma_chipinit;
 	break;
     case MV_61XX:
@@ -251,6 +257,8 @@ ata_marvell_edma_ch_attach(device_t dev)
 	ch->r_io[ATA_SCONTROL].offset = 0x00108 + ATA_MV_HOST_BASE(ch);
 	break;
     case MV_60XX:
+    case MV_6042:
+    case MV_7042:
 	ch->r_io[ATA_SSTATUS].res = ctlr->r_res1;
 	ch->r_io[ATA_SSTATUS].offset =  0x02300 + ATA_MV_EDMA_BASE(ch);
 	ch->r_io[ATA_SERROR].res = ctlr->r_res1;
@@ -384,35 +392,61 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
 	request->dma->sg_bus & 0xffffffff);
     le32enc(bytep + 1 * sizeof(u_int32_t),
 	(u_int64_t)request->dma->sg_bus >> 32);
-    le16enc(bytep + 4 * sizeof(u_int16_t),
-	(request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag << 1));
+    if (ctlr->chip->cfg2 != MV_6042 && ctlr->chip->cfg2 != MV_7042) {
+	    le16enc(bytep + 4 * sizeof(u_int16_t),
+		(request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag << 1));
 
-    i = 10;
-    bytep[i++] = (request->u.ata.count >> 8) & 0xff;
-    bytep[i++] = 0x10 | ATA_COUNT;
-    bytep[i++] = request->u.ata.count & 0xff;
-    bytep[i++] = 0x10 | ATA_COUNT;
+	    i = 10;
+	    bytep[i++] = (request->u.ata.count >> 8) & 0xff;
+	    bytep[i++] = 0x10 | ATA_COUNT;
+	    bytep[i++] = request->u.ata.count & 0xff;
+	    bytep[i++] = 0x10 | ATA_COUNT;
 
-    bytep[i++] = (request->u.ata.lba >> 24) & 0xff;
-    bytep[i++] = 0x10 | ATA_SECTOR;
-    bytep[i++] = request->u.ata.lba & 0xff;
-    bytep[i++] = 0x10 | ATA_SECTOR;
+	    bytep[i++] = (request->u.ata.lba >> 24) & 0xff;
+	    bytep[i++] = 0x10 | ATA_SECTOR;
+	    bytep[i++] = request->u.ata.lba & 0xff;
+	    bytep[i++] = 0x10 | ATA_SECTOR;
 
-    bytep[i++] = (request->u.ata.lba >> 32) & 0xff;
-    bytep[i++] = 0x10 | ATA_CYL_LSB;
-    bytep[i++] = (request->u.ata.lba >> 8) & 0xff;
-    bytep[i++] = 0x10 | ATA_CYL_LSB;
+	    bytep[i++] = (request->u.ata.lba >> 32) & 0xff;
+	    bytep[i++] = 0x10 | ATA_CYL_LSB;
+	    bytep[i++] = (request->u.ata.lba >> 8) & 0xff;
+	    bytep[i++] = 0x10 | ATA_CYL_LSB;
 
-    bytep[i++] = (request->u.ata.lba >> 40) & 0xff;
-    bytep[i++] = 0x10 | ATA_CYL_MSB;
-    bytep[i++] = (request->u.ata.lba >> 16) & 0xff;
-    bytep[i++] = 0x10 | ATA_CYL_MSB;
+	    bytep[i++] = (request->u.ata.lba >> 40) & 0xff;
+	    bytep[i++] = 0x10 | ATA_CYL_MSB;
+	    bytep[i++] = (request->u.ata.lba >> 16) & 0xff;
+	    bytep[i++] = 0x10 | ATA_CYL_MSB;
 
-    bytep[i++] = ATA_D_LBA | ATA_D_IBM | ((request->u.ata.lba >> 24) & 0xf);
-    bytep[i++] = 0x10 | ATA_DRIVE;
+	    bytep[i++] = ATA_D_LBA | ATA_D_IBM | ((request->u.ata.lba >> 24) & 0xf);
+	    bytep[i++] = 0x10 | ATA_DRIVE;
 
-    bytep[i++] = request->u.ata.command;
-    bytep[i++] = 0x90 | ATA_COMMAND;
+	    bytep[i++] = request->u.ata.command;
+	    bytep[i++] = 0x90 | ATA_COMMAND;
+    } else {
+	    le32enc(bytep + 2 * sizeof(u_int32_t),
+		(request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag << 1));
+
+	    i = 16;
+	    bytep[i++] = 0;
+	    bytep[i++] = 0;
+	    bytep[i++] = request->u.ata.command;
+	    bytep[i++] = request->u.ata.feature & 0xff;
+
+	    bytep[i++] = request->u.ata.lba & 0xff;
+	    bytep[i++] = (request->u.ata.lba >> 8) & 0xff;
+	    bytep[i++] = (request->u.ata.lba >> 16) & 0xff;
+	    bytep[i++] = ATA_D_LBA | ATA_D_IBM | ((request->u.ata.lba >> 24) & 0x0f);
+
+	    bytep[i++] = (request->u.ata.lba >> 24) & 0xff;
+	    bytep[i++] = (request->u.ata.lba >> 32) & 0xff;
+	    bytep[i++] = (request->u.ata.lba >> 40) & 0xff;
+	    bytep[i++] = (request->u.ata.feature >> 8) & 0xff;
+
+	    bytep[i++] = request->u.ata.count & 0xff;
+	    bytep[i++] = (request->u.ata.count >> 8) & 0xff;
+	    bytep[i++] = 0;
+	    bytep[i++] = 0;
+    }
 
     bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
 	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -557,7 +591,8 @@ ata_marvell_edma_dmainit(device_t dev)
 	ch->dma.max_address = BUS_SPACE_MAXADDR;
 
     /* chip does not reliably do 64K DMA transfers */
-    ch->dma.max_iosize = 64 * DEV_BSIZE; 
+    if (ctlr->chip->cfg2 == MV_50XX || ctlr->chip->cfg2 == MV_60XX)
+	ch->dma.max_iosize = 64 * DEV_BSIZE; 
 }
 
 ATA_DECLARE_DRIVER(ata_marvell);

From 4145bb53bf1459022a7e00b26f29f2b91ee79974 Mon Sep 17 00:00:00 2001
From: Kirk McKusick 
Date: Fri, 30 Oct 2009 21:54:53 +0000
Subject: [PATCH 426/646] When reading input from a file or device (via -f
 option) set the input to be in non-buffering mode so that input lines are
 logged as they occur rather than being saved up until a buffer's worth of
 input has been logged.

---
 usr.bin/logger/logger.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/usr.bin/logger/logger.c b/usr.bin/logger/logger.c
index 5d9ec4df83b..90271052fdb 100644
--- a/usr.bin/logger/logger.c
+++ b/usr.bin/logger/logger.c
@@ -114,6 +114,7 @@ main(int argc, char *argv[])
 		case 'f':		/* file to log */
 			if (freopen(optarg, "r", stdin) == NULL)
 				err(1, "%s", optarg);
+			setvbuf(stdin, 0, _IONBF, 0);
 			break;
 		case 'h':		/* hostname to deliver to */
 			host = optarg;

From fd66267ffbbbd249f0644b5ad9b99b539ccca95d Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Fri, 30 Oct 2009 23:33:06 +0000
Subject: [PATCH 427/646] - zfs_zaccess() can handle VAPPEND too, so map
 V_APPEND to VAPPEND and call   zfs_access() instead of vaccess() in this case
 as well. - If VADMIN is specified with another V* flag (unlikely) call both  
 zfs_access() and vaccess() after spliting V* flags.

This fixes "dirtying snapshot!" panic.

PR:		kern/139806
Reported by:	Carl Chave 
In co-operation with:	jh
MFC after:	3 days
---
 sys/cddl/compat/opensolaris/sys/vnode.h       |  2 ++
 .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 30 +++++++++++++------
 .../opensolaris/uts/common/sys/vnode.h        |  1 -
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/sys/cddl/compat/opensolaris/sys/vnode.h b/sys/cddl/compat/opensolaris/sys/vnode.h
index 7611a3f8201..7296635cc15 100644
--- a/sys/cddl/compat/opensolaris/sys/vnode.h
+++ b/sys/cddl/compat/opensolaris/sys/vnode.h
@@ -57,6 +57,8 @@ typedef	struct vop_vector	vnodeops_t;
 
 #define	v_count	v_usecount
 
+#define	V_APPEND	VAPPEND
+
 static __inline int
 vn_is_readonly(vnode_t *vp)
 {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index 6d9ec9cd4a7..7608d76308c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -3989,21 +3989,33 @@ zfs_freebsd_access(ap)
 		struct thread *a_td;
 	} */ *ap;
 {
+	accmode_t accmode;
+	int error = 0;
 
 	/*
-	 * ZFS itself only knowns about VREAD, VWRITE and VEXEC, the rest
-	 * we have to handle by calling vaccess().
+	 * ZFS itself only knowns about VREAD, VWRITE, VEXEC and VAPPEND,
 	 */
-	if ((ap->a_accmode & ~(VREAD|VWRITE|VEXEC)) != 0) {
-		vnode_t *vp = ap->a_vp;
-		znode_t *zp = VTOZ(vp);
-		znode_phys_t *zphys = zp->z_phys;
+	accmode = ap->a_accmode & (VREAD|VWRITE|VEXEC|VAPPEND);
+	if (accmode != 0)
+		error = zfs_access(ap->a_vp, accmode, 0, ap->a_cred, NULL);
 
-		return (vaccess(vp->v_type, zphys->zp_mode, zphys->zp_uid,
-		    zphys->zp_gid, ap->a_accmode, ap->a_cred, NULL));
+	/*
+	 * VADMIN has to be handled by vaccess().
+	 */
+	if (error == 0) {
+		accmode = ap->a_accmode & ~(VREAD|VWRITE|VEXEC|VAPPEND);
+		if (accmode != 0) {
+			vnode_t *vp = ap->a_vp;
+			znode_t *zp = VTOZ(vp);
+			znode_phys_t *zphys = zp->z_phys;
+
+			error = vaccess(vp->v_type, zphys->zp_mode,
+			    zphys->zp_uid, zphys->zp_gid, accmode, ap->a_cred,
+			    NULL);
+		}
 	}
 
-	return (zfs_access(ap->a_vp, ap->a_accmode, 0, ap->a_cred, NULL));
+	return (error);
 }
 
 static int
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
index a46b7118735..5f1f4b457fd 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
@@ -304,7 +304,6 @@ typedef struct xvattr {
  * VOP_ACCESS flags
  */
 #define	V_ACE_MASK	0x1	/* mask represents  NFSv4 ACE permissions */
-#define	V_APPEND	0x2	/* want to do append only check */
 
 /*
  * Flags for vnode operations.

From d521940e9a69d053dc871c4c63daffc06197d3f8 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 31 Oct 2009 09:03:48 +0000
Subject: [PATCH 428/646] MFp4: Ensure target/lun passed from user-level
 supported on this bus. Scanning unsupported IDs causes different issues from
 duplicate devices to system crash.

---
 sys/cam/cam_xpt.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 479a6058c44..d3ed9aa6606 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -452,7 +452,34 @@ xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
 			ccb = xpt_alloc_ccb();
 
 			CAM_SIM_LOCK(bus->sim);
-
+			/* Ensure passed in target/lun supported on this bus. */
+			if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD) ||
+			    (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
+				if (xpt_create_path(&ccb->ccb_h.path,
+					    xpt_periph,
+					    inccb->ccb_h.path_id,
+					    CAM_TARGET_WILDCARD,
+					    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+					error = EINVAL;
+					CAM_SIM_UNLOCK(bus->sim);
+					xpt_free_ccb(ccb);
+					break;
+				}
+				xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
+				    inccb->ccb_h.pinfo.priority);
+				ccb->ccb_h.func_code = XPT_PATH_INQ;
+				xpt_action(ccb);
+				xpt_free_path(ccb->ccb_h.path);
+				if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD &&
+				    inccb->ccb_h.target_id > ccb->cpi.max_target) ||
+				    (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD &&
+				    inccb->ccb_h.target_lun > ccb->cpi.max_lun)) {
+					error = EINVAL;
+					CAM_SIM_UNLOCK(bus->sim);
+					xpt_free_ccb(ccb);
+					break;
+				}
+			}
 			/*
 			 * Create a path using the bus, target, and lun the
 			 * user passed in.

From 2d2a89dd2d764fc044968e57ec82997d82d02b28 Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Sat, 31 Oct 2009 10:35:41 +0000
Subject: [PATCH 429/646] Turn unused structure fields of cdevsw into spares.

d_uid, d_gid and d_mode are unused, because permissions are stored in
cdevpriv nowadays. d_kind doesn't seem to be used at all. We no longer
keep a list of cdevsw's, so d_list is also unused.

uid_t and gid_t are 32 bits, but mode_t is 16 bits, Because of alignment
constraints of d_kind, we can safely turn it into three 32-bit integers.
d_kind and d_list is equal in size to three pointers.

Discussed with:	kib
---
 sys/sys/conf.h | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 3df4284fa92..4d89070128c 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -210,15 +210,13 @@ struct cdevsw {
 	d_kqfilter_t		*d_kqfilter;
 	d_purge_t		*d_purge;
 	d_mmap_single_t		*d_mmap_single;
-	uid_t			d_uid;
-	gid_t			d_gid;
-	mode_t			d_mode;
-	const char		*d_kind;
+
+	int32_t			d_spare0[3];
+	void			*d_spare1[3];
 
 	/* These fields should not be messed with by drivers */
-	LIST_ENTRY(cdevsw)	d_list;
 	LIST_HEAD(, cdev)	d_devs;
-	int			d_spare3;
+	int			d_spare2;
 	union {
 		struct cdevsw		*gianttrick;
 		SLIST_ENTRY(cdevsw)	postfree_list;

From 4c88ba2d70047ac796158643c6ac487f5881dbd3 Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Sat, 31 Oct 2009 10:38:30 +0000
Subject: [PATCH 430/646] Unobfuscate unit number handling in apm(4).

There is no need to use the lower 4 bits of the unit number to store the
device type number. Just use 0 and 1 to distinguish them. devfs also
guarantees that there can never be an open call on a device that has a
unit number different to 0 and 1, so there is no need to check for this
in open().
---
 sys/i386/bios/apm.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c
index 49d028b2399..e015cd09f68 100644
--- a/sys/i386/bios/apm.c
+++ b/sys/i386/bios/apm.c
@@ -79,9 +79,8 @@ int	apm_evindex;
 #define	SCFLAG_OCTL	0x0000002
 #define	SCFLAG_OPEN	(SCFLAG_ONORMAL|SCFLAG_OCTL)
 
-#define APMDEV(dev)	(dev2unit(dev)&0x0f)
 #define APMDEV_NORMAL	0
-#define APMDEV_CTL	8
+#define APMDEV_CTL	1
 
 #ifdef PC98
 extern int bios32_apm98(struct bios_regs *, u_int, u_short);
@@ -1249,8 +1248,10 @@ apm_attach(device_t dev)
 	sc->suspending = 0;
 	sc->running = 0;
 
-	make_dev(&apm_cdevsw, 0, 0, 5, 0664, "apm");
-	make_dev(&apm_cdevsw, 8, 0, 5, 0660, "apmctl");
+	make_dev(&apm_cdevsw, APMDEV_NORMAL,
+	    UID_ROOT, GID_OPERATOR, 0664, "apm");
+	make_dev(&apm_cdevsw, APMDEV_CTL,
+	    UID_ROOT, GID_OPERATOR, 0660, "apmctl");
 	return 0;
 }
 
@@ -1258,12 +1259,11 @@ static int
 apmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
 {
 	struct apm_softc *sc = &apm_softc;
-	int ctl = APMDEV(dev);
 
 	if (sc == NULL || sc->initialized == 0)
 		return (ENXIO);
 
-	switch (ctl) {
+	switch (dev2unit(dev)) {
 	case APMDEV_CTL:
 		if (!(flag & FWRITE))
 			return EINVAL;
@@ -1275,9 +1275,6 @@ apmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
 	case APMDEV_NORMAL:
 		sc->sc_flags |= SCFLAG_ONORMAL;
 		break;
-	default:
-		return ENXIO;
-		break;
 	}
 	return 0;
 }
@@ -1286,9 +1283,8 @@ static int
 apmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
 {
 	struct apm_softc *sc = &apm_softc;
-	int ctl = APMDEV(dev);
 
-	switch (ctl) {
+	switch (dev2unit(dev)) {
 	case APMDEV_CTL:
 		apm_lastreq_rejected();
 		sc->sc_flags &= ~SCFLAG_OCTL;
@@ -1429,7 +1425,7 @@ apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
 	}
 
 	/* for /dev/apmctl */
-	if (APMDEV(dev) == APMDEV_CTL) {
+	if (dev2unit(dev) == APMDEV_CTL) {
 		struct apm_event_info *evp;
 		int i;
 
@@ -1468,7 +1464,7 @@ apmwrite(struct cdev *dev, struct uio *uio, int ioflag)
 	int error;
 	u_char enabled;
 
-	if (APMDEV(dev) != APMDEV_CTL)
+	if (dev2unit(dev) != APMDEV_CTL)
 		return(ENODEV);
 	if (uio->uio_resid != sizeof(u_int))
 		return(E2BIG);

From 1e637ba6770e6ae758073120d23b5fbf0f0ac2ef Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 31 Oct 2009 10:43:38 +0000
Subject: [PATCH 431/646] MFp4: - Reduce code duplication in ATA XPT and PMP
 driver. - Move PIO size setting from ada driver to ATA XPT. It is XPT
 business to negotiate transfer details. ada driver is now stateless. - Report
 PIO size to SIM. It is required for correct PATA SIM operation. - Tune PMP
 scan timings. It workarounds some problems with SiI. - If reset hapens during
 PMP initialization - restart it. - Introduce early-initialized periph
 drivers, which are used during initial scan process. Use it for xpt, probe,
 aprobe and pmp. It gives pmp chance to finish scan before mountroot and
 numerate devices in right order.

---
 sys/cam/ata/ata_da.c    |  78 +-----
 sys/cam/ata/ata_pmp.c   | 357 +++++++++++++---------------
 sys/cam/ata/ata_xpt.c   | 511 +++++++++++++++++++---------------------
 sys/cam/cam.h           |   1 +
 sys/cam/cam_ccb.h       |  11 +
 sys/cam/cam_periph.h    |   2 +
 sys/cam/cam_xpt.c       |  46 +++-
 sys/cam/scsi/scsi_da.c  |   4 +-
 sys/cam/scsi/scsi_sg.c  |   4 +-
 sys/cam/scsi/scsi_xpt.c |   3 +-
 10 files changed, 476 insertions(+), 541 deletions(-)

diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 259d49d4252..76ed3d2b57f 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -63,8 +63,7 @@ __FBSDID("$FreeBSD$");
 #define ATA_MAX_28BIT_LBA               268435455UL
 
 typedef enum {
-	ADA_STATE_NORMAL,
-	ADA_STATE_SET_MULTI
+	ADA_STATE_NORMAL
 } ada_state;
 
 typedef enum {
@@ -84,7 +83,6 @@ typedef enum {
 } ada_quirks;
 
 typedef enum {
-	ADA_CCB_SET_MULTI	= 0x01,
 	ADA_CCB_BUFFER_IO	= 0x03,
 	ADA_CCB_WAITING		= 0x04,
 	ADA_CCB_DUMP		= 0x05,
@@ -112,7 +110,6 @@ struct ada_softc {
 	ada_quirks quirks;
 	int	 ordered_tag_count;
 	int	 outstanding_cmds;
-	int	 secsperint;
 	struct	 disk_params params;
 	struct	 disk *disk;
 	union	 ccb saved_ccb;
@@ -550,22 +547,6 @@ adaasync(void *callback_arg, u_int32_t code,
 				"due to status 0x%x\n", status);
 		break;
 	}
-	case AC_SENT_BDR:
-	case AC_BUS_RESET:
-	{
-		struct ada_softc *softc = (struct ada_softc *)periph->softc;
-
-		cam_periph_async(periph, code, path, arg);
-		if (softc->state != ADA_STATE_NORMAL)
-			break;
-		/*
-		 * Restore device configuration.
-		 */
-		softc->state = ADA_STATE_SET_MULTI;
-		cam_periph_acquire(periph);
-		xpt_schedule(periph, CAM_PRIORITY_DEV);
-		break;
-	}
 	default:
 		cam_periph_async(periph, code, path, arg);
 		break;
@@ -644,8 +625,7 @@ adaregister(struct cam_periph *periph, void *arg)
 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
 	    cgd->ident_data.queue >= 31)
 		softc->flags |= ADA_FLAG_CAN_NCQ;
-	softc->secsperint = max(1, min(cgd->ident_data.sectors_intr, 16));
-	softc->state = ADA_STATE_SET_MULTI;
+	softc->state = ADA_STATE_NORMAL;
 
 	periph->softc = softc;
 
@@ -734,17 +714,9 @@ adaregister(struct cam_periph *periph, void *arg)
 	 * them and the only alternative would be to
 	 * not attach the device on failure.
 	 */
-	xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
+	xpt_register_async(AC_LOST_DEVICE,
 			   adaasync, periph, periph->path);
 
-	/*
-	 * Take an exclusive refcount on the periph while adastart is called
-	 * to finish the probe.  The reference will be dropped in adadone at
-	 * the end of probe.
-	 */
-	cam_periph_acquire(periph);
-	xpt_schedule(periph, /*priority*/5);
-
 	/*
 	 * Schedule a periodic event to occasionally send an
 	 * ordered tag to a device.
@@ -901,21 +873,6 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 		}
 		break;
 	}
-	case ADA_STATE_SET_MULTI:
-	{
-		cam_fill_ataio(ataio,
-		    ada_retry_count,
-		    adadone,
-		    CAM_DIR_NONE,
-		    0,
-		    NULL,
-		    0,
-		    ada_default_timeout*1000);
-
-		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, softc->secsperint);
-		start_ccb->ccb_h.ccb_state = ADA_CCB_SET_MULTI;
-		xpt_action(start_ccb);
-	}
 	}
 }
 
@@ -1003,35 +960,6 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 		wakeup(&done_ccb->ccb_h.cbfcnp);
 		return;
 	}
-	case ADA_CCB_SET_MULTI:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-		} else {
-			int	error;
-
-			error = adaerror(done_ccb, 0, 0);
-			if (error == ERESTART) {
-				/* A retry was scheduled, so just return. */
-				return;
-			}
-		}
-		softc->state = ADA_STATE_NORMAL;
-		/*
-		 * Since our peripheral may be invalidated by an error
-		 * above or an external event, we must release our CCB
-		 * before releasing the probe lock on the peripheral.
-		 * The peripheral will only go away once the last lock
-		 * is removed, and we need it around for the CCB release
-		 * operation.
-		 */
-		xpt_release_ccb(done_ccb);
-		if (bioq_first(&softc->bio_queue) != NULL) {
-			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
-		}
-		cam_periph_release_locked(periph);
-		return;
-	}
 	case ADA_CCB_DUMP:
 		/* No-op.  We're polling */
 		return;
diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c
index 76b3c0ad8b6..ea387909b11 100644
--- a/sys/cam/ata/ata_pmp.c
+++ b/sys/cam/ata/ata_pmp.c
@@ -93,7 +93,9 @@ struct pmp_softc {
 	int			pm_step;
 	int			pm_try;
 	int			found;
+	int			reset;
 	int			frozen;
+	int			restart;
 	union			ccb saved_ccb;
 	struct task		sysctl_task;
 	struct sysctl_ctx_list	sysctl_ctx;
@@ -134,7 +136,8 @@ TUNABLE_INT("kern.cam.pmp.default_timeout", &pmp_default_timeout);
 static struct periph_driver pmpdriver =
 {
 	pmpinit, "pmp",
-	TAILQ_HEAD_INITIALIZER(pmpdriver.units), /* generation */ 0
+	TAILQ_HEAD_INITIALIZER(pmpdriver.units), /* generation */ 0,
+	CAM_PERIPH_DRV_EARLY
 };
 
 PERIPHDRIVER_DECLARE(pmp, pmpdriver);
@@ -292,14 +295,21 @@ pmpasync(void *callback_arg, u_int32_t code,
 	case AC_BUS_RESET:
 		softc = (struct pmp_softc *)periph->softc;
 		cam_periph_async(periph, code, path, arg);
-		if (softc->state != PMP_STATE_NORMAL)
+		if (code == AC_SCSI_AEN && softc->state != PMP_STATE_NORMAL &&
+		    softc->state != PMP_STATE_SCAN)
 			break;
-		pmpfreeze(periph, softc->found);
+		if (softc->state != PMP_STATE_SCAN)
+			pmpfreeze(periph, softc->found);
+		else
+			pmpfreeze(periph, softc->found & ~(1 << softc->pm_step));
 		if (code == AC_SENT_BDR || code == AC_BUS_RESET)
 			softc->found = 0; /* We have to reset everything. */
-		softc->state = PMP_STATE_PORTS;
-		cam_periph_acquire(periph);
-		xpt_schedule(periph, CAM_PRIORITY_DEV);
+		if (softc->state == PMP_STATE_NORMAL) {
+			softc->state = PMP_STATE_PORTS;
+			cam_periph_acquire(periph);
+			xpt_schedule(periph, CAM_PRIORITY_BUS);
+		} else
+			softc->restart = 1;
 		break;
 	default:
 		cam_periph_async(periph, code, path, arg);
@@ -395,7 +405,7 @@ pmpregister(struct cam_periph *periph, void *arg)
 	 * the end of probe.
 	 */
 	(void)cam_periph_acquire(periph);
-	xpt_schedule(periph, CAM_PRIORITY_DEV);
+	xpt_schedule(periph, CAM_PRIORITY_BUS);
 
 	return(CAM_REQ_CMP);
 }
@@ -408,6 +418,11 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
 
 	softc = (struct pmp_softc *)periph->softc;
 	ataio = &start_ccb->ataio;
+	
+	if (softc->restart) {
+		softc->restart = 0;
+		softc->state = PMP_STATE_PORTS;
+	}
 
 	switch (softc->state) {
 	case PMP_STATE_PORTS:
@@ -469,6 +484,7 @@ printf("PM RESET %d%s\n", softc->pm_step,
 		ata_pm_read_cmd(ataio, 0, softc->pm_step);
 		break;
 	case PMP_STATE_CLEAR:
+		softc->reset = 0;
 		cam_fill_ataio(ataio,
 		      pmp_retry_count,
 		      pmpdone,
@@ -492,7 +508,7 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
 	struct ccb_ataio *ataio;
 	union ccb *work_ccb;
 	struct cam_path *path, *dpath;
-	u_int32_t  priority;
+	u_int32_t  priority, res;
 
 	softc = (struct pmp_softc *)periph->softc;
 	ataio = &done_ccb->ataio;
@@ -502,193 +518,158 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
 	path = done_ccb->ccb_h.path;
 	priority = done_ccb->ccb_h.pinfo.priority;
 
+	if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+		if (cam_periph_error(done_ccb, 0, 0,
+		    &softc->saved_ccb) == ERESTART) {
+			return;
+		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+			cam_release_devq(done_ccb->ccb_h.path,
+			    /*relsim_flags*/0,
+			    /*reduction*/0,
+			    /*timeout*/0,
+			    /*getcount_only*/0);
+		}
+		goto done;
+	}
+
+	if (softc->restart) {
+		softc->restart = 0;
+		if (softc->state == PMP_STATE_SCAN) {
+			pmpfreeze(periph, 1 << softc->pm_step);
+			work_ccb = done_ccb;
+			done_ccb = (union ccb*)work_ccb->ccb_h.ppriv_ptr0;
+			/* Free the current request path- we're done with it. */
+		    	xpt_free_path(work_ccb->ccb_h.path);
+			xpt_free_ccb(work_ccb);
+		}
+		xpt_release_ccb(done_ccb);
+		softc->state = PMP_STATE_PORTS;
+		xpt_schedule(periph, priority);
+		return;
+	}
+
 	switch (softc->state) {
 	case PMP_STATE_PORTS:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			/* This PM declares 6 ports, while only 5 of them are real.
-			 * Port 5 is enclosure management bridge port, which has implementation
-			 * problems, causing probe faults. Hide it for now. */
-			if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
-				softc->pm_ports = 5;
-			/* This PM declares 7 ports, while only 5 of them are real.
-			 * Port 5 is some fake "Config  Disk" with 640 sectors size,
-			 * port 6 is enclosure management bridge port.
-			 * Both fake ports has implementation problems, causing
-			 * probe faults. Hide them for now. */
-			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
-				softc->pm_ports = 5;
-			printf("PM ports: %d\n", softc->pm_ports);
-			softc->state = PMP_STATE_CONFIG;
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
+		softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
+		    (done_ccb->ataio.res.lba_mid << 16) +
+		    (done_ccb->ataio.res.lba_low << 8) +
+		    done_ccb->ataio.res.sector_count;
+		/* This PM declares 6 ports, while only 5 of them are real.
+		 * Port 5 is enclosure management bridge port, which has implementation
+		 * problems, causing probe faults. Hide it for now. */
+		if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
+			softc->pm_ports = 5;
+		/* This PM declares 7 ports, while only 5 of them are real.
+		 * Port 5 is some fake "Config  Disk" with 640 sectors size,
+		 * port 6 is enclosure management bridge port.
+		 * Both fake ports has implementation problems, causing
+		 * probe faults. Hide them for now. */
+		if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
+			softc->pm_ports = 5;
+		printf("PM ports: %d\n", softc->pm_ports);
+		softc->state = PMP_STATE_CONFIG;
 		xpt_release_ccb(done_ccb);
-		break;
+		xpt_schedule(periph, priority);
+		return;
 	case PMP_STATE_CONFIG:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+		softc->pm_step = 0;
+		softc->state = PMP_STATE_RESET;
+		softc->reset |= ~softc->found;
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_RESET:
+		softc->pm_step++;
+		if (softc->pm_step >= softc->pm_ports) {
 			softc->pm_step = 0;
-			softc->state = PMP_STATE_RESET;
+			cam_freeze_devq(periph->path);
+			cam_release_devq(periph->path,
+			    RELSIM_RELEASE_AFTER_TIMEOUT,
+			    /*reduction*/0,
+			    /*timeout*/5,
+			    /*getcount_only*/0);
+			printf("PM reset done\n");
+			softc->state = PMP_STATE_CONNECT;
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_CONNECT:
+		softc->pm_step++;
+		if (softc->pm_step >= softc->pm_ports) {
+			softc->pm_step = 0;
+			softc->pm_try = 0;
+			cam_freeze_devq(periph->path);
+			cam_release_devq(periph->path,
+			    RELSIM_RELEASE_AFTER_TIMEOUT,
+			    /*reduction*/0,
+			    /*timeout*/10,
+			    /*getcount_only*/0);
+			printf("PM connect done\n");
+			softc->state = PMP_STATE_CHECK;
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_CHECK:
+		res = (done_ccb->ataio.res.lba_high << 24) +
+		    (done_ccb->ataio.res.lba_mid << 16) +
+		    (done_ccb->ataio.res.lba_low << 8) +
+		    done_ccb->ataio.res.sector_count;
+		if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
+			printf("PM status: %d - %08x\n", softc->pm_step, res);
+			softc->found |= (1 << softc->pm_step);
+			softc->pm_step++;
+		} else {
+			if (softc->pm_try < 10) {
+				cam_freeze_devq(periph->path);
+				cam_release_devq(periph->path,
+				    RELSIM_RELEASE_AFTER_TIMEOUT,
+				    /*reduction*/0,
+				    /*timeout*/10,
+				    /*getcount_only*/0);
+				softc->pm_try++;
+			} else {
+				printf("PM status: %d - %08x\n", softc->pm_step, res);
+				softc->found &= ~(1 << softc->pm_step);
+				if (xpt_create_path(&dpath, periph,
+				    done_ccb->ccb_h.path_id,
+				    softc->pm_step, 0) == CAM_REQ_CMP) {
+					xpt_async(AC_LOST_DEVICE, dpath, NULL);
+					xpt_free_path(dpath);
+				}
+				softc->pm_step++;
+			}
+		}
+		if (softc->pm_step >= softc->pm_ports) {
+			if (softc->reset & softc->found) {
+				cam_freeze_devq(periph->path);
+				cam_release_devq(periph->path,
+				    RELSIM_RELEASE_AFTER_TIMEOUT,
+				    /*reduction*/0,
+				    /*timeout*/1000,
+				    /*getcount_only*/0);
+			}
+			softc->state = PMP_STATE_CLEAR;
+			softc->pm_step = 0;
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_CLEAR:
+		softc->pm_step++;
+		if (softc->pm_step < softc->pm_ports) {
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
 			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
+		} else if (softc->found) {
+			softc->pm_step = 0;
+			softc->state = PMP_STATE_SCAN;
+			work_ccb = xpt_alloc_ccb_nowait();
+			if (work_ccb != NULL)
+				goto do_scan;
+			xpt_release_ccb(done_ccb);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
-	case PMP_STATE_RESET:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				DELAY(5000);
-				printf("PM reset done\n");
-				softc->state = PMP_STATE_CONNECT;
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
-		xpt_release_ccb(done_ccb);
-		break;
-	case PMP_STATE_CONNECT:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				softc->pm_try = 0;
-				printf("PM connect done\n");
-				softc->state = PMP_STATE_CHECK;
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
-		xpt_release_ccb(done_ccb);
-		break;
-	case PMP_STATE_CHECK:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			int res = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
-				printf("PM status: %d - %08x\n", softc->pm_step, res);
-				softc->found |= (1 << softc->pm_step);
-				softc->pm_step++;
-			} else {
-				if (softc->pm_try < 100) {
-					DELAY(10000);
-					softc->pm_try++;
-				} else {
-					printf("PM status: %d - %08x\n", softc->pm_step, res);
-					softc->found &= ~(1 << softc->pm_step);
-					if (xpt_create_path(&dpath, periph,
-					    done_ccb->ccb_h.path_id,
-					    softc->pm_step, 0) == CAM_REQ_CMP) {
-						xpt_async(AC_LOST_DEVICE, dpath, NULL);
-						xpt_free_path(dpath);
-					}
-					softc->pm_step++;
-				}
-			}
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else {
-				softc->pm_step = 0;
-				softc->state = PMP_STATE_CLEAR;
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
-		xpt_release_ccb(done_ccb);
-		break;
-	case PMP_STATE_CLEAR:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_step++;
-			if (softc->pm_step < softc->pm_ports) {
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			} else if (softc->found) {
-				softc->pm_step = 0;
-				softc->state = PMP_STATE_SCAN;
-				work_ccb = xpt_alloc_ccb_nowait();
-				if (work_ccb != NULL)
-					goto do_scan;
-				xpt_release_ccb(done_ccb);
-			}
-			break;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
-		xpt_release_ccb(done_ccb);
 		break;
 	case PMP_STATE_SCAN:
 		work_ccb = done_ccb;
@@ -703,7 +684,6 @@ do_scan:
 		}
 		if (softc->pm_step >= softc->pm_ports) {
 			xpt_free_ccb(work_ccb);
-			xpt_release_ccb(done_ccb);
 			break;
 		}
 		if (xpt_create_path(&dpath, periph,
@@ -712,7 +692,6 @@ do_scan:
 			printf("pmpdone: xpt_create_path failed"
 			    ", bus scan halted\n");
 			xpt_free_ccb(work_ccb);
-			xpt_release_ccb(done_ccb);
 			break;
 		}
 		xpt_setup_ccb(&work_ccb->ccb_h, dpath,
@@ -727,6 +706,8 @@ do_scan:
 	default:
 		break;
 	}
+done:
+	xpt_release_ccb(done_ccb);
 	softc->state = PMP_STATE_NORMAL;
 	pmprelease(periph, -1);
 	cam_periph_release_locked(periph);
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index a693e2cdc63..9e781cd72d6 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -83,7 +83,8 @@ static periph_init_t probe_periph_init;
 static struct periph_driver probe_driver =
 {
 	probe_periph_init, "aprobe",
-	TAILQ_HEAD_INITIALIZER(probe_driver.units)
+	TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0,
+	CAM_PERIPH_DRV_EARLY
 };
 
 PERIPHDRIVER_DECLARE(aprobe, probe_driver);
@@ -92,6 +93,7 @@ typedef enum {
 	PROBE_RESET,
 	PROBE_IDENTIFY,
 	PROBE_SETMODE,
+	PROBE_SET_MULTI,
 	PROBE_INQUIRY,
 	PROBE_FULL_INQUIRY,
 	PROBE_PM_PID,
@@ -103,6 +105,7 @@ static char *probe_action_text[] = {
 	"PROBE_RESET",
 	"PROBE_IDENTIFY",
 	"PROBE_SETMODE",
+	"PROBE_SET_MULTI",
 	"PROBE_INQUIRY",
 	"PROBE_FULL_INQUIRY",
 	"PROBE_PM_PID",
@@ -282,12 +285,16 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 	struct ccb_ataio *ataio;
 	struct ccb_scsiio *csio;
 	probe_softc *softc;
+	struct cam_path *path;
+	struct ata_params *ident_buf;
 
 	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
 
 	softc = (probe_softc *)periph->softc;
+	path = start_ccb->ccb_h.path;
 	ataio = &start_ccb->ataio;
 	csio = &start_ccb->csio;
+	ident_buf = &periph->path->device->ident_data;
 
 	switch (softc->action) {
 	case PROBE_RESET:
@@ -302,10 +309,6 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		ata_reset_cmd(ataio);
 		break;
 	case PROBE_IDENTIFY:
-	{
-		struct ata_params *ident_buf =
-		    &periph->path->device->ident_data;
-
 		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 			/* Prepare check that it is the same device. */
 			MD5_CTX context;
@@ -335,12 +338,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		else
 			ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
 		break;
-	}
 	case PROBE_SETMODE:
-	{
-		struct ata_params *ident_buf =
-		    &periph->path->device->ident_data;
-
 		cam_fill_ataio(ataio,
 		      1,
 		      probedone,
@@ -352,6 +350,37 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
 		    ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6));
 		break;
+	case PROBE_SET_MULTI:
+	{
+		struct ccb_trans_settings cts;
+		u_int sectors;
+
+		sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16));
+
+		/* Report bytecount to SIM. */
+		bzero(&cts, sizeof(cts));
+		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+		cts.type = CTS_TYPE_CURRENT_SETTINGS;
+		if (path->device->transport == XPORT_ATA) {
+			cts.xport_specific.ata.bytecount = sectors * 512;
+			cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
+		} else {
+			cts.xport_specific.sata.bytecount = sectors * 512;
+			cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
+		}
+		xpt_action((union ccb *)&cts);
+
+		cam_fill_ataio(ataio,
+		    1,
+		    probedone,
+		    CAM_DIR_NONE,
+		    0,
+		    NULL,
+		    0,
+		    30*1000);
+		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors);
+		break;
 	}
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
@@ -406,7 +435,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
 		ata_pm_read_cmd(ataio, 1, 15);
 		break;
 	case PROBE_INVALID:
-		CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
+		CAM_DEBUG(path, CAM_DEBUG_INFO,
 		    ("probestart: invalid action state\n"));
 	default:
 		break;
@@ -552,135 +581,20 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 	priority = done_ccb->ccb_h.pinfo.priority;
 	ident_buf = &path->device->ident_data;
 
-	switch (softc->action) {
-	case PROBE_RESET:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			int sign = (done_ccb->ataio.res.lba_high << 8) +
-			    done_ccb->ataio.res.lba_mid;
-			xpt_print(path, "SIGNATURE: %04x\n", sign);
-			if (sign == 0x0000 &&
-			    done_ccb->ccb_h.target_id != 15) {
-				path->device->protocol = PROTO_ATA;
-				PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
-			} else if (sign == 0x9669 &&
-			    done_ccb->ccb_h.target_id == 15) {
-				struct ccb_trans_settings cts;
-
-				/* Report SIM that PM is present. */
-				bzero(&cts, sizeof(cts));
-				xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
-				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
-				cts.type = CTS_TYPE_CURRENT_SETTINGS;
-				cts.xport_specific.sata.pm_present = 1;
-				cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
-				xpt_action((union ccb *)&cts);
-				path->device->protocol = PROTO_SATAPM;
-				PROBE_SET_ACTION(softc, PROBE_PM_PID);
-			} else if (sign == 0xeb14 &&
-			    done_ccb->ccb_h.target_id != 15) {
-				path->device->protocol = PROTO_SCSI;
-				PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
-			} else {
-				if (done_ccb->ccb_h.target_id != 15) {
-					xpt_print(path,
-					    "Unexpected signature 0x%04x\n", sign);
-				}
-				goto device_fail;
-			}
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
+	if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+device_fail:	if (cam_periph_error(done_ccb, 0, 0,
+		    &softc->saved_ccb) == ERESTART) {
 			return;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		goto device_fail;
-	case PROBE_IDENTIFY:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			int16_t *ptr;
-
-			for (ptr = (int16_t *)ident_buf;
-			     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
-				*ptr = le16toh(*ptr);
-			}
-			if (strncmp(ident_buf->model, "FX", 2) &&
-			    strncmp(ident_buf->model, "NEC", 3) &&
-			    strncmp(ident_buf->model, "Pioneer", 7) &&
-			    strncmp(ident_buf->model, "SHARP", 5)) {
-				ata_bswap(ident_buf->model, sizeof(ident_buf->model));
-				ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
-				ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
-			}
-			ata_btrim(ident_buf->model, sizeof(ident_buf->model));
-			ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
-			ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
-			ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
-			ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
-			ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
-
-			if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
-				/* Check that it is the same device. */
-				MD5_CTX context;
-				u_int8_t digest[16];
-
-				MD5Init(&context);
-				MD5Update(&context,
-				    (unsigned char *)ident_buf->model,
-				    sizeof(ident_buf->model));
-				MD5Update(&context,
-				    (unsigned char *)ident_buf->revision,
-				    sizeof(ident_buf->revision));
-				MD5Update(&context,
-				    (unsigned char *)ident_buf->serial,
-				    sizeof(ident_buf->serial));
-				MD5Final(digest, &context);
-				if (bcmp(digest, softc->digest, sizeof(digest))) {
-					/* Device changed. */
-					xpt_async(AC_LOST_DEVICE, path, NULL);
-				}
-				xpt_release_ccb(done_ccb);
-				break;
-			}
-
-			/* Clean up from previous instance of this device */
-			if (path->device->serial_num != NULL) {
-				free(path->device->serial_num, M_CAMXPT);
-				path->device->serial_num = NULL;
-				path->device->serial_num_len = 0;
-			}
-			path->device->serial_num =
-				(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
-						   M_CAMXPT, M_NOWAIT);
-			if (path->device->serial_num != NULL) {
-				bcopy(ident_buf->serial,
-				      path->device->serial_num,
-				      sizeof(ident_buf->serial));
-				path->device->serial_num[sizeof(ident_buf->serial)]
-				    = '\0';
-				path->device->serial_num_len =
-				    strlen(path->device->serial_num);
-			}
-
-			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
-			ata_device_transport(path);
-			PROBE_SET_ACTION(softc, PROBE_SETMODE);
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-device_fail:
+		/* Old PIO2 devices may not support mode setting. */
+		if (softc->action == PROBE_SETMODE &&
+		    ata_max_pmode(ident_buf) <= ATA_PIO2 &&
+		    (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0)
+			goto noerror;
 		/*
 		 * If we get to this point, we got an error status back
 		 * from the inquiry and the error status doesn't require
@@ -694,161 +608,226 @@ device_fail:
 		if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 			xpt_async(AC_LOST_DEVICE, path, NULL);
 		found = 0;
+		goto done;
+	}
+noerror:
+	switch (softc->action) {
+	case PROBE_RESET:
+	{
+		int sign = (done_ccb->ataio.res.lba_high << 8) +
+		    done_ccb->ataio.res.lba_mid;
+		xpt_print(path, "SIGNATURE: %04x\n", sign);
+		if (sign == 0x0000 &&
+		    done_ccb->ccb_h.target_id != 15) {
+			path->device->protocol = PROTO_ATA;
+			PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
+		} else if (sign == 0x9669 &&
+		    done_ccb->ccb_h.target_id == 15) {
+			struct ccb_trans_settings cts;
+
+				/* Report SIM that PM is present. */
+			bzero(&cts, sizeof(cts));
+			xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+			cts.type = CTS_TYPE_CURRENT_SETTINGS;
+			cts.xport_specific.sata.pm_present = 1;
+			cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
+			xpt_action((union ccb *)&cts);
+			path->device->protocol = PROTO_SATAPM;
+			PROBE_SET_ACTION(softc, PROBE_PM_PID);
+		} else if (sign == 0xeb14 &&
+		    done_ccb->ccb_h.target_id != 15) {
+			path->device->protocol = PROTO_SCSI;
+			PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
+		} else {
+			if (done_ccb->ccb_h.target_id != 15) {
+				xpt_print(path,
+				    "Unexpected signature 0x%04x\n", sign);
+			}
+			goto device_fail;
+		}
 		xpt_release_ccb(done_ccb);
-		break;
+		xpt_schedule(periph, priority);
+		return;
+	}
+	case PROBE_IDENTIFY:
+	{
+		int16_t *ptr;
+
+		for (ptr = (int16_t *)ident_buf;
+		     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
+			*ptr = le16toh(*ptr);
+		}
+		if (strncmp(ident_buf->model, "FX", 2) &&
+		    strncmp(ident_buf->model, "NEC", 3) &&
+		    strncmp(ident_buf->model, "Pioneer", 7) &&
+		    strncmp(ident_buf->model, "SHARP", 5)) {
+			ata_bswap(ident_buf->model, sizeof(ident_buf->model));
+			ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
+			ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
+		}
+		ata_btrim(ident_buf->model, sizeof(ident_buf->model));
+		ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
+		ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
+		ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
+		ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
+		ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
+
+		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
+			/* Check that it is the same device. */
+			MD5_CTX context;
+			u_int8_t digest[16];
+
+			MD5Init(&context);
+			MD5Update(&context,
+			    (unsigned char *)ident_buf->model,
+			    sizeof(ident_buf->model));
+			MD5Update(&context,
+			    (unsigned char *)ident_buf->revision,
+			    sizeof(ident_buf->revision));
+			MD5Update(&context,
+			    (unsigned char *)ident_buf->serial,
+			    sizeof(ident_buf->serial));
+			MD5Final(digest, &context);
+			if (bcmp(digest, softc->digest, sizeof(digest))) {
+				/* Device changed. */
+				xpt_async(AC_LOST_DEVICE, path, NULL);
+			}
+		} else {
+			/* Clean up from previous instance of this device */
+			if (path->device->serial_num != NULL) {
+				free(path->device->serial_num, M_CAMXPT);
+				path->device->serial_num = NULL;
+				path->device->serial_num_len = 0;
+			}
+			path->device->serial_num =
+				(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
+					   M_CAMXPT, M_NOWAIT);
+			if (path->device->serial_num != NULL) {
+				bcopy(ident_buf->serial,
+				      path->device->serial_num,
+				      sizeof(ident_buf->serial));
+				path->device->serial_num[sizeof(ident_buf->serial)]
+				    = '\0';
+				path->device->serial_num_len =
+				    strlen(path->device->serial_num);
+			}
+
+			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+		}
+		ata_device_transport(path);
+		PROBE_SET_ACTION(softc, PROBE_SETMODE);
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
 	}
 	case PROBE_SETMODE:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-modedone:		if (path->device->protocol == PROTO_ATA) {
-				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-				xpt_action(done_ccb);
-				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
-				    done_ccb);
-				xpt_release_ccb(done_ccb);
-				break;
-			} else {
-				PROBE_SET_ACTION(softc, PROBE_INQUIRY);
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
+		if (path->device->protocol == PROTO_ATA) {
+			PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
+		} else {
+			PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 		}
-		/* Old PIO2 devices may not support mode setting. */
-		if (ata_max_pmode(ident_buf) <= ATA_PIO2 &&
-		    (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0)
-			goto modedone;
-		goto device_fail;
-	}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PROBE_SET_MULTI:
+		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+			xpt_action(done_ccb);
+			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
+			    done_ccb);
+		}
+		break;
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
 	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			struct scsi_inquiry_data *inq_buf;
-			u_int8_t periph_qual;
+		struct scsi_inquiry_data *inq_buf;
+		u_int8_t periph_qual, len;
 
-			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
-			inq_buf = &path->device->inq_data;
+		path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
+		inq_buf = &path->device->inq_data;
 
-			periph_qual = SID_QUAL(inq_buf);
+		periph_qual = SID_QUAL(inq_buf);
 
-			if (periph_qual == SID_QUAL_LU_CONNECTED) {
-				u_int8_t len;
+		if (periph_qual != SID_QUAL_LU_CONNECTED)
+			break;
 
-				/*
-				 * We conservatively request only
-				 * SHORT_INQUIRY_LEN bytes of inquiry
-				 * information during our first try
-				 * at sending an INQUIRY. If the device
-				 * has more information to give,
-				 * perform a second request specifying
-				 * the amount of information the device
-				 * is willing to give.
-				 */
-				len = inq_buf->additional_length
-				    + offsetof(struct scsi_inquiry_data,
-                                               additional_length) + 1;
-				if (softc->action == PROBE_INQUIRY
-				    && len > SHORT_INQUIRY_LENGTH) {
-					PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
-					xpt_release_ccb(done_ccb);
-					xpt_schedule(periph, priority);
-					return;
-				}
-
-				scsi_find_quirk(path->device);
-				ata_device_transport(path);
-				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-				xpt_action(done_ccb);
-				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
-				    done_ccb);
-				xpt_release_ccb(done_ccb);
-				break;
-			}
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		goto device_fail;
-	}
-	case PROBE_PM_PID:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0)
-				bzero(ident_buf, sizeof(*ident_buf));
-			softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			((uint32_t *)ident_buf)[0] = softc->pm_pid;
-			printf("PM Product ID: %08x\n", softc->pm_pid);
-			snprintf(ident_buf->model, sizeof(ident_buf->model),
-			    "Port Multiplier %08x", softc->pm_pid);
-			PROBE_SET_ACTION(softc, PROBE_PM_PRV);
+		/*
+		 * We conservatively request only
+		 * SHORT_INQUIRY_LEN bytes of inquiry
+		 * information during our first try
+		 * at sending an INQUIRY. If the device
+		 * has more information to give,
+		 * perform a second request specifying
+		 * the amount of information the device
+		 * is willing to give.
+		 */
+		len = inq_buf->additional_length
+		    + offsetof(struct scsi_inquiry_data, additional_length) + 1;
+		if (softc->action == PROBE_INQUIRY
+		    && len > SHORT_INQUIRY_LENGTH) {
+			PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
 			return;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
 		}
-		goto device_fail;
+
+		scsi_find_quirk(path->device);
+		ata_device_transport(path);
+		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+			xpt_action(done_ccb);
+			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+		}
+		break;
+	}
+	case PROBE_PM_PID:
+		if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0)
+			bzero(ident_buf, sizeof(*ident_buf));
+		softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
+		    (done_ccb->ataio.res.lba_mid << 16) +
+		    (done_ccb->ataio.res.lba_low << 8) +
+		    done_ccb->ataio.res.sector_count;
+		((uint32_t *)ident_buf)[0] = softc->pm_pid;
+		printf("PM Product ID: %08x\n", softc->pm_pid);
+		snprintf(ident_buf->model, sizeof(ident_buf->model),
+		    "Port Multiplier %08x", softc->pm_pid);
+		PROBE_SET_ACTION(softc, PROBE_PM_PRV);
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
 	case PROBE_PM_PRV:
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
-			    (done_ccb->ataio.res.lba_mid << 16) +
-			    (done_ccb->ataio.res.lba_low << 8) +
-			    done_ccb->ataio.res.sector_count;
-			((uint32_t *)ident_buf)[1] = softc->pm_prv;
-			printf("PM Revision: %08x\n", softc->pm_prv);
-			snprintf(ident_buf->revision, sizeof(ident_buf->revision),
-			    "%04x", softc->pm_prv);
-			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
-			if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
-				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-				xpt_action(done_ccb);
-				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
-				    done_ccb);
-			} else {
-				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-				xpt_action(done_ccb);
-				xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path,
-				    done_ccb);
-			}
-			xpt_release_ccb(done_ccb);
-			break;
-		} else if (cam_periph_error(done_ccb, 0, 0,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
+		softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
+		    (done_ccb->ataio.res.lba_mid << 16) +
+		    (done_ccb->ataio.res.lba_low << 8) +
+		    done_ccb->ataio.res.sector_count;
+		((uint32_t *)ident_buf)[1] = softc->pm_prv;
+		printf("PM Revision: %08x\n", softc->pm_prv);
+		snprintf(ident_buf->revision, sizeof(ident_buf->revision),
+		    "%04x", softc->pm_prv);
+		path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+			xpt_action(done_ccb);
+			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
+			    done_ccb);
+		} else {
+			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+			xpt_action(done_ccb);
+			xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb);
 		}
-		goto device_fail;
+		break;
 	case PROBE_INVALID:
 		CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
 		    ("probedone: invalid action state\n"));
 	default:
 		break;
 	}
+done:
+	xpt_release_ccb(done_ccb);
 	done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 	TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
 	done_ccb->ccb_h.status = CAM_REQ_CMP;
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index 46a5e07eeeb..c26afb4600b 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -66,6 +66,7 @@ struct cam_periph;
  */
 typedef struct {
 	u_int32_t priority;
+#define CAM_PRIORITY_BUS	0
 #define CAM_PRIORITY_DEV	0
 #define CAM_PRIORITY_NORMAL	1
 #define CAM_PRIORITY_NONE	(u_int32_t)-1
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index a750d935f43..483f22b5de1 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -816,12 +816,22 @@ struct ccb_trans_settings_sas {
 	u_int32_t 	bitrate;	/* Mbps */
 };
 
+struct ccb_trans_settings_ata {
+	u_int     	valid;		/* Which fields to honor */
+#define	CTS_ATA_VALID_MODE		0x01
+#define	CTS_ATA_VALID_BYTECOUNT		0x04
+	u_int32_t 	mode;
+	u_int 		bytecount;	/* Length of PIO transaction */
+};
+
 struct ccb_trans_settings_sata {
 	u_int     	valid;		/* Which fields to honor */
 #define	CTS_SATA_VALID_SPEED		0x01
 #define	CTS_SATA_VALID_PM		0x02
+#define	CTS_SATA_VALID_BYTECOUNT	0x04
 	u_int32_t 	bitrate;	/* Mbps */
 	u_int 		pm_present;	/* PM is present (XPT->SIM) */
+	u_int 		bytecount;	/* Length of PIO transaction */
 };
 
 /* Get/Set transfer rate/width/disconnection/tag queueing settings */
@@ -841,6 +851,7 @@ struct ccb_trans_settings {
 		struct ccb_trans_settings_spi spi;
 		struct ccb_trans_settings_fc fc;
 		struct ccb_trans_settings_sas sas;
+		struct ccb_trans_settings_ata ata;
 		struct ccb_trans_settings_sata sata;
 	} xport_specific;
 };
diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h
index f95a94f81b8..258055f5bfc 100644
--- a/sys/cam/cam_periph.h
+++ b/sys/cam/cam_periph.h
@@ -79,6 +79,8 @@ struct periph_driver {
 	char			 *driver_name;
 	TAILQ_HEAD(,cam_periph)	 units;
 	u_int			 generation;
+	u_int			 flags;
+#define CAM_PERIPH_DRV_EARLY		0x01
 };
 
 typedef enum {
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index d3ed9aa6606..187683ed881 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -161,7 +161,8 @@ static periph_init_t xpt_periph_init;
 static struct periph_driver xpt_driver =
 {
 	xpt_periph_init, "xpt",
-	TAILQ_HEAD_INITIALIZER(xpt_driver.units)
+	TAILQ_HEAD_INITIALIZER(xpt_driver.units), /* generation */ 0,
+	CAM_PERIPH_DRV_EARLY
 };
 
 PERIPHDRIVER_DECLARE(xpt, xpt_driver);
@@ -1102,30 +1103,35 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 	speed = cpi.base_transfer_speed;
 	freq = 0;
 	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
-		struct	ccb_trans_settings_spi *spi;
+		struct	ccb_trans_settings_spi *spi =
+		    &cts.xport_specific.spi;
 
-		spi = &cts.xport_specific.spi;
 		if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0
 		  && spi->sync_offset != 0) {
 			freq = scsi_calc_syncsrate(spi->sync_period);
 			speed = freq;
 		}
-
 		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
 			speed *= (0x01 << spi->bus_width);
 	}
 	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
-		struct	ccb_trans_settings_fc *fc = &cts.xport_specific.fc;
+		struct	ccb_trans_settings_fc *fc =
+		    &cts.xport_specific.fc;
+
 		if (fc->valid & CTS_FC_VALID_SPEED)
 			speed = fc->bitrate;
 	}
 	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SAS) {
-		struct	ccb_trans_settings_sas *sas = &cts.xport_specific.sas;
+		struct	ccb_trans_settings_sas *sas =
+		    &cts.xport_specific.sas;
+
 		if (sas->valid & CTS_SAS_VALID_SPEED)
 			speed = sas->bitrate;
 	}
 	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
-		struct	ccb_trans_settings_sata *sata = &cts.xport_specific.sata;
+		struct	ccb_trans_settings_sata *sata =
+		    &cts.xport_specific.sata;
+
 		if (sata->valid & CTS_SATA_VALID_SPEED)
 			speed = sata->bitrate;
 	}
@@ -1173,7 +1179,20 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 		if (fc->valid & CTS_FC_VALID_PORT)
 			printf(" PortID 0x%x", fc->port);
 	}
+	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
+		struct ccb_trans_settings_ata *ata =
+		    &cts.xport_specific.ata;
 
+		if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
+			printf(" (PIO size %dbytes)", ata->bytecount);
+	}
+	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
+		struct ccb_trans_settings_sata *sata =
+		    &cts.xport_specific.sata;
+
+		if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
+			printf(" (PIO size %dbytes)", sata->bytecount);
+	}
 	if (path->device->inq_flags & SID_CmdQue
 	 || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
 		printf("\n%s%d: Command Queueing enabled",
@@ -4676,6 +4695,9 @@ xptconfigfunc(struct cam_eb *bus, void *arg)
 static void
 xpt_config(void *arg)
 {
+	struct	periph_driver **p_drv;
+	int	i;
+
 	/*
 	 * Now that interrupts are enabled, go find our devices
 	 */
@@ -4709,6 +4731,13 @@ xpt_config(void *arg)
 #endif /* CAM_DEBUG_BUS */
 #endif /* CAMDEBUG */
 
+	/* Register early peripheral drivers */
+	/* XXX This will have to change when we have loadable modules */
+	p_drv = periph_drivers;
+	for (i = 0; p_drv[i] != NULL; i++) {
+		if ((p_drv[i]->flags & CAM_PERIPH_DRV_EARLY) != 0)
+			(*p_drv[i]->init)();
+	}
 	/*
 	 * Scan all installed busses.
 	 */
@@ -4759,7 +4788,8 @@ xpt_finishconfig_task(void *context, int pending)
 		/* XXX This will have to change when we have loadable modules */
 		p_drv = periph_drivers;
 		for (i = 0; p_drv[i] != NULL; i++) {
-			(*p_drv[i]->init)();
+			if ((p_drv[i]->flags & CAM_PERIPH_DRV_EARLY) == 0)
+				(*p_drv[i]->init)();
 		}
 
 		/*
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index bb9299a4515..8f740dcdfad 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1491,8 +1491,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
 {
 	struct da_softc *softc;
 	struct ccb_scsiio *csio;
+	u_int32_t  priority;
 
 	softc = (struct da_softc *)periph->softc;
+	priority = done_ccb->ccb_h.pinfo.priority;
 	csio = &done_ccb->csio;
 	switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
 	case DA_CCB_BUFFER_IO:
@@ -1610,7 +1612,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
 					softc->state = DA_STATE_PROBE2;
 					free(rdcap, M_SCSIDA);
 					xpt_release_ccb(done_ccb);
-					xpt_schedule(periph, /*priority*/5);
+					xpt_schedule(periph, priority);
 					return;
 				}
 			} else {
diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c
index 4ab038bc2ee..d47e6e9adb3 100644
--- a/sys/cam/scsi/scsi_sg.c
+++ b/sys/cam/scsi/scsi_sg.c
@@ -510,7 +510,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
 			break;
 		}
 
-		ccb = cam_periph_getccb(periph, /*priority*/5);
+		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 		csio = &ccb->csio;
 
 		error = copyin(req.cmdp, &csio->cdb_io.cdb_bytes,
@@ -729,7 +729,7 @@ sgwrite(struct cdev *dev, struct uio *uio, int ioflag)
 
 	cam_periph_lock(periph);
 	sc = periph->softc;
-	xpt_setup_ccb(&ccb->ccb_h, periph->path, /*priority*/5);
+	xpt_setup_ccb(&ccb->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 	cam_fill_csio(csio,
 		      /*retries*/1,
 		      sgdone,
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index 35a5ac2a706..a240db845ce 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -110,7 +110,8 @@ static periph_init_t probe_periph_init;
 static struct periph_driver probe_driver =
 {
 	probe_periph_init, "probe",
-	TAILQ_HEAD_INITIALIZER(probe_driver.units)
+	TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0,
+	CAM_PERIPH_DRV_EARLY
 };
 
 PERIPHDRIVER_DECLARE(probe, probe_driver);

From 7f8fbd60d4375d12343c6cc63a66e031abe8e832 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 31 Oct 2009 10:47:47 +0000
Subject: [PATCH 432/646] MFp4: Sync connection speed reporting with kernel.
 Report speed in identify command, same as done by inquiry.

---
 sbin/camcontrol/camcontrol.c | 95 +++++++++++++++++++++---------------
 1 file changed, 56 insertions(+), 39 deletions(-)

diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 52316ea6794..c0753e7b621 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -186,7 +186,7 @@ static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
 			 char *combinedopt, int retry_count, int timeout);
 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
-static int scsixferrate(struct cam_device *device);
+static int camxferrate(struct cam_device *device);
 #endif /* MINIMALISTIC */
 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
 		     cam_argmask *arglst);
@@ -663,7 +663,7 @@ scsidoinquiry(struct cam_device *device, int argc, char **argv,
 		return(error);
 
 	if (arglist & CAM_ARG_GET_XFERRATE)
-		error = scsixferrate(device);
+		error = camxferrate(device);
 
 	return(error);
 }
@@ -873,14 +873,18 @@ scsiserial(struct cam_device *device, int retry_count, int timeout)
 }
 
 static int
-scsixferrate(struct cam_device *device)
+camxferrate(struct cam_device *device)
 {
+	struct ccb_pathinq cpi;
 	u_int32_t freq = 0;
 	u_int32_t speed = 0;
 	union ccb *ccb;
 	u_int mb;
 	int retval = 0;
 
+	if ((retval = get_cpi(device, &cpi)) != 0)
+		return (1);
+
 	ccb = cam_getccb(device);
 
 	if (ccb == NULL) {
@@ -913,6 +917,8 @@ scsixferrate(struct cam_device *device)
 
 	}
 
+	speed = cpi.base_transfer_speed;
+	freq = 0;
 	if (ccb->cts.transport == XPORT_SPI) {
 		struct ccb_trans_settings_spi *spi =
 		    &ccb->cts.xport_specific.spi;
@@ -920,31 +926,44 @@ scsixferrate(struct cam_device *device)
 		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
 			freq = scsi_calc_syncsrate(spi->sync_period);
 			speed = freq;
-		} else {
-			struct ccb_pathinq cpi;
-
-			retval = get_cpi(device, &cpi);
-			if (retval == 0) {
-				speed = cpi.base_transfer_speed;
-				freq = 0;
-			}
 		}
-
-		fprintf(stdout, "%s%d: ", device->device_name,
-			device->dev_unit_num);
-
 		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
 			speed *= (0x01 << spi->bus_width);
 		}
+	} else if (ccb->cts.transport == XPORT_FC) {
+		struct ccb_trans_settings_fc *fc =
+		    &ccb->cts.xport_specific.fc;
 
-		mb = speed / 1000;
+		if (fc->valid & CTS_FC_VALID_SPEED)
+			speed = fc->bitrate;
+	} else if (ccb->cts.transport == XPORT_SAS) {
+		struct ccb_trans_settings_sas *sas =
+		    &ccb->cts.xport_specific.sas;
 
-		if (mb > 0) 
-			fprintf(stdout, "%d.%03dMB/s transfers ",
-				mb, speed % 1000);
-		else
-			fprintf(stdout, "%dKB/s transfers ",
-				speed);
+		if (sas->valid & CTS_SAS_VALID_SPEED)
+			speed = sas->bitrate;
+	} else if (ccb->cts.transport == XPORT_SATA) {
+		struct ccb_trans_settings_sata *sata =
+		    &ccb->cts.xport_specific.sata;
+
+		if (sata->valid & CTS_SATA_VALID_SPEED)
+			speed = sata->bitrate;
+	}
+
+	mb = speed / 1000;
+	if (mb > 0) {
+		fprintf(stdout, "%s%d: %d.%03dMB/s transfers ",
+			device->device_name, device->dev_unit_num,
+			mb, speed % 1000);
+	} else {
+		fprintf(stdout, "%s%d: %dKB/s transfers ",
+			device->device_name, device->dev_unit_num,
+			speed);
+	}
+
+	if (ccb->cts.transport == XPORT_SPI) {
+		struct ccb_trans_settings_spi *spi =
+		    &ccb->cts.xport_specific.spi;
 
 		if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
 		 && (spi->sync_offset != 0))
@@ -964,25 +983,22 @@ scsixferrate(struct cam_device *device)
 		 && (spi->sync_offset != 0)) {
 			fprintf(stdout, ")");
 		}
-	} else {
-		struct ccb_pathinq cpi;
+	} else if (ccb->cts.transport == XPORT_ATA) {
+		struct ccb_trans_settings_ata *ata =
+		    &ccb->cts.xport_specific.ata;
 
-		retval = get_cpi(device, &cpi);
+		if (ata->valid & CTS_ATA_VALID_BYTECOUNT) {
+			fprintf(stdout, "(PIO size %dbytes)",
+			    ata->bytecount);
+		}
+	} else if (ccb->cts.transport == XPORT_SATA) {
+		struct ccb_trans_settings_sata *sata =
+		    &ccb->cts.xport_specific.sata;
 
-		if (retval != 0)
-			goto xferrate_bailout;
-
-		speed = cpi.base_transfer_speed;
-		freq = 0;
-
-		mb = speed / 1000;
-
-		if (mb > 0) 
-			fprintf(stdout, "%d.%03dMB/s transfers ",
-				mb, speed % 1000);
-		else
-			fprintf(stdout, "%dKB/s transfers ",
-				speed);
+		if (sata->valid & CTS_SATA_VALID_BYTECOUNT) {
+			fprintf(stdout, "(PIO size %dbytes)",
+			    sata->bytecount);
+		}
 	}
 
 	if (ccb->cts.protocol == PROTO_SCSI) {
@@ -1305,6 +1321,7 @@ ataidentify(struct cam_device *device, int retry_count, int timeout)
 	fprintf(stdout, "%s%d: ", device->device_name,
 		device->dev_unit_num);
 	ata_print_ident(ident_buf);
+	camxferrate(device);
 	atacapprint(ident_buf);
 
 	free(ident_buf);

From a65653d16addf4f0c3b1eb591f64e31785be2377 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 31 Oct 2009 12:22:23 +0000
Subject: [PATCH 433/646] The majors file was removed long ago, 0 should be
 used instead.

PR:		139230
Submitted by:	pluknet 
MFC after:	1 week
---
 sbin/mknod/mknod.8 | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/sbin/mknod/mknod.8 b/sbin/mknod/mknod.8
index 54b544153c9..f9dc3cbc484 100644
--- a/sbin/mknod/mknod.8
+++ b/sbin/mknod/mknod.8
@@ -28,7 +28,7 @@
 .\"     @(#)mknod.8	8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd December 15, 2004
+.Dd October 31, 2009
 .Dt MKNOD 8
 .Os
 .Sh NAME
@@ -74,9 +74,7 @@ and pseudo devices, and are type
 .It Ar major
 The major device number is an integer number which tells the kernel
 which device driver entry point to use.
-To learn what
-major device number to use for a particular device, check
-.Pa /usr/src/sys/conf/majors .
+This is a compatibility shim and should be left zero.
 .It Ar minor
 The minor device number tells the kernel which subunit
 the node corresponds to on the device; for example,

From ebbb35ba70fe09f686a2e352b19c471851504fee Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 31 Oct 2009 13:24:14 +0000
Subject: [PATCH 434/646] MFp4: - Remove most of direct relations between
 ATA(4) peripherial and controller levels. It makes logic more transparent and
 is a mandatory step to wrap ATA(4) controller level into ATA-native CAM SIM.
 - Tune AHCI and SATA2 SiI drivers memory allocation a bit to allow bigger I/O
 transaction sizes without additional cost.

---
 sys/arm/mv/mv_sata.c                    | 13 ++--
 sys/dev/ata/ata-all.c                   |  8 +--
 sys/dev/ata/ata-all.h                   | 14 ++--
 sys/dev/ata/ata-dma.c                   | 17 +++--
 sys/dev/ata/ata-lowlevel.c              | 91 ++++++++++++-------------
 sys/dev/ata/ata-pci.c                   |  2 +-
 sys/dev/ata/ata-queue.c                 | 10 ++-
 sys/dev/ata/ata-sata.c                  | 11 +--
 sys/dev/ata/chipsets/ata-ahci.c         | 29 +++-----
 sys/dev/ata/chipsets/ata-intel.c        | 10 +--
 sys/dev/ata/chipsets/ata-marvell.c      | 13 ++--
 sys/dev/ata/chipsets/ata-promise.c      | 27 +++-----
 sys/dev/ata/chipsets/ata-serverworks.c  | 11 ++-
 sys/dev/ata/chipsets/ata-siliconimage.c | 37 ++++------
 14 files changed, 138 insertions(+), 155 deletions(-)

diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c
index 13372526cce..35939563c50 100644
--- a/sys/arm/mv/mv_sata.c
+++ b/sys/arm/mv/mv_sata.c
@@ -548,14 +548,16 @@ sata_channel_begin_transaction(struct ata_request *request)
 	uint32_t req_in;
 	int error, slot;
 
-	sc = device_get_softc(GRANDPARENT(request->dev));
+	sc = device_get_softc(device_get_parent(request->parent));
 	ch = device_get_softc(request->parent);
 
 	mtx_assert(&ch->state_mtx, MA_OWNED);
 
 	/* Only DMA R/W goes through the EDMA machine. */
 	if (request->u.ata.command != ATA_READ_DMA &&
-	    request->u.ata.command != ATA_WRITE_DMA) {
+	    request->u.ata.command != ATA_WRITE_DMA &&
+	    request->u.ata.command != ATA_READ_DMA48 &&
+	    request->u.ata.command != ATA_WRITE_DMA48) {
 
 		/* Disable EDMA before accessing legacy registers */
 		if (sata_edma_is_running(request->parent)) {
@@ -569,12 +571,9 @@ sata_channel_begin_transaction(struct ata_request *request)
 		return (ata_begin_transaction(request));
 	}
 
-	/* Check for 48 bit access and convert if needed */
-	ata_modify_if_48bit(request);
-
 	/* Prepare data for DMA */
 	if ((error = ch->dma.load(request, NULL, NULL))) {
-		device_printf(request->dev, "setting up DMA failed!\n");
+		device_printf(request->parent, "setting up DMA failed!\n");
 		request->result = error;
 		return ATA_OP_FINISHED;
 	}
@@ -633,7 +632,7 @@ sata_channel_end_transaction(struct ata_request *request)
 	uint32_t res_in, res_out, icr;
 	int slot;
 
-	sc = device_get_softc(GRANDPARENT(request->dev));
+	sc = device_get_softc(device_get_parent(request->parent));
 	ch = device_get_softc(request->parent);
 
 	mtx_assert(&ch->state_mtx, MA_OWNED);
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 1460a2117d4..d0a07c36289 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -798,10 +798,10 @@ ata_default_registers(device_t dev)
 void
 ata_modify_if_48bit(struct ata_request *request)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
+    struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_device *atadev = device_get_softc(request->dev);
 
-    atadev->flags &= ~ATA_D_48BIT_ACTIVE;
+    request->flags &= ~ATA_R_48BIT;
 
     if (((request->u.ata.lba + request->u.ata.count) >= ATA_MAX_28BIT_LBA ||
 	 request->u.ata.count > 256) &&
@@ -875,7 +875,7 @@ ata_modify_if_48bit(struct ata_request *request)
 	default:
 	    return;
 	}
-	atadev->flags |= ATA_D_48BIT_ACTIVE;
+	request->flags |= ATA_R_48BIT;
     }
     else if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) {
 
@@ -893,7 +893,7 @@ ata_modify_if_48bit(struct ata_request *request)
 	default:
 	    return;
 	}
-	atadev->flags |= ATA_D_48BIT_ACTIVE;
+	request->flags |= ATA_R_48BIT;
     }
 }
 
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index adee8f58127..2bc89369159 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -255,7 +255,7 @@
 #define ATA_AHCI_CL_OFFSET              0
 #define ATA_AHCI_FB_OFFSET              (ATA_AHCI_CL_SIZE * 32)
 #define ATA_AHCI_CT_OFFSET              (ATA_AHCI_FB_OFFSET + 4096)
-#define ATA_AHCI_CT_SIZE                (1024 + 128)
+#define ATA_AHCI_CT_SIZE                (2176 + 128)
 
 struct ata_ahci_dma_prd {
     u_int64_t                   dba;
@@ -269,7 +269,7 @@ struct ata_ahci_cmd_tab {
     u_int8_t                    cfis[64];
     u_int8_t                    acmd[32];
     u_int8_t                    reserved[32];
-#define ATA_AHCI_DMA_ENTRIES            64
+#define ATA_AHCI_DMA_ENTRIES            129
     struct ata_ahci_dma_prd     prd_tab[ATA_AHCI_DMA_ENTRIES];
 } __packed;
 
@@ -364,6 +364,7 @@ struct ata_composite {
 struct ata_request {
     device_t                    dev;            /* device handle */
     device_t                    parent;         /* channel handle */
+    int				unit;		/* physical unit */
     union {
 	struct {
 	    u_int8_t            command;        /* command reg */
@@ -389,6 +390,7 @@ struct ata_request {
 #define         ATA_R_DMA               0x00000010
 #define         ATA_R_QUIET             0x00000020
 #define         ATA_R_TIMEOUT           0x00000040
+#define         ATA_R_48BIT             0x00000080
 
 #define         ATA_R_ORDERED           0x00000100
 #define         ATA_R_AT_HEAD           0x00000200
@@ -396,6 +398,9 @@ struct ata_request {
 #define         ATA_R_THREAD            0x00000800
 #define         ATA_R_DIRECT            0x00001000
 
+#define         ATA_R_ATAPI16           0x00010000
+#define         ATA_R_ATAPI_INTR        0x00020000
+
 #define         ATA_R_DEBUG             0x10000000
 #define         ATA_R_DANGER1           0x20000000
 #define         ATA_R_DANGER2           0x40000000
@@ -423,7 +428,7 @@ struct ata_request {
 #define ATA_DEBUG_RQ(request, string) \
     { \
     if (request->flags & ATA_R_DEBUG) \
-	device_printf(request->dev, "req=%p %s " string "\n", \
+	device_printf(request->parent, "req=%p %s " string "\n", \
 		      request, ata_cmd2str(request)); \
     }
 #else
@@ -449,7 +454,6 @@ struct ata_device {
 #define         ATA_D_USE_CHS           0x0001
 #define         ATA_D_MEDIA_CHANGED     0x0002
 #define         ATA_D_ENC_PRESENT       0x0004
-#define         ATA_D_48BIT_ACTIVE      0x0008
 };
 
 /* structure for holding DMA Physical Region Descriptors (PRD) entries */
@@ -483,7 +487,7 @@ struct ata_dma {
     u_int8_t                    *work;          /* workspace */
     bus_addr_t                  work_bus;       /* bus address of dmatab */
 
-#define ATA_DMA_SLOTS			32
+#define ATA_DMA_SLOTS			1
     int				dma_slots;	/* DMA slots allocated */
     struct ata_dmaslot		slot[ATA_DMA_SLOTS];
     u_int32_t                   alignment;      /* DMA SG list alignment */
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 770b13f0e3c..eae43483346 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -78,7 +78,7 @@ ata_dmainit(device_t dev)
     ch->dma.segsize = 65536;
     ch->dma.max_iosize = 128 * DEV_BSIZE;
     ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
-    ch->dma.dma_slots = 6;
+    ch->dma.dma_slots = 1;
 
     if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0,
 			   ch->dma.max_address, BUS_SPACE_MAXADDR,
@@ -256,37 +256,36 @@ static int
 ata_dmaload(struct ata_request *request, void *addr, int *entries)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
     struct ata_dmasetprd_args dspa;
     int error;
 
     ATA_DEBUG_RQ(request, "dmaload");
 
     if (request->dma) {
-	device_printf(request->dev,
+	device_printf(request->parent,
 		      "FAILURE - already active DMA on this device\n");
 	return EIO;
     }
     if (!request->bytecount) {
-	device_printf(request->dev,
+	device_printf(request->parent,
 		      "FAILURE - zero length DMA transfer attempted\n");
 	return EIO;
     }
     if (request->bytecount & (ch->dma.alignment - 1)) {
-	device_printf(request->dev,
+	device_printf(request->parent,
 		      "FAILURE - odd-sized DMA transfer attempt %d %% %d\n",
 		      request->bytecount, ch->dma.alignment);
 	return EIO;
     }
     if (request->bytecount > ch->dma.max_iosize) {
-	device_printf(request->dev,
+	device_printf(request->parent,
 		      "FAILURE - oversized DMA transfer attempt %d > %d\n",
 		      request->bytecount, ch->dma.max_iosize);
 	return EIO;
     }
 
-    /* set our slot, unit for simplicity XXX SOS NCQ will change that */
-    request->dma = &ch->dma.slot[atadev->unit];
+    /* set our slot. XXX SOS NCQ will change that */
+    request->dma = &ch->dma.slot[0];
 
     if (addr)
 	dspa.dmatab = addr;
@@ -297,7 +296,7 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries)
 				 request->data, request->bytecount,
 				 ch->dma.setprd, &dspa, BUS_DMA_NOWAIT)) ||
 				 (error = dspa.error)) {
-	device_printf(request->dev, "FAILURE - load data\n");
+	device_printf(request->parent, "FAILURE - load data\n");
 	goto error;
     }
 
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index c46caa68013..2dbb9862d0e 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
 
 /* prototypes */
 static int ata_generic_status(device_t dev);
-static int ata_wait(struct ata_channel *ch, struct ata_device *, u_int8_t);
+static int ata_wait(struct ata_channel *ch, int unit, u_int8_t);
 static void ata_pio_read(struct ata_request *, int);
 static void ata_pio_write(struct ata_request *, int);
 static void ata_tf_read(struct ata_request *);
@@ -77,7 +77,6 @@ int
 ata_begin_transaction(struct ata_request *request)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
     int dummy, error;
 
     ATA_DEBUG_RQ(request, "begin transaction");
@@ -88,9 +87,6 @@ ata_begin_transaction(struct ata_request *request)
 	 (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)))
 	request->flags &= ~ATA_R_DMA;
 
-    /* check for 48 bit access and convert if needed */
-    ata_modify_if_48bit(request);
-
     switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) {
 
     /* ATA PIO data transfer and control commands */
@@ -101,7 +97,7 @@ ata_begin_transaction(struct ata_request *request)
 
 	    /* issue command */
 	    if (ch->hw.command(request)) {
-		device_printf(request->dev, "error issuing %s command\n",
+		device_printf(request->parent, "error issuing %s command\n",
 			   ata_cmd2str(request));
 		request->result = EIO;
 		goto begin_finished;
@@ -122,8 +118,8 @@ ata_begin_transaction(struct ata_request *request)
 
 	    /* if write command output the data */
 	    if (write) {
-		if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) {
-		    device_printf(request->dev,
+		if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) {
+		    device_printf(request->parent,
 				  "timeout waiting for write DRQ\n");
 		    request->result = EIO;
 		    goto begin_finished;
@@ -137,14 +133,14 @@ ata_begin_transaction(struct ata_request *request)
     case ATA_R_DMA:
 	/* check sanity, setup SG list and DMA engine */
 	if ((error = ch->dma.load(request, NULL, &dummy))) {
-	    device_printf(request->dev, "setting up DMA failed\n");
+	    device_printf(request->parent, "setting up DMA failed\n");
 	    request->result = error;
 	    goto begin_finished;
 	}
 
 	/* issue command */
 	if (ch->hw.command(request)) {
-	    device_printf(request->dev, "error issuing %s command\n",
+	    device_printf(request->parent, "error issuing %s command\n",
 		       ata_cmd2str(request));
 	    request->result = EIO;
 	    goto begin_finished;
@@ -152,7 +148,7 @@ ata_begin_transaction(struct ata_request *request)
 
 	/* start DMA engine */
 	if (ch->dma.start && ch->dma.start(request)) {
-	    device_printf(request->dev, "error starting DMA\n");
+	    device_printf(request->parent, "error starting DMA\n");
 	    request->result = EIO;
 	    goto begin_finished;
 	}
@@ -162,7 +158,7 @@ ata_begin_transaction(struct ata_request *request)
     case ATA_R_ATAPI:
 	/* is this just a POLL DSC command ? */
 	if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
-	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit));
+	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit));
 	    DELAY(10);
 	    if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC))
 		request->result = EBUSY;
@@ -171,7 +167,7 @@ ata_begin_transaction(struct ata_request *request)
 
 	/* start ATAPI operation */
 	if (ch->hw.command(request)) {
-	    device_printf(request->dev, "error issuing ATA PACKET command\n");
+	    device_printf(request->parent, "error issuing ATA PACKET command\n");
 	    request->result = EIO;
 	    goto begin_finished;
 	}
@@ -181,7 +177,7 @@ ata_begin_transaction(struct ata_request *request)
     case ATA_R_ATAPI|ATA_R_DMA:
 	/* is this just a POLL DSC command ? */
 	if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
-	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit));
+	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit));
 	    DELAY(10);
 	    if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC))
 		request->result = EBUSY;
@@ -190,14 +186,14 @@ ata_begin_transaction(struct ata_request *request)
 
 	/* check sanity, setup SG list and DMA engine */
 	if ((error = ch->dma.load(request, NULL, &dummy))) {
-	    device_printf(request->dev, "setting up DMA failed\n");
+	    device_printf(request->parent, "setting up DMA failed\n");
 	    request->result = error;
 	    goto begin_finished;
 	}
 
 	/* start ATAPI operation */
 	if (ch->hw.command(request)) {
-	    device_printf(request->dev, "error issuing ATA PACKET command\n");
+	    device_printf(request->parent, "error issuing ATA PACKET command\n");
 	    request->result = EIO;
 	    goto begin_finished;
 	}
@@ -229,7 +225,6 @@ int
 ata_end_transaction(struct ata_request *request)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
     int length;
 
     ATA_DEBUG_RQ(request, "end transaction");
@@ -266,8 +261,8 @@ ata_end_transaction(struct ata_request *request)
 
 		if (request->u.ata.command != ATA_ATAPI_IDENTIFY)
 		    flags |= ATA_S_READY;
-		if (ata_wait(ch, atadev, flags) < 0) {
-		    device_printf(request->dev,
+		if (ata_wait(ch, request->unit, flags) < 0) {
+		    device_printf(request->parent,
 				  "timeout waiting for read DRQ\n");
 		    request->result = EIO;
 		    goto end_finished;
@@ -290,8 +285,8 @@ ata_end_transaction(struct ata_request *request)
 		if (request->flags & ATA_R_WRITE) {
 
 		    /* if we get an error here we are done with the HW */
-		    if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) {
-			device_printf(request->dev,
+		    if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) {
+			device_printf(request->parent,
 				      "timeout waiting for write DRQ\n");
 			request->status = ATA_IDX_INB(ch, ATA_STATUS);
 			goto end_finished;
@@ -347,20 +342,19 @@ ata_end_transaction(struct ata_request *request)
 	    DELAY(10);
 
 	    if (!(request->status & ATA_S_DRQ)) {
-		device_printf(request->dev, "command interrupt without DRQ\n");
+		device_printf(request->parent, "command interrupt without DRQ\n");
 		request->status = ATA_S_ERROR;
 		goto end_finished;
 	    }
 	    ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb,
-			       (atadev->param.config &
-				ATA_PROTO_MASK)== ATA_PROTO_ATAPI_12 ? 6 : 8);
+			       (request->flags & ATA_R_ATAPI16) ? 8 : 6);
 	    /* return wait for interrupt */
 	    goto end_continue;
 
 	case ATAPI_P_WRITE:
 	    if (request->flags & ATA_R_READ) {
 		request->status = ATA_S_ERROR;
-		device_printf(request->dev,
+		device_printf(request->parent,
 			      "%s trying to write on read buffer\n",
 			   ata_cmd2str(request));
 		goto end_finished;
@@ -378,7 +372,7 @@ ata_end_transaction(struct ata_request *request)
 	case ATAPI_P_READ:
 	    if (request->flags & ATA_R_WRITE) {
 		request->status = ATA_S_ERROR;
-		device_printf(request->dev,
+		device_printf(request->parent,
 			      "%s trying to read on write buffer\n",
 			   ata_cmd2str(request));
 		goto end_finished;
@@ -393,7 +387,7 @@ ata_end_transaction(struct ata_request *request)
 	    goto end_continue;
 
 	case ATAPI_P_DONEDRQ:
-	    device_printf(request->dev,
+	    device_printf(request->parent,
 			  "WARNING - %s DONEDRQ non conformant device\n",
 			  ata_cmd2str(request));
 	    if (request->flags & ATA_R_READ) {
@@ -415,7 +409,7 @@ ata_end_transaction(struct ata_request *request)
 	    goto end_finished;
 
 	default:
-	    device_printf(request->dev, "unknown transfer phase\n");
+	    device_printf(request->parent, "unknown transfer phase\n");
 	    request->status = ATA_S_ERROR;
 	}
 
@@ -603,7 +597,7 @@ ata_generic_status(device_t dev)
 }
 
 static int
-ata_wait(struct ata_channel *ch, struct ata_device *atadev, u_int8_t mask)
+ata_wait(struct ata_channel *ch, int unit, u_int8_t mask)
 {
     u_int8_t status;
     int timeout = 0;
@@ -616,7 +610,7 @@ ata_wait(struct ata_channel *ch, struct ata_device *atadev, u_int8_t mask)
 
 	/* if drive fails status, reselect the drive and try again */
 	if (status == 0xff) {
-	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit));
+	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(unit));
 	    timeout += 1000;
 	    DELAY(1000);
 	    continue;
@@ -657,14 +651,13 @@ int
 ata_generic_command(struct ata_request *request)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
 
     /* select device */
-    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit));
+    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit));
 
     /* ready to issue command ? */
-    if (ata_wait(ch, atadev, 0) < 0) { 
-	device_printf(request->dev, "timeout waiting to issue command\n");
+    if (ata_wait(ch, request->unit, 0) < 0) { 
+	device_printf(request->parent, "timeout waiting to issue command\n");
 	return -1;
     }
 
@@ -673,6 +666,7 @@ ata_generic_command(struct ata_request *request)
 
     if (request->flags & ATA_R_ATAPI) {
 	int timeout = 5000;
+	int res;
 
 	/* issue packet command to controller */
 	if (request->flags & ATA_R_DMA) {
@@ -688,9 +682,16 @@ ata_generic_command(struct ata_request *request)
 	ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD);
 
 	/* command interrupt device ? just return and wait for interrupt */
-	if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR)
+	if (request->flags & ATA_R_ATAPI_INTR)
 	    return 0;
 
+	/* command processed ? */
+	res = ata_wait(ch, request->unit, 0);
+	if (res != 0) {
+	    if (res < 0)
+		    device_printf(request->parent, "timeout waiting for PACKET command\n");
+	    return (-1);
+	}
 	/* wait for ready to write ATAPI command block */
 	while (timeout--) {
 	    int reason = ATA_IDX_INB(ch, ATA_IREASON);
@@ -702,7 +703,7 @@ ata_generic_command(struct ata_request *request)
 	    DELAY(20);
 	}
 	if (timeout <= 0) {
-	    device_printf(request->dev, "timeout waiting for ATAPI ready\n");
+	    device_printf(request->parent, "timeout waiting for ATAPI ready\n");
 	    request->result = EIO;
 	    return -1;
 	}
@@ -712,8 +713,7 @@ ata_generic_command(struct ata_request *request)
 		    
 	/* output command block */
 	ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb,
-			   (atadev->param.config & ATA_PROTO_MASK) ==
-			   ATA_PROTO_ATAPI_12 ? 6 : 8);
+			   (request->flags & ATA_R_ATAPI16) ? 8 : 6);
     }
     else {
 	ch->hw.tf_write(request);
@@ -728,9 +728,8 @@ static void
 ata_tf_read(struct ata_request *request)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB);
 	request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8);
 	request->u.ata.lba =
@@ -760,7 +759,7 @@ ata_tf_write(struct ata_request *request)
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_device *atadev = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8);
 	ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
 	ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8);
@@ -771,7 +770,7 @@ ata_tf_write(struct ata_request *request)
 	ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
 	ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40);
 	ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
-	ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit));
+	ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
     }
     else {
 	ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
@@ -793,7 +792,7 @@ ata_tf_write(struct ata_request *request)
 			 (request->u.ata.lba / (sectors * heads)));
 	    ATA_IDX_OUTB(ch, ATA_CYL_MSB,
 			 (request->u.ata.lba / (sectors * heads)) >> 8);
-	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | 
+	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | 
 			 (((request->u.ata.lba% (sectors * heads)) /
 			   sectors) & 0xf));
 	}
@@ -802,7 +801,7 @@ ata_tf_write(struct ata_request *request)
 	    ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
 	    ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
 	    ATA_IDX_OUTB(ch, ATA_DRIVE,
-			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) |
+			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
 			 ((request->u.ata.lba >> 24) & 0x0f));
 	}
     }
@@ -825,7 +824,7 @@ ata_pio_read(struct ata_request *request, int length)
 			  size / sizeof(int32_t));
 
     if (request->transfersize < length) {
-	device_printf(request->dev, "WARNING - %s read data overrun %d>%d\n",
+	device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n",
 		   ata_cmd2str(request), length, request->transfersize);
 	for (resid = request->transfersize; resid < length;
 	     resid += sizeof(int16_t))
@@ -850,7 +849,7 @@ ata_pio_write(struct ata_request *request, int length)
 			   size / sizeof(int32_t));
 
     if (request->transfersize < length) {
-	device_printf(request->dev, "WARNING - %s write data underrun %d>%d\n",
+	device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n",
 		   ata_cmd2str(request), length, request->transfersize);
 	for (resid = request->transfersize; resid < length;
 	     resid += sizeof(int16_t))
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 9a0af1cf55c..4440bdea292 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -477,7 +477,7 @@ ata_pci_dmareset(device_t dev)
     ch->dma.flags &= ~ATA_DMA_ACTIVE;
     ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
     if ((request = ch->running)) {
-	device_printf(request->dev, "DMA reset calling unload\n");
+	device_printf(dev, "DMA reset calling unload\n");
 	ch->dma.unload(request);
     }
 }
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index c0eb558e717..eeb7a1a4805 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -52,17 +52,25 @@ void
 ata_queue_request(struct ata_request *request)
 {
     struct ata_channel *ch;
+    struct ata_device *atadev = device_get_softc(request->dev);
 
     /* treat request as virgin (this might be an ATA_R_REQUEUE) */
     request->result = request->status = request->error = 0;
 
-    /* check that the device is still valid */
+    /* Prepare paramers required by low-level code. */
+    request->unit = atadev->unit;
     if (!(request->parent = device_get_parent(request->dev))) {
 	request->result = ENXIO;
 	if (request->callback)
 	    (request->callback)(request);
 	return;
     }
+    if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16)
+	request->flags |= ATA_R_ATAPI16;
+    if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR)
+	request->flags |= ATA_R_ATAPI_INTR;
+    if ((request->flags & ATA_R_ATAPI) == 0)
+	ata_modify_if_48bit(request);
     ch = device_get_softc(request->parent);
     callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
     if (!request->callback && !(request->flags & ATA_R_REQUEUE))
diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c
index b00bf01e508..5f5daa48f3f 100644
--- a/sys/dev/ata/ata-sata.c
+++ b/sys/dev/ata/ata-sata.c
@@ -246,11 +246,10 @@ ata_sata_setmode(device_t dev, int mode)
 int
 ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
 {
-    struct ata_device *atadev = device_get_softc(request->dev);
 
     if (request->flags & ATA_R_ATAPI) {
 	fis[0] = 0x27;  		/* host to device */
-	fis[1] = 0x80 | (atadev->unit & 0x0f);
+	fis[1] = 0x80 | (request->unit & 0x0f);
 	fis[2] = ATA_PACKET_CMD;
 	if (request->flags & (ATA_R_READ | ATA_R_WRITE))
 	    fis[3] = ATA_F_DMA;
@@ -263,16 +262,15 @@ ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
 	return 20;
     }
     else {
-	ata_modify_if_48bit(request);
 	fis[0] = 0x27;			/* host to device */
-	fis[1] = 0x80 | (atadev->unit & 0x0f);
+	fis[1] = 0x80 | (request->unit & 0x0f);
 	fis[2] = request->u.ata.command;
 	fis[3] = request->u.ata.feature;
 	fis[4] = request->u.ata.lba;
 	fis[5] = request->u.ata.lba >> 8;
 	fis[6] = request->u.ata.lba >> 16;
 	fis[7] = ATA_D_LBA;
-	if (!(atadev->flags & ATA_D_48BIT_ACTIVE))
+	if (!(request->flags & ATA_R_48BIT))
 	    fis[7] |= (ATA_D_IBM | (request->u.ata.lba >> 24 & 0x0f));
 	fis[8] = request->u.ata.lba >> 24;
 	fis[9] = request->u.ata.lba >> 32; 
@@ -339,9 +337,6 @@ ata_pm_identify(device_t dev)
 		      pm_chipid, pm_revision, pm_ports);
     }
 
-    /* realloc space for needed DMA slots */
-    ch->dma.dma_slots = pm_ports;
-
     /* reset all ports and register if anything connected */
     for (port=0; port < pm_ports; port++) {
 	u_int32_t signature;
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index 79544bb8554..9e3f9af94b6 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -385,23 +385,22 @@ ata_ahci_status(device_t dev)
 static int
 ata_ahci_begin_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
     struct ata_ahci_cmd_tab *ctp;
     struct ata_ahci_cmd_list *clp;
     int offset = ch->unit << 7;
-    int port = atadev->unit & 0x0f;
+    int port = request->unit & 0x0f;
     int entries = 0;
     int fis_size;
 	
     /* get a piece of the workspace for this request */
     ctp = (struct ata_ahci_cmd_tab *)
-	  (ch->dma.work + ATA_AHCI_CT_OFFSET + (ATA_AHCI_CT_SIZE*request->tag));
+	  (ch->dma.work + ATA_AHCI_CT_OFFSET);
 
     /* setup the FIS for this request */
     if (!(fis_size = ata_ahci_setup_fis(ctp, request))) {
-	device_printf(request->dev, "setting up SATA FIS failed\n");
+	device_printf(request->parent, "setting up SATA FIS failed\n");
 	request->result = EIO;
 	return ATA_OP_FINISHED;
     }
@@ -409,7 +408,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
     /* if request moves data setup and load SG list */
     if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
 	if (ch->dma.load(request, ctp->prd_tab, &entries)) {
-	    device_printf(request->dev, "setting up DMA failed\n");
+	    device_printf(request->parent, "setting up DMA failed\n");
 	    request->result = EIO;
 	    return ATA_OP_FINISHED;
 	}
@@ -417,7 +416,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
 
     /* setup the command list entry */
     clp = (struct ata_ahci_cmd_list *)
-	  (ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag));
+	  (ch->dma.work + ATA_AHCI_CL_OFFSET);
 
     clp->prd_length = entries;
     clp->cmd_flags = (request->flags & ATA_R_WRITE ? ATA_AHCI_CMD_WRITE : 0) |
@@ -426,12 +425,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
 		     (fis_size / sizeof(u_int32_t)) |
     		     (port << 12);
     clp->bytecount = 0;
-    clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET +
-				  (ATA_AHCI_CT_SIZE * request->tag));
-
-    /* clear eventual ACTIVE bit */
-    ATA_IDX_OUTL(ch, ATA_SACTIVE,
-		 ATA_IDX_INL(ch, ATA_SACTIVE) & (1 << request->tag));
+    clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET);
 
     /* set command type bit */
     if (request->flags & ATA_R_ATAPI)
@@ -444,7 +438,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
 		 ~ATA_AHCI_P_CMD_ATAPI);
 
     /* issue command to controller */
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, (1 << request->tag));
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, 1);
     
     if (!(request->flags & ATA_R_ATAPI)) {
 	/* device reset doesn't interrupt */
@@ -476,7 +470,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
 static int
 ata_ahci_end_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_ahci_cmd_list *clp;
     u_int32_t tf_data;
@@ -495,13 +489,12 @@ ata_ahci_end_transaction(struct ata_request *request)
 
     /* on control commands read back registers to the request struct */
     if (request->flags & ATA_R_CONTROL) {
-	struct ata_device *atadev = device_get_softc(request->dev);
 	u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40;
 
 	request->u.ata.count = fis[12] | ((u_int16_t)fis[13] << 8);
 	request->u.ata.lba = fis[4] | ((u_int64_t)fis[5] << 8) |
 			     ((u_int64_t)fis[6] << 16);
-	if (atadev->flags & ATA_D_48BIT_ACTIVE)
+	if (request->flags & ATA_R_48BIT)
 	    request->u.ata.lba |= ((u_int64_t)fis[8] << 24) |
 				  ((u_int64_t)fis[9] << 32) |
 				  ((u_int64_t)fis[10] << 40);
@@ -511,7 +504,7 @@ ata_ahci_end_transaction(struct ata_request *request)
 
     /* record how much data we actually moved */
     clp = (struct ata_ahci_cmd_list *)
-	  (ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag));
+	  (ch->dma.work + ATA_AHCI_CL_OFFSET);
     request->donecount = clp->bytecount;
 
     /* release SG list etc */
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index c8ed0c05c0b..38c296b1f4b 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -466,10 +466,10 @@ ata_intel_31244_status(device_t dev)
 static void
 ata_intel_31244_tf_write(struct ata_request *request)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
+    struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_device *atadev = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
 	ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
 	ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) |
@@ -478,7 +478,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
 				       ((request->u.ata.lba >> 8) & 0x00ff));
 	ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | 
 				       ((request->u.ata.lba >> 16) & 0x00ff));
-	ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit));
+	ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
     }
     else {
 	ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
@@ -499,7 +499,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
 			 (request->u.ata.lba / (sectors * heads)));
 	    ATA_IDX_OUTB(ch, ATA_CYL_MSB,
 			 (request->u.ata.lba / (sectors * heads)) >> 8);
-	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | 
+	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | 
 			 (((request->u.ata.lba% (sectors * heads)) /
 			   sectors) & 0xf));
 	}
@@ -508,7 +508,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
 	    ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
 	    ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
 	    ATA_IDX_OUTB(ch, ATA_DRIVE,
-			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) |
+			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
 			 ((request->u.ata.lba >> 24) & 0x0f));
 	}
     }
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index adf4d9893d5..dede9bb4c6d 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -354,7 +354,7 @@ ata_marvell_edma_status(device_t dev)
 static int
 ata_marvell_edma_begin_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
     u_int32_t req_in;
     u_int8_t *bytep;
@@ -363,7 +363,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
 
     /* only DMA R/W goes through the EMDA machine */
     if (request->u.ata.command != ATA_READ_DMA &&
-	request->u.ata.command != ATA_WRITE_DMA) {
+	request->u.ata.command != ATA_WRITE_DMA &&
+	request->u.ata.command != ATA_READ_DMA48 &&
+	request->u.ata.command != ATA_WRITE_DMA48) {
 
 	/* disable the EDMA machinery */
 	if (ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001)
@@ -371,12 +373,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
 	return ata_begin_transaction(request);
     }
 
-    /* check for 48 bit access and convert if needed */
-    ata_modify_if_48bit(request);
-
     /* check sanity, setup SG list and DMA engine */
     if ((error = ch->dma.load(request, NULL, NULL))) {
-	device_printf(request->dev, "setting up DMA failed\n");
+	device_printf(request->parent, "setting up DMA failed\n");
 	request->result = error;
 	return ATA_OP_FINISHED;
     }
@@ -472,7 +471,7 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
 static int
 ata_marvell_edma_end_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
     int offset = (ch->unit > 3 ? 0x30014 : 0x20014);
     u_int32_t icr = ATA_INL(ctlr->r_res1, offset);
diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c
index 37863ce7ff2..ca3243adb74 100644
--- a/sys/dev/ata/chipsets/ata-promise.c
+++ b/sys/dev/ata/chipsets/ata-promise.c
@@ -387,11 +387,10 @@ ata_promise_status(device_t dev)
 static int
 ata_promise_dmastart(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev  = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_OUTB(ctlr->r_res1, 0x11,
 		 ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02));
 	ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20,
@@ -411,12 +410,11 @@ ata_promise_dmastart(struct ata_request *request)
 static int
 ata_promise_dmastop(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev  = device_get_softc(request->dev);
     int error;
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_OUTB(ctlr->r_res1, 0x11,
 		 ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02));
 	ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0);
@@ -682,9 +680,8 @@ ata_promise_mio_status(device_t dev)
 static int
 ata_promise_mio_command(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
 
     u_int32_t *wordp = (u_int32_t *)ch->dma.work;
 
@@ -693,7 +690,7 @@ ata_promise_mio_command(struct ata_request *request)
     if ((ctlr->chip->cfg2 == PR_SATA2) ||
         ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {
 	/* set portmultiplier port */
-	ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), atadev->unit & 0x0f);
+	ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), request->unit & 0x0f);
     }
 
     /* XXX SOS add ATAPI commands support later */
@@ -1051,7 +1048,7 @@ ata_promise_sx4_intr(void *data)
 static int
 ata_promise_sx4_command(struct ata_request *request)
 {
-    device_t gparent = GRANDPARENT(request->dev);
+    device_t gparent = device_get_parent(request->parent);
     struct ata_pci_controller *ctlr = device_get_softc(gparent);
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_dma_prdentry *prd;
@@ -1158,15 +1155,14 @@ ata_promise_sx4_command(struct ata_request *request)
 static int
 ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
 { 
-    struct ata_device *atadev = device_get_softc(request->dev);
     int i = 12;
 
     bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE;
-    bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit);
+    bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit);
     bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL;
     bytep[i++] = ATA_A_4BIT;
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE;
 	bytep[i++] = request->u.ata.feature >> 8;
 	bytep[i++] = request->u.ata.feature;
@@ -1183,7 +1179,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
 	bytep[i++] = request->u.ata.lba >> 40;
 	bytep[i++] = request->u.ata.lba >> 16;
 	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
-	bytep[i++] = ATA_D_LBA | ATA_DEV(atadev->unit);
+	bytep[i++] = ATA_D_LBA | ATA_DEV(request->unit);
     }
     else {
 	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE;
@@ -1197,8 +1193,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
 	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;
 	bytep[i++] = request->u.ata.lba >> 16;
 	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
-	bytep[i++] = (atadev->flags & ATA_D_USE_CHS ? 0 : ATA_D_LBA) |
-		     ATA_D_IBM | ATA_DEV(atadev->unit) |
+	bytep[i++] = ATA_D_LBA | ATA_D_IBM | ATA_DEV(request->unit) |
 		     ((request->u.ata.lba >> 24)&0xf);
     }
     bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND;
diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c
index dfa01f5f80c..886282ebb37 100644
--- a/sys/dev/ata/chipsets/ata-serverworks.c
+++ b/sys/dev/ata/chipsets/ata-serverworks.c
@@ -259,9 +259,8 @@ static void
 ata_serverworks_tf_read(struct ata_request *request)
 {
     struct ata_channel *ch = device_get_softc(request->parent);
-    struct ata_device *atadev = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	u_int16_t temp;
 
 	request->u.ata.count = ATA_IDX_INW(ch, ATA_COUNT);
@@ -290,7 +289,7 @@ ata_serverworks_tf_write(struct ata_request *request)
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_device *atadev = device_get_softc(request->dev);
 
-    if (atadev->flags & ATA_D_48BIT_ACTIVE) {
+    if (request->flags & ATA_R_48BIT) {
 	ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
 	ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
 	ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) |
@@ -299,7 +298,7 @@ ata_serverworks_tf_write(struct ata_request *request)
 				       ((request->u.ata.lba >> 8) & 0x00ff));
 	ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | 
 				       ((request->u.ata.lba >> 16) & 0x00ff));
-	ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit));
+	ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
     }
     else {
 	ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@@ -320,7 +319,7 @@ ata_serverworks_tf_write(struct ata_request *request)
 			 (request->u.ata.lba / (sectors * heads)));
 	    ATA_IDX_OUTW(ch, ATA_CYL_MSB,
 			 (request->u.ata.lba / (sectors * heads)) >> 8);
-	    ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | 
+	    ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | 
 			 (((request->u.ata.lba% (sectors * heads)) /
 			   sectors) & 0xf));
 	}
@@ -329,7 +328,7 @@ ata_serverworks_tf_write(struct ata_request *request)
 	    ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
 	    ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
 	    ATA_IDX_OUTW(ch, ATA_DRIVE,
-			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) |
+			 ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
 			 ((request->u.ata.lba >> 24) & 0x0f));
 	}
     }
diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c
index 232592e071a..1ed48e48786 100644
--- a/sys/dev/ata/chipsets/ata-siliconimage.c
+++ b/sys/dev/ata/chipsets/ata-siliconimage.c
@@ -457,7 +457,7 @@ struct ata_siiprb_dma_prdentry {
     u_int32_t control;
 } __packed;
 
-#define ATA_SIIPRB_DMA_ENTRIES		125
+#define ATA_SIIPRB_DMA_ENTRIES		129
 struct ata_siiprb_ata_command {
     struct ata_siiprb_dma_prdentry prd[ATA_SIIPRB_DMA_ENTRIES];
 } __packed;
@@ -542,7 +542,7 @@ ata_siiprb_status(device_t dev)
 static int
 ata_siiprb_begin_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_siiprb_command *prb;
     struct ata_siiprb_dma_prdentry *prd;
@@ -556,28 +556,25 @@ ata_siiprb_begin_transaction(struct ata_request *request)
     }
 
     /* get a piece of the workspace for this request */
-    prb = (struct ata_siiprb_command *)
-	(ch->dma.work + (sizeof(struct ata_siiprb_command) * request->tag));
+    prb = (struct ata_siiprb_command *)ch->dma.work;
 
     /* clear the prb structure */
     bzero(prb, sizeof(struct ata_siiprb_command));
 
     /* setup the FIS for this request */
     if (!ata_request2fis_h2d(request, &prb->fis[0])) {
-        device_printf(request->dev, "setting up SATA FIS failed\n");
+        device_printf(request->parent, "setting up SATA FIS failed\n");
         request->result = EIO;
         return ATA_OP_FINISHED;
     }
 
     /* setup transfer type */
     if (request->flags & ATA_R_ATAPI) {
-        struct ata_device *atadev = device_get_softc(request->dev);
-
 	bcopy(request->u.atapi.ccb, prb->u.atapi.ccb, 16);
-	if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12)
-	    ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000020);
-	else
+	if (request->flags & ATA_R_ATAPI16)
 	    ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000020);
+	else
+	    ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000020);
 	if (request->flags & ATA_R_READ)
 	    prb->control = htole16(0x0010);
 	if (request->flags & ATA_R_WRITE)
@@ -590,19 +587,16 @@ ata_siiprb_begin_transaction(struct ata_request *request)
     /* if request moves data setup and load SG list */
     if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
 	if (ch->dma.load(request, prd, NULL)) {
-	    device_printf(request->dev, "setting up DMA failed\n");
+	    device_printf(request->parent, "setting up DMA failed\n");
 	    request->result = EIO;
 	    return ATA_OP_FINISHED;
 	}
     }
 
     /* activate the prb */
-    prb_bus = ch->dma.work_bus +
-	      (sizeof(struct ata_siiprb_command) * request->tag);
-    ATA_OUTL(ctlr->r_res2,
-	     0x1c00 + offset + (request->tag * sizeof(u_int64_t)), prb_bus);
-    ATA_OUTL(ctlr->r_res2,
-	     0x1c04 + offset + (request->tag * sizeof(u_int64_t)), prb_bus>>32);
+    prb_bus = ch->dma.work_bus;
+    ATA_OUTL(ctlr->r_res2, 0x1c00 + offset, prb_bus);
+    ATA_OUTL(ctlr->r_res2, 0x1c04 + offset, prb_bus>>32);
 
     /* start the timeout */
     callout_reset(&request->callout, request->timeout * hz,
@@ -613,7 +607,7 @@ ata_siiprb_begin_transaction(struct ata_request *request)
 static int
 ata_siiprb_end_transaction(struct ata_request *request)
 {
-    struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
+    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
     struct ata_channel *ch = device_get_softc(request->parent);
     struct ata_siiprb_command *prb;
     int offset = ch->unit * 0x2000;
@@ -623,7 +617,7 @@ ata_siiprb_end_transaction(struct ata_request *request)
     callout_stop(&request->callout);
     
     prb = (struct ata_siiprb_command *)
-	((u_int8_t *)rman_get_virtual(ctlr->r_res2)+(request->tag << 7)+offset);
+	((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset);
 
     /* any controller errors flagged ? */
     if ((error = ATA_INL(ctlr->r_res2, 0x1024 + offset))) {
@@ -659,12 +653,10 @@ ata_siiprb_end_transaction(struct ata_request *request)
 
     /* on control commands read back registers to the request struct */
     if (request->flags & ATA_R_CONTROL) {
-        struct ata_device *atadev = device_get_softc(request->dev);
-
 	request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8);
 	request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) |
 			     ((u_int64_t)prb->fis[6] << 16);
-	if (atadev->flags & ATA_D_48BIT_ACTIVE)
+	if (request->flags & ATA_R_48BIT)
 	    request->u.ata.lba |= ((u_int64_t)prb->fis[8] << 24) |
 				  ((u_int64_t)prb->fis[9] << 32) |
 				  ((u_int64_t)prb->fis[10] << 40);
@@ -907,6 +899,7 @@ ata_siiprb_dmainit(device_t dev)
     /* note start and stop are not used here */
     ch->dma.setprd = ata_siiprb_dmasetprd;
     ch->dma.max_address = BUS_SPACE_MAXADDR;
+    ch->dma.max_iosize = (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE;
 }
 
 ATA_DECLARE_DRIVER(ata_sii);

From 25dd82a35b1a142c8c17f853e90b91a76d027bae Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 31 Oct 2009 14:19:50 +0000
Subject: [PATCH 435/646] Allow newly added controllers to use full I/O sizes.

---
 sys/dev/ata/chipsets/ata-marvell.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index dede9bb4c6d..346fed5ee74 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -591,7 +591,9 @@ ata_marvell_edma_dmainit(device_t dev)
 
     /* chip does not reliably do 64K DMA transfers */
     if (ctlr->chip->cfg2 == MV_50XX || ctlr->chip->cfg2 == MV_60XX)
-	ch->dma.max_iosize = 64 * DEV_BSIZE; 
+	ch->dma.max_iosize = 64 * DEV_BSIZE;
+    else
+	ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
 }
 
 ATA_DECLARE_DRIVER(ata_marvell);

From 7bcfccda405870bde90f4b94ab738bea077d5ed4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20E=C3=9Fer?= 
Date: Sat, 31 Oct 2009 17:06:36 +0000
Subject: [PATCH 436/646] While certain supported Symbios/LSI SCSI chips
 (532c896, 53c1000, 53c1010) do support 64bit addresses, the current SCRIPTS
 code supports only 32bit addresses causing data corruption for buffer
 addresses >4GB. This problem affects 64bit machines with more than 4GB RAM or
 amd64 with 4GB and memory hole remapping. Work-around this problem with a
 bus_dma tag that requests bounce-buffers for addresses >4GB. This causes some
 overhead, but given the maximum SCSI bus speed of 160MB/s compared, the
 effect should hardly be noticeable. The problem was reported by Mike Watters
 (mike at mwatters net) who also verified that this fix cures the problem.

Since this change is a NOOP on systems with less than 4GB RAM and fixes
data corruption (in RAM and on disk) on systems with more than 4GB, I hope
that this change is accepted for 8.0.

MFC after:	3 days (pending approval)
---
 sys/dev/sym/sym_hipd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index ab74a55c94d..a43c816c65f 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -8582,7 +8582,7 @@ sym_pci_attach(device_t dev)
 	 *  Allocate a tag for the DMA of user data.
 	 */
 	if (bus_dma_tag_create(np->bus_dmat, 1, (1<<24),
-				BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
+				BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
 				NULL, NULL,
 				BUS_SPACE_MAXSIZE, SYM_CONF_MAX_SG,
 				(1<<24), 0, busdma_lock_mutex, &np->mtx,

From e4ed417a355e2cfcb7ee5b9caa6be9c2ed239fae Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sat, 31 Oct 2009 17:39:56 +0000
Subject: [PATCH 437/646] Correct an error in vm_fault_copy_entry() that has
 existed since the first version of this file.  When a process forks, any
 wired pages are immediately copied because copy-on-write is not supported for
 wired pages.  In other words, the child process is given its own private copy
 of each wired page from its parent's address space.  Unfortunately, to date,
 these copied pages have been mapped into the child's address space with the
 wrong permissions, typically VM_PROT_ALL.  This change corrects the
 permissions.

Reviewed by:	kib
---
 sys/vm/vm_fault.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 68057fb4f3f..de871834c4d 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1179,7 +1179,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 		dst_object->uip = dst_entry->uip;
 		dst_entry->uip = NULL;
 	}
-	access = prot = dst_entry->max_protection;
+	access = prot = dst_entry->protection;
 	/*
 	 * If not an upgrade, then enter the mappings in the pmap as
 	 * read and/or execute accesses.  Otherwise, enter them as

From 2bbd567acb4e3de86537f48d78e6f56ae2fe6c09 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 31 Oct 2009 17:46:50 +0000
Subject: [PATCH 438/646] Garbage collect set_user_sr(), which is declared
 static inline and never called.

---
 sys/powerpc/aim/trap.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 0ab58f3830f..ee9c7d30ef0 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -85,8 +85,6 @@ static int	fix_unaligned(struct thread *td, struct trapframe *frame);
 static int	handle_onfault(struct trapframe *frame);
 static void	syscall(struct trapframe *frame);
 
-static __inline void	setusr(u_int);
-
 int	setfault(faultbuf);		/* defined in locore.S */
 
 /* Why are these not defined in a header? */
@@ -558,13 +556,6 @@ trap_pfault(struct trapframe *frame, int user)
 	return (SIGSEGV);
 }
 
-static __inline void
-setusr(u_int content)
-{
-	__asm __volatile ("isync; mtsr %0,%1; isync"
-		      :: "n"(USER_SR), "r"(content));
-}
-
 int
 badaddr(void *addr, size_t size)
 {

From ad26477892ecdcc9a4a226fa2e6ebb6b2fe28002 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 31 Oct 2009 17:55:48 +0000
Subject: [PATCH 439/646] Loop on blocked threads when using ULE scheduler,
 removing an XXX MP comment.

---
 sys/powerpc/aim/swtch.S | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S
index 71d39d0b77f..0f7e8291811 100644
--- a/sys/powerpc/aim/swtch.S
+++ b/sys/powerpc/aim/swtch.S
@@ -57,6 +57,7 @@
  */
 
 #include "assym.s"
+#include "opt_sched.h"
 
 #include 
 
@@ -81,25 +82,23 @@ ENTRY(cpu_throw)
  * Switch to a new thread saving the current state in the old thread.
  */
 ENTRY(cpu_switch)
-	stw	%r5,TD_LOCK(%r3)	/* ULE:	update old thread's lock */
-					/* XXX needs to change for MP */
-
-	lwz	%r5,TD_PCB(%r3)		/* Get the old thread's PCB ptr */
+	lwz	%r6,TD_PCB(%r3)		/* Get the old thread's PCB ptr */
 	mr	%r12,%r2	
-	stmw	%r12,PCB_CONTEXT(%r5)	/* Save the non-volatile GP regs.
+	stmw	%r12,PCB_CONTEXT(%r6)	/* Save the non-volatile GP regs.
 					   These can now be used for scratch */
 
 	mfcr	%r16			/* Save the condition register */
-	stw	%r16,PCB_CR(%r5)
+	stw	%r16,PCB_CR(%r6)
 	mflr	%r16			/* Save the link register */
-	stw	%r16,PCB_LR(%r5)
+	stw	%r16,PCB_LR(%r6)
 	mfsr	%r16,USER_SR		/* Save USER_SR for copyin/out */
 	isync
-	stw	%r16,PCB_AIM_USR(%r5)
-	stw	%r1,PCB_SP(%r5)		/* Save the stack pointer */
+	stw	%r16,PCB_AIM_USR(%r6)
+	stw	%r1,PCB_SP(%r6)		/* Save the stack pointer */
 
 	mr	%r14,%r3		/* Copy the old thread ptr... */
 	mr	%r15,%r4		/* and the new thread ptr in scratch */
+	mr	%r16,%r5		/* and the new lock */
 	
 	lwz	%r6,PCB_FLAGS(%r5)
 	/* Save FPU context if needed */
@@ -118,7 +117,20 @@ ENTRY(cpu_switch)
 	mr	%r3,%r14		/* restore old thread ptr */
 	bl	pmap_deactivate		/* Deactivate the current pmap */
 
+	stw	%r16,TD_LOCK(%r14)	/* ULE:	update old thread's lock */
+
 cpu_switchin:
+#if defined(SMP) && defined(SCHED_ULE)
+	/* Wait for the new thread to become unblocked */
+	sync
+	lis	%r6,blocked_lock@ha
+	addi	%r6,%r6,blocked_lock@l
+blocked_loop:
+	lwz	%r7,TD_LOCK(%r15)
+	cmpw	%r6,%r7 
+	beq	blocked_loop
+#endif
+
 	mfsprg	%r7,0			/* Get the pcpu pointer */
 	stw	%r15,PC_CURTHREAD(%r7)	/* Store new current thread */
 	lwz	%r17,TD_PCB(%r15)	/* Store new current PCB */

From e2cd4c2a655db3b21fb5bf1b4d7e549f83a28479 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 31 Oct 2009 17:59:24 +0000
Subject: [PATCH 440/646] Fix a race in casuword() exposed by csup. casuword()
 non-atomically read the current value of its argument before atomically
 replacing it, which could occasionally return the wrong value on an SMP
 system. This resulted in user mutex operations hanging when using threaded
 applications.

---
 sys/powerpc/aim/copyinout.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c
index 4e9f77746f1..e023b3f7992 100644
--- a/sys/powerpc/aim/copyinout.c
+++ b/sys/powerpc/aim/copyinout.c
@@ -347,8 +347,19 @@ casuword(volatile u_long *addr, u_long old, u_long new)
 		return (-1);
 	}
 
-	val = *p;
-	(void) atomic_cmpset_32((volatile uint32_t *)p, old, new);
+	__asm __volatile (
+		"1:\tlwarx %0, 0, %2\n\t"	/* load old value */
+		"cmplw %3, %0\n\t"		/* compare */
+		"bne 2f\n\t"			/* exit if not equal */
+		"stwcx. %4, 0, %2\n\t"      	/* attempt to store */
+		"bne- 1b\n\t"			/* spin if failed */
+		"b 3f\n\t"			/* we've succeeded */
+		"2:\n\t"
+		"stwcx. %0, 0, %2\n\t"       	/* clear reservation (74xx) */
+		"3:\n\t"
+		: "=&r" (val), "=m" (*p)
+		: "r" (p), "r" (old), "r" (new), "m" (*p)
+		: "cc", "memory");
 
 	td->td_pcb->pcb_onfault = NULL;
 

From 011db0bc81cc1712ef7ec32cb4ee5942ac76b4f2 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 31 Oct 2009 18:04:34 +0000
Subject: [PATCH 441/646] Remove an unnecessary sync that crept in the last
 commit.

---
 sys/powerpc/aim/swtch.S | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S
index 0f7e8291811..2d6bf8a0a0f 100644
--- a/sys/powerpc/aim/swtch.S
+++ b/sys/powerpc/aim/swtch.S
@@ -122,7 +122,6 @@ ENTRY(cpu_switch)
 cpu_switchin:
 #if defined(SMP) && defined(SCHED_ULE)
 	/* Wait for the new thread to become unblocked */
-	sync
 	lis	%r6,blocked_lock@ha
 	addi	%r6,%r6,blocked_lock@l
 blocked_loop:

From 156ef7611e8c2644383091b0b166e2123ad4ee98 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 31 Oct 2009 20:59:13 +0000
Subject: [PATCH 442/646] Unbreak cpu_switch(). The register allocator in my
 brain is clearly broken. Also, Altivec context switching worked before only
 by accident, but should work now by design.

---
 sys/powerpc/aim/swtch.S | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S
index 2d6bf8a0a0f..079705709f5 100644
--- a/sys/powerpc/aim/swtch.S
+++ b/sys/powerpc/aim/swtch.S
@@ -99,17 +99,19 @@ ENTRY(cpu_switch)
 	mr	%r14,%r3		/* Copy the old thread ptr... */
 	mr	%r15,%r4		/* and the new thread ptr in scratch */
 	mr	%r16,%r5		/* and the new lock */
+	mr	%r17,%r6		/* and the PCB */
 	
-	lwz	%r6,PCB_FLAGS(%r5)
+	lwz	%r7,PCB_FLAGS(%r17)
 	/* Save FPU context if needed */
-	andi.	%r6, %r6, PCB_FPU
+	andi.	%r7, %r7, PCB_FPU
 	beq	.L1
 	bl	save_fpu
 
 .L1:
-	lwz	%r6,PCB_FLAGS(%r5)
+	mr	%r3,%r14		/* restore old thread ptr */
+	lwz	%r7,PCB_FLAGS(%r17)
 	/* Save Altivec context if needed */
-	andi.	%r6, %r6, PCB_VEC
+	andi.	%r7, %r7, PCB_VEC
 	beq	.L2
 	bl	save_vec
 	

From 8d077f48f0612726aef1c5a85c98d9839c6e4e3c Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 31 Oct 2009 22:27:31 +0000
Subject: [PATCH 443/646] Reimplement the lazy FP context switching: o   Move
 all code into a single file for easier maintenance. o   Use a single global
 lock to avoid having to handle either     multiple locks or race conditions.
 o   Make sure to disable the high FP registers after saving     or dropping
 them. o   use msleep() to wait for the other CPU to save the high     FP
 registers.

This change fixes the high FP inconsistency panics.

A single global lock typically serializes too much, which may
be noticable when a lot of threads use the high FP registers,
but in that case it's probably better to switch the high FP
context synchronuously. Put differently: cpu_switch() should
switch the high FP registers if the incoming and outgoing
threads both use the high FP registers.
---
 sys/conf/files.ia64        |   1 +
 sys/ia64/ia64/highfp.c     | 181 +++++++++++++++++++++++++++++++++++++
 sys/ia64/ia64/interrupt.c  |   9 +-
 sys/ia64/ia64/machdep.c    |  75 ---------------
 sys/ia64/ia64/trap.c       |  62 +------------
 sys/ia64/ia64/vm_machdep.c |   5 +-
 sys/ia64/include/md_var.h  |   2 +
 sys/ia64/include/proc.h    |   1 -
 8 files changed, 190 insertions(+), 146 deletions(-)
 create mode 100644 sys/ia64/ia64/highfp.c

diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
index 864be05c93a..9b095f4209a 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -84,6 +84,7 @@ ia64/ia64/elf_machdep.c		standard
 ia64/ia64/emulate.c		standard
 ia64/ia64/exception.S		standard
 ia64/ia64/gdb_machdep.c		optional	gdb
+ia64/ia64/highfp.c		standard
 ia64/ia64/in_cksum.c		optional	inet
 ia64/ia64/interrupt.c		standard
 ia64/ia64/locore.S		standard	no-obj
diff --git a/sys/ia64/ia64/highfp.c b/sys/ia64/ia64/highfp.c
new file mode 100644
index 00000000000..145ee488ba6
--- /dev/null
+++ b/sys/ia64/ia64/highfp.c
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 2009 Marcel Moolenaar
+ * 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.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static struct mtx ia64_highfp_mtx;
+
+static void
+ia64_highfp_init(void *_)
+{
+	mtx_init(&ia64_highfp_mtx, "High FP lock", NULL, MTX_SPIN);
+}
+SYSINIT(ia64_highfp_init, SI_SUB_LOCK, SI_ORDER_ANY, ia64_highfp_init, NULL);
+
+#ifdef SMP
+static int
+ia64_highfp_ipi(struct pcpu *cpu)
+{
+	int error;
+
+	ipi_send(cpu, IPI_HIGH_FP);
+	error = msleep_spin(&cpu->pc_fpcurthread, &ia64_highfp_mtx,
+	    "High FP", 0);
+	return (error);
+}
+#endif
+
+int
+ia64_highfp_drop(struct thread *td)
+{
+	struct pcb *pcb;
+	struct pcpu *cpu;
+
+	pcb = td->td_pcb;
+
+	mtx_lock_spin(&ia64_highfp_mtx);
+	cpu = pcb->pcb_fpcpu;
+	if (cpu != NULL) {
+		KASSERT(cpu->pc_fpcurthread == td,
+		    ("cpu->pc_fpcurthread != td"));
+		td->td_frame->tf_special.psr |= IA64_PSR_DFH;
+		pcb->pcb_fpcpu = NULL;
+		cpu->pc_fpcurthread = NULL;
+	}
+	mtx_unlock_spin(&ia64_highfp_mtx);
+
+	return ((cpu != NULL) ? 1 : 0);
+}
+
+int
+ia64_highfp_enable(struct thread *td, struct trapframe *tf)
+{
+	struct pcb *pcb;
+	struct pcpu *cpu;
+	struct thread *td1;
+
+	pcb = td->td_pcb;
+
+	mtx_lock_spin(&ia64_highfp_mtx);
+	KASSERT((tf->tf_special.psr & IA64_PSR_DFH) != 0,
+	    ("(tf->tf_special.psr & IA64_PSR_DFH) == 0"));
+	cpu = pcb->pcb_fpcpu;
+#ifdef SMP
+	if (cpu != NULL && cpu != pcpup) {
+		KASSERT(cpu->pc_fpcurthread == td,
+		    ("cpu->pc_fpcurthread != td"));
+		ia64_highfp_ipi(cpu);
+	}
+#endif
+	td1 = PCPU_GET(fpcurthread);
+	if (td1 != NULL && td1 != td) {
+		KASSERT(td1->td_pcb->pcb_fpcpu == pcpup,
+		    ("td1->td_pcb->pcb_fpcpu != pcpup"));
+		save_high_fp(&td1->td_pcb->pcb_high_fp);
+		td1->td_frame->tf_special.psr |= IA64_PSR_DFH;
+		td1->td_pcb->pcb_fpcpu = NULL;
+		PCPU_SET(fpcurthread, NULL);
+		td1 = NULL;
+	}
+	if (td1 == NULL) {
+		KASSERT(pcb->pcb_fpcpu == NULL, ("pcb->pcb_fpcpu != NULL"));
+		KASSERT(PCPU_GET(fpcurthread) == NULL,
+		    ("PCPU_GET(fpcurthread) != NULL"));
+		restore_high_fp(&pcb->pcb_high_fp);
+		PCPU_SET(fpcurthread, td);
+		pcb->pcb_fpcpu = pcpup;
+		tf->tf_special.psr &= ~IA64_PSR_MFH;
+	}
+	tf->tf_special.psr &= ~IA64_PSR_DFH;
+	mtx_unlock_spin(&ia64_highfp_mtx);
+
+	return ((td1 != NULL) ? 1 : 0);
+}
+
+int
+ia64_highfp_save(struct thread *td)
+{
+	struct pcb *pcb;
+	struct pcpu *cpu;
+
+	pcb = td->td_pcb;
+
+	mtx_lock_spin(&ia64_highfp_mtx);
+	cpu = pcb->pcb_fpcpu;
+#ifdef SMP
+	if (cpu != NULL && cpu != pcpup) {
+		KASSERT(cpu->pc_fpcurthread == td,
+		    ("cpu->pc_fpcurthread != td"));
+		ia64_highfp_ipi(cpu);
+	} else
+#endif
+	if (cpu != NULL) {
+		KASSERT(cpu->pc_fpcurthread == td,
+		    ("cpu->pc_fpcurthread != td"));
+		save_high_fp(&pcb->pcb_high_fp);
+		td->td_frame->tf_special.psr |= IA64_PSR_DFH;
+		pcb->pcb_fpcpu = NULL;
+		cpu->pc_fpcurthread = NULL;
+	}
+	mtx_unlock_spin(&ia64_highfp_mtx);
+
+	return ((cpu != NULL) ? 1 : 0);
+}
+
+#ifdef SMP
+int
+ia64_highfp_save_ipi(void)
+{
+	struct thread *td;
+
+	mtx_lock_spin(&ia64_highfp_mtx);
+	td = PCPU_GET(fpcurthread);
+	if (td != NULL) {
+		KASSERT(td->td_pcb->pcb_fpcpu == pcpup,
+		    ("td->td_pcb->pcb_fpcpu != pcpup"));
+		save_high_fp(&td->td_pcb->pcb_high_fp);
+		td->td_frame->tf_special.psr |= IA64_PSR_DFH;
+		td->td_pcb->pcb_fpcpu = NULL;
+		PCPU_SET(fpcurthread, NULL);
+	}
+	mtx_unlock_spin(&ia64_highfp_mtx);
+	wakeup(&PCPU_GET(fpcurthread));
+
+	return ((td != NULL) ? 1 : 0);
+}
+#endif
diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c
index b70a807591a..a2b1ec5cd0d 100644
--- a/sys/ia64/ia64/interrupt.c
+++ b/sys/ia64/ia64/interrupt.c
@@ -216,14 +216,7 @@ interrupt(struct trapframe *tf)
 		asts[PCPU_GET(cpuid)]++;
 		CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
 	} else if (vector == ipi_vector[IPI_HIGH_FP]) {
-		struct thread *thr = PCPU_GET(fpcurthread);
-		if (thr != NULL) {
-			mtx_lock_spin(&thr->td_md.md_highfp_mtx);
-			save_high_fp(&thr->td_pcb->pcb_high_fp);
-			thr->td_pcb->pcb_fpcpu = NULL;
-			PCPU_SET(fpcurthread, NULL);
-			mtx_unlock_spin(&thr->td_md.md_highfp_mtx);
-		}
+		ia64_highfp_save_ipi();
 	} else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
 		rdvs[PCPU_GET(cpuid)]++;
 		CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 299c9ec8253..e578e8bb05a 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1461,81 +1461,6 @@ set_fpregs(struct thread *td, struct fpreg *fpregs)
 	return (0);
 }
 
-/*
- * High FP register functions.
- */
-
-int
-ia64_highfp_drop(struct thread *td)
-{
-	struct pcb *pcb;
-	struct pcpu *cpu;
-	struct thread *thr;
-
-	mtx_lock_spin(&td->td_md.md_highfp_mtx);
-	pcb = td->td_pcb;
-	cpu = pcb->pcb_fpcpu;
-	if (cpu == NULL) {
-		mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-		return (0);
-	}
-	pcb->pcb_fpcpu = NULL;
-	thr = cpu->pc_fpcurthread;
-	cpu->pc_fpcurthread = NULL;
-	mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-
-	/* Post-mortem sanity checking. */
-	KASSERT(thr == td, ("Inconsistent high FP state"));
-	return (1);
-}
-
-int
-ia64_highfp_save(struct thread *td)
-{
-	struct pcb *pcb;
-	struct pcpu *cpu;
-	struct thread *thr;
-
-	/* Don't save if the high FP registers weren't modified. */
-	if ((td->td_frame->tf_special.psr & IA64_PSR_MFH) == 0)
-		return (ia64_highfp_drop(td));
-
-	mtx_lock_spin(&td->td_md.md_highfp_mtx);
-	pcb = td->td_pcb;
-	cpu = pcb->pcb_fpcpu;
-	if (cpu == NULL) {
-		mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-		return (0);
-	}
-#ifdef SMP
-	if (td == curthread)
-		sched_pin();
-	if (cpu != pcpup) {
-		mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-		ipi_send(cpu, IPI_HIGH_FP);
-		if (td == curthread)
-			sched_unpin();
-		while (pcb->pcb_fpcpu == cpu)
-			DELAY(100);
-		return (1);
-	} else {
-		save_high_fp(&pcb->pcb_high_fp);
-		if (td == curthread)
-			sched_unpin();
-	}
-#else
-	save_high_fp(&pcb->pcb_high_fp);
-#endif
-	pcb->pcb_fpcpu = NULL;
-	thr = cpu->pc_fpcurthread;
-	cpu->pc_fpcurthread = NULL;
-	mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-
-	/* Post-mortem sanity cxhecking. */
-	KASSERT(thr == td, ("Inconsistent high FP state"));
-	return (1);
-}
-
 void
 ia64_sync_icache(vm_offset_t va, vm_offset_t sz)
 {
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index aa31e6c5b19..2633ad208e4 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -652,66 +652,10 @@ trap(int vector, struct trapframe *tf)
 		break;
 
 	case IA64_VEC_DISABLED_FP: {
-		struct pcpu *pcpu;
-		struct pcb *pcb;
-		struct thread *thr;
-
-		/* Always fatal in kernel. Should never happen. */
-		if (!user)
+		if (user)
+			ia64_highfp_enable(td, tf);
+		else
 			trap_panic(vector, tf);
-
-		sched_pin();
-		thr = PCPU_GET(fpcurthread);
-		if (thr == td) {
-			/*
-			 * Short-circuit handling the trap when this CPU
-			 * already holds the high FP registers for this
-			 * thread.  We really shouldn't get the trap in the
-			 * first place, but since it's only a performance
-			 * issue and not a correctness issue, we emit a
-			 * message for now, enable the high FP registers and
-			 * return.
-			 */
-			printf("XXX: bogusly disabled high FP regs\n");
-			tf->tf_special.psr &= ~IA64_PSR_DFH;
-			sched_unpin();
-			goto out;
-		} else if (thr != NULL) {
-			mtx_lock_spin(&thr->td_md.md_highfp_mtx);
-			pcb = thr->td_pcb;
-			save_high_fp(&pcb->pcb_high_fp);
-			pcb->pcb_fpcpu = NULL;
-			PCPU_SET(fpcurthread, NULL);
-			mtx_unlock_spin(&thr->td_md.md_highfp_mtx);
-			thr = NULL;
-		}
-
-		mtx_lock_spin(&td->td_md.md_highfp_mtx);
-		pcb = td->td_pcb;
-		pcpu = pcb->pcb_fpcpu;
-
-#ifdef SMP
-		if (pcpu != NULL) {
-			mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-			ipi_send(pcpu, IPI_HIGH_FP);
-			while (pcb->pcb_fpcpu == pcpu)
-				DELAY(100);
-			mtx_lock_spin(&td->td_md.md_highfp_mtx);
-			pcpu = pcb->pcb_fpcpu;
-			thr = PCPU_GET(fpcurthread);
-		}
-#endif
-
-		if (thr == NULL && pcpu == NULL) {
-			restore_high_fp(&pcb->pcb_high_fp);
-			PCPU_SET(fpcurthread, td);
-			pcb->pcb_fpcpu = pcpup;
-			tf->tf_special.psr &= ~IA64_PSR_MFH;
-			tf->tf_special.psr &= ~IA64_PSR_DFH;
-		}
-
-		mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-		sched_unpin();
 		goto out;
 	}
 
diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c
index 4259875324b..e5088a5a9c2 100644
--- a/sys/ia64/ia64/vm_machdep.c
+++ b/sys/ia64/ia64/vm_machdep.c
@@ -120,14 +120,11 @@ cpu_thread_alloc(struct thread *td)
 	sp -= sizeof(struct trapframe);
 	td->td_frame = (struct trapframe *)sp;
 	td->td_frame->tf_length = sizeof(struct trapframe);
-	mtx_init(&td->td_md.md_highfp_mtx, "High FP lock", NULL, MTX_SPIN);
 }
 
 void
 cpu_thread_free(struct thread *td)
 {
-
-	mtx_destroy(&td->td_md.md_highfp_mtx);
 }
 
 void
@@ -148,6 +145,8 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
 	struct pcb *pcb;
 	struct trapframe *tf;
 
+	ia64_highfp_save(td0);
+
 	tf = td->td_frame;
 	KASSERT(tf != NULL, ("foo"));
 	bcopy(td0->td_frame, tf, sizeof(*tf));
diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h
index adc4725fcb4..6ee4cb4ee5c 100644
--- a/sys/ia64/include/md_var.h
+++ b/sys/ia64/include/md_var.h
@@ -86,7 +86,9 @@ int	ia64_emulate(struct trapframe *, struct thread *);
 int	ia64_flush_dirty(struct thread *, struct _special *);
 uint64_t ia64_get_hcdp(void);
 int	ia64_highfp_drop(struct thread *);
+int	ia64_highfp_enable(struct thread *, struct trapframe *);
 int	ia64_highfp_save(struct thread *);
+int	ia64_highfp_save_ipi(void);
 struct ia64_init_return ia64_init(void);
 void	ia64_probe_sapics(void);
 void	ia64_sync_icache(vm_offset_t, vm_size_t);
diff --git a/sys/ia64/include/proc.h b/sys/ia64/include/proc.h
index 5cbc0bf89f5..6bf9c78c88b 100644
--- a/sys/ia64/include/proc.h
+++ b/sys/ia64/include/proc.h
@@ -30,7 +30,6 @@
 #define	_MACHINE_PROC_H_
 
 struct mdthread {
-	struct mtx md_highfp_mtx;
 	int	md_spinlock_count;	/* (k) */
 	int	md_saved_intr;		/* (k) */
 };

From 98c98d78d4d36f947795205533a72da04a071dae Mon Sep 17 00:00:00 2001
From: Roman Divacky 
Date: Sun, 1 Nov 2009 08:20:30 +0000
Subject: [PATCH 444/646] Replace -iprefix with -isystem. We only need
 alternative header files search path and thus -isystem is sufficient.
 -iprefix is meant to do something entirely different.

Approved by:	ed (mentor)
OKed by:	ru, kan
Tested by:	make universe
---
 Makefile.inc1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 591d79f7a09..6a59f02f51a 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -272,7 +272,7 @@ LIB32CPUFLAGS=	-march=i686 -mmmx -msse -msse2
 LIB32CPUFLAGS=	-march=${TARGET_CPUTYPE}
 .endif
 LIB32FLAGS=	-m32 ${LIB32CPUFLAGS} -mfancy-math-387 -DCOMPAT_32BIT \
-		-iprefix ${LIB32TMP}/usr/ \
+		-isystem ${LIB32TMP}/usr/include/ \
 		-L${LIB32TMP}/usr/lib32 \
 		-B${LIB32TMP}/usr/lib32
 

From f98d7a47e2d41e52623e3237bcd1e061ff8b6441 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sun, 1 Nov 2009 11:31:06 +0000
Subject: [PATCH 445/646] MFp4: Fix reference counting bug, when device
 unreferenced before then invalidated. To do it, do not handle validity flag
 as another reference, but explicitly modify reference count each time flag is
 modified.

Discovered by:	thompsa
---
 sys/cam/ata/ata_xpt.c      |  7 +++++-
 sys/cam/cam_xpt.c          | 45 ++++++++++++++++++++------------------
 sys/cam/cam_xpt_internal.h |  6 ++---
 sys/cam/scsi/scsi_xpt.c    | 22 ++++++++++++++-----
 4 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 9e781cd72d6..065f3ee70a9 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -733,6 +733,7 @@ noerror:
 	case PROBE_SET_MULTI:
 		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
 			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			xpt_acquire_device(path->device);
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action(done_ccb);
 			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
@@ -777,6 +778,7 @@ noerror:
 		ata_device_transport(path);
 		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
 			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			xpt_acquire_device(path->device);
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action(done_ccb);
 			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
@@ -810,6 +812,7 @@ noerror:
 		path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
 		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
 			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			xpt_acquire_device(path->device);
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action(done_ccb);
 			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
@@ -1485,8 +1488,10 @@ ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
 				     CAM_EXPECT_INQ_CHANGE, NULL);
 		}
 		xpt_release_path(&newpath);
-	} else if (async_code == AC_LOST_DEVICE) {
+	} else if (async_code == AC_LOST_DEVICE &&
+	    (device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 		device->flags |= CAM_DEV_UNCONFIGURED;
+		xpt_release_device(device);
 	} else if (async_code == AC_TRANSFER_NEG) {
 		struct ccb_trans_settings *settings;
 
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 187683ed881..700363a1dda 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -217,9 +217,7 @@ static void	 xpt_release_devq_device(struct cam_ed *dev, u_int count,
 					 int run_queue);
 static struct cam_et*
 		 xpt_alloc_target(struct cam_eb *bus, target_id_t target_id);
-static void	 xpt_release_target(struct cam_eb *bus, struct cam_et *target);
-static void	 xpt_release_device(struct cam_eb *bus, struct cam_et *target,
-				    struct cam_ed *device);
+static void	 xpt_release_target(struct cam_et *target);
 static struct cam_eb*
 		 xpt_find_bus(path_id_t path_id);
 static struct cam_et*
@@ -3521,9 +3519,9 @@ xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
 		CAM_DEBUG(new_path, CAM_DEBUG_TRACE, ("xpt_compile_path\n"));
 	} else {
 		if (device != NULL)
-			xpt_release_device(bus, target, device);
+			xpt_release_device(device);
 		if (target != NULL)
-			xpt_release_target(bus, target);
+			xpt_release_target(target);
 		if (bus != NULL)
 			xpt_release_bus(bus);
 	}
@@ -3535,11 +3533,11 @@ xpt_release_path(struct cam_path *path)
 {
 	CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
 	if (path->device != NULL) {
-		xpt_release_device(path->bus, path->target, path->device);
+		xpt_release_device(path->device);
 		path->device = NULL;
 	}
 	if (path->target != NULL) {
-		xpt_release_target(path->bus, path->target);
+		xpt_release_target(path->target);
 		path->target = NULL;
 	}
 	if (path->bus != NULL) {
@@ -4375,15 +4373,15 @@ xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
 }
 
 static void
-xpt_release_target(struct cam_eb *bus, struct cam_et *target)
+xpt_release_target(struct cam_et *target)
 {
 
 	if ((--target->refcount == 0)
 	 && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
-		TAILQ_REMOVE(&bus->et_entries, target, links);
-		bus->generation++;
+		TAILQ_REMOVE(&target->bus->et_entries, target, links);
+		target->bus->generation++;
+		xpt_release_bus(target->bus);
 		free(target, M_CAMXPT);
-		xpt_release_bus(bus);
 	}
 }
 
@@ -4470,13 +4468,18 @@ xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 	return (device);
 }
 
-static void
-xpt_release_device(struct cam_eb *bus, struct cam_et *target,
-		   struct cam_ed *device)
+void
+xpt_acquire_device(struct cam_ed *device)
 {
 
-	if ((--device->refcount == 0)
-	 && ((device->flags & CAM_DEV_UNCONFIGURED) != 0)) {
+	device->refcount++;
+}
+
+void
+xpt_release_device(struct cam_ed *device)
+{
+
+	if (--device->refcount == 0) {
 		struct cam_devq *devq;
 
 		if (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX
@@ -4486,16 +4489,16 @@ xpt_release_device(struct cam_eb *bus, struct cam_et *target,
 		if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0)
 				callout_stop(&device->callout);
 
-		TAILQ_REMOVE(&target->ed_entries, device,links);
-		target->generation++;
-		bus->sim->max_ccbs -= device->ccbq.devq_openings;
+		TAILQ_REMOVE(&device->target->ed_entries, device,links);
+		device->target->generation++;
+		device->target->bus->sim->max_ccbs -= device->ccbq.devq_openings;
 		/* Release our slot in the devq */
-		devq = bus->sim->devq;
+		devq = device->target->bus->sim->devq;
 		cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 		camq_fini(&device->drvq);
 		cam_ccbq_fini(&device->ccbq);
+		xpt_release_target(device->target);
 		free(device, M_CAMXPT);
-		xpt_release_target(bus, target);
 	}
 }
 
diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
index 9e5e3f1e951..643ddf16f5b 100644
--- a/sys/cam/cam_xpt_internal.h
+++ b/sys/cam/cam_xpt_internal.h
@@ -37,9 +37,7 @@ struct cam_ed;
 typedef struct cam_ed * (*xpt_alloc_device_func)(struct cam_eb *bus,
 					         struct cam_et *target,
 					         lun_id_t lun_id);
-typedef void (*xpt_release_device_func)(struct cam_eb *bus,
-				        struct cam_et *target,
-				        struct cam_ed *device);
+typedef void (*xpt_release_device_func)(struct cam_ed *device);
 typedef void (*xpt_action_func)(union ccb *start_ccb);
 typedef void (*xpt_dev_async_func)(u_int32_t async_code,
 				   struct cam_eb *bus,
@@ -172,6 +170,8 @@ struct xpt_xport *	ata_get_xport(void);
 struct cam_ed *		xpt_alloc_device(struct cam_eb *bus,
 					 struct cam_et *target,
 					 lun_id_t lun_id);
+void			xpt_acquire_device(struct cam_ed *device);
+void			xpt_release_device(struct cam_ed *device);
 void			xpt_run_dev_sendq(struct cam_eb *bus);
 int			xpt_schedule_dev(struct camq *queue, cam_pinfo *dev_pinfo,
 					 u_int32_t new_priority);
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index a240db845ce..d780f9a9019 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -1076,8 +1076,10 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 				else
 					PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
 
-				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-
+				if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+					path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+					xpt_acquire_device(path->device);
+				}
 				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
 				return;
@@ -1336,8 +1338,12 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 			CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 			    ("Leave Domain Validation\n"));
 		}
+		if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			xpt_acquire_device(path->device);
+		}
 		path->device->flags &=
-		    ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
+		    ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 		if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 			/* Inform the XPT that a new device has been found */
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
@@ -1387,8 +1393,12 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
 			CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 			    ("Leave Domain Validation Successfully\n"));
 		}
+		if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			xpt_acquire_device(path->device);
+		}
 		path->device->flags &=
-		    ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
+		    ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 		if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 			/* Inform the XPT that a new device has been found */
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
@@ -2375,8 +2385,10 @@ scsi_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
 				     CAM_EXPECT_INQ_CHANGE, NULL);
 		}
 		xpt_release_path(&newpath);
-	} else if (async_code == AC_LOST_DEVICE) {
+	} else if (async_code == AC_LOST_DEVICE &&
+	    (device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 		device->flags |= CAM_DEV_UNCONFIGURED;
+		xpt_release_device(device);
 	} else if (async_code == AC_TRANSFER_NEG) {
 		struct ccb_trans_settings *settings;
 

From 94b7ebd774d11563c9b314fcde5f09f06cb29335 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 1 Nov 2009 11:39:07 +0000
Subject: [PATCH 446/646] Expand DESCRIPTION and a basic EXAMPLES section.

PR:		139605
Submitted by:	Warren Block 
MFC after:	1 week
---
 usr.sbin/usbconfig/usbconfig.8 | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
index 07dbed2586e..0914d9ebb17 100644
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd Sep 28, 2008
+.Dd November 1, 2009
 .Dt USBCONFIG 8
 .Os
 .Sh NAME
@@ -49,5 +49,13 @@ Should only be used in conjunction with the unit argument.
 .It Fl h
 Show help and available commands.
 .El
+.Pp
+When called without options,
+.Nm
+prints a list of all available USB devices.
+.Sh EXAMPLES
+Show information about the device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_info
 .Sh SEE ALSO
 .Xr usb 4

From 6fd3e622e25382a7df981afc3c1d2e3007a64078 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sun, 1 Nov 2009 13:06:15 +0000
Subject: [PATCH 447/646] MFp4: Allow SATA1 SiI chips to do full-sized DMA.
 Specification tells that we may release DMA constrants even more, but it
 require some additional handling.

---
 sys/dev/ata/chipsets/ata-siliconimage.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c
index 1ed48e48786..34bd92f57c5 100644
--- a/sys/dev/ata/chipsets/ata-siliconimage.c
+++ b/sys/dev/ata/chipsets/ata-siliconimage.c
@@ -340,6 +340,7 @@ ata_sii_ch_attach(device_t dev)
 	ATA_OUTL(ctlr->r_res2, 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
     }
 
+    ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
     if (ctlr->chip->cfg2 & SII_BUG) {
 	/* work around errata in early chips */
 	ch->dma.boundary = 8192;

From 91b010c9d946b0d6eb1946604c4f70b83bf3ee99 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 1 Nov 2009 18:25:11 +0000
Subject: [PATCH 448/646] Refine r198714, it's not as easy as just leaving the
 major number zero.

Submitted by:	ed
MFC after:	1 week
---
 sbin/mknod/mknod.8 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sbin/mknod/mknod.8 b/sbin/mknod/mknod.8
index f9dc3cbc484..9de2804df6c 100644
--- a/sbin/mknod/mknod.8
+++ b/sbin/mknod/mknod.8
@@ -74,7 +74,6 @@ and pseudo devices, and are type
 .It Ar major
 The major device number is an integer number which tells the kernel
 which device driver entry point to use.
-This is a compatibility shim and should be left zero.
 .It Ar minor
 The minor device number tells the kernel which subunit
 the node corresponds to on the device; for example,

From acf4080f439b41fd91c40f8a1686864fb6940314 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 1 Nov 2009 21:41:44 +0000
Subject: [PATCH 449/646] Check unit number and provide string name for
 consdev.

Submitted by:	HPS
---
 sys/dev/usb/serial/usb_serial.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index ca54712890b..871ae54190b 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -1300,7 +1300,12 @@ CONSOLE_DRIVER(ucom);
 static void
 ucom_cnprobe(struct consdev  *cp)
 {
-	cp->cn_pri = CN_NORMAL;
+	if (ucom_cons_unit != -1)
+		cp->cn_pri = CN_NORMAL;
+	else
+		cp->cn_pri = CN_DEAD;
+
+	strlcpy(cp->cn_name, "ucom", sizeof(cp->cn_name));
 }
 
 static void

From bb9c7a8b22acbcb1792b7bdec6fd7ee47fdbff80 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 1 Nov 2009 21:44:37 +0000
Subject: [PATCH 450/646] Fix a corner case where usbd_transfer_drain() can
 return too early if the callback has dropped the mutex, leading to a panic.

Submitted by:	HPS
MFC after:	3 days
---
 sys/dev/usb/usb_core.h     |  1 +
 sys/dev/usb/usb_transfer.c | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h
index 84c163b381c..a9d273d427f 100644
--- a/sys/dev/usb/usb_core.h
+++ b/sys/dev/usb/usb_core.h
@@ -112,6 +112,7 @@ struct usb_xfer_flags_int {
 	uint8_t	curr_dma_set:1;		/* used by USB HC/DC driver */
 	uint8_t	can_cancel_immed:1;	/* set if USB transfer can be
 					 * cancelled immediately */
+	uint8_t	doing_callback:1;	/* set if executing the callback */
 };
 
 /*
diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
index 8031b84597b..bfb6430085f 100644
--- a/sys/dev/usb/usb_transfer.c
+++ b/sys/dev/usb/usb_transfer.c
@@ -1797,8 +1797,18 @@ usbd_transfer_drain(struct usb_xfer *xfer)
 
 	usbd_transfer_stop(xfer);
 
-	while (usbd_transfer_pending(xfer)) {
+	while (usbd_transfer_pending(xfer) || 
+	    xfer->flags_int.doing_callback) {
+
+		/* 
+		 * It is allowed that the callback can drop its
+		 * transfer mutex. In that case checking only
+		 * "usbd_transfer_pending()" is not enough to tell if
+		 * the USB transfer is fully drained. We also need to
+		 * check the internal "doing_callback" flag.
+		 */
 		xfer->flags_int.draining = 1;
+
 		/*
 		 * Wait until the current outstanding USB
 		 * transfer is complete !
@@ -2043,6 +2053,9 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
 	/* get next USB transfer in the queue */
 	info->done_q.curr = NULL;
 
+	/* set flag in case of drain */
+	xfer->flags_int.doing_callback = 1;
+
 	USB_BUS_UNLOCK(info->bus);
 	USB_BUS_LOCK_ASSERT(info->bus, MA_NOTOWNED);
 
@@ -2095,12 +2108,17 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
 	if ((!xfer->flags_int.open) &&
 	    (xfer->flags_int.started) &&
 	    (xfer->usb_state == USB_ST_ERROR)) {
+		/* clear flag in case of drain */
+		xfer->flags_int.doing_callback = 0;
 		/* try to loop, but not recursivly */
 		usb_command_wrapper(&info->done_q, xfer);
 		return;
 	}
 
 done:
+	/* clear flag in case of drain */
+	xfer->flags_int.doing_callback = 0;
+
 	/*
 	 * Check if we are draining.
 	 */

From 0f92028501be24c4dada1bbf9ba7b54f4a5a78c3 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 1 Nov 2009 21:48:18 +0000
Subject: [PATCH 451/646] - Add usb_fill_bulk_urb() and usb_bulk_msg() linux
 compat functions [1] - Don't write actual length if the actual length pointer
 is NULL [2] - correct Linux Compatibility error codes for short isochronous
 IN transfers   and make status field signed.

Submitted by:	Leunam Elebek [1], Manuel Gebele [2]
---
 sys/dev/usb/usb_compat_linux.c | 80 +++++++++++++++++++++++++++++++---
 sys/dev/usb/usb_compat_linux.h |  7 ++-
 2 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c
index 604ac4d8845..b95a4f6f349 100644
--- a/sys/dev/usb/usb_compat_linux.c
+++ b/sys/dev/usb/usb_compat_linux.c
@@ -624,10 +624,11 @@ usb_start_wait_urb(struct urb *urb, usb_timeout_t timeout, uint16_t *p_actlen)
 done:
 	if (do_unlock)
 		mtx_unlock(&Giant);
-	if (err) {
-		*p_actlen = 0;
-	} else {
-		*p_actlen = urb->actual_length;
+	if (p_actlen != NULL) {
+		if (err)
+			*p_actlen = 0;
+		else
+			*p_actlen = urb->actual_length;
 	}
 	return (err);
 }
@@ -1362,8 +1363,17 @@ usb_linux_isoc_callback(struct usb_xfer *xfer, usb_error_t error)
 
 			for (x = 0; x < urb->number_of_packets; x++) {
 				uipd = urb->iso_frame_desc + x;
+				if (uipd->length > xfer->frlengths[x]) {
+					if (urb->transfer_flags & URB_SHORT_NOT_OK) {
+						/* XXX should be EREMOTEIO */
+						uipd->status = -EPIPE;
+					} else {
+						uipd->status = 0;
+					}
+				} else {
+					uipd->status = 0;
+				}
 				uipd->actual_length = xfer->frlengths[x];
-				uipd->status = 0;
 				if (!xfer->flags.ext_buffer) {
 					usbd_copy_out(xfer->frbuffers, offset,
 					    USB_ADD_BYTES(urb->transfer_buffer,
@@ -1385,8 +1395,8 @@ usb_linux_isoc_callback(struct usb_xfer *xfer, usb_error_t error)
 		if (xfer->actlen < xfer->sumlen) {
 			/* short transfer */
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
-				urb->status = -EPIPE;	/* XXX should be
-							 * EREMOTEIO */
+				/* XXX should be EREMOTEIO */
+				urb->status = -EPIPE;
 			} else {
 				urb->status = 0;
 			}
@@ -1482,6 +1492,7 @@ tr_setup:
 		/* Set zero for "actual_length" */
 		for (x = 0; x < urb->number_of_packets; x++) {
 			urb->iso_frame_desc[x].actual_length = 0;
+			urb->iso_frame_desc[x].status = urb->status;
 		}
 
 		/* call callback */
@@ -1663,3 +1674,58 @@ setup_bulk:
 		goto tr_setup;
 	}
 }
+
+/*------------------------------------------------------------------------*
+ *	usb_fill_bulk_urb
+ *------------------------------------------------------------------------*/
+void
+usb_fill_bulk_urb(struct urb *urb, struct usb_device *udev,
+    struct usb_host_endpoint *uhe, void *buf,
+    int length, usb_complete_t callback, void *arg)
+{
+	urb->dev = udev;
+	urb->endpoint = uhe;
+	urb->transfer_buffer = buf;
+	urb->transfer_buffer_length = length;
+	urb->complete = callback;
+	urb->context = arg;
+}
+
+/*------------------------------------------------------------------------*
+ *	usb_bulk_msg
+ *
+ * NOTE: This function can also be used for interrupt endpoints!
+ *
+ * Return values:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+int
+usb_bulk_msg(struct usb_device *udev, struct usb_host_endpoint *uhe,
+    void *data, int len, uint16_t *pactlen, usb_timeout_t timeout)
+{
+	struct urb *urb;
+	int err;
+
+	if (uhe == NULL)
+		return (-EINVAL);
+	if (len < 0)
+		return (-EINVAL);
+
+	err = usb_setup_endpoint(udev, uhe, 4096 /* bytes */);
+	if (err)
+		return (err);
+
+	urb = usb_alloc_urb(0, 0);
+	if (urb == NULL)
+		return (-ENOMEM);
+
+        usb_fill_bulk_urb(urb, udev, uhe, data, len,
+	    usb_linux_wait_complete, NULL);
+
+	err = usb_start_wait_urb(urb, timeout, pactlen);
+
+	usb_free_urb(urb);
+
+	return (err);
+}
diff --git a/sys/dev/usb/usb_compat_linux.h b/sys/dev/usb/usb_compat_linux.h
index 25a5bfb5d1e..1f00d4b4add 100644
--- a/sys/dev/usb/usb_compat_linux.h
+++ b/sys/dev/usb/usb_compat_linux.h
@@ -217,7 +217,7 @@ struct usb_iso_packet_descriptor {
 					 * packets are usually back to back) */
 	uint16_t length;		/* expected length */
 	uint16_t actual_length;
-	uint16_t status;
+	 int16_t status;		/* transfer status */
 };
 
 /*
@@ -299,6 +299,11 @@ void	usb_set_intfdata(struct usb_interface *intf, void *data);
 void	usb_linux_register(void *arg);
 void	usb_linux_deregister(void *arg);
 
+void	usb_fill_bulk_urb(struct urb *, struct usb_device *,
+	    struct usb_host_endpoint *, void *, int, usb_complete_t, void *);
+int	usb_bulk_msg(struct usb_device *, struct usb_host_endpoint *,
+	    void *, int, uint16_t *, usb_timeout_t);
+
 #define	interface_to_usbdev(intf) (intf)->linux_udev
 #define	interface_to_bsddev(intf) (intf)->linux_udev
 

From 4054af4fb0fcdc6115601d6b27cc5dd3a7875da6 Mon Sep 17 00:00:00 2001
From: Colin Percival 
Date: Mon, 2 Nov 2009 07:21:13 +0000
Subject: [PATCH 452/646] Attempt to reduce accidental foot-shooting by
 pointing out that accept(2)ed sockets do not necessarily inherit O_NONBLOCK
 from listening sockets on non-FreeBSD platforms.

Feet shot:	cperciva
MFC after:	1 month
---
 lib/libc/sys/accept.2 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
index 4387dc65a8f..df6c0b15d8c 100644
--- a/lib/libc/sys/accept.2
+++ b/lib/libc/sys/accept.2
@@ -126,6 +126,10 @@ new socket.
 For some applications, performance may be enhanced by using an
 .Xr accept_filter 9
 to pre-process incoming connections.
+.Pp
+Portable programs should not rely on the
+.Dv O_NONBLOCK
+property being inherited.
 .Sh RETURN VALUES
 The call returns \-1 on error.
 If it succeeds, it returns a non-negative

From 9efda2c9089835ffeb37141aa826644fb0385562 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 2 Nov 2009 08:31:00 +0000
Subject: [PATCH 453/646] The async callback could free the device. If it is a
 broadcast async, it doesn't hold device reference, so take our own reference.

Submitted by:   thompsa
---
 sys/cam/cam_xpt.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 700363a1dda..8c568ecc452 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4022,13 +4022,19 @@ xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
 			 && path->device->lun_id != CAM_LUN_WILDCARD
 			 && device->lun_id != CAM_LUN_WILDCARD)
 				continue;
-
+			/*
+			 * The async callback could free the device.
+			 * If it is a broadcast async, it doesn't hold
+			 * device reference, so take our own reference.
+			 */
+			xpt_acquire_device(device);
 			(*(bus->xport->async))(async_code, bus,
 					       target, device,
 					       async_arg);
 
 			xpt_async_bcast(&device->asyncs, async_code,
 					path, async_arg);
+			xpt_release_device(device);
 		}
 	}
 

From eabd1bcb212010997ca90f8182b7c7ce76db0e10 Mon Sep 17 00:00:00 2001
From: Remko Lodder 
Date: Mon, 2 Nov 2009 09:56:46 +0000
Subject: [PATCH 454/646] Execute the start/stop process of a jail in the
 background. This will prevent that the script hangs during startup, which
 could cause annoying effects after rebooting for example.

PR:		kern/139422
Submitted by:	Andrey Groshev 
Approved by:	imp (mentor, implicit)
MFC after:	3 days
Facilitated by:	Snow B.V.
---
 etc/rc.d/jail | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/etc/rc.d/jail b/etc/rc.d/jail
index 830cd5f8170..084acb713b5 100755
--- a/etc/rc.d/jail
+++ b/etc/rc.d/jail
@@ -728,4 +728,4 @@ fi
 if [ -n "$*" ]; then
 	jail_list="$*"
 fi
-run_rc_command "${cmd}"
+run_rc_command "${cmd}" &

From 99081d1c6179f5b7f7c4abdf104e5b3892e5e416 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Mon, 2 Nov 2009 11:07:42 +0000
Subject: [PATCH 455/646] Big style cleanup. While there remove references to
 FreeBSD versions older than 6.0.

Submitted by:	Paul B Mahol 
---
 sys/compat/ndis/kern_ndis.c     | 176 +++++-----------
 sys/compat/ndis/kern_windrv.c   |  81 ++++----
 sys/compat/ndis/subr_hal.c      |  41 ++--
 sys/compat/ndis/subr_ndis.c     | 298 ++++++++------------------
 sys/compat/ndis/subr_ntoskrnl.c | 357 +++++++++++---------------------
 sys/compat/ndis/subr_pe.c       |  74 +++----
 sys/compat/ndis/subr_usbd.c     |  15 +-
 sys/dev/if_ndis/if_ndis.c       | 186 ++++++-----------
 sys/dev/if_ndis/if_ndis_usb.c   |   4 +-
 9 files changed, 426 insertions(+), 806 deletions(-)

diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index 18938894849..f4d4b3aa05a 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -184,7 +184,7 @@ ndis_modevent(module_t mod, int cmd, void *arg)
 		break;
 	}
 
-	return(error);
+	return (error);
 }
 DEV_MODULE(ndisapi, ndis_modevent, NULL);
 MODULE_VERSION(ndisapi, 1);
@@ -193,7 +193,6 @@ static void
 ndis_sendrsrcavail_func(adapter)
 	ndis_handle		adapter;
 {
-	return;
 }
 
 static void
@@ -211,8 +210,7 @@ ndis_status_func(adapter, status, sbuf, slen)
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
 	ifp = sc->ifp;
 	if (ifp->if_flags & IFF_DEBUG)
-		device_printf (sc->ndis_dev, "status: %x\n", status);
-	return;
+		device_printf(sc->ndis_dev, "status: %x\n", status);
 }
 
 static void
@@ -227,8 +225,7 @@ ndis_statusdone_func(adapter)
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
 	ifp = sc->ifp;
 	if (ifp->if_flags & IFF_DEBUG)
-		device_printf (sc->ndis_dev, "status complete\n");
-	return;
+		device_printf(sc->ndis_dev, "status complete\n");
 }
 
 static void
@@ -241,7 +238,6 @@ ndis_setdone_func(adapter, status)
 
 	block->nmb_setstat = status;
 	KeSetEvent(&block->nmb_setevent, IO_NO_INCREMENT, FALSE);
-	return;
 }
 
 static void
@@ -254,7 +250,6 @@ ndis_getdone_func(adapter, status)
 
 	block->nmb_getstat = status;
 	KeSetEvent(&block->nmb_getevent, IO_NO_INCREMENT, FALSE);
-	return;
 }
 
 static void
@@ -270,10 +265,8 @@ ndis_resetdone_func(ndis_handle adapter, ndis_status status,
 	ifp = sc->ifp;
 
 	if (ifp->if_flags & IFF_DEBUG)
-		device_printf (sc->ndis_dev, "reset done...\n");
+		device_printf(sc->ndis_dev, "reset done...\n");
 	KeSetEvent(&block->nmb_resetevent, IO_NO_INCREMENT, FALSE);
-
-	return;
 }
 
 int
@@ -287,7 +280,7 @@ ndis_create_sysctls(arg)
 	struct sysctl_ctx_entry	*e;
 
 	if (arg == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	sc = arg;
 	vals = sc->ndis_regvals;
@@ -367,7 +360,7 @@ ndis_create_sysctls(arg)
 		    "Interrupt Number", buf, CTLFLAG_RD);
 	}
 
-	return(0);
+	return (0);
 }
 
 int
@@ -388,7 +381,7 @@ ndis_add_sysctl(arg, key, desc, val, flag)
 
 	if (cfg == NULL) {
 		printf("failed for %s\n", key);
-		return(ENOMEM);
+		return (ENOMEM);
 	}
 
 	cfg->ndis_cfg.nc_cfgkey = strdup(key, M_DEVBUF);
@@ -415,7 +408,7 @@ ndis_add_sysctl(arg, key, desc, val, flag)
 	    cfg->ndis_cfg.nc_cfgdesc);
 #endif
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -451,7 +444,7 @@ ndis_flush_sysctls(arg)
 		free(cfg, M_DEVBUF);
 	}
 
-	return(0);
+	return (0);
 }
 
 static void
@@ -488,8 +481,6 @@ ndis_return(dobj, arg)
 		KeAcquireSpinLock(&block->nmb_returnlock, &irql);
 	}
 	KeReleaseSpinLock(&block->nmb_returnlock, irql);
-
-	return;
 }
 
 void
@@ -522,8 +513,6 @@ ndis_return_packet(buf, arg)
 	IoQueueWorkItem(block->nmb_returnitem,
 	    (io_workitem_func)kernndis_functbl[7].ipt_wrap,
 	    WORKQUEUE_CRITICAL, block);
-
-	return;
 }
 
 void
@@ -540,8 +529,6 @@ ndis_free_bufs(b0)
 		IoFreeMdl(b0);
 		b0 = next;
 	}
-
-	return;
 }
 
 void
@@ -553,7 +540,6 @@ ndis_free_packet(p)
 
 	ndis_free_bufs(p->np_private.npp_head);
 	NdisFreePacket(p);
-	return;
 }
 
 int
@@ -567,26 +553,18 @@ ndis_convert_res(arg)
 	device_t		dev;
 	struct resource_list	*brl;
 	struct resource_list_entry	*brle;
-#if __FreeBSD_version < 600022
-	struct resource_list	brl_rev;
-	struct resource_list_entry	*n;
-#endif
 	int			error = 0;
 
 	sc = arg;
 	block = sc->ndis_block;
 	dev = sc->ndis_dev;
 
-#if __FreeBSD_version < 600022
-	SLIST_INIT(&brl_rev);
-#endif
-
 	rl = malloc(sizeof(ndis_resource_list) +
 	    (sizeof(cm_partial_resource_desc) * (sc->ndis_rescnt - 1)),
 	    M_DEVBUF, M_NOWAIT|M_ZERO);
 
 	if (rl == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	rl->cprl_version = 5;
 	rl->cprl_version = 1;
@@ -597,37 +575,7 @@ ndis_convert_res(arg)
 
 	if (brl != NULL) {
 
-#if __FreeBSD_version < 600022
-		/*
-		 * We have a small problem. Some PCI devices have
-		 * multiple I/O ranges. Windows orders them starting
-		 * from lowest numbered BAR to highest. We discover
-		 * them in that order too, but insert them into a singly
-		 * linked list head first, which means when time comes
-		 * to traverse the list, we enumerate them in reverse
-		 * order. This screws up some drivers which expect the
-		 * BARs to be in ascending order so that they can choose
-		 * the "first" one as their register space. Unfortunately,
-		 * in order to fix this, we have to create our own
-		 * temporary list with the entries in reverse order.
-		 */
-
-		SLIST_FOREACH(brle, brl, link) {
-			n = malloc(sizeof(struct resource_list_entry),
-			    M_TEMP, M_NOWAIT);
-			if (n == NULL) {
-				error = ENOMEM;
-				goto bad;
-			}
-			bcopy((char *)brle, (char *)n,
-			    sizeof(struct resource_list_entry));
-			SLIST_INSERT_HEAD(&brl_rev, n, link);
-		}
-
-		SLIST_FOREACH(brle, &brl_rev, link) {
-#else
 		STAILQ_FOREACH(brle, brl, link) {
-#endif
 			switch (brle->type) {
 			case SYS_RES_IOPORT:
 				prd->cprd_type = CmResourceTypePort;
@@ -671,17 +619,7 @@ ndis_convert_res(arg)
 
 	block->nmb_rlist = rl;
 
-#if __FreeBSD_version < 600022
-bad:
-
-	while (!SLIST_EMPTY(&brl_rev)) {
-		n = SLIST_FIRST(&brl_rev);
-		SLIST_REMOVE_HEAD(&brl_rev, link);
-		free (n, M_TEMP);
-	}
-#endif
-
-	return(error);
+	return (error);
 }
 
 /*
@@ -711,7 +649,7 @@ ndis_ptom(m0, p)
 	int			diff;
 
 	if (p == NULL || m0 == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	priv = &p->np_private;
 	buf = priv->npp_head;
@@ -729,7 +667,7 @@ ndis_ptom(m0, p)
 		if (m == NULL) {
 			m_freem(*m0);
 			*m0 = NULL;
-			return(ENOBUFS);
+			return (ENOBUFS);
 		}
 		m->m_len = MmGetMdlByteCount(buf);
 		m->m_data = MmGetMdlVirtualAddress(buf);
@@ -765,7 +703,7 @@ ndis_ptom(m0, p)
 	}
 	(*m0)->m_pkthdr.len = totlen;
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -793,7 +731,7 @@ ndis_mtop(m0, p)
 	ndis_packet_private	*priv;
 
 	if (p == NULL || *p == NULL || m0 == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	priv = &(*p)->np_private;
 	priv->npp_totlen = m0->m_pkthdr.len;
@@ -805,7 +743,7 @@ ndis_mtop(m0, p)
 		if (buf == NULL) {
 			ndis_free_packet(*p);
 			*p = NULL;
-			return(ENOMEM);
+			return (ENOMEM);
 		}
 		MmBuildMdlForNonPagedPool(buf);
 
@@ -818,7 +756,7 @@ ndis_mtop(m0, p)
 
 	priv->npp_tail = buf;
 
-	return(0);
+	return (0);
 }
 
 int
@@ -831,25 +769,25 @@ ndis_get_supported_oids(arg, oids, oidcnt)
 	ndis_oid		*o;
 
 	if (arg == NULL || oids == NULL || oidcnt == NULL)
-		return(EINVAL);
+		return (EINVAL);
 	len = 0;
 	ndis_get_info(arg, OID_GEN_SUPPORTED_LIST, NULL, &len);
 
 	o = malloc(len, M_DEVBUF, M_NOWAIT);
 	if (o == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	rval = ndis_get_info(arg, OID_GEN_SUPPORTED_LIST, o, &len);
 
 	if (rval) {
 		free(o, M_DEVBUF);
-		return(rval);
+		return (rval);
 	}
 
 	*oids = o;
 	*oidcnt = len / 4;
 
-	return(0);
+	return (0);
 }
 
 int
@@ -893,7 +831,7 @@ ndis_set_info(arg, oid, buf, buflen)
 	    sc->ndis_block->nmb_devicectx == NULL) {
 		sc->ndis_block->nmb_pendingreq = NULL;
 		KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
-		return(ENXIO);
+		return (ENXIO);
 	}
 
 	rval = MSCALL6(setfunc, adapter, oid, buf, *buflen,
@@ -917,19 +855,19 @@ ndis_set_info(arg, oid, buf, buflen)
 		*buflen = bytesneeded;
 
 	if (rval == NDIS_STATUS_INVALID_LENGTH)
-		return(ENOSPC);
+		return (ENOSPC);
 
 	if (rval == NDIS_STATUS_INVALID_OID)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (rval == NDIS_STATUS_NOT_SUPPORTED ||
 	    rval == NDIS_STATUS_NOT_ACCEPTED)
-		return(ENOTSUP);
+		return (ENOTSUP);
 
 	if (rval != NDIS_STATUS_SUCCESS)
-		return(ENODEV);
+		return (ENODEV);
 
-	return(0);
+	return (0);
 }
 
 typedef void (*ndis_senddone_func)(ndis_handle, ndis_packet *, ndis_status);
@@ -951,7 +889,7 @@ ndis_send_packets(arg, packets, cnt)
 	sc = arg;
 	adapter = sc->ndis_block->nmb_miniportadapterctx;
 	if (adapter == NULL)
-		return(ENXIO);
+		return (ENXIO);
 	sendfunc = sc->ndis_chars->nmc_sendmulti_func;
 	senddonefunc = sc->ndis_block->nmb_senddone_func;
 
@@ -976,7 +914,7 @@ ndis_send_packets(arg, packets, cnt)
 	if (NDIS_SERIALIZED(sc->ndis_block))
 		KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -994,7 +932,7 @@ ndis_send_packet(arg, packet)
 	sc = arg;
 	adapter = sc->ndis_block->nmb_miniportadapterctx;
 	if (adapter == NULL)
-		return(ENXIO);
+		return (ENXIO);
 	sendfunc = sc->ndis_chars->nmc_sendsingle_func;
 	senddonefunc = sc->ndis_block->nmb_senddone_func;
 
@@ -1006,7 +944,7 @@ ndis_send_packet(arg, packet)
 	if (status == NDIS_STATUS_PENDING) {
 		if (NDIS_SERIALIZED(sc->ndis_block))
 			KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
-		return(0);
+		return (0);
 	}
 
 	MSCALL3(senddonefunc, sc->ndis_block, packet, status);
@@ -1014,7 +952,7 @@ ndis_send_packet(arg, packet)
 	if (NDIS_SERIALIZED(sc->ndis_block))
 		KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1030,18 +968,18 @@ ndis_init_dma(arg)
 	    M_DEVBUF, M_NOWAIT|M_ZERO);
 
 	if (sc->ndis_tmaps == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	for (i = 0; i < sc->ndis_maxpkts; i++) {
 		error = bus_dmamap_create(sc->ndis_ttag, 0,
 		    &sc->ndis_tmaps[i]);
 		if (error) {
 			free(sc->ndis_tmaps, M_DEVBUF);
-			return(ENODEV);
+			return (ENODEV);
 		}
 	}
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1070,7 +1008,7 @@ ndis_destroy_dma(arg)
 
 	bus_dma_tag_destroy(sc->ndis_ttag);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1093,7 +1031,7 @@ ndis_reset_nic(arg)
 	if (adapter == NULL || resetfunc == NULL ||
 	    sc->ndis_block->nmb_devicectx == NULL) {
 		NDIS_UNLOCK(sc);
-		return(EIO);
+		return (EIO);
 	}
 
 	NDIS_UNLOCK(sc);
@@ -1112,7 +1050,7 @@ ndis_reset_nic(arg)
 		KeWaitForSingleObject(&sc->ndis_block->nmb_resetevent,
 		    0, 0, FALSE, NULL);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1149,7 +1087,7 @@ ndis_halt_nic(arg)
 	adapter = sc->ndis_block->nmb_miniportadapterctx;
 	if (adapter == NULL) {
 		NDIS_UNLOCK(sc);
-		return(EIO);
+		return (EIO);
 	}
 
 	sc->ndis_block->nmb_devicectx = NULL;
@@ -1169,7 +1107,7 @@ ndis_halt_nic(arg)
 	sc->ndis_block->nmb_miniportadapterctx = NULL;
 	NDIS_UNLOCK(sc);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1186,7 +1124,7 @@ ndis_shutdown_nic(arg)
 	shutdownfunc = sc->ndis_chars->nmc_shutdown_handler;
 	NDIS_UNLOCK(sc);
 	if (adapter == NULL || shutdownfunc == NULL)
-		return(EIO);
+		return (EIO);
 
 	if (sc->ndis_chars->nmc_rsvd0 == NULL)
 		MSCALL1(shutdownfunc, adapter);
@@ -1195,7 +1133,7 @@ ndis_shutdown_nic(arg)
 
 	TAILQ_REMOVE(&ndis_devhead, sc->ndis_block, link);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1215,7 +1153,7 @@ ndis_pnpevent_nic(arg, type)
 	pnpeventfunc = sc->ndis_chars->nmc_pnpevent_handler;
 	NDIS_UNLOCK(sc);
 	if (adapter == NULL || pnpeventfunc == NULL)
-		return(EIO);
+		return (EIO);
 
 	if (sc->ndis_chars->nmc_rsvd0 == NULL)
 		MSCALL4(pnpeventfunc, adapter, type, NULL, 0);
@@ -1237,7 +1175,7 @@ ndis_init_nic(arg)
 	uint32_t		chosenmedium, i;
 
 	if (arg == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	sc = arg;
 	NDIS_LOCK(sc);
@@ -1262,7 +1200,7 @@ ndis_init_nic(arg)
 		NDIS_LOCK(sc);
 		sc->ndis_block->nmb_miniportadapterctx = NULL;
 		NDIS_UNLOCK(sc);
-		return(ENXIO);
+		return (status);
 	}
 
 	/*
@@ -1281,7 +1219,7 @@ ndis_init_nic(arg)
 	sc->ndis_block->nmb_devicectx = sc;
 	NDIS_UNLOCK(sc);
 
-	return(0);
+	return (0);
 }
 
 static void
@@ -1305,8 +1243,6 @@ ndis_intrsetup(dpc, dobj, ip, sc)
 	if (KeInsertQueueDpc(&intr->ni_dpc, NULL, NULL) == TRUE)
 		intr->ni_dpccnt++;
 	KeReleaseSpinLockFromDpcLevel(&intr->ni_dpccountlock);
-
-	return;
 }
 
 int
@@ -1343,7 +1279,7 @@ ndis_get_info(arg, oid, buf, buflen)
 	    sc->ndis_block->nmb_devicectx == NULL) {
 		sc->ndis_block->nmb_pendingreq = NULL;
 		KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
-		return(ENXIO);
+		return (ENXIO);
 	}
 
 	rval = MSCALL6(queryfunc, adapter, oid, buf, *buflen,
@@ -1370,19 +1306,19 @@ ndis_get_info(arg, oid, buf, buflen)
 
 	if (rval == NDIS_STATUS_INVALID_LENGTH ||
 	    rval == NDIS_STATUS_BUFFER_TOO_SHORT)
-		return(ENOSPC);
+		return (ENOSPC);
 
 	if (rval == NDIS_STATUS_INVALID_OID)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (rval == NDIS_STATUS_NOT_SUPPORTED ||
 	    rval == NDIS_STATUS_NOT_ACCEPTED)
-		return(ENOTSUP);
+		return (ENOTSUP);
 
 	if (rval != NDIS_STATUS_SUCCESS)
-		return(ENODEV);
+		return (ENODEV);
 
-	return(0);
+	return (0);
 }
 
 uint32_t
@@ -1403,14 +1339,14 @@ NdisAddDevice(drv, pdo)
 		    INTR_TYPE_NET | INTR_MPSAFE,
 		    NULL, ntoskrnl_intr, NULL, &sc->ndis_intrhand);
 		if (error)
-			return(NDIS_STATUS_FAILURE);
+			return (NDIS_STATUS_FAILURE);
 	}
 
 	status = IoCreateDevice(drv, sizeof(ndis_miniport_block), NULL,
 	    FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
 
 	if (status != STATUS_SUCCESS)
-		return(status);
+		return (status);
 
 	block = fdo->do_devext;
 
@@ -1446,7 +1382,7 @@ NdisAddDevice(drv, pdo)
 		if (status != NDIS_STATUS_SUCCESS) {
 			IoDetachDevice(block->nmb_nextdeviceobj);
 			IoDeleteDevice(fdo);
-			return(status);
+			return (status);
 		}
 		InitializeListHead((&block->nmb_packetlist));
 	}
@@ -1498,5 +1434,5 @@ ndis_unload_driver(arg)
 	IoDetachDevice(sc->ndis_block->nmb_nextdeviceobj);
 	IoDeleteDevice(fdo);
 
-	return(0);
+	return (0);
 }
diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c
index 1d4f76c93f5..f231863e888 100644
--- a/sys/compat/ndis/kern_windrv.c
+++ b/sys/compat/ndis/kern_windrv.c
@@ -123,7 +123,7 @@ windrv_libinit(void)
 		panic("failed to allocate thread info blocks");
 	smp_rendezvous(NULL, x86_newldt, NULL, NULL);
 #endif
-	return(0);
+	return (0);
 }
 
 int
@@ -148,7 +148,7 @@ windrv_libfini(void)
 	smp_rendezvous(NULL, x86_oldldt, NULL, NULL);
 	ExFreePool(my_tids);
 #endif
-	return(0);
+	return (0);
 }
 
 /*
@@ -172,7 +172,7 @@ windrv_lookup(img, name)
 	if (name != NULL) {
 		RtlInitAnsiString(&as, name);
 		if (RtlAnsiStringToUnicodeString(&us, &as, TRUE))
-			return(NULL);
+			return (NULL);
 	}
 
 	mtx_lock(&drvdb_mtx); 
@@ -183,7 +183,7 @@ windrv_lookup(img, name)
 			mtx_unlock(&drvdb_mtx);
 			if (name != NULL)
 				ExFreePool(us.us_buf);
-			return(d->windrv_object);
+			return (d->windrv_object);
 		}
 	}
 	mtx_unlock(&drvdb_mtx);
@@ -191,7 +191,7 @@ windrv_lookup(img, name)
 	if (name != NULL)
 		RtlFreeUnicodeString(&us);
 
-	return(NULL);
+	return (NULL);
 }
 
 struct drvdb_ent *
@@ -209,12 +209,12 @@ windrv_match(matchfunc, ctx)
 		match = matchfunc(d->windrv_bustype, d->windrv_devlist, ctx);
 		if (match == TRUE) {
 			mtx_unlock(&drvdb_mtx);
-			return(d);
+			return (d);
 		}
 	}
 	mtx_unlock(&drvdb_mtx);
 
-	return(NULL);
+	return (NULL);
 }
 
 /*
@@ -283,7 +283,7 @@ windrv_unload(mod, img, len)
 		return (ENOENT);
 
 	if (drv == NULL)
-		return(ENOENT);
+		return (ENOENT);
 
 	/*
 	 * Destroy any custom extensions that may have been added.
@@ -306,7 +306,7 @@ windrv_unload(mod, img, len)
 	/* Free our DB handle */
 	free(r, M_DEVBUF);
 
-	return(0);
+	return (0);
 }
 
 #define WINDRV_LOADED		htonl(0x42534F44)
@@ -345,28 +345,28 @@ windrv_load(mod, img, len, bustype, devlist, regvals)
 
 	/* Perform text relocation */
 	if (pe_relocate(img))
-		return(ENOEXEC);
+		return (ENOEXEC);
 
 	/* Dynamically link the NDIS.SYS routines -- required. */
 	if (pe_patch_imports(img, "NDIS", ndis_functbl))
-		return(ENOEXEC);
+		return (ENOEXEC);
 
 	/* Dynamically link the HAL.dll routines -- optional. */
 	if (pe_get_import_descriptor(img, &imp_desc, "HAL") == 0) {
 		if (pe_patch_imports(img, "HAL", hal_functbl))
-			return(ENOEXEC);
+			return (ENOEXEC);
 	}
 
 	/* Dynamically link ntoskrnl.exe -- optional. */
 	if (pe_get_import_descriptor(img, &imp_desc, "ntoskrnl") == 0) {
 		if (pe_patch_imports(img, "ntoskrnl", ntoskrnl_functbl))
-			return(ENOEXEC);
+			return (ENOEXEC);
 	}
 
 	/* Dynamically link USBD.SYS -- optional */
 	if (pe_get_import_descriptor(img, &imp_desc, "USBD") == 0) {
 		if (pe_patch_imports(img, "USBD", usbd_functbl))
-			return(ENOEXEC);
+			return (ENOEXEC);
 	}
 
 	*ptr = WINDRV_LOADED;
@@ -398,7 +398,7 @@ skipreloc:
 	if (drv->dro_driverext == NULL) {
 		free(new, M_DEVBUF);
 		free(drv, M_DEVBUF);
-		return(ENOMEM);
+		return (ENOMEM);
 	}
 
 	InitializeListHead((&drv->dro_driverext->dre_usrext));
@@ -410,7 +410,7 @@ skipreloc:
 	if (RtlAnsiStringToUnicodeString(&drv->dro_drivername, &as, TRUE)) {
 		free(new, M_DEVBUF);
 		free(drv, M_DEVBUF);
-		return(ENOMEM);
+		return (ENOMEM);
 	}
 
 	new->windrv_object = drv;
@@ -426,7 +426,7 @@ skipreloc:
 		RtlFreeUnicodeString(&drv->dro_drivername);
 		free(drv, M_DEVBUF);
 		free(new, M_DEVBUF);
-		return(ENODEV);
+		return (ENODEV);
 	}
 
 	mtx_lock(&drvdb_mtx); 
@@ -463,7 +463,7 @@ windrv_create_pdo(drv, bsddev)
 
 	dev->do_devext = bsddev;
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 void
@@ -482,8 +482,6 @@ windrv_destroy_pdo(drv, bsddev)
 	mtx_lock(&drvdb_mtx);
 	IoDeleteDevice(pdo);
 	mtx_unlock(&drvdb_mtx);
-
-	return;
 }
 
 /*
@@ -503,13 +501,13 @@ windrv_find_pdo(drv, bsddev)
 	while (pdo != NULL) {
 		if (pdo->do_devext == bsddev) {
 			mtx_unlock(&drvdb_mtx);
-			return(pdo);
+			return (pdo);
 		}
 		pdo = pdo->do_nextdev;
 	}
 	mtx_unlock(&drvdb_mtx);
 
-	return(NULL);
+	return (NULL);
 }
 
 /*
@@ -533,7 +531,7 @@ windrv_bus_attach(drv, name)
 	if (RtlAnsiStringToUnicodeString(&drv->dro_drivername, &as, TRUE))
 	{
 		free(new, M_DEVBUF);
-		return(ENOMEM);
+		return (ENOMEM);
 	}
 
 	/*
@@ -550,7 +548,7 @@ windrv_bus_attach(drv, name)
 	STAILQ_INSERT_HEAD(&drvdb_head, new, link);
 	mtx_unlock(&drvdb_mtx);
 
-	return(0);
+	return (0);
 }
 
 #ifdef __amd64__
@@ -578,7 +576,7 @@ windrv_wrap(func, wrap, argcnt, ftype)
 
 	p = malloc((wrapend - wrapstart), M_DEVBUF, M_NOWAIT);
 	if (p == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	/* Copy over the code. */
 
@@ -591,7 +589,7 @@ windrv_wrap(func, wrap, argcnt, ftype)
 
 	*wrap = p;
 
-	return(0);
+	return (0);
 }
 #endif /* __amd64__ */
 
@@ -695,8 +693,6 @@ ctxsw_utow(void)
 	x86_critical_exit();
 
 	/* Now entering Windows land, population: you. */
-
-	return;
 }
 
 /*
@@ -722,7 +718,6 @@ ctxsw_wtou(void)
 	if (t->tid_cpu != curthread->td_oncpu)
 		panic("ctxsw GOT MOVED TO OTHER CPU!");
 #endif
-	return;
 }
 
 static int	windrv_wrap_stdcall(funcptr, funcptr *, int);
@@ -754,7 +749,7 @@ windrv_wrap_fastcall(func, wrap, argcnt)
 
 	p = malloc((wrapend - wrapstart), M_DEVBUF, M_NOWAIT);
 	if (p == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	/* Copy over the code. */
 
@@ -774,7 +769,7 @@ windrv_wrap_fastcall(func, wrap, argcnt)
 
 	*wrap = p;
 
-	return(0);
+	return (0);
 }
 
 extern void	x86_stdcall_wrap(void);
@@ -802,7 +797,7 @@ windrv_wrap_stdcall(func, wrap, argcnt)
 
 	p = malloc((wrapend - wrapstart), M_DEVBUF, M_NOWAIT);
 	if (p == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	/* Copy over the code. */
 
@@ -818,7 +813,7 @@ windrv_wrap_stdcall(func, wrap, argcnt)
 
 	*wrap = p;
 
-	return(0);
+	return (0);
 }
 
 extern void	x86_regparm_wrap(void);
@@ -842,7 +837,7 @@ windrv_wrap_regparm(func, wrap)
 
 	p = malloc((wrapend - wrapstart), M_DEVBUF, M_NOWAIT);
 	if (p == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	/* Copy over the code. */
 
@@ -855,7 +850,7 @@ windrv_wrap_regparm(func, wrap)
 
 	*wrap = p;
 
-	return(0);
+	return (0);
 }
 
 int
@@ -867,18 +862,18 @@ windrv_wrap(func, wrap, argcnt, ftype)
 {
 	switch(ftype) {
 	case WINDRV_WRAP_FASTCALL:
-		return(windrv_wrap_fastcall(func, wrap, argcnt));
+		return (windrv_wrap_fastcall(func, wrap, argcnt));
 	case WINDRV_WRAP_STDCALL:
-		return(windrv_wrap_stdcall(func, wrap, argcnt));
+		return (windrv_wrap_stdcall(func, wrap, argcnt));
 	case WINDRV_WRAP_REGPARM:
-		return(windrv_wrap_regparm(func, wrap));
+		return (windrv_wrap_regparm(func, wrap));
 	case WINDRV_WRAP_CDECL:
-		return(windrv_wrap_stdcall(func, wrap, 0));
+		return (windrv_wrap_stdcall(func, wrap, 0));
 	default:
 		break;
 	}
 
-	return(EINVAL);
+	return (EINVAL);
 }
 
 static void
@@ -909,8 +904,6 @@ x86_oldldt(dummy)
 	x86_setldt(>able, ltable);
 
 	mtx_unlock_spin(&dt_lock);
-
-	return;
 }
 
 static void
@@ -959,8 +952,6 @@ x86_newldt(dummy)
 	mtx_unlock_spin(&dt_lock);
 
 	/* Whew. */
-
-	return;
 }
 
 #endif /* __i386__ */
@@ -971,5 +962,5 @@ windrv_unwrap(func)
 {
 	free(func, M_DEVBUF);
 
-	return(0);
+	return (0);
 }
diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c
index 72b6db2915e..45f34408c46 100644
--- a/sys/compat/ndis/subr_hal.c
+++ b/sys/compat/ndis/subr_hal.c
@@ -102,8 +102,7 @@ hal_libinit()
 		patch++;
 	}
 
-
-	return(0);
+	return (0);
 }
 
 int
@@ -121,7 +120,7 @@ hal_libfini()
 		patch++;
 	}
 
-	return(0);
+	return (0);
 }
 
 static void
@@ -129,7 +128,6 @@ KeStallExecutionProcessor(usecs)
 	uint32_t		usecs;
 {
 	DELAY(usecs);
-	return;
 }
 
 static void
@@ -138,21 +136,18 @@ WRITE_PORT_ULONG(port, val)
 	uint32_t		val;
 {
 	bus_space_write_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
-	return;
 }
 
 static void
 WRITE_PORT_USHORT(uint16_t *port, uint16_t val)
 {
 	bus_space_write_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
-	return;
 }
 
 static void
 WRITE_PORT_UCHAR(uint8_t *port, uint8_t val)
 {
 	bus_space_write_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
-	return;
 }
 
 static void
@@ -163,7 +158,6 @@ WRITE_PORT_BUFFER_ULONG(port, val, cnt)
 {
 	bus_space_write_multi_4(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 static void
@@ -174,7 +168,6 @@ WRITE_PORT_BUFFER_USHORT(port, val, cnt)
 {
 	bus_space_write_multi_2(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 static void
@@ -185,28 +178,27 @@ WRITE_PORT_BUFFER_UCHAR(port, val, cnt)
 {
 	bus_space_write_multi_1(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 static uint16_t
 READ_PORT_USHORT(port)
 	uint16_t		*port;
 {
-	return(bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
+	return (bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
 }
 
 static uint32_t
 READ_PORT_ULONG(port)
 	uint32_t		*port;
 {
-	return(bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
+	return (bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
 }
 
 static uint8_t
 READ_PORT_UCHAR(port)
 	uint8_t			*port;
 {
-	return(bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
+	return (bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
 }
 
 static void
@@ -217,7 +209,6 @@ READ_PORT_BUFFER_ULONG(port, val, cnt)
 {
 	bus_space_read_multi_4(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 static void
@@ -228,7 +219,6 @@ READ_PORT_BUFFER_USHORT(port, val, cnt)
 {
 	bus_space_read_multi_2(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 static void
@@ -239,7 +229,6 @@ READ_PORT_BUFFER_UCHAR(port, val, cnt)
 {
 	bus_space_read_multi_1(NDIS_BUS_SPACE_IO, 0x0,
 	    (bus_size_t)port, val, cnt);
-	return;
 }
 
 /*
@@ -370,7 +359,7 @@ KfAcquireSpinLock(lock)
 	KeRaiseIrql(DISPATCH_LEVEL, &oldirql);
 	KeAcquireSpinLockAtDpcLevel(lock);
 
-	return(oldirql);
+	return (oldirql);
 }
 
 void
@@ -378,16 +367,14 @@ KfReleaseSpinLock(kspin_lock *lock, uint8_t newirql)
 {
 	KeReleaseSpinLockFromDpcLevel(lock);
 	KeLowerIrql(newirql);
-
-	return;
 }
 
 uint8_t
 KeGetCurrentIrql()
 {
 	if (mtx_owned(&disp_lock[curthread->td_oncpu]))
-		return(DISPATCH_LEVEL);
-	return(PASSIVE_LEVEL);
+		return (DISPATCH_LEVEL);
+	return (PASSIVE_LEVEL);
 }
 
 static uint64_t
@@ -397,7 +384,7 @@ KeQueryPerformanceCounter(freq)
 	if (freq != NULL)
 		*freq = hz;
 
-	return((uint64_t)ticks);
+	return ((uint64_t)ticks);
 }
 
 uint8_t
@@ -417,7 +404,7 @@ KfRaiseIrql(uint8_t irql)
 	}
 /*printf("RAISE IRQL: %d %d\n", irql, oldirql);*/
 
-	return(oldirql);
+	return (oldirql);
 }
 
 void
@@ -431,8 +418,6 @@ KfLowerIrql(uint8_t oldirql)
 
 	mtx_unlock(&disp_lock[curthread->td_oncpu]);
 	sched_unpin();
-
-	return;
 }
 
 static uint8_t
@@ -441,20 +426,18 @@ KeRaiseIrqlToDpcLevel(void)
 	uint8_t			irql;
 
 	KeRaiseIrql(DISPATCH_LEVEL, &irql);
-	return(irql);
+	return (irql);
 }
 
 static void
 _KeLowerIrql(uint8_t oldirql)
 {
 	KeLowerIrql(oldirql);
-	return;
 }
 
 static void dummy()
 {
-	printf ("hal dummy called...\n");
-	return;
+	printf("hal dummy called...\n");
 }
 
 image_patch_table hal_functbl[] = {
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index d60e5268fe7..6f2b57dd3b4 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -319,7 +319,7 @@ ndis_libinit()
 		patch++;
 	}
 
-	return(0);
+	return (0);
 }
 
 int
@@ -333,7 +333,7 @@ ndis_libfini()
 		patch++;
 	}
 
-	return(0);
+	return (0);
 }
 
 static funcptr
@@ -345,11 +345,11 @@ ndis_findwrap(func)
 	patch = ndis_functbl;
 	while (patch->ipt_func != NULL) {
 		if ((funcptr)patch->ipt_func == func)
-			return((funcptr)patch->ipt_wrap);
+			return ((funcptr)patch->ipt_wrap);
 		patch++;
 	}
 
-	return(NULL);
+	return (NULL);
 }
 
 /*
@@ -385,8 +385,6 @@ NdisInitializeWrapper(wrapper, drv, path, unused)
 	 */
 
 	drv->dro_driverext->dre_adddevicefunc = NdisAddDevice;
-
-	return;
 }
 
 static void
@@ -395,7 +393,6 @@ NdisTerminateWrapper(handle, syspec)
 	void			*syspec;
 {
 	/* Nothing to see here, move along. */
-	return;
 }
 
 static ndis_status
@@ -422,7 +419,7 @@ NdisMRegisterMiniport(handle, characteristics, len)
 	if (IoAllocateDriverObjectExtension(drv, (void *)1,
 	    sizeof(ndis_miniport_characteristics), (void **)&ch) !=
 	    STATUS_SUCCESS) {
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	}
 
 	bzero((char *)ch, sizeof(ndis_miniport_characteristics));
@@ -435,7 +432,7 @@ NdisMRegisterMiniport(handle, characteristics, len)
 		ch->nmc_pnpevent_handler = NULL;
 	}
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static ndis_status
@@ -448,11 +445,11 @@ NdisAllocateMemoryWithTag(vaddr, len, tag)
 
 	mem = ExAllocatePoolWithTag(NonPagedPool, len, tag);
 	if (mem == NULL) {
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	}
 	*vaddr = mem;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static ndis_status
@@ -466,10 +463,10 @@ NdisAllocateMemory(vaddr, len, flags, highaddr)
 
 	mem = ExAllocatePoolWithTag(NonPagedPool, len, 0);
 	if (mem == NULL)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	*vaddr = mem;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -482,8 +479,6 @@ NdisFreeMemory(vaddr, len, flags)
 		return;
 
 	ExFreePool(vaddr);
-
-	return;
 }
 
 static ndis_status
@@ -506,7 +501,7 @@ NdisMSetAttributesEx(adapter_handle, adapter_ctx, hangsecs,
 	block->nmb_checkforhangsecs = hangsecs;
 	block->nmb_flags = flags;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -517,8 +512,6 @@ NdisOpenConfiguration(status, cfg, wrapctx)
 {
 	*cfg = wrapctx;
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 static void
@@ -530,8 +523,6 @@ NdisOpenConfigurationKeyByName(status, cfg, subkey, subhandle)
 {
 	*subhandle = cfg;
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 static void
@@ -543,8 +534,6 @@ NdisOpenConfigurationKeyByIndex(status, cfg, idx, subkey, subhandle)
 	ndis_handle		*subhandle;
 {
 	*status = NDIS_STATUS_FAILURE;
-
-	return;
 }
 
 static ndis_status
@@ -565,7 +554,7 @@ ndis_encode_parm(block, oid, type, parm)
 	np = ExAllocatePoolWithTag(NonPagedPool,
 	    sizeof(ndis_parmlist_entry), 0);
 	if (np == NULL)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	InsertHeadList((&block->nmb_parmlist), (&np->np_list));
 	*parm = p = &np->np_parm;
 
@@ -584,7 +573,7 @@ ndis_encode_parm(block, oid, type, parm)
 
 		if (RtlAnsiStringToUnicodeString(us, &as, TRUE)) {
 			ExFreePool(np);
-			return(NDIS_STATUS_RESOURCES);
+			return (NDIS_STATUS_RESOURCES);
 		}
 		break;
 	case ndis_parm_int:
@@ -609,11 +598,11 @@ ndis_encode_parm(block, oid, type, parm)
 		    strtoul((char *)oid->oid_arg1, NULL, base);
 		break;
 	default:
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 		break;
 	}
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -690,8 +679,6 @@ NdisReadConfiguration(status, parm, cfg, key, type)
 
 	RtlFreeAnsiString(&as);
 	*status = NDIS_STATUS_FAILURE;
-
-	return;
 }
 
 static ndis_status
@@ -707,7 +694,7 @@ ndis_decode_parm(block, parm, val)
 	case ndis_parm_string:
 		ustr = &parm->ncp_parmdata.ncp_stringdata;
 		if (RtlUnicodeStringToAnsiString(&as, ustr, TRUE))
-			return(NDIS_STATUS_RESOURCES);
+			return (NDIS_STATUS_RESOURCES);
 		bcopy(as.as_buf, val, as.as_len);
 		RtlFreeAnsiString(&as);
 		break;
@@ -718,10 +705,10 @@ ndis_decode_parm(block, parm, val)
 		sprintf(val, "%xu", parm->ncp_parmdata.ncp_intdata);
 		break;
 	default:
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 		break;
 	}
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -779,7 +766,6 @@ NdisWriteConfiguration(status, cfg, key, parm)
 
 	RtlFreeAnsiString(&as);
 	*status = NDIS_STATUS_SUCCESS;
-	return;
 }
 
 static void
@@ -801,8 +787,6 @@ NdisCloseConfiguration(cfg)
 			RtlFreeUnicodeString(&p->ncp_parmdata.ncp_stringdata);
 		ExFreePool(e);
 	}
-
-	return;
 }
 
 /*
@@ -814,8 +798,6 @@ NdisAllocateSpinLock(lock)
 {
 	KeInitializeSpinLock(&lock->nsl_spinlock);
 	lock->nsl_kirql = 0;
-
-	return;
 }
 
 /*
@@ -834,7 +816,6 @@ NdisFreeSpinLock(lock)
 	KeInitializeSpinLock(&lock->nsl_spinlock);
 	lock->nsl_kirql = 0;
 #endif
-	return;
 }
 
 /*
@@ -846,7 +827,6 @@ NdisAcquireSpinLock(lock)
 	ndis_spin_lock		*lock;
 {
 	KeAcquireSpinLock(&lock->nsl_spinlock, &lock->nsl_kirql);
-	return;
 }
 
 /*
@@ -858,7 +838,6 @@ NdisReleaseSpinLock(lock)
 	ndis_spin_lock		*lock;
 {
 	KeReleaseSpinLock(&lock->nsl_spinlock, lock->nsl_kirql);
-	return;
 }
 
 /*
@@ -869,7 +848,6 @@ NdisDprAcquireSpinLock(lock)
 	ndis_spin_lock		*lock;
 {
 	KeAcquireSpinLockAtDpcLevel(&lock->nsl_spinlock);
-	return;
 }
 
 /*
@@ -880,7 +858,6 @@ NdisDprReleaseSpinLock(lock)
 	ndis_spin_lock		*lock;
 {
 	KeReleaseSpinLockFromDpcLevel(&lock->nsl_spinlock);
-	return;
 }
 
 static void
@@ -889,7 +866,6 @@ NdisInitializeReadWriteLock(lock)
 {
 	KeInitializeSpinLock(&lock->nrl_spinlock);
 	bzero((char *)&lock->nrl_rsvd, sizeof(lock->nrl_rsvd));
-	return;
 }
 
 static void
@@ -901,8 +877,6 @@ NdisAcquireReadWriteLock(ndis_rw_lock *lock, uint8_t writeacc,
 		lock->nrl_rsvd[0]++;
 	} else
 		lock->nrl_rsvd[1]++;
-
-	return;
 }
 
 static void
@@ -915,8 +889,6 @@ NdisReleaseReadWriteLock(lock, state)
 		KeReleaseSpinLock(&lock->nrl_spinlock, state->nls_oldirql);
 	} else
 		lock->nrl_rsvd[1]--;
-
-	return;
 }
 
 static uint32_t
@@ -935,7 +907,7 @@ NdisReadPciSlotInformation(adapter, slot, offset, buf, len)
 	block = (ndis_miniport_block *)adapter;
 	dest = buf;
 	if (block == NULL)
-		return(0);
+		return (0);
 
 	dev = block->nmb_physdeviceobj->do_devext;
 
@@ -959,7 +931,7 @@ NdisReadPciSlotInformation(adapter, slot, offset, buf, len)
 		dest[i] = pci_read_config(dev, i + offset, 1);
 	}
 
-	return(len);
+	return (len);
 }
 
 static uint32_t
@@ -979,7 +951,7 @@ NdisWritePciSlotInformation(adapter, slot, offset, buf, len)
 	dest = buf;
 
 	if (block == NULL)
-		return(0);
+		return (0);
 
 	dev = block->nmb_physdeviceobj->do_devext;
 	for (i = 0; i < len; i++) {
@@ -987,7 +959,7 @@ NdisWritePciSlotInformation(adapter, slot, offset, buf, len)
 		pci_write_config(dev, i + offset, dest[i], 1);
 	}
 
-	return(len);
+	return (len);
 }
 
 /*
@@ -1033,22 +1005,20 @@ NdisWriteErrorLogEntry(ndis_handle adapter, ndis_error_code code,
 		}
 	}
 
-	device_printf (dev, "NDIS ERROR: %x (%s)\n", code,
+	device_printf(dev, "NDIS ERROR: %x (%s)\n", code,
 	    str == NULL ? "unknown error" : str);
 
 	if (ifp != NULL && ifp->if_flags & IFF_DEBUG) {
-		device_printf (dev, "NDIS NUMERRORS: %x\n", numerrors);
+		device_printf(dev, "NDIS NUMERRORS: %x\n", numerrors);
 		va_start(ap, numerrors);
 		for (i = 0; i < numerrors; i++)
-			device_printf (dev, "argptr: %p\n",
+			device_printf(dev, "argptr: %p\n",
 			    va_arg(ap, void *));
 		va_end(ap);
 	}
 
 	if (as.as_len)
 		RtlFreeAnsiString(&as);
-
-	return;
 }
 
 static void
@@ -1072,8 +1042,6 @@ ndis_map_cb(arg, segs, nseg, error)
 	}
 
 	ctx->nma_cnt = nseg;
-
-	return;
 }
 
 static void
@@ -1110,8 +1078,6 @@ NdisMStartBufferPhysicalMapping(ndis_handle adapter, ndis_buffer *buf,
 	    writedev ? BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD);
 
 	*arraysize = nma.nma_cnt;
-
-	return;
 }
 
 static void
@@ -1139,8 +1105,6 @@ NdisMCompleteBufferPhysicalMapping(adapter, buf, mapreg)
 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 
 	bus_dmamap_unload(sc->ndis_mtag, map);
-
-	return;
 }
 
 /*
@@ -1158,8 +1122,6 @@ NdisInitializeTimer(timer, func, ctx)
 	KeInitializeTimer(&timer->nt_ktimer);
 	KeInitializeDpc(&timer->nt_kdpc, func, ctx);
 	KeSetImportanceDpc(&timer->nt_kdpc, KDPC_IMPORTANCE_LOW);
-
-	return;
 }
 
 static void
@@ -1183,8 +1145,6 @@ ndis_timercall(dpc, timer, sysarg1, sysarg2)
 
 	if (NDIS_SERIALIZED(timer->nmt_block))
 		KeReleaseSpinLockFromDpcLevel(&timer->nmt_block->nmb_lock);
-
-	return;
 }
 
 /*
@@ -1250,8 +1210,6 @@ NdisSetTimer(timer, msecs)
 	 */
 	KeSetTimer(&timer->nt_ktimer,
 	    ((int64_t)msecs * -10000), &timer->nt_kdpc);
-
-	return;
 }
 
 static void
@@ -1261,8 +1219,6 @@ NdisMSetPeriodicTimer(timer, msecs)
 {
 	KeSetTimerEx(&timer->nmt_ktimer,
 	    ((int64_t)msecs * -10000), msecs, &timer->nmt_kdpc);
-
-	return;
 }
 
 /*
@@ -1279,7 +1235,6 @@ NdisMCancelTimer(timer, cancelled)
 {
 
 	*cancelled = KeCancelTimer(&timer->nt_ktimer);
-	return;
 }
 
 static void
@@ -1291,7 +1246,7 @@ NdisMQueryAdapterResources(status, adapter, list, buflen)
 {
 	ndis_miniport_block	*block;
 	struct ndis_softc	*sc;
-	int			rsclen;
+	uint32_t		rsclen;
 
 	block = (ndis_miniport_block *)adapter;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
@@ -1306,8 +1261,6 @@ NdisMQueryAdapterResources(status, adapter, list, buflen)
 
 	bcopy((char *)block->nmb_rlist, (char *)list, rsclen);
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 static ndis_status
@@ -1321,21 +1274,21 @@ NdisMRegisterIoPortRange(offset, adapter, port, numports)
 	struct ndis_softc	*sc;
 
 	if (adapter == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	block = (ndis_miniport_block *)adapter;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
 
 	if (sc->ndis_res_io == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	/* Don't let the device map more ports than we have. */
 	if (rman_get_size(sc->ndis_res_io) < numports)
-		return(NDIS_STATUS_INVALID_LENGTH);
+		return (NDIS_STATUS_INVALID_LENGTH);
 
 	*offset = (void *)rman_get_start(sc->ndis_res_io);
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -1345,7 +1298,6 @@ NdisMDeregisterIoPortRange(adapter, port, numports, offset)
 	uint32_t		numports;
 	void			*offset;
 {
-	return;
 }
 
 static void
@@ -1386,8 +1338,6 @@ NdisReadNetworkAddress(status, addr, addrlen, adapter)
 		*addrlen = ETHER_ADDR_LEN;
 		*status = NDIS_STATUS_SUCCESS;
 	}
-
-	return;
 }
 
 static ndis_status
@@ -1396,7 +1346,7 @@ NdisQueryMapRegisterCount(bustype, cnt)
 	uint32_t		*cnt;
 {
 	*cnt = 8192;
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static ndis_status
@@ -1414,7 +1364,7 @@ NdisMAllocateMapRegisters(ndis_handle adapter, uint32_t dmachannel,
 	    M_DEVBUF, M_NOWAIT|M_ZERO);
 
 	if (sc->ndis_mmaps == NULL)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 
 	error = bus_dma_tag_create(sc->ndis_parent_tag, ETHER_ALIGN, 0,
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
@@ -1423,7 +1373,7 @@ NdisMAllocateMapRegisters(ndis_handle adapter, uint32_t dmachannel,
 
 	if (error) {
 		free(sc->ndis_mmaps, M_DEVBUF);
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	}
 
 	for (i = 0; i < physmapneeded; i++)
@@ -1431,7 +1381,7 @@ NdisMAllocateMapRegisters(ndis_handle adapter, uint32_t dmachannel,
 
 	sc->ndis_mmapcnt = physmapneeded;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -1451,8 +1401,6 @@ NdisMFreeMapRegisters(adapter)
 	free(sc->ndis_mmaps, M_DEVBUF);
 
 	bus_dma_tag_destroy(sc->ndis_mtag);
-
-	return;
 }
 
 static void
@@ -1470,8 +1418,6 @@ ndis_mapshared_cb(arg, segs, nseg, error)
 	p = arg;
 
 	p->np_quad = segs[0].ds_addr;
-
-	return;
 }
 
 /*
@@ -1556,8 +1502,6 @@ NdisMAllocateSharedMemory(ndis_handle adapter, uint32_t len, uint8_t cached,
 	sh->ndis_saddr = *vaddr;
 	InsertHeadList((&sc->ndis_shlist), (&sh->ndis_list));
 	NDIS_UNLOCK(sc);
-
-	return;
 }
 
 struct ndis_allocwork {
@@ -1593,8 +1537,6 @@ ndis_asyncmem_complete(dobj, arg)
 
 	IoFreeWorkItem(w->na_iw);
 	free(w, M_DEVBUF);
-
-	return;
 }
 
 static ndis_status
@@ -1607,18 +1549,18 @@ NdisMAllocateSharedMemoryAsync(ndis_handle adapter, uint32_t len,
 	io_workitem_func	ifw;
 
 	if (adapter == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	block = adapter;
 
 	iw = IoAllocateWorkItem(block->nmb_deviceobj);
 	if (iw == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	w = malloc(sizeof(struct ndis_allocwork), M_TEMP, M_NOWAIT);
 
 	if (w == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	w->na_cached = cached;
 	w->na_len = len;
@@ -1628,7 +1570,7 @@ NdisMAllocateSharedMemoryAsync(ndis_handle adapter, uint32_t len,
 	ifw = (io_workitem_func)ndis_findwrap((funcptr)ndis_asyncmem_complete);
 	IoQueueWorkItem(iw, ifw, WORKQUEUE_DELAYED, w);
 
-	return(NDIS_STATUS_PENDING);
+	return (NDIS_STATUS_PENDING);
 }
 
 static void
@@ -1683,8 +1625,6 @@ NdisMFreeSharedMemory(ndis_handle adapter, uint32_t len, uint8_t cached,
 	bus_dma_tag_destroy(sh->ndis_stag);
 
 	free(sh, M_DEVBUF);
-
-	return;
 }
 
 static ndis_status
@@ -1695,14 +1635,14 @@ NdisMMapIoSpace(vaddr, adapter, paddr, len)
 	uint32_t		len;
 {
 	if (adapter == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	*vaddr = MmMapIoSpace(paddr.np_quad, len, 0);
 
 	if (*vaddr == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -1712,20 +1652,19 @@ NdisMUnmapIoSpace(adapter, vaddr, len)
 	uint32_t		len;
 {
 	MmUnmapIoSpace(vaddr, len);
-	return;
 }
 
 static uint32_t
 NdisGetCacheFillSize(void)
 {
-	return(128);
+	return (128);
 }
 
 static uint32_t
 NdisMGetDmaAlignment(handle)
 	ndis_handle		handle;
 {
-	return(16);
+	return (16);
 }
 
 /*
@@ -1748,13 +1687,13 @@ NdisMInitializeScatterGatherDma(ndis_handle adapter, uint8_t is64,
 	int			error;
 
 	if (adapter == NULL)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 	block = (ndis_miniport_block *)adapter;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
 
 	/* Don't do this twice. */
 	if (sc->ndis_sc == 1)
-		return(NDIS_STATUS_SUCCESS);
+		return (NDIS_STATUS_SUCCESS);
 
 	error = bus_dma_tag_create(sc->ndis_parent_tag, ETHER_ALIGN, 0,
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
@@ -1763,7 +1702,7 @@ NdisMInitializeScatterGatherDma(ndis_handle adapter, uint8_t is64,
 
 	sc->ndis_sc = 1;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 void
@@ -1811,7 +1750,6 @@ NdisAllocatePacketPool(status, pool, descnum, protrsvdlen)
 
 	*pool = p; 
 	*status = NDIS_STATUS_SUCCESS;
-	return;
 }
 
 void
@@ -1822,7 +1760,7 @@ NdisAllocatePacketPoolEx(status, pool, descnum, oflowdescnum, protrsvdlen)
 	uint32_t		oflowdescnum;
 	uint32_t		protrsvdlen;
 {
-	return(NdisAllocatePacketPool(status, pool,
+	return (NdisAllocatePacketPool(status, pool,
 	    descnum + oflowdescnum, protrsvdlen));
 }
 
@@ -1833,7 +1771,7 @@ NdisPacketPoolUsage(pool)
 	ndis_packet_pool	*p;
 
 	p = (ndis_packet_pool *)pool;
-	return(p->np_cnt - ExQueryDepthSList(&p->np_head));
+	return (p->np_cnt - ExQueryDepthSList(&p->np_head));
 }
 
 void
@@ -1866,8 +1804,6 @@ NdisFreePacketPool(pool)
 
 	ExFreePool(p->np_pktmem);
 	ExFreePool(p);
-
-	return;
 }
 
 void
@@ -1927,8 +1863,6 @@ NdisAllocatePacket(status, packet, pool)
 	*packet = pkt;
 
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 void
@@ -1955,8 +1889,6 @@ NdisFreePacket(packet)
 	}
 	KeReleaseSpinLock(&p->np_lock, irql);
 #endif
-
-	return;
 }
 
 static void
@@ -1980,8 +1912,6 @@ NdisUnchainBufferAtFront(packet, buf)
 		*buf = priv->npp_head;
 		priv->npp_head = (*buf)->mdl_next;
 	}
-
-	return;
 }
 
 static void
@@ -2010,8 +1940,6 @@ NdisUnchainBufferAtBack(packet, buf)
 		priv->npp_tail = tmp;
 		tmp->mdl_next = NULL;
 	}
-
-	return;
 }
 
 /*
@@ -2042,14 +1970,12 @@ NdisAllocateBufferPool(status, pool, descnum)
 
 	*pool = NonPagedPool;
 	*status = NDIS_STATUS_SUCCESS;
-	return;
 }
 
 static void
 NdisFreeBufferPool(pool)
 	ndis_handle		pool;
 {
-	return;
 }
 
 static void
@@ -2072,8 +1998,6 @@ NdisAllocateBuffer(status, buffer, pool, vaddr, len)
 
 	*buffer = buf;
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 static void
@@ -2081,7 +2005,6 @@ NdisFreeBuffer(buf)
 	ndis_buffer		*buf;
 {
 	IoFreeMdl(buf);
-	return;
 }
 
 /* Aw c'mon. */
@@ -2090,7 +2013,7 @@ static uint32_t
 NdisBufferLength(buf)
 	ndis_buffer		*buf;
 {
-	return(MmGetMdlByteCount(buf));
+	return (MmGetMdlByteCount(buf));
 }
 
 /*
@@ -2107,8 +2030,6 @@ NdisQueryBuffer(buf, vaddr, len)
 	if (vaddr != NULL)
 		*vaddr = MmGetMdlVirtualAddress(buf);
 	*len = MmGetMdlByteCount(buf);
-
-	return;
 }
 
 /* Same as above -- we don't care about the priority. */
@@ -2123,8 +2044,6 @@ NdisQueryBufferSafe(buf, vaddr, len, prio)
 	if (vaddr != NULL)
 		*vaddr = MmGetMdlVirtualAddress(buf);
 	*len = MmGetMdlByteCount(buf);
-
-	return;
 }
 
 /* Damnit Microsoft!! How many ways can you do the same thing?! */
@@ -2133,7 +2052,7 @@ static void *
 NdisBufferVirtualAddress(buf)
 	ndis_buffer		*buf;
 {
-	return(MmGetMdlVirtualAddress(buf));
+	return (MmGetMdlVirtualAddress(buf));
 }
 
 static void *
@@ -2141,7 +2060,7 @@ NdisBufferVirtualAddressSafe(buf, prio)
 	ndis_buffer		*buf;
 	uint32_t		prio;
 {
-	return(MmGetMdlVirtualAddress(buf));
+	return (MmGetMdlVirtualAddress(buf));
 }
 
 static void
@@ -2150,8 +2069,6 @@ NdisAdjustBufferLength(buf, len)
 	int			len;
 {
 	MmGetMdlByteCount(buf) = len;
-
-	return;
 }
 
 static uint32_t
@@ -2159,7 +2076,7 @@ NdisInterlockedIncrement(addend)
 	uint32_t		*addend;
 {
 	atomic_add_long((u_long *)addend, 1);
-	return(*addend);
+	return (*addend);
 }
 
 static uint32_t
@@ -2167,7 +2084,7 @@ NdisInterlockedDecrement(addend)
 	uint32_t		*addend;
 {
 	atomic_subtract_long((u_long *)addend, 1);
-	return(*addend);
+	return (*addend);
 }
 
 static void
@@ -2180,7 +2097,6 @@ NdisInitializeEvent(event)
 	 * not signaled state.
 	 */
 	KeInitializeEvent(&event->ne_event, EVENT_TYPE_NOTIFY, FALSE);
-	return;
 }
 
 static void
@@ -2188,7 +2104,6 @@ NdisSetEvent(event)
 	ndis_event		*event;
 {
 	KeSetEvent(&event->ne_event, IO_NO_INCREMENT, FALSE);
-	return;
 }
 
 static void
@@ -2196,7 +2111,6 @@ NdisResetEvent(event)
 	ndis_event		*event;
 {
 	KeResetEvent(&event->ne_event);
-	return;
 }
 
 static uint8_t
@@ -2212,9 +2126,9 @@ NdisWaitEvent(event, msecs)
 	    0, 0, TRUE, msecs ? & duetime : NULL);
 
 	if (rval == STATUS_TIMEOUT)
-		return(FALSE);
+		return (FALSE);
 
-	return(TRUE);
+	return (TRUE);
 }
 
 static ndis_status
@@ -2227,9 +2141,9 @@ NdisUnicodeStringToAnsiString(dstr, sstr)
 	rval = RtlUnicodeStringToAnsiString(dstr, sstr, FALSE);
 
 	if (rval == STATUS_INSUFFICIENT_RESOURCES)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	if (rval)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	return (NDIS_STATUS_SUCCESS);
 }
@@ -2244,9 +2158,9 @@ NdisAnsiStringToUnicodeString(dstr, sstr)
 	rval = RtlAnsiStringToUnicodeString(dstr, sstr, FALSE);
 
 	if (rval == STATUS_INSUFFICIENT_RESOURCES)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 	if (rval)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	return (NDIS_STATUS_SUCCESS);
 }
@@ -2282,7 +2196,7 @@ ndis_intr(iobj, arg)
 	intr = sc->ndis_block->nmb_interrupt;
 
 	if (intr == NULL || sc->ndis_block->nmb_miniportadapterctx == NULL)
-		return(FALSE);
+		return (FALSE);
 
 	if (sc->ndis_block->nmb_interrupt->ni_isrreq == TRUE)
 		MSCALL3(intr->ni_isrfunc, &is_our_intr, &call_isr,
@@ -2296,7 +2210,7 @@ ndis_intr(iobj, arg)
 	if (call_isr)
 		IoRequestDpc(sc->ndis_block->nmb_deviceobj, NULL, sc);
 
-	return(is_our_intr);
+	return (is_our_intr);
 }
 
 static void
@@ -2337,8 +2251,6 @@ ndis_intrhand(dpc, intr, sysarg1, sysarg2)
 	if (intr->ni_dpccnt == 0)
 		KeSetEvent(&intr->ni_dpcevt, IO_NO_INCREMENT, FALSE);
 	KeReleaseSpinLockFromDpcLevel(&intr->ni_dpccountlock);
-
-	return;
 }
 
 static ndis_status
@@ -2359,7 +2271,7 @@ NdisMRegisterInterrupt(ndis_miniport_interrupt *intr, ndis_handle adapter,
 	intr->ni_rsvd = ExAllocatePoolWithTag(NonPagedPool,
 	    sizeof(struct mtx), 0);
 	if (intr->ni_rsvd == NULL)
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 
 	intr->ni_block = adapter;
 	intr->ni_isrreq = reqisr;
@@ -2378,11 +2290,11 @@ NdisMRegisterInterrupt(ndis_miniport_interrupt *intr, ndis_handle adapter,
 	    ivec, ilevel, 0, imode, shared, 0, FALSE);
 
 	if (error != STATUS_SUCCESS)
-		return(NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
 
 	block->nmb_interrupt = intr;
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -2408,8 +2320,6 @@ NdisMDeregisterInterrupt(intr)
 
 	KeWaitForSingleObject(&intr->ni_dpcevt, 0, 0, FALSE, NULL);
 	KeResetEvent(&intr->ni_dpcevt);
-
-	return;
 }
 
 static void
@@ -2431,8 +2341,6 @@ NdisMRegisterAdapterShutdownHandler(adapter, shutdownctx, shutdownfunc)
 
 	chars->nmc_shutdown_handler = shutdownfunc;
 	chars->nmc_rsvd0 = shutdownctx;
-
-	return;
 }
 
 static void
@@ -2452,8 +2360,6 @@ NdisMDeregisterAdapterShutdownHandler(adapter)
 
 	chars->nmc_shutdown_handler = NULL;
 	chars->nmc_rsvd0 = NULL;
-
-	return;
 }
 
 static uint32_t
@@ -2461,10 +2367,10 @@ NDIS_BUFFER_TO_SPAN_PAGES(buf)
 	ndis_buffer		*buf;
 {
 	if (buf == NULL)
-		return(0);
+		return (0);
 	if (MmGetMdlByteCount(buf) == 0)
-		return(1);
-	return(SPAN_PAGES(MmGetMdlVirtualAddress(buf),
+		return (1);
+	return (SPAN_PAGES(MmGetMdlVirtualAddress(buf),
 	    MmGetMdlByteCount(buf)));
 }
 
@@ -2477,7 +2383,6 @@ NdisGetBufferPhysicalArraySize(buf, pages)
 		return;
 
 	*pages = NDIS_BUFFER_TO_SPAN_PAGES(buf);
-	return;
 }
 
 static void
@@ -2491,8 +2396,6 @@ NdisQueryBufferOffset(buf, off, len)
 
 	*off = MmGetMdlByteOffset(buf);
 	*len = MmGetMdlByteCount(buf);
-
-	return;
 }
 
 void
@@ -2514,8 +2417,6 @@ NdisMSleep(usecs)
 		KeSetTimer(&timer, ((int64_t)usecs * -10), NULL);
 		KeWaitForSingleObject(&timer, 0, 0, FALSE, NULL);
 	}
-
-	return;
 }
 
 static uint32_t
@@ -2533,7 +2434,7 @@ NdisReadPcmciaAttributeMemory(handle, offset, buf, len)
 	int			i;
 
 	if (handle == NULL)
-		return(0);
+		return (0);
 
 	block = (ndis_miniport_block *)handle;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
@@ -2545,7 +2446,7 @@ NdisReadPcmciaAttributeMemory(handle, offset, buf, len)
 	for (i = 0; i < len; i++)
 		dest[i] = bus_space_read_1(bt, bh, (offset + i) * 2);
 
-	return(i);
+	return (i);
 }
 
 static uint32_t
@@ -2563,7 +2464,7 @@ NdisWritePcmciaAttributeMemory(handle, offset, buf, len)
 	int			i;
 
 	if (handle == NULL)
-		return(0);
+		return (0);
 
 	block = (ndis_miniport_block *)handle;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
@@ -2575,7 +2476,7 @@ NdisWritePcmciaAttributeMemory(handle, offset, buf, len)
 	for (i = 0; i < len; i++)
 		bus_space_write_1(bt, bh, (offset + i) * 2, src[i]);
 
-	return(i);
+	return (i);
 }
 
 static list_entry *
@@ -2594,7 +2495,7 @@ NdisInterlockedInsertHeadList(head, entry, lock)
 	head->nle_flink = entry;
 	KeReleaseSpinLock(&lock->nsl_spinlock, lock->nsl_kirql);
 
-	return(flink);
+	return (flink);
 }
 
 static list_entry *
@@ -2612,7 +2513,7 @@ NdisInterlockedRemoveHeadList(head, lock)
 	flink->nle_blink = head;
 	KeReleaseSpinLock(&lock->nsl_spinlock, lock->nsl_kirql);
 
-	return(entry);
+	return (entry);
 }
 
 static list_entry *
@@ -2631,7 +2532,7 @@ NdisInterlockedInsertTailList(head, entry, lock)
 	head->nle_blink = entry;
 	KeReleaseSpinLock(&lock->nsl_spinlock, lock->nsl_kirql);
 
-	return(blink);
+	return (blink);
 }
 
 static uint8_t
@@ -2640,7 +2541,7 @@ NdisMSynchronizeWithInterrupt(intr, syncfunc, syncctx)
 	void			*syncfunc;
 	void			*syncctx;
 {
-	return(KeSynchronizeExecution(intr->ni_introbj, syncfunc, syncctx));
+	return (KeSynchronizeExecution(intr->ni_introbj, syncfunc, syncctx));
 }
 
 static void
@@ -2648,7 +2549,6 @@ NdisGetCurrentSystemTime(tval)
 	uint64_t		*tval;
 {
 	ntoskrnl_time(tval);
-	return;
 }
 
 /*
@@ -2662,8 +2562,6 @@ NdisGetSystemUpTime(tval)
 
 	nanouptime(&ts);
 	*tval = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;
-
-	return;
 }
 
 static void
@@ -2674,7 +2572,6 @@ NdisInitializeString(dst, src)
 	ansi_string		as;
 	RtlInitAnsiString(&as, src);
 	RtlAnsiStringToUnicodeString(dst, &as, TRUE);
-	return;
 }
 
 static void
@@ -2682,14 +2579,13 @@ NdisFreeString(str)
 	unicode_string		*str;
 {
 	RtlFreeUnicodeString(str);
-	return;
 }
 
 static ndis_status
 NdisMRemoveMiniport(adapter)
 	ndis_handle		*adapter;
 {
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -2698,7 +2594,6 @@ NdisInitAnsiString(dst, src)
 	char			*src;
 {
 	RtlInitAnsiString(dst, src);
-	return;
 }
 
 static void
@@ -2707,7 +2602,6 @@ NdisInitUnicodeString(dst, src)
 	uint16_t		*src;
 {
 	RtlInitUnicodeString(dst, src);
-	return;
 }
 
 static void NdisMGetDeviceProperty(adapter, phydevobj,
@@ -2729,8 +2623,6 @@ static void NdisMGetDeviceProperty(adapter, phydevobj,
 		*funcdevobj = block->nmb_deviceobj;
 	if (nextdevobj != NULL)
 		*nextdevobj = block->nmb_nextdeviceobj;
-
-	return;
 }
 
 static void
@@ -2754,8 +2646,6 @@ NdisGetFirstBufferFromPacket(packet, buf, firstva, firstlen, totlen)
 		for (tmp = tmp->mdl_next; tmp != NULL; tmp = tmp->mdl_next)
 			*totlen += MmGetMdlByteCount(tmp);
 	}
-
-	return;
 }
 
 static void
@@ -2783,13 +2673,13 @@ ndis_find_sym(lf, filename, suffix, sym)
 
 	fullsym = ExAllocatePoolWithTag(NonPagedPool, MAXPATHLEN, 0);
 	if (fullsym == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	bzero(fullsym, MAXPATHLEN);
 	strncpy(fullsym, filename, MAXPATHLEN);
 	if (strlen(filename) < 4) {
 		ExFreePool(fullsym);
-		return(EINVAL);
+		return (EINVAL);
 	}
 
 	/* If the filename has a .ko suffix, strip if off. */
@@ -2807,9 +2697,9 @@ ndis_find_sym(lf, filename, suffix, sym)
 	*sym = linker_file_lookup_symbol(lf, fullsym, 0);
 	ExFreePool(fullsym);
 	if (*sym == 0)
-		return(ENOENT);
+		return (ENOENT);
 
-	return(0);
+	return (0);
 }
 
 struct ndis_checkmodule {
@@ -2960,8 +2850,6 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
 	*filehandle = fh;
 	*filelength = fh->nf_maplen = vap->va_size & 0xFFFFFFFF;
 	*status = NDIS_STATUS_SUCCESS;
-
-	return;
 }
 
 static void
@@ -3025,8 +2913,6 @@ NdisMapFile(status, mappedbuffer, filehandle)
 		*status = NDIS_STATUS_SUCCESS;
 		*mappedbuffer = fh->nf_map;
 	}
-
-	return;
 }
 
 static void
@@ -3042,8 +2928,6 @@ NdisUnmapFile(filehandle)
 	if (fh->nf_type == NDIS_FH_TYPE_VFS)
 		ExFreePool(fh->nf_map);
 	fh->nf_map = NULL;
-
-	return;
 }
 
 static void
@@ -3078,14 +2962,12 @@ NdisCloseFile(filehandle)
 	fh->nf_vp = NULL;
 	free(fh->nf_name, M_DEVBUF);
 	ExFreePool(fh);
-
-	return;
 }
 
 static uint8_t
 NdisSystemProcessorCount()
 {
-	return(mp_ncpus);
+	return (mp_ncpus);
 }
 
 typedef void (*ndis_statusdone_handler)(ndis_handle);
@@ -3103,7 +2985,6 @@ NdisMIndicateStatusComplete(adapter)
 	statusdonefunc = block->nmb_statusdone_func;
 
 	MSCALL1(statusdonefunc, adapter);
-	return;
 }
 
 static void
@@ -3120,7 +3001,6 @@ NdisMIndicateStatus(adapter, status, sbuf, slen)
 	statusfunc = block->nmb_status_func;
 
 	MSCALL4(statusfunc, adapter, status, sbuf, slen);
-	return;
 }
 
 /*
@@ -3154,7 +3034,7 @@ NdisScheduleWorkItem(work)
 	    (work_item_func)work->nwi_func, work->nwi_ctx);
 	ExQueueWorkItem(wqi, WORKQUEUE_DELAYED);
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -3244,7 +3124,6 @@ NdisCopyFromPacketToPacket(dpkt, doff, reqlen, spkt, soff, cpylen)
 	}
 
 	*cpylen = copied;
-	return;
 }
 
 static void
@@ -3258,7 +3137,6 @@ NdisCopyFromPacketToPacketSafe(dpkt, doff, reqlen, spkt, soff, cpylen, prio)
 	uint32_t		prio;
 {
 	NdisCopyFromPacketToPacket(dpkt, doff, reqlen, spkt, soff, cpylen);
-	return;
 }
 
 static void
@@ -3289,7 +3167,7 @@ NdisMRegisterDevice(handle, devname, symname, majorfuncs, devobj, devhandle)
 		*devhandle = dobj;
 	}
 
-	return(status);
+	return (status);
 }
 
 static ndis_status
@@ -3297,7 +3175,7 @@ NdisMDeregisterDevice(handle)
 	ndis_handle		handle;
 {
 	IoDeleteDevice(handle);
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static ndis_status
@@ -3314,9 +3192,9 @@ NdisMQueryAdapterInstanceName(name, handle)
 
 	RtlInitAnsiString(&as, __DECONST(char *, device_get_nameunit(dev)));
 	if (RtlAnsiStringToUnicodeString(name, &as, TRUE))
-		return(NDIS_STATUS_RESOURCES);
+		return (NDIS_STATUS_RESOURCES);
 
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 static void
@@ -3324,14 +3202,12 @@ NdisMRegisterUnloadHandler(handle, func)
 	ndis_handle		handle;
 	void			*func;
 {
-	return;
 }
 
 static void
 dummy()
 {
-	printf ("NDIS dummy called...\n");
-	return;
+	printf("NDIS dummy called...\n");
 }
 
 /*
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index 69bea9e15d6..ba1e49ffaf6 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -295,13 +295,13 @@ ntoskrnl_libinit()
 #endif
 
 	if (kq_queues == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	wq_queues = ExAllocatePoolWithTag(NonPagedPool,
 	    sizeof(kdpc_queue) * WORKITEM_THREADS, 0);
 
 	if (wq_queues == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 #ifdef NTOSKRNL_MULTIPLE_DPCS
 	bzero((char *)kq_queues, sizeof(kdpc_queue) * mp_ncpus);
@@ -378,7 +378,7 @@ ntoskrnl_libinit()
 	iw_zone = uma_zcreate("Windows WorkItem", sizeof(io_workitem),
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -419,7 +419,7 @@ ntoskrnl_libfini()
 	mtx_destroy(&ntoskrnl_interlock);
 	mtx_destroy(&ntoskrnl_calllock);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -432,7 +432,7 @@ ntoskrnl_memset(buf, ch, size)
 	int			ch;
 	size_t			size;
 {
-	return(memset(buf, ch, size));
+	return (memset(buf, ch, size));
 }
 
 static void *
@@ -442,7 +442,7 @@ ntoskrnl_memmove(dst, src, size)
 	size_t			size;
 {
 	bcopy(src, dst, size);
-	return(dst);
+	return (dst);
 }
 
 static void *
@@ -506,14 +506,14 @@ static int
 ntoskrnl_toupper(c)
 	int			c;
 {
-	return(toupper(c));
+	return (toupper(c));
 }
 
 static int
 ntoskrnl_tolower(c)
 	int			c;
 {
-	return(tolower(c));
+	return (tolower(c));
 }
 
 static uint8_t
@@ -523,20 +523,20 @@ RtlEqualUnicodeString(unicode_string *str1, unicode_string *str2,
 	int			i;
 
 	if (str1->us_len != str2->us_len)
-		return(FALSE);
+		return (FALSE);
 
 	for (i = 0; i < str1->us_len; i++) {
 		if (caseinsensitive == TRUE) {
 			if (toupper((char)(str1->us_buf[i] & 0xFF)) !=
 			    toupper((char)(str2->us_buf[i] & 0xFF)))
-				return(FALSE);
+				return (FALSE);
 		} else {
 			if (str1->us_buf[i] != str2->us_buf[i])
-				return(FALSE);
+				return (FALSE);
 		}
 	}
 
-	return(TRUE);
+	return (TRUE);
 }
 
 static void
@@ -550,7 +550,6 @@ RtlCopyUnicodeString(dest, src)
 	else
 		dest->us_len = dest->us_maxlen;
 	memcpy(dest->us_buf, src->us_buf, dest->us_len);
-	return;
 }
 
 static void
@@ -567,8 +566,6 @@ ntoskrnl_ascii_to_unicode(ascii, unicode, len)
 		*ustr = (uint16_t)ascii[i];
 		ustr++;
 	}
-
-	return;
 }
 
 static void
@@ -585,15 +582,13 @@ ntoskrnl_unicode_to_ascii(unicode, ascii, len)
 		*astr = (uint8_t)unicode[i];
 		astr++;
 	}
-
-	return;
 }
 
 uint32_t
 RtlUnicodeStringToAnsiString(ansi_string *dest, unicode_string *src, uint8_t allocate)
 {
 	if (dest == NULL || src == NULL)
-		return(STATUS_INVALID_PARAMETER);
+		return (STATUS_INVALID_PARAMETER);
 
 	dest->as_len = src->us_len / 2;
 	if (dest->as_maxlen < dest->as_len)
@@ -603,7 +598,7 @@ RtlUnicodeStringToAnsiString(ansi_string *dest, unicode_string *src, uint8_t all
 		dest->as_buf = ExAllocatePoolWithTag(NonPagedPool,
 		    (src->us_len / 2) + 1, 0);
 		if (dest->as_buf == NULL)
-			return(STATUS_INSUFFICIENT_RESOURCES);
+			return (STATUS_INSUFFICIENT_RESOURCES);
 		dest->as_len = dest->as_maxlen = src->us_len / 2;
 	} else {
 		dest->as_len = src->us_len / 2; /* XXX */
@@ -622,13 +617,13 @@ RtlAnsiStringToUnicodeString(unicode_string *dest, ansi_string *src,
 	uint8_t allocate)
 {
 	if (dest == NULL || src == NULL)
-		return(STATUS_INVALID_PARAMETER);
+		return (STATUS_INVALID_PARAMETER);
 
 	if (allocate == TRUE) {
 		dest->us_buf = ExAllocatePoolWithTag(NonPagedPool,
 		    src->as_len * 2, 0);
 		if (dest->us_buf == NULL)
-			return(STATUS_INSUFFICIENT_RESOURCES);
+			return (STATUS_INSUFFICIENT_RESOURCES);
 		dest->us_len = dest->us_maxlen = strlen(src->as_buf) * 2;
 	} else {
 		dest->us_len = src->as_len * 2; /* XXX */
@@ -652,9 +647,9 @@ ExAllocatePoolWithTag(pooltype, len, tag)
 
 	buf = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
 	if (buf == NULL)
-		return(NULL);
+		return (NULL);
 
-	return(buf);
+	return (buf);
 }
 
 void
@@ -662,7 +657,6 @@ ExFreePool(buf)
 	void			*buf;
 {
 	free(buf, M_DEVBUF);
-	return;
 }
 
 uint32_t
@@ -678,14 +672,14 @@ IoAllocateDriverObjectExtension(drv, clid, extlen, ext)
 	    + extlen, 0);
 
 	if (ce == NULL)
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 
 	ce->ce_clid = clid;
 	InsertTailList((&drv->dro_driverext->dre_usrext), (&ce->ce_list));
 
 	*ext = (void *)(ce + 1);
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 void *
@@ -702,17 +696,17 @@ IoGetDriverObjectExtension(drv, clid)
 	 */
 
 	if (drv->dro_driverext == NULL)
-		return(NULL);
+		return (NULL);
 
 	e = drv->dro_driverext->dre_usrext.nle_flink;
 	while (e != &drv->dro_driverext->dre_usrext) {
 		ce = (custom_extension *)e;
 		if (ce->ce_clid == clid)
-			return((void *)(ce + 1));
+			return ((void *)(ce + 1));
 		e = e->nle_flink;
 	}
 
-	return(NULL);
+	return (NULL);
 }
 
 
@@ -725,7 +719,7 @@ IoCreateDevice(driver_object *drv, uint32_t devextlen, unicode_string *devname,
 
 	dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(device_object), 0);
 	if (dev == NULL)
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 
 	dev->do_type = devtype;
 	dev->do_drvobj = drv;
@@ -738,7 +732,7 @@ IoCreateDevice(driver_object *drv, uint32_t devextlen, unicode_string *devname,
 
 		if (dev->do_devext == NULL) {
 			ExFreePool(dev);
-			return(STATUS_INSUFFICIENT_RESOURCES);
+			return (STATUS_INSUFFICIENT_RESOURCES);
 		}
 
 		bzero(dev->do_devext, devextlen);
@@ -769,7 +763,7 @@ IoCreateDevice(driver_object *drv, uint32_t devextlen, unicode_string *devname,
 		if (dev->do_devext != NULL)
 			ExFreePool(dev->do_devext);
 		ExFreePool(dev);
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 	}
 
 	dev->do_devobj_ext->dve_type = 0;
@@ -794,7 +788,7 @@ IoCreateDevice(driver_object *drv, uint32_t devextlen, unicode_string *devname,
 
 	*newdev = dev;
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 void
@@ -824,8 +818,6 @@ IoDeleteDevice(dev)
 	}
 
 	ExFreePool(dev);
-
-	return;
 }
 
 device_object *
@@ -859,10 +851,10 @@ IoBuildSynchronousFsdRequest(func, dobj, buf, len, off, event, status)
 
 	ip = IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status);
 	if (ip == NULL)
-		return(NULL);
+		return (NULL);
 	ip->irp_usrevent = event;
 
-	return(ip);
+	return (ip);
 }
 
 static irp *
@@ -879,7 +871,7 @@ IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status)
 
 	ip = IoAllocateIrp(dobj->do_stacksize, TRUE);
 	if (ip == NULL)
-		return(NULL);
+		return (NULL);
 
 	ip->irp_usriostat = status;
 	ip->irp_tail.irp_overlay.irp_thread = NULL;
@@ -900,7 +892,7 @@ IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status)
 		    ExAllocatePoolWithTag(NonPagedPool, len, 0);
 		if (ip->irp_assoc.irp_sysbuf == NULL) {
 			IoFreeIrp(ip);
-			return(NULL);
+			return (NULL);
 		}
 		bcopy(buf, ip->irp_assoc.irp_sysbuf, len);
 	}
@@ -911,7 +903,7 @@ IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status)
 			if (ip->irp_assoc.irp_sysbuf != NULL)
 				ExFreePool(ip->irp_assoc.irp_sysbuf);
 			IoFreeIrp(ip);
-			return(NULL);
+			return (NULL);
 		}
 		ip->irp_userbuf = NULL;
 		ip->irp_assoc.irp_sysbuf = NULL;
@@ -933,7 +925,7 @@ IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status)
 			sl->isl_parameters.isl_write.isl_byteoff = 0;
 	}
 
-	return(ip);
+	return (ip);
 }
 
 static irp *
@@ -947,7 +939,7 @@ IoBuildDeviceIoControlRequest(uint32_t iocode, device_object *dobj, void *ibuf,
 
 	ip = IoAllocateIrp(dobj->do_stacksize, TRUE);
 	if (ip == NULL)
-		return(NULL);
+		return (NULL);
 	ip->irp_usrevent = event;
 	ip->irp_usriostat = status;
 	ip->irp_tail.irp_overlay.irp_thread = NULL;
@@ -976,7 +968,7 @@ IoBuildDeviceIoControlRequest(uint32_t iocode, device_object *dobj, void *ibuf,
 			    ExAllocatePoolWithTag(NonPagedPool, buflen, 0);
 			if (ip->irp_assoc.irp_sysbuf == NULL) {
 				IoFreeIrp(ip);
-				return(NULL);
+				return (NULL);
 			}
 		}
 		if (ilen && ibuf != NULL) {
@@ -994,7 +986,7 @@ IoBuildDeviceIoControlRequest(uint32_t iocode, device_object *dobj, void *ibuf,
 			    ExAllocatePoolWithTag(NonPagedPool, ilen, 0);
 			if (ip->irp_assoc.irp_sysbuf == NULL) {
 				IoFreeIrp(ip);
-				return(NULL);
+				return (NULL);
 			}
 			bcopy(ibuf, ip->irp_assoc.irp_sysbuf, ilen);
 		}
@@ -1045,7 +1037,7 @@ IoMakeAssociatedIrp(irp *ip, uint8_t stsize)
 
 	associrp = IoAllocateIrp(stsize, FALSE);
 	if (associrp == NULL)
-		return(NULL);
+		return (NULL);
 
 	mtx_lock(&ntoskrnl_dispatchlock);
 	associrp->irp_flags |= IRP_ASSOCIATED_IRP;
@@ -1054,7 +1046,7 @@ IoMakeAssociatedIrp(irp *ip, uint8_t stsize)
 	associrp->irp_assoc.irp_master = ip;
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(associrp);
+	return (associrp);
 }
 
 static void
@@ -1062,7 +1054,6 @@ IoFreeIrp(ip)
 	irp			*ip;
 {
 	ExFreePool(ip);
-	return;
 }
 
 static void
@@ -1075,8 +1066,6 @@ IoInitializeIrp(irp *io, uint16_t psize, uint8_t ssize)
 	InitializeListHead(&io->irp_thlist);
 	io->irp_tail.irp_overlay.irp_csl =
 	    (io_stack_location *)(io + 1) + ssize;
-
-	return;
 }
 
 static void
@@ -1090,22 +1079,18 @@ IoReuseIrp(ip, status)
 	IoInitializeIrp(ip, ip->irp_size, ip->irp_stackcnt);
 	ip->irp_iostat.isb_status = status;
 	ip->irp_allocflags = allocflags;
-
-	return;
 }
 
 void
 IoAcquireCancelSpinLock(uint8_t *irql)
 {
 	KeAcquireSpinLock(&ntoskrnl_cancellock, irql);
-	return;
 }
 
 void
 IoReleaseCancelSpinLock(uint8_t irql)
 {
 	KeReleaseSpinLock(&ntoskrnl_cancellock, irql);
-	return;
 }
 
 uint8_t
@@ -1119,7 +1104,7 @@ IoCancelIrp(irp *ip)
 	ip->irp_cancel = TRUE;
 	if (cfunc == NULL) {
 		IoReleaseCancelSpinLock(cancelirql);
-		return(FALSE);
+		return (FALSE);
 	}
 	ip->irp_cancelirql = cancelirql;
 	MSCALL2(cfunc, IoGetCurrentIrpStackLocation(ip)->isl_devobj, ip);
@@ -1149,7 +1134,7 @@ IofCallDriver(dobj, ip)
 	disp = drvobj->dro_dispatch[sl->isl_major];
 	status = MSCALL2(disp, dobj, ip);
 
-	return(status);
+	return (status);
 }
 
 void
@@ -1230,8 +1215,6 @@ IofCompleteRequest(irp *ip, uint8_t prioboost)
 			IoFreeMdl(ip->irp_mdl);
 		IoFreeIrp(ip);
 	}
-
-	return;
 }
 
 void
@@ -1253,8 +1236,6 @@ ntoskrnl_intr(arg)
 		l = l->nle_flink;
 	}
 	KeReleaseSpinLock(&ntoskrnl_intlock, irql);
-
-	return;
 }
 
 uint8_t
@@ -1263,14 +1244,13 @@ KeAcquireInterruptSpinLock(iobj)
 {
 	uint8_t			irql;
 	KeAcquireSpinLock(&ntoskrnl_intlock, &irql);
-	return(irql);
+	return (irql);
 }
 
 void
 KeReleaseInterruptSpinLock(kinterrupt *iobj, uint8_t irql)
 {
 	KeReleaseSpinLock(&ntoskrnl_intlock, irql);
-	return;
 }
 
 uint8_t
@@ -1285,7 +1265,7 @@ KeSynchronizeExecution(iobj, syncfunc, syncctx)
 	MSCALL1(syncfunc, syncctx);
 	KeReleaseSpinLock(&ntoskrnl_intlock, irql);
 
-	return(TRUE);
+	return (TRUE);
 }
 
 /*
@@ -1313,7 +1293,7 @@ IoConnectInterrupt(kinterrupt **iobj, void *svcfunc, void *svcctx,
 
 	*iobj = ExAllocatePoolWithTag(NonPagedPool, sizeof(kinterrupt), 0);
 	if (*iobj == NULL)
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 
 	(*iobj)->ki_svcfunc = svcfunc;
 	(*iobj)->ki_svcctx = svcctx;
@@ -1328,7 +1308,7 @@ IoConnectInterrupt(kinterrupt **iobj, void *svcfunc, void *svcctx,
 	InsertHeadList((&ntoskrnl_intlist), (&(*iobj)->ki_list));
 	KeReleaseSpinLock(&ntoskrnl_intlock, curirql);
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 void
@@ -1345,8 +1325,6 @@ IoDisconnectInterrupt(iobj)
 	KeReleaseSpinLock(&ntoskrnl_intlock, irql);
 
 	ExFreePool(iobj);
-
-	return;
 }
 
 device_object *
@@ -1363,7 +1341,7 @@ IoAttachDeviceToDeviceStack(src, dst)
 	src->do_stacksize = attached->do_stacksize + 1;
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(attached);
+	return (attached);
 }
 
 void
@@ -1392,8 +1370,6 @@ IoDetachDevice(topdev)
 	}
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
-
-	return;
 }
 
 /*
@@ -1419,13 +1395,13 @@ ntoskrnl_is_signalled(obj, td)
 		km = (kmutant *)obj;
 		if ((obj->dh_sigstate <= 0 && km->km_ownerthread == td) ||
 		    obj->dh_sigstate == 1)
-			return(TRUE);
-		return(FALSE);
+			return (TRUE);
+		return (FALSE);
 	}
 
 	if (obj->dh_sigstate > 0)
-		return(TRUE);
-	return(FALSE);
+		return (TRUE);
+	return (FALSE);
 }
 
 static void
@@ -1460,8 +1436,6 @@ ntoskrnl_satisfy_wait(obj, td)
 	default:
 		break;
 	}
-
-	return;
 }
 
 static void
@@ -1479,8 +1453,6 @@ ntoskrnl_satisfy_multiple_waits(wb)
 		cur->wb_awakened = TRUE;
 		cur = cur->wb_next;
 	} while (cur != wb);
-
-	return;
 }
 
 /* Always called with dispatcher lock held. */
@@ -1562,8 +1534,6 @@ ntoskrnl_waittest(obj, increment)
 
 		e = e->nle_flink;
 	}
-
-	return;
 }
 
 /*
@@ -1579,8 +1549,6 @@ ntoskrnl_time(tval)
 	nanotime(&ts);
 	*tval = (uint64_t)ts.tv_nsec / 100 + (uint64_t)ts.tv_sec * 10000000 +
 	    11644473600 * 10000000; /* 100ns ticks from 1601 to 1970 */
-
-	return;
 }
 
 static void
@@ -1666,7 +1634,7 @@ KeWaitForSingleObject(void *arg, uint32_t reason, uint32_t mode,
 	obj = arg;
 
 	if (obj == NULL)
-		return(STATUS_INVALID_PARAMETER);
+		return (STATUS_INVALID_PARAMETER);
 
 	mtx_lock(&ntoskrnl_dispatchlock);
 
@@ -1747,14 +1715,14 @@ KeWaitForSingleObject(void *arg, uint32_t reason, uint32_t mode,
 
 	if (error == EWOULDBLOCK) {
 		mtx_unlock(&ntoskrnl_dispatchlock);
-		return(STATUS_TIMEOUT);
+		return (STATUS_TIMEOUT);
 	}
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 /*
-	return(KeWaitForMultipleObjects(1, &obj, WAITTYPE_ALL, reason,
+	return (KeWaitForMultipleObjects(1, &obj, WAITTYPE_ALL, reason,
 	    mode, alertable, duetime, &w));
 */
 }
@@ -1776,9 +1744,9 @@ KeWaitForMultipleObjects(uint32_t cnt, nt_dispatch_header *obj[], uint32_t wtype
 	wb_ext			we;
 
 	if (cnt > MAX_WAIT_OBJECTS)
-		return(STATUS_INVALID_PARAMETER);
+		return (STATUS_INVALID_PARAMETER);
 	if (cnt > THREAD_WAIT_OBJECTS && wb_array == NULL)
-		return(STATUS_INVALID_PARAMETER);
+		return (STATUS_INVALID_PARAMETER);
 
 	mtx_lock(&ntoskrnl_dispatchlock);
 
@@ -1959,21 +1927,20 @@ wait_done:
 	}
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(status);
+	return (status);
 }
 
 static void
 WRITE_REGISTER_USHORT(uint16_t *reg, uint16_t val)
 {
 	bus_space_write_2(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg, val);
-	return;
 }
 
 static uint16_t
 READ_REGISTER_USHORT(reg)
 	uint16_t		*reg;
 {
-	return(bus_space_read_2(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
+	return (bus_space_read_2(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
 }
 
 static void
@@ -1982,27 +1949,25 @@ WRITE_REGISTER_ULONG(reg, val)
 	uint32_t		val;
 {
 	bus_space_write_4(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg, val);
-	return;
 }
 
 static uint32_t
 READ_REGISTER_ULONG(reg)
 	uint32_t		*reg;
 {
-	return(bus_space_read_4(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
+	return (bus_space_read_4(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
 }
 
 static uint8_t
 READ_REGISTER_UCHAR(uint8_t *reg)
 {
-	return(bus_space_read_1(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
+	return (bus_space_read_1(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg));
 }
 
 static void
 WRITE_REGISTER_UCHAR(uint8_t *reg, uint8_t val)
 {
 	bus_space_write_1(NDIS_BUS_SPACE_MEM, 0x0, (bus_size_t)reg, val);
-	return;
 }
 
 static int64_t
@@ -2090,7 +2055,7 @@ ntoskrnl_pushsl(head, entry)
 	head->slh_list.slh_depth++;
 	head->slh_list.slh_seq++;
 
-	return(oldhead);
+	return (oldhead);
 }
 
 static slist_entry *
@@ -2106,7 +2071,7 @@ ntoskrnl_popsl(head)
 		head->slh_list.slh_seq++;
 	}
 
-	return(first);
+	return (first);
 }
 
 /*
@@ -2129,11 +2094,11 @@ ntoskrnl_findwrap(func)
 	patch = ntoskrnl_functbl;
 	while (patch->ipt_func != NULL) {
 		if ((funcptr)patch->ipt_func == func)
-			return((funcptr)patch->ipt_wrap);
+			return ((funcptr)patch->ipt_wrap);
 		patch++;
 	}
 
-	return(NULL);
+	return (NULL);
 }
 
 static void
@@ -2167,8 +2132,6 @@ ExInitializePagedLookasideList(paged_lookaside_list *lookaside,
 	lookaside->nll_l.gl_type = NonPagedPool;
 	lookaside->nll_l.gl_depth = depth;
 	lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH;
-
-	return;
 }
 
 static void
@@ -2181,8 +2144,6 @@ ExDeletePagedLookasideList(lookaside)
 	freefunc = lookaside->nll_l.gl_freefunc;
 	while((buf = ntoskrnl_popsl(&lookaside->nll_l.gl_listhead)) != NULL)
 		MSCALL1(freefunc, buf);
-
-	return;
 }
 
 static void
@@ -2216,8 +2177,6 @@ ExInitializeNPagedLookasideList(npaged_lookaside_list *lookaside,
 	lookaside->nll_l.gl_type = NonPagedPool;
 	lookaside->nll_l.gl_depth = depth;
 	lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH;
-
-	return;
 }
 
 static void
@@ -2230,8 +2189,6 @@ ExDeleteNPagedLookasideList(lookaside)
 	freefunc = lookaside->nll_l.gl_freefunc;
 	while((buf = ntoskrnl_popsl(&lookaside->nll_l.gl_listhead)) != NULL)
 		MSCALL1(freefunc, buf);
-
-	return;
 }
 
 slist_entry *
@@ -2245,7 +2202,7 @@ InterlockedPushEntrySList(head, entry)
 	oldhead = ntoskrnl_pushsl(head, entry);
 	mtx_unlock_spin(&ntoskrnl_interlock);
 
-	return(oldhead);
+	return (oldhead);
 }
 
 slist_entry *
@@ -2258,7 +2215,7 @@ InterlockedPopEntrySList(head)
 	first = ntoskrnl_popsl(head);
 	mtx_unlock_spin(&ntoskrnl_interlock);
 
-	return(first);
+	return (first);
 }
 
 static slist_entry *
@@ -2267,7 +2224,7 @@ ExInterlockedPushEntrySList(head, entry, lock)
 	slist_entry		*entry;
 	kspin_lock		*lock;
 {
-	return(InterlockedPushEntrySList(head, entry));
+	return (InterlockedPushEntrySList(head, entry));
 }
 
 static slist_entry *
@@ -2275,7 +2232,7 @@ ExInterlockedPopEntrySList(head, lock)
 	slist_header		*head;
 	kspin_lock		*lock;
 {
-	return(InterlockedPopEntrySList(head));
+	return (InterlockedPopEntrySList(head));
 }
 
 uint16_t
@@ -2288,7 +2245,7 @@ ExQueryDepthSList(head)
 	depth = head->slh_list.slh_depth;
 	mtx_unlock_spin(&ntoskrnl_interlock);
 
-	return(depth);
+	return (depth);
 }
 
 void
@@ -2296,8 +2253,6 @@ KeInitializeSpinLock(lock)
 	kspin_lock		*lock;
 {
 	*lock = 0;
-
-	return;
 }
 
 #ifdef __i386__
@@ -2317,8 +2272,6 @@ KefAcquireSpinLockAtDpcLevel(lock)
 			panic("DEADLOCK!");
 #endif
 	}
-
-	return;
 }
 
 void
@@ -2326,8 +2279,6 @@ KefReleaseSpinLockFromDpcLevel(lock)
 	kspin_lock		*lock;
 {
 	atomic_store_rel_int((volatile u_int *)lock, 0);
-
-	return;
 }
 
 uint8_t
@@ -2341,7 +2292,7 @@ KeAcquireSpinLockRaiseToDpc(kspin_lock *lock)
 	KeRaiseIrql(DISPATCH_LEVEL, &oldirql);
 	KeAcquireSpinLockAtDpcLevel(lock);
 
-	return(oldirql);
+	return (oldirql);
 }
 #else
 void
@@ -2349,16 +2300,12 @@ KeAcquireSpinLockAtDpcLevel(kspin_lock *lock)
 {
 	while (atomic_cmpset_acq_int((volatile u_int *)lock, 0, 1) == 0)
 		/* sit and spin */;
-
-	return;
 }
 
 void
 KeReleaseSpinLockFromDpcLevel(kspin_lock *lock)
 {
 	atomic_store_rel_int((volatile u_int *)lock, 0);
-
-	return;
 }
 #endif /* __i386__ */
 
@@ -2374,7 +2321,7 @@ InterlockedExchange(dst, val)
 	*dst = val;
 	mtx_unlock_spin(&ntoskrnl_interlock);
 
-	return(r);
+	return (r);
 }
 
 static uint32_t
@@ -2382,7 +2329,7 @@ InterlockedIncrement(addend)
 	volatile uint32_t	*addend;
 {
 	atomic_add_long((volatile u_long *)addend, 1);
-	return(*addend);
+	return (*addend);
 }
 
 static uint32_t
@@ -2390,7 +2337,7 @@ InterlockedDecrement(addend)
 	volatile uint32_t	*addend;
 {
 	atomic_subtract_long((volatile u_long *)addend, 1);
-	return(*addend);
+	return (*addend);
 }
 
 static void
@@ -2401,8 +2348,6 @@ ExInterlockedAddLargeStatistic(addend, inc)
 	mtx_lock_spin(&ntoskrnl_interlock);
 	*addend += inc;
 	mtx_unlock_spin(&ntoskrnl_interlock);
-
-	return;
 };
 
 mdl *
@@ -2462,8 +2407,6 @@ IoFreeMdl(m)
 		uma_zfree(mdl_zone, m);
 	else
 		ExFreePool(m);
-
-	return;
 }
 
 static void *
@@ -2476,7 +2419,7 @@ MmAllocateContiguousMemory(size, highest)
 
 	addr = ExAllocatePoolWithTag(NonPagedPool, pagelength, 0);
 
-	return(addr);
+	return (addr);
 }
 
 static void *
@@ -2493,7 +2436,7 @@ MmAllocateContiguousMemorySpecifyCache(size, lowest, highest,
 
 	addr = ExAllocatePoolWithTag(NonPagedPool, pagelength, 0);
 
-	return(addr);
+	return (addr);
 }
 
 static void
@@ -2522,7 +2465,7 @@ MmSizeOfMdl(vaddr, len)
 	l = sizeof(struct mdl) +
 	    (sizeof(vm_offset_t *) * SPAN_PAGES(vaddr, len));
 
-	return(l);
+	return (l);
 }
 
 /*
@@ -2551,22 +2494,20 @@ MmBuildMdlForNonPagedPool(m)
 
 	m->mdl_flags |= MDL_SOURCE_IS_NONPAGED_POOL;
 	m->mdl_mappedsystemva = MmGetMdlVirtualAddress(m);
-
-	return;
 }
 
 static void *
 MmMapLockedPages(mdl *buf, uint8_t accessmode)
 {
 	buf->mdl_flags |= MDL_MAPPED_TO_SYSTEM_VA;
-	return(MmGetMdlVirtualAddress(buf));
+	return (MmGetMdlVirtualAddress(buf));
 }
 
 static void *
 MmMapLockedPagesSpecifyCache(mdl *buf, uint8_t accessmode, uint32_t cachetype,
 	void *vaddr, uint32_t bugcheck, uint32_t prio)
 {
-	return(MmMapLockedPages(buf, accessmode));
+	return (MmMapLockedPages(buf, accessmode));
 }
 
 static void
@@ -2575,7 +2516,6 @@ MmUnmapLockedPages(vaddr, buf)
 	mdl			*buf;
 {
 	buf->mdl_flags &= ~MDL_MAPPED_TO_SYSTEM_VA;
-	return;
 }
 
 /*
@@ -2592,9 +2532,9 @@ MmIsAddressValid(vaddr)
 	void			*vaddr;
 {
 	if (pmap_extract(kernel_map->pmap, (vm_offset_t)vaddr))
-		return(TRUE);
+		return (TRUE);
 
-	return(FALSE);
+	return (FALSE);
 }
 
 void *
@@ -2626,13 +2566,13 @@ MmMapIoSpace(paddr, len, cachetype)
 	free(nexus_devs, M_TEMP);
 
 	if (matching_dev == NULL)
-		return(NULL);
+		return (NULL);
 
 	v = (vm_offset_t)rman_get_virtual(res);
 	if (paddr > rman_get_start(res))
 		v += paddr - rman_get_start(res);
 
-	return((void *)v);
+	return ((void *)v);
 }
 
 void
@@ -2640,7 +2580,6 @@ MmUnmapIoSpace(vaddr, len)
 	void			*vaddr;
 	size_t			len;
 {
-	return;
 }
 
 
@@ -2662,7 +2601,7 @@ ntoskrnl_finddev(dev, paddr, res)
 	/* We only want devices that have been successfully probed. */
 
 	if (device_is_alive(dev) == FALSE)
-		return(NULL);
+		return (NULL);
 
 	rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
 	if (rl != NULL) {
@@ -2685,7 +2624,7 @@ ntoskrnl_finddev(dev, paddr, res)
 					bus_activate_resource(dev,
 					    SYS_RES_MEMORY, 0, r);
 				*res = r;
-				return(dev);
+				return (dev);
 			}
 		}
 	}
@@ -2701,7 +2640,7 @@ ntoskrnl_finddev(dev, paddr, res)
 		matching_dev = ntoskrnl_finddev(children[i], paddr, res);
 		if (matching_dev != NULL) {
 			free(children, M_TEMP);
-			return(matching_dev);
+			return (matching_dev);
 		}
 	}
 
@@ -2711,7 +2650,7 @@ ntoskrnl_finddev(dev, paddr, res)
 	if (children != NULL)
 		free(children, M_TEMP);
 
-	return(NULL);
+	return (NULL);
 }
 
 /*
@@ -2782,8 +2721,6 @@ ntoskrnl_destroy_workitem_threads(void)
 		while (kq->kq_exit)
 			tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", hz/10);
 	}
-
-	return;
 }
 
 io_workitem *
@@ -2794,7 +2731,7 @@ IoAllocateWorkItem(dobj)
 
 	iw = uma_zalloc(iw_zone, M_NOWAIT);
 	if (iw == NULL)
-		return(NULL);
+		return (NULL);
 
 	InitializeListHead(&iw->iw_listentry);
 	iw->iw_dobj = dobj;
@@ -2804,7 +2741,7 @@ IoAllocateWorkItem(dobj)
 	WORKIDX_INC(wq_idx);
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(iw);
+	return (iw);
 }
 
 void
@@ -2812,7 +2749,6 @@ IoFreeWorkItem(iw)
 	io_workitem		*iw;
 {
 	uma_zfree(iw_zone, iw);
-	return;
 }
 
 void
@@ -2855,8 +2791,6 @@ IoQueueWorkItem(iw, iw_func, qtype, ctx)
 	KeReleaseSpinLock(&kq->kq_lock, irql);
 
 	KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE);
-
-	return;
 }
 
 static void
@@ -2873,8 +2807,6 @@ ntoskrnl_workitem(dobj, arg)
 	f = (work_item_func)w->wqi_func;
 	uma_zfree(iw_zone, iw);
 	MSCALL2(f, w, w->wqi_ctx);
-
-	return;
 }
 
 /*
@@ -2945,8 +2877,6 @@ ExQueueWorkItem(w, qtype)
 	iw->iw_idx = WORKITEM_LEGACY_THREAD;
 	iwf = (io_workitem_func)ntoskrnl_findwrap((funcptr)ntoskrnl_workitem);
 	IoQueueWorkItem(iw, iwf, qtype, iw);
-
-	return;
 }
 
 static void
@@ -2955,7 +2885,6 @@ RtlZeroMemory(dst, len)
 	size_t			len;
 {
 	bzero(dst, len);
-	return;
 }
 
 static void
@@ -2965,7 +2894,6 @@ RtlCopyMemory(dst, src, len)
 	size_t			len;
 {
 	bcopy(src, dst, len);
-	return;
 }
 
 static size_t
@@ -2984,7 +2912,7 @@ RtlCompareMemory(s1, s2, len)
 		if (m1[i] == m2[i])
 			total++;
 	}
-	return(total);
+	return (total);
 }
 
 void
@@ -3004,8 +2932,6 @@ RtlInitAnsiString(dst, src)
 		a->as_buf = src;
 		a->as_len = a->as_maxlen = strlen(src);
 	}
-
-	return;
 }
 
 void
@@ -3029,8 +2955,6 @@ RtlInitUnicodeString(dst, src)
 		u->us_buf = src;
 		u->us_len = u->us_maxlen = i * 2;
 	}
-
-	return;
 }
 
 ndis_status
@@ -3084,7 +3008,7 @@ RtlUnicodeStringToInteger(ustr, base, val)
 	ntoskrnl_unicode_to_ascii(uchr, astr, len);
 	*val = strtoul(abuf, NULL, base);
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 void
@@ -3095,7 +3019,6 @@ RtlFreeUnicodeString(ustr)
 		return;
 	ExFreePool(ustr->us_buf);
 	ustr->us_buf = NULL;
-	return;
 }
 
 void
@@ -3106,7 +3029,6 @@ RtlFreeAnsiString(astr)
 		return;
 	ExFreePool(astr->as_buf);
 	astr->as_buf = NULL;
-	return;
 }
 
 static int
@@ -3130,7 +3052,7 @@ rand(void)
 
 	microtime(&tv);
 	srandom(tv.tv_usec);
-	return((int)random());
+	return ((int)random());
 }
 
 static void
@@ -3138,15 +3060,14 @@ srand(seed)
 	unsigned int		seed;
 {
 	srandom(seed);
-	return;
 }
 
 static uint8_t
 IoIsWdmVersionAvailable(uint8_t major, uint8_t minor)
 {
 	if (major == WDM_MAJOR && minor == WDM_MINOR_WINXP)
-		return(TRUE);
-	return(FALSE);
+		return (TRUE);
+	return (FALSE);
 }
 
 static ndis_status
@@ -3156,7 +3077,7 @@ IoGetDeviceObjectPointer(name, reqaccess, fileobj, devobj)
 	void			*fileobj;
 	device_object		*devobj;
 {
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static ndis_status
@@ -3179,11 +3100,11 @@ IoGetDeviceProperty(devobj, regprop, buflen, prop, reslen)
 		*reslen = drv->dro_drivername.us_len;
 		break;
 	default:
-		return(STATUS_INVALID_PARAMETER_2);
+		return (STATUS_INVALID_PARAMETER_2);
 		break;
 	}
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static void
@@ -3198,7 +3119,6 @@ KeInitializeMutex(kmutex, level)
 	kmutex->km_header.dh_type = DISP_TYPE_MUTANT;
 	kmutex->km_header.dh_size = sizeof(kmutant) / sizeof(uint32_t);
 	kmutex->km_ownerthread = NULL;
-	return;
 }
 
 static uint32_t
@@ -3210,7 +3130,7 @@ KeReleaseMutex(kmutant *kmutex, uint8_t kwait)
 	prevstate = kmutex->km_header.dh_sigstate;
 	if (kmutex->km_ownerthread != curthread) {
 		mtx_unlock(&ntoskrnl_dispatchlock);
-		return(STATUS_MUTANT_NOT_OWNED);
+		return (STATUS_MUTANT_NOT_OWNED);
 	}
 
 	kmutex->km_header.dh_sigstate++;
@@ -3223,14 +3143,14 @@ KeReleaseMutex(kmutant *kmutex, uint8_t kwait)
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(prevstate);
+	return (prevstate);
 }
 
 static uint32_t
 KeReadStateMutex(kmutex)
 	kmutant			*kmutex;
 {
-	return(kmutex->km_header.dh_sigstate);
+	return (kmutex->km_header.dh_sigstate);
 }
 
 void
@@ -3243,7 +3163,6 @@ KeInitializeEvent(nt_kevent *kevent, uint32_t type, uint8_t state)
 	else
 		kevent->k_header.dh_type = DISP_TYPE_SYNCHRONIZATION_EVENT;
 	kevent->k_header.dh_size = sizeof(nt_kevent) / sizeof(uint32_t);
-	return;
 }
 
 uint32_t
@@ -3257,7 +3176,7 @@ KeResetEvent(kevent)
 	kevent->k_header.dh_sigstate = FALSE;
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(prevstate);
+	return (prevstate);
 }
 
 uint32_t
@@ -3310,7 +3229,7 @@ KeSetEvent(nt_kevent *kevent, uint32_t increment, uint8_t kwait)
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(prevstate);
+	return (prevstate);
 }
 
 void
@@ -3318,14 +3237,13 @@ KeClearEvent(kevent)
 	nt_kevent		*kevent;
 {
 	kevent->k_header.dh_sigstate = FALSE;
-	return;
 }
 
 uint32_t
 KeReadStateEvent(kevent)
 	nt_kevent		*kevent;
 {
-	return(kevent->k_header.dh_sigstate);
+	return (kevent->k_header.dh_sigstate);
 }
 
 /*
@@ -3370,7 +3288,7 @@ ObReferenceObjectByHandle(ndis_handle handle, uint32_t reqaccess, void *otype,
 
 	nr = malloc(sizeof(nt_objref), M_DEVBUF, M_NOWAIT|M_ZERO);
 	if (nr == NULL)
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 
 	InitializeListHead((&nr->no_dh.dh_waitlisthead));
 	nr->no_obj = handle;
@@ -3381,7 +3299,7 @@ ObReferenceObjectByHandle(ndis_handle handle, uint32_t reqaccess, void *otype,
 	TAILQ_INSERT_TAIL(&ntoskrnl_reflist, nr, link);
 	*object = nr;
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static void
@@ -3393,15 +3311,13 @@ ObfDereferenceObject(object)
 	nr = object;
 	TAILQ_REMOVE(&ntoskrnl_reflist, nr, link);
 	free(nr, M_DEVBUF);
-
-	return;
 }
 
 static uint32_t
 ZwClose(handle)
 	ndis_handle		handle;
 {
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static uint32_t
@@ -3412,14 +3328,14 @@ WmiQueryTraceInformation(traceclass, traceinfo, infolen, reqlen, buf)
 	uint32_t		reqlen;
 	void			*buf;
 {
-	return(STATUS_NOT_FOUND);
+	return (STATUS_NOT_FOUND);
 }
 
 static uint32_t
 WmiTraceMessage(uint64_t loghandle, uint32_t messageflags,
 	void *guid, uint16_t messagenum, ...)
 {
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static uint32_t
@@ -3427,7 +3343,7 @@ IoWMIRegistrationControl(dobj, action)
 	device_object		*dobj;
 	uint32_t		action;
 {
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 /*
@@ -3472,7 +3388,7 @@ PsCreateSystemThread(handle, reqaccess, objattrs, phandle,
 
 	tc = malloc(sizeof(thread_context), M_TEMP, M_NOWAIT);
 	if (tc == NULL)
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 
 	tc->tc_thrctx = thrctx;
 	tc->tc_thrfunc = thrfunc;
@@ -3483,13 +3399,13 @@ PsCreateSystemThread(handle, reqaccess, objattrs, phandle,
 
 	if (error) {
 		free(tc, M_TEMP);
-		return(STATUS_INSUFFICIENT_RESOURCES);
+		return (STATUS_INSUFFICIENT_RESOURCES);
 	}
 
 	*handle = p;
 	ntoskrnl_kth++;
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 /*
@@ -3522,7 +3438,7 @@ PsTerminateSystemThread(status)
 	mtx_lock(&Giant);
 #endif
 	kproc_exit(0);
-	return(0);	/* notreached */
+	return (0);	/* notreached */
 }
 
 static uint32_t
@@ -3535,7 +3451,7 @@ DbgPrint(char *fmt, ...)
 		vprintf(fmt, ap);
 	}
 
-	return(STATUS_SUCCESS);
+	return (STATUS_SUCCESS);
 }
 
 static void
@@ -3625,8 +3541,6 @@ ntoskrnl_timercall(arg)
 
 	if (dpc != NULL)
 		KeInsertQueueDpc(dpc, NULL, NULL);
-
-	return;
 }
 
 #ifdef NTOSKRNL_DEBUG_TIMERS
@@ -3661,8 +3575,6 @@ ntoskrnl_show_timers()
 	printf("timer cancels: %qu\n", ntoskrnl_timer_cancels);
 	printf("timer fires: %qu\n", ntoskrnl_timer_fires);
 	printf("\n");
-
-	return;
 }
 #endif
 
@@ -3700,8 +3612,6 @@ ntoskrnl_insert_timer(timer, ticks)
 
 	callout_init(c, CALLOUT_MPSAFE);
 	callout_reset(c, ticks, ntoskrnl_timercall, timer);
-
-	return;
 }
 
 static void
@@ -3716,8 +3626,6 @@ ntoskrnl_remove_timer(timer)
 	mtx_lock_spin(&ntoskrnl_calllock);
 	InsertHeadList((&ntoskrnl_calllist), (&e->ce_list));
 	mtx_unlock_spin(&ntoskrnl_calllock);
-
-	return;
 }
 
 void
@@ -3728,8 +3636,6 @@ KeInitializeTimer(timer)
 		return;
 
 	KeInitializeTimerEx(timer,  EVENT_TYPE_NOTIFY);
-
-	return;
 }
 
 void
@@ -3749,8 +3655,6 @@ KeInitializeTimerEx(timer, type)
 	else
 		timer->k_header.dh_type = DISP_TYPE_SYNCHRONIZATION_TIMER;
 	timer->k_header.dh_size = sizeof(ktimer) / sizeof(uint32_t);
-
-	return;
 }
 
 /*
@@ -3867,8 +3771,6 @@ ntoskrnl_destroy_dpc_threads(void)
 		while (kq->kq_exit)
 			tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", hz/10);
 	}
-
-	return;
 }
 
 static uint8_t
@@ -3883,7 +3785,7 @@ ntoskrnl_insert_dpc(head, dpc)
 	while (l != head) {
 		d = CONTAINING_RECORD(l, kdpc, k_dpclistentry);
 		if (d == dpc)
-			return(FALSE);
+			return (FALSE);
 		l = l->nle_flink;
 	}
 
@@ -3910,8 +3812,6 @@ KeInitializeDpc(dpc, dpcfunc, dpcctx)
 	dpc->k_num = KDPC_CPU_DEFAULT;
 	dpc->k_importance = KDPC_IMPORTANCE_MEDIUM;
 	InitializeListHead((&dpc->k_dpclistentry));
-
-	return;
 }
 
 uint8_t
@@ -3925,7 +3825,7 @@ KeInsertQueueDpc(dpc, sysarg1, sysarg2)
 	uint8_t			irql;
 
 	if (dpc == NULL)
-		return(FALSE);
+		return (FALSE);
 
 	kq = kq_queues;
 
@@ -3954,11 +3854,11 @@ KeInsertQueueDpc(dpc, sysarg1, sysarg2)
 	KeReleaseSpinLock(&kq->kq_lock, irql);
 
 	if (r == FALSE)
-		return(r);
+		return (r);
 
 	KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE);
 
-	return(r);
+	return (r);
 }
 
 uint8_t
@@ -3969,7 +3869,7 @@ KeRemoveQueueDpc(dpc)
 	uint8_t			irql;
 
 	if (dpc == NULL)
-		return(FALSE);
+		return (FALSE);
 
 #ifdef NTOSKRNL_MULTIPLE_DPCS
 	KeRaiseIrql(DISPATCH_LEVEL, &irql);
@@ -3985,7 +3885,7 @@ KeRemoveQueueDpc(dpc)
 	if (dpc->k_dpclistentry.nle_flink == &dpc->k_dpclistentry) {
 		KeReleaseSpinLockFromDpcLevel(&kq->kq_lock);
 		KeLowerIrql(irql);
-		return(FALSE);
+		return (FALSE);
 	}
 
 	RemoveEntryList((&dpc->k_dpclistentry));
@@ -3993,7 +3893,7 @@ KeRemoveQueueDpc(dpc)
 
 	KeReleaseSpinLock(&kq->kq_lock, irql);
 
-	return(TRUE);
+	return (TRUE);
 }
 
 void
@@ -4007,7 +3907,6 @@ KeSetImportanceDpc(dpc, imp)
 		return;
 
 	dpc->k_importance = (uint8_t)imp;
-	return;
 }
 
 void
@@ -4017,7 +3916,6 @@ KeSetTargetProcessorDpc(kdpc *dpc, uint8_t cpu)
 		return;
 
 	dpc->k_num = cpu;
-	return;
 }
 
 void
@@ -4040,14 +3938,12 @@ KeFlushQueuedDpcs(void)
 		KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE);
 		KeWaitForSingleObject(&kq->kq_done, 0, 0, TRUE, NULL);
 	}
-
-	return;
 }
 
 uint32_t
 KeGetCurrentProcessorNumber(void)
 {
-	return((uint32_t)curthread->td_oncpu);
+	return ((uint32_t)curthread->td_oncpu);
 }
 
 uint8_t
@@ -4062,7 +3958,7 @@ KeSetTimerEx(timer, duetime, period, dpc)
 	uint8_t			pending;
 
 	if (timer == NULL)
-		return(FALSE);
+		return (FALSE);
 
 	mtx_lock(&ntoskrnl_dispatchlock);
 
@@ -4104,7 +4000,7 @@ KeSetTimerEx(timer, duetime, period, dpc)
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(pending);
+	return (pending);
 }
 
 uint8_t
@@ -4129,7 +4025,7 @@ KeCancelTimer(timer)
 	uint8_t			pending;
 
 	if (timer == NULL)
-		return(FALSE);
+		return (FALSE);
 
 	mtx_lock(&ntoskrnl_dispatchlock);
 
@@ -4145,14 +4041,14 @@ KeCancelTimer(timer)
 
 	mtx_unlock(&ntoskrnl_dispatchlock);
 
-	return(pending);
+	return (pending);
 }
 
 uint8_t
 KeReadStateTimer(timer)
 	ktimer			*timer;
 {
-	return(timer->k_header.dh_sigstate);
+	return (timer->k_header.dh_sigstate);
 }
 
 static int32_t
@@ -4222,8 +4118,7 @@ KeSetPriorityThread(td, pri)
 static void
 dummy()
 {
-	printf ("ntoskrnl dummy called...\n");
-	return;
+	printf("ntoskrnl dummy called...\n");
 }
 
 
diff --git a/sys/compat/ndis/subr_pe.c b/sys/compat/ndis/subr_pe.c
index 6a347a427eb..fcbaef28acc 100644
--- a/sys/compat/ndis/subr_pe.c
+++ b/sys/compat/ndis/subr_pe.c
@@ -89,7 +89,7 @@ pe_get_dos_header(imgbase, hdr)
 
 	bcopy ((char *)imgbase, (char *)hdr, sizeof(image_dos_header));
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -111,10 +111,10 @@ pe_is_nt_image(imgbase)
 		dos_hdr = (image_dos_header *)imgbase;
 		signature = *(uint32_t *)(imgbase + dos_hdr->idh_lfanew);
 		if (signature == IMAGE_NT_SIGNATURE)
-			return(0);
+			return (0);
 	}
 
-	return(ENOEXEC);
+	return (ENOEXEC);
 }
 
 /*
@@ -132,7 +132,7 @@ pe_get_optional_header(imgbase, hdr)
 	image_nt_header		*nt_hdr;
 
 	if (imgbase == 0 || hdr == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (pe_is_nt_image(imgbase))
 		return (EINVAL);
@@ -143,7 +143,7 @@ pe_get_optional_header(imgbase, hdr)
 	bcopy ((char *)&nt_hdr->inh_optionalhdr, (char *)hdr,
 	    nt_hdr->inh_filehdr.ifh_optionalhdrlen);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -160,7 +160,7 @@ pe_get_file_header(imgbase, hdr)
 	image_nt_header		*nt_hdr;
 
 	if (imgbase == 0 || hdr == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (pe_is_nt_image(imgbase))
 		return (EINVAL);
@@ -179,7 +179,7 @@ pe_get_file_header(imgbase, hdr)
 	bcopy ((char *)&nt_hdr->inh_filehdr, (char *)hdr,
 	    sizeof(image_file_header));
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -197,7 +197,7 @@ pe_get_section_header(imgbase, hdr)
 	image_section_header	*sect_hdr;
 
 	if (imgbase == 0 || hdr == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (pe_is_nt_image(imgbase))
 		return (EINVAL);
@@ -208,7 +208,7 @@ pe_get_section_header(imgbase, hdr)
 
 	bcopy ((char *)sect_hdr, (char *)hdr, sizeof(image_section_header));
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -222,7 +222,7 @@ pe_numsections(imgbase)
 	image_file_header	file_hdr;
 
 	if (pe_get_file_header(imgbase, &file_hdr))
-		return(0);
+		return (0);
 
 	return (file_hdr.ifh_numsections);
 }
@@ -239,7 +239,7 @@ pe_imagebase(imgbase)
 	image_optional_header	optional_hdr;
 
 	if (pe_get_optional_header(imgbase, &optional_hdr))
-		return(0);
+		return (0);
 
 	return (optional_hdr.ioh_imagebase);
 }
@@ -258,14 +258,14 @@ pe_directory_offset(imgbase, diridx)
 	vm_offset_t		dir;
 
 	if (pe_get_optional_header(imgbase, &opt_hdr))
-		return(0);
+		return (0);
 
 	if (diridx >= opt_hdr.ioh_rva_size_cnt)
-		return(0);
+		return (0);
 
 	dir = opt_hdr.ioh_datadir[diridx].idd_vaddr;
 
-	return(pe_translate_addr(imgbase, dir));
+	return (pe_translate_addr(imgbase, dir));
 }
 
 vm_offset_t
@@ -280,7 +280,7 @@ pe_translate_addr(imgbase, rva)
 	int			i = 0, sections, fixedlen;
 
 	if (pe_get_optional_header(imgbase, &opt_hdr))
-		return(0);
+		return (0);
 
 	sections = pe_numsections(imgbase);
 
@@ -310,9 +310,9 @@ pe_translate_addr(imgbase, rva)
 	}
 
 	if (i > sections)
-		return(0);
+		return (0);
 
-	return((vm_offset_t)(imgbase + rva - sect_hdr->ish_vaddr +
+	return ((vm_offset_t)(imgbase + rva - sect_hdr->ish_vaddr +
 	    sect_hdr->ish_rawdataaddr));
 }
 
@@ -335,7 +335,7 @@ pe_get_section(imgbase, hdr, name)
 	int			i, sections;
 
 	if (imgbase == 0 || hdr == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (pe_is_nt_image(imgbase))
 		return (EINVAL);
@@ -350,7 +350,7 @@ pe_get_section(imgbase, hdr, name)
 		if (!strcmp ((char *)§_hdr->ish_name, name)) {
 			bcopy((char *)sect_hdr, (char *)hdr,
 			    sizeof(image_section_header));
-			return(0);
+			return (0);
 		} else
 			sect_hdr++;
 	}
@@ -420,7 +420,7 @@ pe_relocate(imgbase)
 				break;
 
 			default:
-				printf ("[%d]reloc type: %d\n",i,
+				printf("[%d]reloc type: %d\n",i,
 				    IMR_RELTYPE(rel));
 				break;
 			}
@@ -429,7 +429,7 @@ pe_relocate(imgbase)
 		    relhdr->ibr_blocksize);
 	} while (relhdr->ibr_blocksize);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -452,7 +452,7 @@ pe_get_import_descriptor(imgbase, desc, module)
 	char			*modname;
 
 	if (imgbase == 0 || module == NULL || desc == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_IMPORT);
 	if (offset == 0)
@@ -466,7 +466,7 @@ pe_get_import_descriptor(imgbase, desc, module)
 		if (!strncasecmp(module, modname, strlen(module))) {
 			bcopy((char *)imp_desc, (char *)desc,
 			    sizeof(image_import_descriptor));
-			return(0);
+			return (0);
 		}
 		imp_desc++;
 	}
@@ -486,7 +486,7 @@ pe_get_messagetable(imgbase, md)
 	int			i;
 
 	if (imgbase == 0)
-		return(EINVAL);
+		return (EINVAL);
 
 	offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_RESOURCE);
 	if (offset == 0)
@@ -514,10 +514,10 @@ pe_get_messagetable(imgbase, md)
 		    dent2->irde_dataoff);
 		*md = (message_resource_data *)pe_translate_addr(imgbase,
 		    rent->irde_offset);
-		return(0);
+		return (0);
 	}
 
-	return(ENOENT);
+	return (ENOENT);
 }
 
 int
@@ -536,7 +536,7 @@ pe_get_message(imgbase, id, str, len, flags)
 	pe_get_messagetable(imgbase, &md);
 
 	if (md == NULL)
-		return(ENOENT);
+		return (ENOENT);
 
 	mb = (message_resource_block *)((uintptr_t)md +
 	    sizeof(message_resource_data));
@@ -551,12 +551,12 @@ pe_get_message(imgbase, id, str, len, flags)
 			*str = me->mre_text;
 			*len = me->mre_len;
 			*flags = me->mre_flags;
-			return(0);
+			return (0);
 		}
 		mb++;
 	}
 
-	return(ENOENT);
+	return (ENOENT);
 }
 
 /*
@@ -573,16 +573,16 @@ pe_functbl_match(functbl, name)
 	image_patch_table	*p;
 
 	if (functbl == NULL || name == NULL)
-		return(0);
+		return (0);
 
 	p = functbl;
 
 	while (p->ipt_name != NULL) {
 		if (!strcmp(p->ipt_name, name))
-			return((vm_offset_t)p->ipt_wrap);
+			return ((vm_offset_t)p->ipt_wrap);
 		p++;
 	}
-	printf ("no match for %s\n", name);
+	printf("no match for %s\n", name);
 
 	/*
 	 * Return the wrapper pointer for this routine.
@@ -591,7 +591,7 @@ pe_functbl_match(functbl, name)
 	 * that does calling convention translation and
 	 * then invokes the underlying routine.
 	 */
-	return((vm_offset_t)p->ipt_wrap);
+	return ((vm_offset_t)p->ipt_wrap);
 }
 
 /*
@@ -615,10 +615,10 @@ pe_patch_imports(imgbase, module, functbl)
 	vm_offset_t		func;
 
 	if (imgbase == 0 || module == NULL || functbl == NULL)
-		return(EINVAL);
+		return (EINVAL);
 
 	if (pe_get_import_descriptor(imgbase, &imp_desc, module))
-		return(ENOEXEC);
+		return (ENOEXEC);
 
 	nptr = (vm_offset_t *)pe_translate_addr(imgbase,
 	    imp_desc.iid_import_name_table_addr);
@@ -632,11 +632,11 @@ pe_patch_imports(imgbase, module, functbl)
 			*fptr = func;
 #ifdef notdef
 		if (*fptr == 0)
-			return(ENOENT);
+			return (ENOENT);
 #endif
 		nptr++;
 		fptr++;
 	}
 
-	return(0);
+	return (0);
 }
diff --git a/sys/compat/ndis/subr_usbd.c b/sys/compat/ndis/subr_usbd.c
index 1aae8686515..3b38aab7c80 100644
--- a/sys/compat/ndis/subr_usbd.c
+++ b/sys/compat/ndis/subr_usbd.c
@@ -206,7 +206,7 @@ usbd_libinit(void)
 	usbd_driver.dro_dispatch[IRP_MJ_PNP] =
 	    (driver_dispatch)usbd_pnp_wrap;
 
-	return(0);
+	return (0);
 }
 
 int
@@ -230,7 +230,7 @@ usbd_libfini(void)
 
 	free(usbd_driver.dro_drivername.us_buf, M_DEVBUF);
 
-	return(0);
+	return (0);
 }
 
 static int32_t
@@ -589,7 +589,7 @@ usbd_func_selconf(ip)
 		    intf->uii_len);
 	}
 
-	return USBD_STATUS_SUCCESS;
+	return (USBD_STATUS_SUCCESS);
 }
 
 static usb_error_t
@@ -1348,10 +1348,10 @@ USBD_CreateConfigurationRequest(conf, len)
 	    -1, -1, -1, -1, -1);
 	urb = USBD_CreateConfigurationRequestEx(conf, list);
 	if (urb == NULL)
-		return NULL;
+		return (NULL);
 
 	*len = urb->uu_selconf.usc_hdr.uuh_len;
-	return urb;
+	return (urb);
 }
 
 static union usbd_urb *
@@ -1375,7 +1375,7 @@ USBD_CreateConfigurationRequestEx(conf, list)
 
 	selconf = ExAllocatePoolWithTag(NonPagedPool, size, 0);
 	if (selconf == NULL)
-		return NULL;
+		return (NULL);
 	selconf->usc_hdr.uuh_func = URB_FUNCTION_SELECT_CONFIGURATION;
 	selconf->usc_hdr.uuh_len = size;
 	selconf->usc_handle = conf;
@@ -1421,8 +1421,6 @@ USBD_GetUSBDIVersion(ui)
 
 	ui->uvi_usbdi_vers = USBDI_VERSION;
 	ui->uvi_supported_vers = USB_VER_2_0;
-
-	return;
 }
 
 static usb_interface_descriptor_t *
@@ -1473,7 +1471,6 @@ static void
 dummy(void)
 {
 	printf("USBD dummy called\n");
-	return;
 }
 
 image_patch_table usbd_functbl[] = {
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 2c8b32455d7..7651145f6b0 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-
 #include 
 #include 
 #include 
@@ -137,7 +136,6 @@ static void ndis_linksts	(ndis_handle, ndis_status, void *, uint32_t);
 static void ndis_linksts_done	(ndis_handle);
 
 /* We need to wrap these functions for amd64. */
-
 static funcptr ndis_txeof_wrap;
 static funcptr ndis_rxeof_wrap;
 static funcptr ndis_rxeof_eth_wrap;
@@ -210,7 +208,6 @@ static int ndisdrv_loaded = 0;
  * image, and create a Windows driver object which will be
  * saved in our driver database.
  */
-
 int
 ndisdrv_modevent(mod, cmd, arg)
 	module_t		mod;
@@ -299,7 +296,7 @@ ndis_setmulti(sc)
 		error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
 		    &sc->ndis_filter, &len);
 		if (error)
-			device_printf (sc->ndis_dev,
+			device_printf(sc->ndis_dev,
 			    "set allmulti failed: %d\n", error);
 		return;
 	}
@@ -339,7 +336,7 @@ ndis_setmulti(sc)
 	len = len * ETHER_ADDR_LEN;
 	error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len);
 	if (error) {
-		device_printf (sc->ndis_dev, "set mclist failed: %d\n", error);
+		device_printf(sc->ndis_dev, "set mclist failed: %d\n", error);
 		sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
 		sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
 	}
@@ -351,9 +348,7 @@ out:
 	error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
 	    &sc->ndis_filter, &len);
 	if (error)
-		device_printf (sc->ndis_dev, "set multi failed: %d\n", error);
-
-	return;
+		device_printf(sc->ndis_dev, "set multi failed: %d\n", error);
 }
 
 static int
@@ -369,16 +364,16 @@ ndis_set_offload(sc)
 	ifp = sc->ifp;
 
 	if (!NDIS_INITIALIZED(sc))
-		return(EINVAL);
+		return (EINVAL);
 
 	/* See if there's anything to set. */
 
 	error = ndis_probe_offload(sc);
 	if (error)
-		return(error);
+		return (error);
 		
 	if (sc->ndis_hwassist == 0 && ifp->if_capabilities == 0)
-		return(0);
+		return (0);
 
 	len = sizeof(ndis_task_offload_hdr) + sizeof(ndis_task_offload) +
 	    sizeof(ndis_task_tcpip_csum);
@@ -386,7 +381,7 @@ ndis_set_offload(sc)
 	ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
 
 	if (ntoh == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
 	ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
@@ -415,7 +410,7 @@ ndis_set_offload(sc)
 	error = ndis_set_info(sc, OID_TCP_TASK_OFFLOAD, ntoh, &len);
 	free(ntoh, M_TEMP);
 
-	return(error);
+	return (error);
 }
 
 static int
@@ -434,12 +429,12 @@ ndis_probe_offload(sc)
 	error = ndis_get_info(sc, OID_TCP_TASK_OFFLOAD, &dummy, &len);
 
 	if (error != ENOSPC)
-		return(error);
+		return (error);
 
 	ntoh = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
 
 	if (ntoh == NULL)
-		return(ENOMEM);
+		return (ENOMEM);
 
 	ntoh->ntoh_vers = NDIS_TASK_OFFLOAD_VERSION;
 	ntoh->ntoh_len = sizeof(ndis_task_offload_hdr);
@@ -451,12 +446,12 @@ ndis_probe_offload(sc)
 
 	if (error) {
 		free(ntoh, M_TEMP);
-		return(error);
+		return (error);
 	}
 
 	if (ntoh->ntoh_vers != NDIS_TASK_OFFLOAD_VERSION) {
 		free(ntoh, M_TEMP);
-		return(EINVAL);
+		return (EINVAL);
 	}
 
 	nto = (ndis_task_offload *)((char *)ntoh +
@@ -481,7 +476,7 @@ ndis_probe_offload(sc)
 
 	if (nttc == NULL) {
 		free(ntoh, M_TEMP);
-		return(ENOENT);
+		return (ENOENT);
 	}
 
 	sc->ndis_v4tx = nttc->nttc_v4tx;
@@ -505,7 +500,7 @@ ndis_probe_offload(sc)
 		ifp->if_capabilities |= IFCAP_RXCSUM;
 
 	free(ntoh, M_TEMP);
-	return(0);
+	return (0);
 }
 
 static int
@@ -632,7 +627,7 @@ ndis_attach(dev)
 
 	/* Call driver's init routine. */
 	if (ndis_init_nic(sc)) {
-		device_printf (dev, "init handler failed\n");
+		device_printf(dev, "init handler failed\n");
 		error = ENXIO;
 		goto fail;
 	}
@@ -650,7 +645,7 @@ ndis_attach(dev)
 	len = sizeof(sc->ndis_maxpkts);
 	if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS,
 		    &sc->ndis_maxpkts, &len)) {
-		device_printf (dev, "failed to get max TX packets\n");
+		device_printf(dev, "failed to get max TX packets\n");
 		error = ENXIO;
 		goto fail;
 	}
@@ -659,7 +654,6 @@ ndis_attach(dev)
 	 * If this is a deserialized miniport, we don't have
 	 * to honor the OID_GEN_MAXIMUM_SEND_PACKETS result.
 	 */
-
 	if (!NDIS_SERIALIZED(sc->ndis_block))
 		sc->ndis_maxpkts = NDIS_TXPKTS;
 
@@ -698,12 +692,11 @@ ndis_attach(dev)
 	 * supported by this driver. If it is, then this an 802.11
 	 * wireless driver, and we should set up media for wireless.
 	 */
-	for (i = 0; i < sc->ndis_oidcnt; i++) {
+	for (i = 0; i < sc->ndis_oidcnt; i++)
 		if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) {
 			sc->ndis_80211++;
 			break;
 		}
-	}
 
 	if (sc->ndis_80211)
 		ifp = if_alloc(IFT_IEEE80211);
@@ -783,7 +776,7 @@ nonettypes:
 		r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
 		    (void *)rates, &len);
 		if (r)
-			device_printf (dev, "get rates failed: 0x%x\n", r);
+			device_printf(dev, "get rates failed: 0x%x\n", r);
 		/*
 		 * Since the supported rates only up to 8 can be supported,
 		 * if this is not 802.11b we're just going to be faking it
@@ -975,7 +968,7 @@ fail:
 	ndis_halt_nic(sc);
 	DPRINTF(("halting done.\n"));
 
-	return(error);
+	return (error);
 }
 
 static struct ieee80211vap *
@@ -1116,7 +1109,7 @@ ndis_detach(dev)
 	if (sc->ndis_iftype == PCIBus)
 		bus_dma_tag_destroy(sc->ndis_parent_tag);
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1134,7 +1127,7 @@ ndis_suspend(dev)
         	ndis_stop(sc);
 #endif
 
-	return(0);
+	return (0);
 }
 
 int
@@ -1150,7 +1143,7 @@ ndis_resume(dev)
 	if (NDIS_INITIALIZED(sc))
         	ndis_init(sc);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -1160,7 +1153,6 @@ ndis_resume(dev)
  * serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
  * miniports.
  */
- 
 static void
 ndis_rxeof_eth(adapter, ctx, addr, hdr, hdrlen, lookahead, lookaheadlen, pktlen)
 	ndis_handle		adapter;
@@ -1230,8 +1222,6 @@ ndis_rxeof_eth(adapter, ctx, addr, hdr, hdrlen, lookahead, lookaheadlen, pktlen)
 
 	if (!NDIS_SERIALIZED(block))
 		KeReleaseSpinLock(&block->nmb_lock, irql);
-
-	return;
 }
 
 /*
@@ -1239,7 +1229,6 @@ ndis_rxeof_eth(adapter, ctx, addr, hdr, hdrlen, lookahead, lookaheadlen, pktlen)
  * for serialized miniports, or IRQL <= DISPATCH_LEVEL for deserialized
  * miniports.
  */
-
 static void
 ndis_rxeof_done(adapter)
 	ndis_handle		adapter;
@@ -1254,8 +1243,6 @@ ndis_rxeof_done(adapter)
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
 
 	KeInsertQueueDpc(&sc->ndis_rxdpc, NULL, NULL);
-
-	return;
 }
 
 /*
@@ -1330,8 +1317,6 @@ ndis_rxeof_xfr(dpc, adapter, sysarg1, sysarg2)
 	}
 
 	KeReleaseSpinLockFromDpcLevel(&block->nmb_lock);
-
-	return;
 }
 
 /*
@@ -1370,8 +1355,6 @@ ndis_rxeof_xfr_done(adapter, packet, status, len)
 	IoQueueWorkItem(sc->ndis_inputitem,
 	    (io_workitem_func)ndis_inputtask_wrap,
 	    WORKQUEUE_CRITICAL, ifp);
-
-	return;
 }
 /*
  * A frame has been uploaded: pass the resulting mbuf chain up to
@@ -1416,7 +1399,6 @@ ndis_rxeof(adapter, packets, pktcnt)
 	 * before we're completely ready to handle them. If we detect this,
 	 * we need to return them to the miniport and ignore them.
 	 */
-
         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		for (i = 0; i < pktcnt; i++) {
 			p = packets[i];
@@ -1433,7 +1415,7 @@ ndis_rxeof(adapter, packets, pktcnt)
 		/* Stash the softc here so ptom can use it. */
 		p->np_softc = sc;
 		if (ndis_ptom(&m0, p)) {
-			device_printf (sc->ndis_dev, "ptom failed\n");
+			device_printf(sc->ndis_dev, "ptom failed\n");
 			if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS)
 				ndis_return_packet(p, block);
 		} else {
@@ -1498,8 +1480,6 @@ ndis_rxeof(adapter, packets, pktcnt)
 			    WORKQUEUE_CRITICAL, ifp);
 		}
 	}
-
-	return;
 }
 
 /*
@@ -1508,7 +1488,6 @@ ndis_rxeof(adapter, packets, pktcnt)
  * with any locks held (at DISPATCH_LEVEL, we'll be holding the
  * 'dispatch level' per-cpu sleep lock).
  */
-
 static void
 ndis_inputtask(dobj, arg)
 	device_object		*dobj;
@@ -1541,8 +1520,6 @@ ndis_inputtask(dobj, arg)
 		KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
 	}
 	KeReleaseSpinLock(&sc->ndis_rxlock, irql);
-
-	return;
 }
 
 /*
@@ -1591,8 +1568,6 @@ ndis_txeof(adapter, packet, status)
 	IoQueueWorkItem(sc->ndis_startitem,
 	    (io_workitem_func)ndis_starttask_wrap,
 	    WORKQUEUE_CRITICAL, ifp);
-
-	return;
 }
 
 static void
@@ -1633,8 +1608,6 @@ ndis_linksts(adapter, status, sbuf, slen)
 	sc->ndis_evt[sc->ndis_evtpidx].ne_len = slen;
 	NDIS_EVTINC(sc->ndis_evtpidx);
 	NDIS_UNLOCK(sc);
-
-	return;
 }
 
 static void
@@ -1674,8 +1647,6 @@ ndis_linksts_done(adapter)
 	/* Notify possible listners of interface change. */
 
 	rt_ifmsg(ifp);
-
-	return;
 }
 
 static void
@@ -1765,8 +1736,6 @@ ndis_ticktask(d, xsc)
 	}
 
 	NDIS_UNLOCK(sc);
-
-	return;
 }
 
 static void
@@ -1792,8 +1761,6 @@ ndis_map_sclist(arg, segs, nseg, mapsize, error)
 		sclist->nsl_elements[i].nse_addr.np_quad = segs[i].ds_addr;
 		sclist->nsl_elements[i].nse_len = segs[i].ds_len;
 	}
-
-	return;
 }
 
 static int
@@ -1803,7 +1770,7 @@ ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 	/* no support; just discard */
 	m_freem(m);
 	ieee80211_free_node(ni);
-	return 0;
+	return (0);
 }
 
 static void
@@ -1831,7 +1798,6 @@ ndis_starttask(d, arg)
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		ndis_start(ifp);
-	return;
 }
 
 /*
@@ -1846,7 +1812,6 @@ ndis_starttask(d, arg)
  * we need to perform busdma work here. Those that use map registers
  * will do the mapping themselves on a buffer by buffer basis.
  */
-
 static void
 ndis_start(ifp)
 	struct ifnet		*ifp;
@@ -1860,7 +1825,6 @@ ndis_start(ifp)
 	sc = ifp->if_softc;
 
 	NDIS_LOCK(sc);
-
 	if (!sc->ndis_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) {
 		NDIS_UNLOCK(sc);
 		return;
@@ -1933,7 +1897,6 @@ ndis_start(ifp)
 		 * If there's a BPF listener, bounce a copy of this frame
 		 * to him.
 		 */
-
 		if (!sc->ndis_80211)	/* XXX handle 80211 */
 			BPF_MTAP(ifp, m);
 
@@ -1944,7 +1907,6 @@ ndis_start(ifp)
 		 * so the this batch of packets can be transmitted, then
 		 * wait for txeof to ask us to send the rest.
 		 */
-
 		if (sc->ndis_txidx == 0)
 			break;
 	}
@@ -1970,7 +1932,6 @@ ndis_start(ifp)
 	 * a MiniportSend() routine (which sends just a single
 	 * packet).
 	 */
-
 	if (sc->ndis_chars->nmc_sendmulti_func != NULL)
 		ndis_send_packets(sc, p0, pcnt);
 	else
@@ -2029,12 +1990,11 @@ ndis_init(xsc)
 	    &sc->ndis_filter, &len);
 
 	if (error)
-		device_printf (sc->ndis_dev, "set filter failed: %d\n", error);
+		device_printf(sc->ndis_dev, "set filter failed: %d\n", error);
 
 	/*
 	 * Set lookahead.
  	 */
-
 	i = ifp->if_mtu;
 	len = sizeof(i);
 	ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len);
@@ -2091,7 +2051,7 @@ ndis_ifmedia_upd(ifp)
 	if (NDIS_INITIALIZED(sc))
 		ndis_init(sc);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -2105,7 +2065,7 @@ ndis_ifmedia_sts(ifp, ifmr)
 	struct ndis_softc	*sc;
 	uint32_t		media_info;
 	ndis_media_state	linkstate;
-	int			error, len;
+	int			len;
 
 	ifmr->ifm_status = IFM_AVALID;
 	ifmr->ifm_active = IFM_ETHER;
@@ -2115,17 +2075,17 @@ ndis_ifmedia_sts(ifp, ifmr)
 		return;
 
 	len = sizeof(linkstate);
-	error = ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
+	ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS,
 	    (void *)&linkstate, &len);
 
 	len = sizeof(media_info);
-	error = ndis_get_info(sc, OID_GEN_LINK_SPEED,
+	ndis_get_info(sc, OID_GEN_LINK_SPEED,
 	    (void *)&media_info, &len);
 
 	if (linkstate == nmc_connected)
 		ifmr->ifm_status |= IFM_ACTIVE;
 
-	switch(media_info) {
+	switch (media_info) {
 	case 100000:
 		ifmr->ifm_active |= IFM_10_T;
 		break;
@@ -2139,8 +2099,6 @@ ndis_ifmedia_sts(ifp, ifmr)
 		device_printf(sc->ndis_dev, "unknown speed: %d\n", media_info);
 		break;
 	}
-
-	return;
 }
 
 static int
@@ -2158,19 +2116,19 @@ ndis_set_cipher(sc, cipher)
 
 	if (cipher == WPA_CSE_WEP40 || WPA_CSE_WEP104) {
 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP))
-			return(ENOTSUP);
+			return (ENOTSUP);
 		arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
 	}
 
 	if (cipher == WPA_CSE_TKIP) {
 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP))
-			return(ENOTSUP);
+			return (ENOTSUP);
 		arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
 	}
 
 	if (cipher == WPA_CSE_CCMP) {
 		if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM))
-			return(ENOTSUP);
+			return (ENOTSUP);
 		arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
 	}
 
@@ -2179,7 +2137,7 @@ ndis_set_cipher(sc, cipher)
 	rval = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
 
 	if (rval)
-		return(rval);
+		return (rval);
 
 	/* Check that the cipher was set correctly. */
 
@@ -2187,9 +2145,9 @@ ndis_set_cipher(sc, cipher)
 	rval = ndis_get_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
 
 	if (rval != 0 || arg != save)
-		return(ENODEV);
+		return (ENODEV);
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -2200,7 +2158,6 @@ ndis_set_cipher(sc, cipher)
  * of the WPA authentication modes isn't enabled, the driver
  * might not permit the TKIP or AES ciphers to be selected.
  */
-
 static int
 ndis_set_wpa(sc, ie, ielen)
 	struct ndis_softc	*sc;
@@ -2226,7 +2183,7 @@ ndis_set_wpa(sc, ie, ielen)
 	/* Check for the right kind of IE. */
 	if (w->wpa_id != IEEE80211_ELEMID_VENDOR) {
 		DPRINTF(("Incorrect IE type %d\n", w->wpa_id));
-		return(EINVAL);
+		return (EINVAL);
 	}
 
 	/* Skip over the ucast cipher OIDs. */
@@ -2254,7 +2211,7 @@ ndis_set_wpa(sc, ie, ielen)
 	DPRINTF(("Setting WPA auth mode to %d\n", arg));
 	i = sizeof(arg);
 	if (ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i))
-		return(ENOTSUP);
+		return (ENOTSUP);
 	i = sizeof(arg);
 	ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
 
@@ -2264,7 +2221,7 @@ ndis_set_wpa(sc, ie, ielen)
 	n = (struct ndis_ie *)&w->wpa_mcipher[0];
 
 	if (ndis_set_cipher(sc, n->ni_val))
-		return(ENOTSUP);
+		return (ENOTSUP);
 
 	/* Now start looking around for the unicast ciphers. */
 	pos = (char *)&w->wpa_uciphers[0];
@@ -2272,11 +2229,11 @@ ndis_set_wpa(sc, ie, ielen)
 
 	for (i = 0; i < w->wpa_uciphercnt; i++) {
 		if (ndis_set_cipher(sc, n->ni_val))
-			return(ENOTSUP);
+			return (ENOTSUP);
 		n++;
 	}
 
-	return(0);
+	return (0);
 }
 
 static void
@@ -2301,7 +2258,6 @@ ndis_setstate_80211(sc)
 	}
 
 	/* Disassociate and turn off radio. */
-
 	len = sizeof(arg);
 	arg = 1;
 	ndis_set_info(sc, OID_802_11_DISASSOCIATE, &arg, &len);
@@ -2320,7 +2276,6 @@ ndis_setstate_80211(sc)
 		device_printf (sc->ndis_dev, "set infra failed: %d\n", rval);
 
 	/* Set power management */
-
 	len = sizeof(arg);
 	if (vap->iv_flags & IEEE80211_F_PMGTON)
 		arg = NDIS_80211_POWERMODE_FAST_PSP;
@@ -2340,7 +2295,6 @@ ndis_setstate_80211(sc)
 	 * Default encryption mode to off, authentication
 	 * to open and privacy to 'accept everything.'
 	 */
-
 	len = sizeof(arg);
 	arg = NDIS_80211_WEPSTAT_DISABLED;
 	ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &len);
@@ -2350,7 +2304,7 @@ ndis_setstate_80211(sc)
 	ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
 
 	/*
-	 * Note that OID_80211_PRIVACY_FILTER is optional:
+	 * Note that OID_802_11_PRIVACY_FILTER is optional:
 	 * not all drivers implement it.
 	 */
 	len = sizeof(arg);
@@ -2407,7 +2361,6 @@ ndis_setstate_80211(sc)
 	if (rval)
 		device_printf(sc->ndis_dev,
 		    "setting BSSID failed: %d\n", rval);
-
 }
 
 static void
@@ -2465,7 +2418,7 @@ ndis_auth_and_assoc(sc, vap)
 
 	if (vap->iv_flags & IEEE80211_F_PRIVACY &&
 	    !(vap->iv_flags & IEEE80211_F_WPA)) {
-		int			keys_set = 0;
+		int keys_set = 0;
 
 		if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
 			len = sizeof(arg);
@@ -2484,9 +2437,9 @@ ndis_auth_and_assoc(sc, vap)
 
 				/*
 				 * 5, 13 and 16 are the only valid
-				 * only valid key lengths. Anything
-				 * in between will be zero padded out to
-				 * the next highest boundary.
+				 * key lengths. Anything in between
+				 * will be zero padded out to the
+				 * next highest boundary.
 				 */
 				if (vap->iv_nw_keys[i].wk_keylen < 5)
 					wep.nw_keylen = 5;
@@ -2569,7 +2522,7 @@ ndis_auth_and_assoc(sc, vap)
 		rval = ndis_set_info(sc, OID_802_11_NETWORK_TYPE_IN_USE,
 		    &arg, &len);
 		if (rval)
-			device_printf (sc->ndis_dev,
+			device_printf(sc->ndis_dev,
 			    "set nettype failed: %d\n", rval);
 	}
 #endif
@@ -2672,13 +2625,13 @@ ndis_get_assoc(sc, assoc)
 	int			i, len, error;
 
 	if (!sc->ndis_link)
-		return(ENOENT);
+		return (ENOENT);
 
 	len = sizeof(bssid);
 	error = ndis_get_info(sc, OID_802_11_BSSID, &bssid, &len);
 	if (error) {
 		device_printf(sc->ndis_dev, "failed to get bssid\n");
-		return(ENOENT);
+		return (ENOENT);
 	}
 
 	vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -2694,19 +2647,19 @@ ndis_get_assoc(sc, assoc)
 			*assoc = malloc(bs->nwbx_len, M_TEMP, M_NOWAIT);
 			if (*assoc == NULL) {
 				free(bl, M_TEMP);
-				return(ENOMEM);
+				return (ENOMEM);
 			}
 			bcopy((char *)bs, (char *)*assoc, bs->nwbx_len);
 			free(bl, M_TEMP);
 			if (ic->ic_opmode == IEEE80211_M_STA)
 				ni->ni_associd = 1 | 0xc000; /* fake associd */
-			return(0);
+			return (0);
 		}
 		bs = (ndis_wlan_bssid_ex *)((char *)bs + bs->nwbx_len);
 	}
 
 	free(bl, M_TEMP);
-	return(ENOENT);
+	return (ENOENT);
 }
 
 static void
@@ -2746,7 +2699,7 @@ ndis_getstate_80211(sc)
 	len = sizeof(arg);
 	rval = ndis_get_info(sc, OID_GEN_LINK_SPEED, &arg, &len);
 	if (rval)
-		device_printf (sc->ndis_dev, "get link speed failed: %d\n",
+		device_printf(sc->ndis_dev, "get link speed failed: %d\n",
 		    rval);
 	ni->ni_txrate = arg / 5000;
 
@@ -2787,18 +2740,16 @@ ndis_getstate_80211(sc)
 	free(bs, M_TEMP);
 
 	/*
-	 * Determine current authentication mode. Note: authmode
-	 * reporting isn't supported prior to FreeBSD 6.x.
+	 * Determine current authentication mode.
 	 */
-
 	len = sizeof(arg);
 	rval = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &len);
 	if (rval)
-		device_printf (sc->ndis_dev,
+		device_printf(sc->ndis_dev,
 		    "get authmode status failed: %d\n", rval);
 	else {
 		vap->iv_flags &= ~IEEE80211_F_WPA;
-		switch(arg) {
+		switch (arg) {
 		case NDIS_80211_AUTHMODE_OPEN:
 			ni->ni_authmode = IEEE80211_AUTH_OPEN;
 			break;
@@ -2829,14 +2780,13 @@ ndis_getstate_80211(sc)
 	rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len);
 
 	if (rval)
-		device_printf (sc->ndis_dev,
+		device_printf(sc->ndis_dev,
 		    "get wep status failed: %d\n", rval);
 
 	if (arg == NDIS_80211_WEPSTAT_ENABLED)
 		vap->iv_flags |= IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC;
 	else
 		vap->iv_flags &= ~(IEEE80211_F_PRIVACY|IEEE80211_F_DROPUNENC);
-	return;
 }
 
 static int
@@ -2851,7 +2801,7 @@ ndis_ioctl(ifp, command, data)
 
 	/*NDIS_LOCK(sc);*/
 
-	switch(command) {
+	switch (command) {
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
@@ -2922,7 +2872,7 @@ ndis_ioctl_80211(ifp, command, data)
 	void			*oidbuf;
 	int			error = 0;
 
-	switch(command) {
+	switch (command) {
 	case SIOCSIFFLAGS:
 		/*NDIS_LOCK(sc);*/
 		if (ifp->if_flags & IFF_UP) {
@@ -3045,7 +2995,7 @@ ndis_ioctl_80211(ifp, command, data)
 		error = EINVAL;
 		break;
 	}
-	return(error);
+	return (error);
 }
 
 int
@@ -3071,9 +3021,9 @@ ndis_del_key(vap, key)
 	error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len);
 
 	if (error)
-		return(0);
+		return (0);
 
-	return(1);
+	return (1);
 }
 
 /*
@@ -3081,7 +3031,6 @@ ndis_del_key(vap, key)
  * only use it for WPA TKIP or AES keys. These need to be
  * set after initial authentication with the AP.
  */
-
 static int
 ndis_add_key(vap, key, mac)
 	struct ieee80211vap	*vap;
@@ -3159,7 +3108,7 @@ ndis_add_key(vap, key, mac)
 	/* We need to return 1 for success, 0 for failure. */
 
 	if (error)
-		return(0);
+		return (0);
 
 	return (1);
 }
@@ -3173,7 +3122,6 @@ ndis_resettask(d, arg)
 
 	sc = arg;
 	ndis_reset_nic(sc);
-	return;
 }
 
 /*
@@ -3214,8 +3162,6 @@ ndis_stop(sc)
 	sc->ndis_evtcidx = 0;
 	sc->ndis_evtpidx = 0;
 	NDIS_UNLOCK(sc);
-
-	return;
 }
 
 /*
@@ -3230,8 +3176,6 @@ ndis_shutdown(dev)
 
 	sc = device_get_softc(dev);
 	ndis_stop(sc);
-
-	return;
 }
 
 static int
@@ -3426,8 +3370,7 @@ ndis_scan_start(struct ieee80211com *ic)
 		DPRINTF(("%s: set ESSID failed\n", __func__));
 
 	len = 0;
-	error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN,
-	    NULL, &len);
+	error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, NULL, &len);
 	if (error) {
 		DPRINTF(("%s: scan command failed\n", __func__));
 		ieee80211_cancel_scan(vap);
@@ -3460,4 +3403,3 @@ ndis_scan_end(struct ieee80211com *ic)
 {
 	/* ignore */
 }
-
diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c
index be03919cc8a..af5a284f4c0 100644
--- a/sys/dev/if_ndis/if_ndis_usb.c
+++ b/sys/dev/if_ndis/if_ndis_usb.c
@@ -194,9 +194,9 @@ ndisusb_attach(device_t self)
 	}
 
 	if (ndis_attach(self) != 0)
-		return ENXIO;
+		return (ENXIO);
 
-	return 0;
+	return (0);
 }
 
 static int

From ad8b9147e645cbaba8a953fb00bf28e14d48a0a5 Mon Sep 17 00:00:00 2001
From: Remko Lodder 
Date: Mon, 2 Nov 2009 12:03:04 +0000
Subject: [PATCH 456/646] Document the WWWSUPFILE variable.

PR:		137723
Submitted by:	Sofian Brabez 
Approved by:	imp (mentor, implicit)
MFC after:	3 days
Facilitated by:	Snow B.V.
---
 share/man/man5/make.conf.5 | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/share/man/man5/make.conf.5 b/share/man/man5/make.conf.5
index a1428013e26..505af4f7d4a 100644
--- a/share/man/man5/make.conf.5
+++ b/share/man/man5/make.conf.5
@@ -318,6 +318,14 @@ Set this to use
 .Xr cvsup 1
 to update your ports with
 .Dq Li "make update" .
+.It Va WWWSUPFILE
+.Pq Vt str
+The www
+.Ar supfile
+to use when doing a
+.Dq Li "make update"
+This defaults to
+.Pa /usr/share/examples/cvsup/www\-supfile .
 .El
 .Ss "BUILDING THE KERNEL"
 The following list provides a name and short description for variables

From cf6c5eebe7a6f0f1e8b75d249a54989c5fa3bcdc Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 2 Nov 2009 12:35:38 +0000
Subject: [PATCH 457/646] Use our canonical .Dd format.

Submitted by:	Ulrich Spoerlein
---
 bin/getfacl/getfacl.1                           | 2 +-
 lib/libc/gen/posix_spawn.3                      | 2 +-
 lib/libc/gen/posix_spawn_file_actions_addopen.3 | 2 +-
 lib/libc/gen/posix_spawn_file_actions_init.3    | 2 +-
 lib/libc/gen/posix_spawnattr_getflags.3         | 2 +-
 lib/libc/gen/posix_spawnattr_getpgroup.3        | 2 +-
 lib/libc/gen/posix_spawnattr_getschedparam.3    | 2 +-
 lib/libc/gen/posix_spawnattr_getschedpolicy.3   | 2 +-
 lib/libc/gen/posix_spawnattr_getsigdefault.3    | 2 +-
 lib/libc/gen/posix_spawnattr_getsigmask.3       | 2 +-
 lib/libc/gen/posix_spawnattr_init.3             | 2 +-
 lib/libpmc/pmc_attach.3                         | 2 +-
 share/man/man4/tty.4                            | 2 +-
 share/man/man5/ar.5                             | 2 +-
 share/man/man5/msdosfs.5                        | 2 +-
 share/man/man7/adding_user.7                    | 2 +-
 usr.bin/tail/tail.1                             | 2 +-
 usr.sbin/i2c/i2c.8                              | 2 +-
 usr.sbin/nfsd/stablerestart.5                   | 2 +-
 usr.sbin/wake/wake.8                            | 2 +-
 20 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/bin/getfacl/getfacl.1 b/bin/getfacl/getfacl.1
index 58202299f65..e787349336b 100644
--- a/bin/getfacl/getfacl.1
+++ b/bin/getfacl/getfacl.1
@@ -30,7 +30,7 @@
 .\" Developed by the TrustedBSD Project.
 .\" Support for POSIX.1e access control lists.
 .\"
-.Dd September 04, 2009
+.Dd September 4, 2009
 .Dt GETFACL 1
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3
index 518be2e2d75..756923986ff 100644
--- a/lib/libc/gen/posix_spawn.3
+++ b/lib/libc/gen/posix_spawn.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWN 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawn_file_actions_addopen.3 b/lib/libc/gen/posix_spawn_file_actions_addopen.3
index b1fc2595cc7..c6fd017f22d 100644
--- a/lib/libc/gen/posix_spawn_file_actions_addopen.3
+++ b/lib/libc/gen/posix_spawn_file_actions_addopen.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWN_FILE_ACTIONS_ADDOPEN 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawn_file_actions_init.3 b/lib/libc/gen/posix_spawn_file_actions_init.3
index 31b677e0976..d826b8bf445 100644
--- a/lib/libc/gen/posix_spawn_file_actions_init.3
+++ b/lib/libc/gen/posix_spawn_file_actions_init.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWN_FILE_ACTIONS_INIT 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getflags.3 b/lib/libc/gen/posix_spawnattr_getflags.3
index c3f9ee547f1..a2dda02c128 100644
--- a/lib/libc/gen/posix_spawnattr_getflags.3
+++ b/lib/libc/gen/posix_spawnattr_getflags.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETFLAGS 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getpgroup.3 b/lib/libc/gen/posix_spawnattr_getpgroup.3
index 8ba8142037f..5cd51d687ab 100644
--- a/lib/libc/gen/posix_spawnattr_getpgroup.3
+++ b/lib/libc/gen/posix_spawnattr_getpgroup.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETPGROUP 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getschedparam.3 b/lib/libc/gen/posix_spawnattr_getschedparam.3
index 59cece893c0..70009b9b409 100644
--- a/lib/libc/gen/posix_spawnattr_getschedparam.3
+++ b/lib/libc/gen/posix_spawnattr_getschedparam.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETSCHEDPARAM 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getschedpolicy.3 b/lib/libc/gen/posix_spawnattr_getschedpolicy.3
index 158923a0634..45c1965408b 100644
--- a/lib/libc/gen/posix_spawnattr_getschedpolicy.3
+++ b/lib/libc/gen/posix_spawnattr_getschedpolicy.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETSCHEDPOLICY 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getsigdefault.3 b/lib/libc/gen/posix_spawnattr_getsigdefault.3
index f37992a594f..9e13c3742cf 100644
--- a/lib/libc/gen/posix_spawnattr_getsigdefault.3
+++ b/lib/libc/gen/posix_spawnattr_getsigdefault.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETSIGDEFAULT 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_getsigmask.3 b/lib/libc/gen/posix_spawnattr_getsigmask.3
index 44b5c176120..5cee7ec6853 100644
--- a/lib/libc/gen/posix_spawnattr_getsigmask.3
+++ b/lib/libc/gen/posix_spawnattr_getsigmask.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_GETSIGMASK 3
 .Os
 .Sh NAME
diff --git a/lib/libc/gen/posix_spawnattr_init.3 b/lib/libc/gen/posix_spawnattr_init.3
index 7eddc750acc..66c99cd5afa 100644
--- a/lib/libc/gen/posix_spawnattr_init.3
+++ b/lib/libc/gen/posix_spawnattr_init.3
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Mar 24, 2008
+.Dd March 24, 2008
 .Dt POSIX_SPAWNATTR_INIT 3
 .Os
 .Sh NAME
diff --git a/lib/libpmc/pmc_attach.3 b/lib/libpmc/pmc_attach.3
index 62b0be6b089..be340a77598 100644
--- a/lib/libpmc/pmc_attach.3
+++ b/lib/libpmc/pmc_attach.3
@@ -23,7 +23,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 25 2007
+.Dd November 25, 2007
 .Os
 .Dt PMC_ATTACH 3
 .Sh NAME
diff --git a/share/man/man4/tty.4 b/share/man/man4/tty.4
index ba0379eb09a..6e8cd8ee329 100644
--- a/share/man/man4/tty.4
+++ b/share/man/man4/tty.4
@@ -32,7 +32,7 @@
 .\"     @(#)tty.4	8.3 (Berkeley) 4/19/94
 .\" $FreeBSD$
 .\"
-.Dd Jun 27, 2007
+.Dd June 27, 2007
 .Dt TTY 4
 .Os
 .Sh NAME
diff --git a/share/man/man5/ar.5 b/share/man/man5/ar.5
index 1796795398d..58d2d788701 100644
--- a/share/man/man5/ar.5
+++ b/share/man/man5/ar.5
@@ -23,7 +23,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 07, 2007
+.Dd September 7, 2007
 .Os
 .Dt AR 5
 .Sh NAME
diff --git a/share/man/man5/msdosfs.5 b/share/man/man5/msdosfs.5
index 9dd679c1b0c..933577aeb5a 100644
--- a/share/man/man5/msdosfs.5
+++ b/share/man/man5/msdosfs.5
@@ -2,7 +2,7 @@
 .\" Written by Tom Rhodes
 .\" This file is in the public domain.
 .\"
-.Dd Aug 22, 2007
+.Dd August 22, 2007
 .Dt MSDOSFS 5
 .Os
 .Sh NAME
diff --git a/share/man/man7/adding_user.7 b/share/man/man7/adding_user.7
index 1b467714a37..499bd481615 100644
--- a/share/man/man7/adding_user.7
+++ b/share/man/man7/adding_user.7
@@ -32,7 +32,7 @@
 .\"     @(#)adduser.8	8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd Jan 30, 2009
+.Dd January 30, 2009
 .Dt ADDING_USER 8
 .Os
 .Sh NAME
diff --git a/usr.bin/tail/tail.1 b/usr.bin/tail/tail.1
index 7f91e715951..5e382e91b17 100644
--- a/usr.bin/tail/tail.1
+++ b/usr.bin/tail/tail.1
@@ -35,7 +35,7 @@
 .\"	@(#)tail.1	8.1 (Berkeley) 6/6/93
 .\" $FreeBSD$
 .\"
-.Dd June 05, 2009
+.Dd June 5, 2009
 .Dt TAIL 1
 .Os
 .Sh NAME
diff --git a/usr.sbin/i2c/i2c.8 b/usr.sbin/i2c/i2c.8
index 0067be79648..e2bea3c4fe9 100644
--- a/usr.sbin/i2c/i2c.8
+++ b/usr.sbin/i2c/i2c.8
@@ -26,7 +26,7 @@
 .\" $FreeBSD$ 
 .\"
 
-.Dd Jan 23, 2009
+.Dd January 23, 2009
 .Dt I2C 8
 .Os
 .Sh NAME
diff --git a/usr.sbin/nfsd/stablerestart.5 b/usr.sbin/nfsd/stablerestart.5
index c469835fc0d..8499986056e 100644
--- a/usr.sbin/nfsd/stablerestart.5
+++ b/usr.sbin/nfsd/stablerestart.5
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Sept 7, 2007
+.Dd September 7, 2007
 .Dt STABLERESTART 5
 .Os
 .Sh NAME
diff --git a/usr.sbin/wake/wake.8 b/usr.sbin/wake/wake.8
index 03a283b19cc..bc508da3364 100644
--- a/usr.sbin/wake/wake.8
+++ b/usr.sbin/wake/wake.8
@@ -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.
 .\"
-.Dd June 27 2009
+.Dd June 27, 2009
 .Dt WAKE 8
 .Os
 .Sh NAME

From 8a9c731f13d57ce21118e71fef17fe56b9aa988a Mon Sep 17 00:00:00 2001
From: Ivan Voras 
Date: Mon, 2 Nov 2009 16:56:59 +0000
Subject: [PATCH 458/646] Add sysctl documentation strings. The descriptions
 are derived from tuning(7). One of the descriptions references tuning(7)
 because it is too complex to adequatly describe here (it is not a simple
 boolean sysctl) and users should be warned to that.

Reviewed by:	alc, kib
Approved by:	gnn (mentor)
---
 sys/vm/swap_pager.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 229dac8585b..ef64b31ae09 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -155,11 +155,15 @@ int swap_pager_avail;
 static int swdev_syscall_active = 0; /* serialize swap(on|off) */
 
 static vm_ooffset_t swap_total;
-SYSCTL_QUAD(_vm, OID_AUTO, swap_total, CTLFLAG_RD, &swap_total, 0, "");
+SYSCTL_QUAD(_vm, OID_AUTO, swap_total, CTLFLAG_RD, &swap_total, 0, 
+    "Total amount of available swap storage.");
 static vm_ooffset_t swap_reserved;
-SYSCTL_QUAD(_vm, OID_AUTO, swap_reserved, CTLFLAG_RD, &swap_reserved, 0, "");
+SYSCTL_QUAD(_vm, OID_AUTO, swap_reserved, CTLFLAG_RD, &swap_reserved, 0, 
+    "Amount of swap storage needed to back all allocated anonymous memory.");
 static int overcommit = 0;
-SYSCTL_INT(_vm, OID_AUTO, overcommit, CTLFLAG_RW, &overcommit, 0, "");
+SYSCTL_INT(_vm, OID_AUTO, overcommit, CTLFLAG_RW, &overcommit, 0, 
+    "Configure virtual memory overcommit behavior. See tuning(7) "
+    "for details.");
 
 /* bits from overcommit */
 #define	SWAP_RESERVE_FORCE_ON		(1 << 0)

From 2fafce9e4c2d533b8e36eb78556f1017092939bc Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Mon, 2 Nov 2009 17:45:39 +0000
Subject: [PATCH 459/646] Avoid pointless calls to pmap_protect().

Reviewed by:	kib
---
 sys/vm/vm_map.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 06ae63e622b..414d4e6378e 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1914,10 +1914,10 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
 		}
 
 		/*
-		 * Update physical map if necessary. Worry about copy-on-write
-		 * here.
+		 * When restricting access, update the physical map.  Worry
+		 * about copy-on-write here.
 		 */
-		if (current->protection != old_prot) {
+		if ((old_prot & ~current->protection) != 0) {
 #define MASK(entry)	(((entry)->eflags & MAP_ENTRY_COW) ? ~VM_PROT_WRITE : \
 							VM_PROT_ALL)
 			pmap_protect(map->pmap, current->start,

From bb08f033189b9df79b2a329f5bc1fae938e0900e Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Mon, 2 Nov 2009 18:15:11 +0000
Subject: [PATCH 460/646] Add BCM5761 PHY id.

---
 sys/dev/mii/brgphy.c | 1 +
 sys/dev/mii/miidevs  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 8884354f90b..3e3c9504391 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -134,6 +134,7 @@ static const struct mii_phydesc brgphys[] = {
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
+	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
 	MII_PHY_DESC(BROADCOM2, BCM5906),
 	MII_PHY_END
 };
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index 801c6a8971d..f3aa2e9999b 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -154,6 +154,7 @@ model xxBROADCOM_ALT1 BCM5708S	0x0015 BCM5708S 1000/2500BaseSX PHY
 model xxBROADCOM_ALT1 BCM5709CAX	0x002c BCM5709C(AX) 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5722	0x002d BCM5722 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5709C	0x003c BCM5709C 10/100/1000baseTX PHY
+model xxBROADCOM_ALT1 BCM5761	0x003d BCM5761 10/100/1000baseTX PHY
 model BROADCOM2 BCM5906		0x0004 BCM5906 10/100baseTX PHY
 
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */

From 5b6d1d9d08ad0f872f2932f030bcf01132efa75d Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Mon, 2 Nov 2009 18:35:05 +0000
Subject: [PATCH 461/646] Add a check to know whether driver is still running
 after reacquiring driver lock in Rx handler. re(4) drops a driver lock before
 passing received frame to upper stack and reacquire the lock. During the time
 window ioctl calls could be executed and if the ioctl was interface down
 request, driver will stop the controller and free allocated mbufs. After that
 when driver comes back to Rx handler again it does not know what was happend
 so it could access free mbufs which in turn cause panic.

Reported by:	 Norbert Papke < npapk <> acm dot org >
Tested by:	 Norbert Papke < npapk <> acm dot org >
---
 sys/dev/re/if_re.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 5a5790d0c25..25d189b7982 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -1817,6 +1817,8 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
 
 	for (i = sc->rl_ldata.rl_rx_prodidx; maxpkt > 0;
 	    i = RL_RX_DESC_NXT(sc, i)) {
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+			break;
 		cur_rx = &sc->rl_ldata.rl_rx_list[i];
 		rxstat = le32toh(cur_rx->rl_cmdstat);
 		if ((rxstat & RL_RDESC_STAT_OWN) != 0)

From f8b8dab2ebcd449d53cb195a549392d534c3f131 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Mon, 2 Nov 2009 18:51:24 +0000
Subject: [PATCH 462/646] Fix a non-style change that snuck in.

Spotted by: danfe
---
 sys/compat/ndis/kern_ndis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index f4d4b3aa05a..62bb465899d 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -1200,7 +1200,7 @@ ndis_init_nic(arg)
 		NDIS_LOCK(sc);
 		sc->ndis_block->nmb_miniportadapterctx = NULL;
 		NDIS_UNLOCK(sc);
-		return (status);
+		return (ENXIO);
 	}
 
 	/*

From 99844cbf6510dd4fd7bd5471da93e5e6cff3c6ba Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 2 Nov 2009 19:02:31 +0000
Subject: [PATCH 463/646] Add IDs for nVidia MCP65/77/79/89 SATA conntrollers.

---
 sys/dev/ata/ata-pci.h             | 46 ++++++++++++++++++++++++++++++-
 sys/dev/ata/chipsets/ata-nvidia.c | 44 +++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 7a6ed42f0c9..7d7a08eb520 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -260,6 +260,15 @@ struct ata_pci_controller {
 #define ATA_NFORCE_MCP61_S2     0x03f610de
 #define ATA_NFORCE_MCP61_S3     0x03f710de
 #define ATA_NFORCE_MCP65        0x044810de
+#define ATA_NFORCE_MCP65_A0     0x044c10de
+#define ATA_NFORCE_MCP65_A1     0x044d10de
+#define ATA_NFORCE_MCP65_A2     0x044e10de
+#define ATA_NFORCE_MCP65_A3     0x044f10de
+#define ATA_NFORCE_MCP65_A4     0x045c10de
+#define ATA_NFORCE_MCP65_A5     0x045d10de
+#define ATA_NFORCE_MCP65_A6     0x045e10de
+#define ATA_NFORCE_MCP65_A7     0x045f10de
+#define ATA_NFORCE_MCP67        0x056010de
 #define ATA_NFORCE_MCP67_A0     0x055010de
 #define ATA_NFORCE_MCP67_A1     0x055110de
 #define ATA_NFORCE_MCP67_A2     0x055210de
@@ -273,7 +282,6 @@ struct ata_pci_controller {
 #define ATA_NFORCE_MCP67_AA     0x055A10de
 #define ATA_NFORCE_MCP67_AB     0x055B10de
 #define ATA_NFORCE_MCP67_AC     0x058410de
-#define ATA_NFORCE_MCP67        0x056010de
 #define ATA_NFORCE_MCP73        0x056c10de
 #define ATA_NFORCE_MCP73_A0     0x07f010de
 #define ATA_NFORCE_MCP73_A1     0x07f110de
@@ -288,6 +296,42 @@ struct ata_pci_controller {
 #define ATA_NFORCE_MCP73_AA     0x07fa10de
 #define ATA_NFORCE_MCP73_AB     0x07fb10de
 #define ATA_NFORCE_MCP77        0x075910de
+#define ATA_NFORCE_MCP77_A0     0x0ad010de
+#define ATA_NFORCE_MCP77_A1     0x0ad110de
+#define ATA_NFORCE_MCP77_A2     0x0ad210de
+#define ATA_NFORCE_MCP77_A3     0x0ad310de
+#define ATA_NFORCE_MCP77_A4     0x0ad410de
+#define ATA_NFORCE_MCP77_A5     0x0ad510de
+#define ATA_NFORCE_MCP77_A6     0x0ad610de
+#define ATA_NFORCE_MCP77_A7     0x0ad710de
+#define ATA_NFORCE_MCP77_A8     0x0ad810de
+#define ATA_NFORCE_MCP77_A9     0x0ad910de
+#define ATA_NFORCE_MCP77_AA     0x0ada10de
+#define ATA_NFORCE_MCP77_AB     0x0adb10de
+#define ATA_NFORCE_MCP79_A0     0x0ab410de
+#define ATA_NFORCE_MCP79_A1     0x0ab510de
+#define ATA_NFORCE_MCP79_A2     0x0ab610de
+#define ATA_NFORCE_MCP79_A3     0x0ab710de
+#define ATA_NFORCE_MCP79_A4     0x0ab810de
+#define ATA_NFORCE_MCP79_A5     0x0ab910de
+#define ATA_NFORCE_MCP79_A6     0x0aba10de
+#define ATA_NFORCE_MCP79_A7     0x0abb10de
+#define ATA_NFORCE_MCP79_A8     0x0abc10de
+#define ATA_NFORCE_MCP79_A9     0x0abd10de
+#define ATA_NFORCE_MCP79_AA     0x0abe10de
+#define ATA_NFORCE_MCP79_AB     0x0abf10de
+#define ATA_NFORCE_MCP89_A0     0x0d8410de
+#define ATA_NFORCE_MCP89_A1     0x0d8510de
+#define ATA_NFORCE_MCP89_A2     0x0d8610de
+#define ATA_NFORCE_MCP89_A3     0x0d8710de
+#define ATA_NFORCE_MCP89_A4     0x0d8810de
+#define ATA_NFORCE_MCP89_A5     0x0d8910de
+#define ATA_NFORCE_MCP89_A6     0x0d8a10de
+#define ATA_NFORCE_MCP89_A7     0x0d8b10de
+#define ATA_NFORCE_MCP89_A8     0x0d8c10de
+#define ATA_NFORCE_MCP89_A9     0x0d8d10de
+#define ATA_NFORCE_MCP89_AA     0x0d8e10de
+#define ATA_NFORCE_MCP89_AB     0x0d8f10de
 
 #define ATA_PROMISE_ID          0x105a
 #define ATA_PDC20246            0x4d33105a
diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index bb763161d5b..cdff8259876 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -97,6 +97,14 @@ ata_nvidia_probe(device_t dev)
      { ATA_NFORCE_MCP61_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
      { ATA_NFORCE_MCP61_S3, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
      { ATA_NFORCE_MCP65,    0, 0,       0, ATA_UDMA6, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
+     { ATA_NFORCE_MCP65_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
      { ATA_NFORCE_MCP67,    0, 0,       0, ATA_UDMA6, "nForce MCP67" },
      { ATA_NFORCE_MCP67_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
      { ATA_NFORCE_MCP67_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
@@ -125,6 +133,42 @@ ata_nvidia_probe(device_t dev)
      { ATA_NFORCE_MCP73_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
      { ATA_NFORCE_MCP73_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
      { ATA_NFORCE_MCP77,    0, 0,       0, ATA_UDMA6, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP77_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
+     { ATA_NFORCE_MCP79_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP79_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
+     { ATA_NFORCE_MCP89_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
+     { ATA_NFORCE_MCP89_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
      { 0, 0, 0, 0, 0, 0}} ;
 
     if (pci_get_vendor(dev) != ATA_NVIDIA_ID)

From 060ed74b533653b09e4718d407b0dc2449637756 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Mon, 2 Nov 2009 19:13:12 +0000
Subject: [PATCH 464/646] Revert a functional change that snuck in.

---
 sys/compat/ndis/subr_ndis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index 6f2b57dd3b4..558398d7167 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -1246,7 +1246,7 @@ NdisMQueryAdapterResources(status, adapter, list, buflen)
 {
 	ndis_miniport_block	*block;
 	struct ndis_softc	*sc;
-	uint32_t		rsclen;
+	int			rsclen;
 
 	block = (ndis_miniport_block *)adapter;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);

From 5ef5fd6e5397eb7583f2b238bad50de0f97b8301 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 2 Nov 2009 20:18:50 +0000
Subject: [PATCH 465/646] Ensure 'kvm' is always initialized.  If "-M" was not
 specified and the garbage value on the stack was not zero, then 'ddb capture'
 would try to use the garbage value as a kvm_t pointer.

MFC after:	1 week
---
 sbin/ddb/ddb_capture.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sbin/ddb/ddb_capture.c b/sbin/ddb/ddb_capture.c
index ffc9b91552d..370fc0058ba 100644
--- a/sbin/ddb/ddb_capture.c
+++ b/sbin/ddb/ddb_capture.c
@@ -204,6 +204,7 @@ ddb_capture(int argc, char *argv[])
 
 	mflag = NULL;
 	nflag = NULL;
+	kvm = NULL;
 	while ((ch = getopt(argc, argv, "M:N:")) != -1) {
 		switch (ch) {
 		case 'M':

From 0bd051b8696b2d7afb53437cb5934128294de862 Mon Sep 17 00:00:00 2001
From: Matt Jacob 
Date: Mon, 2 Nov 2009 21:22:30 +0000
Subject: [PATCH 466/646] Unbreak SBus cards which have been broken
 (apparently) for a while. Most of the pieces came from Marius- correct
 settings for channels and resource management. The one piece missing was that
 you cannot for SBus cards replace 32 bit operations with A64 operations- not
 supported.

Submitted by:	marius
MFC after:	3 days
---
 sys/dev/isp/isp_sbus.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index af7cb88d602..a50d0f20ed8 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -193,6 +193,8 @@ isp_sbus_attach(device_t dev)
 	isp->isp_param = &sbs->sbus_param;
 	isp->isp_osinfo.pc.ptr = &sbs->sbus_spi;
 	isp->isp_revision = 0;	/* XXX */
+	isp->isp_dev = dev;
+	isp->isp_nchan = 1;
 	ISP_SET_PC(isp, 0, role, role);
 
 	/*
@@ -316,18 +318,16 @@ isp_sbus_attach(device_t dev)
 		goto bad;
 	}
 	isp_init(isp);
-	if (role != ISP_ROLE_NONE && isp->isp_state != ISP_INITSTATE) {
-		isp_uninit(isp);
-		ISP_UNLOCK(isp);
-		goto bad;
-	}
-	isp_attach(isp);
-	if (role != ISP_ROLE_NONE && isp->isp_state != ISP_RUNSTATE) {
-		isp_uninit(isp);
-		ISP_UNLOCK(isp);
-		goto bad;
+	if (isp->isp_state == ISP_INITSTATE) {
+		isp->isp_state = ISP_RUNSTATE;
 	}
 	ISP_UNLOCK(isp);
+	if (isp_attach(isp)) {
+		ISP_LOCK(isp);
+		isp_uninit(isp);
+		ISP_UNLOCK(isp);
+		goto bad;
+	}
 	return (0);
 
 bad:
@@ -345,13 +345,10 @@ bad:
 	}
 
 	if (regs) {
-		(void) bus_release_resource(dev, 0, 0, regs);
+		(void) bus_release_resource(dev, SYS_RES_MEMORY, 0, regs);
 	}
 
 	if (sbs) {
-		if (sbs->sbus_isp.isp_param) {
-			free(sbs->sbus_isp.isp_param, M_DEVBUF);
-		}
 		free(sbs, M_DEVBUF);
 	}
 	return (ENXIO);
@@ -584,13 +581,6 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	isp = mp->isp;
 	rq = mp->rq;
 	if (nseg) {
-		if (sizeof (bus_addr_t) > 4) {
-			if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
-				rq->req_header.rqs_entry_type = RQSTYPE_T3RQS;
-			} else if (rq->req_header.rqs_entry_type == RQSTYPE_REQUEST) {
-				rq->req_header.rqs_entry_type = RQSTYPE_A64;
-			}
-		}
 		if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 			bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD);
 			ddir = ISP_FROM_DEVICE;

From e98bf236189933d5fb70fcbfbe4b0279ee56a8f8 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Mon, 2 Nov 2009 21:39:45 +0000
Subject: [PATCH 467/646] Vendor import of tzdata2009q:

- New region: Asia/Novokuznetsk
- Kemerovo oblast' (Kemerovo region) in Russia will change current
  time zone on 29 March 2010
- Add historical data for Hongkong 1941 - 1980
- Syria will go to winter time in the last weekend of October 2009.

Obtained from:	ftp://elsie.nci.nih.gov/pub/
---
 asia     | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 europe   | 38 ++++++++++++++++++++--
 zone.tab |  3 +-
 3 files changed, 130 insertions(+), 10 deletions(-)

diff --git a/asia b/asia
index 7f063cb4bff..1987fc815ba 100644
--- a/asia
+++ b/asia
@@ -1,5 +1,4 @@
-# 
-# @(#)asia	8.42
+# @(#)asia	8.44
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -369,14 +368,84 @@ Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
 			5:00	-	KAST	1980 May
 			8:00	PRC	C%sT
 
+
+# From Lee Yiu Chung (2009-10-24):
+# I found there are some mistakes for the historial DST rule for Hong
+# Kong. Accoring to the DST record from Hong Kong Observatory (actually,
+# it is not [an] observatory, but the official meteorological agency of HK,
+# and also serves as the official timing agency), there are some missing
+# and incorrect rules. Although the exact switch over time is missing, I
+# think 3:30 is correct. The official DST record for Hong Kong can be
+# obtained from
+# 
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# .
+
+# From Arthur David Olson (2009-10-28):
+# Here are the dates given at
+# 
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# 
+# as of 2009-10-28:
+# Year        Period
+# 1941        1 Apr to 30 Sep
+# 1942        Whole year 
+# 1943        Whole year
+# 1944        Whole year
+# 1945        Whole year
+# 1946        20 Apr to 1 Dec
+# 1947        13 Apr to 30 Dec
+# 1948        2 May to 31 Oct
+# 1949        3 Apr to 30 Oct
+# 1950        2 Apr to 29 Oct
+# 1951        1 Apr to 28 Oct
+# 1952        6 Apr to 25 Oct
+# 1953        5 Apr to 1 Nov
+# 1954        21 Mar to 31 Oct
+# 1955        20 Mar to 6 Nov
+# 1956        18 Mar to 4 Nov
+# 1957        24 Mar to 3 Nov
+# 1958        23 Mar to 2 Nov
+# 1959        22 Mar to 1 Nov
+# 1960        20 Mar to 6 Nov
+# 1961        19 Mar to 5 Nov
+# 1962        18 Mar to 4 Nov
+# 1963        24 Mar to 3 Nov
+# 1964        22 Mar to 1 Nov
+# 1965        18 Apr to 17 Oct
+# 1966        17 Apr to 16 Oct
+# 1967        16 Apr to 22 Oct
+# 1968        21 Apr to 20 Oct
+# 1969        20 Apr to 19 Oct
+# 1970        19 Apr to 18 Oct
+# 1971        18 Apr to 17 Oct
+# 1972        16 Apr to 22 Oct
+# 1973        22 Apr to 21 Oct
+# 1973/74     30 Dec 73 to 20 Oct 74
+# 1975        20 Apr to 19 Oct
+# 1976        18 Apr to 17 Oct
+# 1977        Nil
+# 1978        Nil
+# 1979        13 May to 21 Oct
+# 1980 to Now Nil
+# The page does not give start or end times of day.
+# The page does not give a start date for 1942.
+# The page does not givw an end date for 1945.
+# The Japanese occupation of Hong Kong began on 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-15.
+# For lack of anything better, use start of those days as the transition times.
+
 # Hong Kong (Xianggang)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
+Rule	HK	1941	only	-	Sep	30	3:30	0	-
 Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
 Rule	HK	1946	only	-	Dec	1	3:30	0	-
 Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
 Rule	HK	1947	only	-	Dec	30	3:30	0	-
 Rule	HK	1948	only	-	May	2	3:30	1:00	S
-Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
+Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
+Rule	HK	1952	only	-	Oct	25	3:30	0	-
 Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
 Rule	HK	1953	only	-	Nov	1	3:30	0	-
 Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
@@ -384,13 +453,15 @@ Rule	HK	1954	only	-	Oct	31	3:30	0	-
 Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
 Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
 Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
-Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
-Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
+Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT	1941 Dec 25
+			9:00	-	JST	1945 Sep 15
 			8:00	HK	HK%sT
 
-
 ###############################################################################
 
 # Taiwan
@@ -2236,9 +2307,23 @@ Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
 # http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
 # 
 
+# From Steffen Thorsen (2009-10-27):
+# The Syrian Arab News Network on 2009-09-29 reported that Syria will 
+# revert back to winter (standard) time on midnight between Thursday 
+# 2009-10-29 and Friday 2009-10-30:
+# 
+# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
+# 
+
+# From Arthur David Olson (2009-10-28):
+# We'll see if future DST switching times turn out to be end of the last
+# Thursday of the month or the start of the last Friday of the month or
+# something else. For now, use the start of the last Friday.
+
 Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2008	max	-	Nov	1	0:00	0	-
+Rule	Syria	2008	only	-	Nov	1	0:00	0	-
 Rule	Syria	2009	max	-	Mar	lastFri	0:00	1:00	S
+Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
diff --git a/europe b/europe
index adf20a2828c..66ab880e8eb 100644
--- a/europe
+++ b/europe
@@ -1,5 +1,5 @@
 # 
-# @(#)europe	8.22
+# @(#)europe	8.24
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -2072,9 +2072,43 @@ Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
 			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
 			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
 			 6:00	Russia	NOV%sT
+
+# From Alexander Krivenyshev (2009-10-13):
+# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
+# March 28, 2010:
+# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
+# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
+#
+# This is according to Government of Russia decree # 740, on September
+# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
+# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
+#
+# Russian Government web site (Russian language)
+# 
+# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
+# 
+# or Russian-English translation by WorldTimeZone.com with reference
+# map to local region and new Russia Time Zone map after March 28, 2010
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
+# 
+#
+# Thus, when Russia will switch to DST on the night of March 28, 2010
+# Kemerovo region (Kemerovo oblast') will not change the clock.
+#
+# As a result, Kemerovo oblast' will be in the same time zone as
+# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
+
+Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
+			 7:00	Russia	KRA%sT	2010 Mar 28 2:00s
+			 6:00	Russia	NOV%sT # Novosibirsk/Novokuznetsk Time
+
 #
 # From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Kemerovskaya oblast', Krasnoyarskij kraj,
+# Krasnoyarskij kraj,
 # Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
 # Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
 Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
diff --git a/zone.tab b/zone.tab
index 18aff1bb5a0..0f919414d49 100644
--- a/zone.tab
+++ b/zone.tab
@@ -1,5 +1,5 @@
 # 
-# @(#)zone.tab	8.28
+# @(#)zone.tab	8.29
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 #
@@ -330,6 +330,7 @@ RU	+5312+05009	Europe/Samara	Moscow+01 - Samara, Udmurtia
 RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
 RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
 RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
+RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
 RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River

From 68b27eaa458c119f24ec54c581601412bbcd5d5d Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Mon, 2 Nov 2009 22:32:14 +0000
Subject: [PATCH 468/646] Vendor import of tzcode2009q:

- Add more references in tz-art.htm
- Cleanup unnecessary local variables in zdump.

Obtained from:	ftp://elsie.nci.nih.gov/pub/
---
 unused/tz-art.htm | 30 ++++++++++++++++++++++++++++--
 zic/zdump.c       | 10 ++++++----
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/unused/tz-art.htm b/unused/tz-art.htm
index cba330e0b76..4bc32b24a10 100644
--- a/unused/tz-art.htm
+++ b/unused/tz-art.htm
@@ -9,7 +9,7 @@ PUBLIC "-//W3C//DTD HTML 4.01//EN"
 
 

Time and the Arts

-@(#)tz-art.htm 8.13 +@(#)tz-art.htm 8.14

This file is in the public domain, so clarified as of @@ -354,7 +354,8 @@ premonition in the "We Had a Dream" episode of "Medium" (originally aired 2007-02-28).

  • -In the 1946 "A Matter of Life and Death," +In the 1946 movie "A Matter of Life and Death" +(U.S. title "Stairway to Heaven") there is a reference to British Double Summer Time. The time does not play a large part in the plot; it's just a passing reference to the time when one of the @@ -363,6 +364,31 @@ The IMDb page is at http://us.imdb.com/title/tt0038733/ . (Dave Cantor) +
  • +The 1953 railway comedy movie "The Titfield Thunderbolt" includes a +play on words on British Double Summer Time. Valentine's wife wants +him to leave the pub and asks him, "Do you know what time it is?" +And he, happy where he is, replies: "Yes, my love. Summer double time." +IMDB page: + +http://us.imdb.com/title/tt0046436/ +. (Mark Brader, 2009-10-02) +
  • +
  • +The premise of the 1999 caper movie "Entrapment" involves computers +in an international banking network being shut down briefly at +midnight in each time zone to avoid any problems at the transition +from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown +is extended by 10 seconds, it will create a one-time opportunity for +a gigantic computerized theft. To achieve this, at one location the +crooks interfere with the microwave system supplying time signals to +the computer, advancing the time by 0.1 second each minute over the +last hour of 1999. (So this movie teaches us that 0.1 x 60 = 10.) +IMDB page: + +http://us.imdb.com/title/tt0137494/ +. (Mark Brader, 2009-10-02) +

  • diff --git a/zic/zdump.c b/zic/zdump.c index 7122bbf8918..7985b9269da 100644 --- a/zic/zdump.c +++ b/zic/zdump.c @@ -3,7 +3,7 @@ ** 2009-05-17 by Arthur David Olson. */ -static char elsieid[] = "@(#)zdump.c 8.9"; +static char elsieid[] = "@(#)zdump.c 8.10"; /* ** This code has been made independent of the rest of the time @@ -236,7 +236,9 @@ const char * const zone; } static void -usage(const char *progname, FILE *stream, int status) +usage(stream, status) +FILE * const stream; +const int status { (void) fprintf(stream, _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n\ @@ -283,7 +285,7 @@ char * argv[]; (void) printf("%s\n", elsieid); exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "--help") == 0) { - usage(progname, stdout, EXIT_SUCCESS); + usage(stdout, EXIT_SUCCESS); } vflag = 0; cutarg = NULL; @@ -293,7 +295,7 @@ char * argv[]; else cutarg = optarg; if ((c != EOF && c != -1) || (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { - usage(progname, stderr, EXIT_FAILURE); + usage(stderr, EXIT_FAILURE); } if (vflag) { if (cutarg != NULL) { From bd6d02e7e9c7d34a69e2da2384e4da0b8dbb03b2 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 2 Nov 2009 23:30:15 +0000 Subject: [PATCH 469/646] Provide the same sanity check on the sector size in dagetcapacity as when the disk is first probed. dagetcapacity is called whenever the disk is opened from geom via d_open(), a zero sector size will cause geom to panic later on. --- sys/cam/scsi/scsi_da.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 8f740dcdfad..32ca51bb379 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -1948,8 +1948,15 @@ dagetcapacity(struct cam_periph *periph) done: - if (error == 0) - dasetgeom(periph, block_len, maxsector); + if (error == 0) { + if (block_len >= MAXPHYS || block_len == 0) { + xpt_print(periph->path, + "unsupportable block size %ju\n", + (uintmax_t) block_len); + error = EINVAL; + } else + dasetgeom(periph, block_len, maxsector); + } xpt_release_ccb(ccb); From e975f97cd0c9fad29bc71753f2154f4e485ba83d Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 2 Nov 2009 23:50:12 +0000 Subject: [PATCH 470/646] Add more verbose output when dumping the configuration descriptor. Submitted by: Hans Petter Selasky --- usr.sbin/usbconfig/dump.c | 71 ++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c index 6a2fd026062..6dfc6ec4dfb 100644 --- a/usr.sbin/usbconfig/dump.c +++ b/usr.sbin/usbconfig/dump.c @@ -100,21 +100,66 @@ dump_field(struct libusb20_device *pdev, const char *plevel, printf("%s%s = 0x%04x ", plevel, field, value); - if ((field[0] != 'i') || (field[1] == 'd')) { - printf("\n"); + if (strlen(plevel) == 8) { + /* Endpoint Descriptor */ + + if (strcmp(field, "bEndpointAddress") == 0) { + if (value & 0x80) + printf(" \n"); + else + printf(" \n"); + return; + } + + if (strcmp(field, "bmAttributes") == 0) { + switch (value & 0x03) { + case 0: + printf(" \n"); + break; + case 1: + switch (value & 0x0C) { + case 0x00: + printf(" \n"); + break; + case 0x04: + printf(" \n"); + break; + case 0x08: + printf(" \n"); + break; + default: + printf(" \n"); + break; + } + break; + case 2: + printf(" \n"); + break; + default: + printf(" \n"); + break; + } + return; + } + } + + if ((field[0] == 'i') && (field[1] != 'd')) { + /* Indirect String Descriptor */ + if (value == 0) { + printf(" \n"); + return; + } + if (libusb20_dev_req_string_simple_sync(pdev, value, + temp_string, sizeof(temp_string))) { + printf(" \n"); + return; + } + printf(" <%s>\n", temp_string); return; } - if (value == 0) { - printf(" \n"); - return; - } - if (libusb20_dev_req_string_simple_sync(pdev, value, - temp_string, sizeof(temp_string))) { - printf(" \n"); - return; - } - printf(" <%s>\n", temp_string); - return; + + /* No additional information */ + printf("\n"); } static void From 5661377e37716a18e2a1f13dc8cfd1eed6a78546 Mon Sep 17 00:00:00 2001 From: Oleg Bulyzhin Date: Tue, 3 Nov 2009 08:41:14 +0000 Subject: [PATCH 471/646] Fix two issues that can lead to exceeding configured pipe bandwidth: - do not expire queues which are not ready to be expired. - properly calculate available burst size. MFC after: 3 days --- sys/netinet/ipfw/ip_dummynet.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c index d5620997b3e..3de27a1ca11 100644 --- a/sys/netinet/ipfw/ip_dummynet.c +++ b/sys/netinet/ipfw/ip_dummynet.c @@ -243,6 +243,17 @@ static void dummynet_send(struct mbuf *); void dummynet_drain(void); static int dummynet_io(struct mbuf **, int , struct ip_fw_args *); +/* + * Flow queue is idle if: + * 1) it's empty for at least 1 tick + * 2) it has invalid timestamp (WF2Q case) + * 3) parent pipe has no 'exhausted' burst. + */ +#define QUEUE_IS_IDLE(q) ((q)->head == NULL && (q)->S == (q)->F + 1 && \ + curr_time > (q)->idle_time + 1 && \ + ((q)->numbytes + (curr_time - (q)->idle_time - 1) * \ + (q)->fs->pipe->bandwidth >= q->fs->pipe->burst)) + /* * Heap management functions. * @@ -1004,7 +1015,7 @@ expire_queues(struct dn_flow_set *fs) fs->last_expired = time_uptime ; for (i = 0 ; i <= fs->rq_size ; i++) /* last one is overflow */ for (prev=NULL, q = fs->rq[i] ; q != NULL ; ) - if (q->head != NULL || q->S != q->F+1) { + if (!QUEUE_IS_IDLE(q)) { prev = q ; q = q->next ; } else { /* entry is idle, expire it */ @@ -1134,7 +1145,7 @@ find_queue(struct dn_flow_set *fs, struct ipfw_flow_id *id) break ; /* found */ /* No match. Check if we can expire the entry */ - if (pipe_expire && q->head == NULL && q->S == q->F+1 ) { + if (pipe_expire && QUEUE_IS_IDLE(q)) { /* entry is idle and not in any heap, expire it */ struct dn_flow_queue *old_q = q ; @@ -1408,7 +1419,7 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) if (q->idle_time < curr_time) { /* Calculate available burst size. */ q->numbytes += - (curr_time - q->idle_time) * pipe->bandwidth; + (curr_time - q->idle_time - 1) * pipe->bandwidth; if (q->numbytes > pipe->burst) q->numbytes = pipe->burst; if (io_fast) @@ -1418,8 +1429,8 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) if (pipe->idle_time < curr_time) { /* Calculate available burst size. */ pipe->numbytes += - (curr_time - pipe->idle_time) * pipe->bandwidth; - if (pipe->numbytes > pipe->burst) + (curr_time - pipe->idle_time - 1) * pipe->bandwidth; + if (pipe->numbytes > 0 && pipe->numbytes > pipe->burst) pipe->numbytes = pipe->burst; if (io_fast) pipe->numbytes += pipe->bandwidth; From 59bf36c3a797699801b9fe746d44650134554074 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 3 Nov 2009 09:17:23 +0000 Subject: [PATCH 472/646] Set umask to 0x077 instead of the default. This prevents non-root user from reading crashinfo output, which could contain some sensitive information. Reviewed by: jhb MFC after: 1 week --- usr.sbin/crashinfo/crashinfo.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.sbin/crashinfo/crashinfo.sh b/usr.sbin/crashinfo/crashinfo.sh index 886affd6f0e..60f036014c4 100755 --- a/usr.sbin/crashinfo/crashinfo.sh +++ b/usr.sbin/crashinfo/crashinfo.sh @@ -147,6 +147,8 @@ fi echo "Writing crash summary to $FILE." +umask 077 + # Simulate uname ostype=$(echo -e printf '"%s", ostype' | gdb -x /dev/stdin -batch $KERNEL) osrelease=$(echo -e printf '"%s", osrelease' | gdb -x /dev/stdin -batch $KERNEL) From 49fc79609a0a93e1adeff13def61414f64ad2f91 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 3 Nov 2009 09:25:08 +0000 Subject: [PATCH 473/646] Static'ify signal handler which is not called from outside. --- usr.bin/leave/leave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/leave/leave.c b/usr.bin/leave/leave.c index 89c3f528571..c7f93c6b2c5 100644 --- a/usr.bin/leave/leave.c +++ b/usr.bin/leave/leave.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include -void doalarm(u_int); +static void doalarm(u_int); static void usage(void); /* From 1575bd0a6d699d264e2eaff24bd35061fcffac57 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 3 Nov 2009 09:28:45 +0000 Subject: [PATCH 474/646] Increase width for %CPU, RSS and VSZ columns for now. Modern systems tend to have larger memory, larger process, and more CPU. --- bin/ps/keyword.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c index ade8123a0da..609c52e363b 100644 --- a/bin/ps/keyword.c +++ b/bin/ps/keyword.c @@ -70,7 +70,7 @@ static int vcmp(const void *, const void *); /* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */ static VAR var[] = { - {"%cpu", "%CPU", NULL, 0, pcpu, NULL, 4, 0, CHAR, NULL, 0}, + {"%cpu", "%CPU", NULL, 0, pcpu, NULL, 5, 0, CHAR, NULL, 0}, {"%mem", "%MEM", NULL, 0, pmem, NULL, 4, 0, CHAR, NULL, 0}, {"acflag", "ACFLG", NULL, 0, kvar, NULL, 3, KOFF(ki_acflag), USHORT, "x", 0}, @@ -159,7 +159,7 @@ static VAR var[] = { UINT, UIDFMT, 0}, {"rgroup", "RGROUP", NULL, LJUST|DSIZ, rgroupname, s_rgroupname, USERLEN, 0, CHAR, NULL, 0}, - {"rss", "RSS", NULL, 0, kvar, NULL, 5, KOFF(ki_rssize), PGTOK, "ld", 0}, + {"rss", "RSS", NULL, 0, kvar, NULL, 6, KOFF(ki_rssize), PGTOK, "ld", 0}, {"rtprio", "RTPRIO", NULL, 0, priorityr, NULL, 7, KOFF(ki_pri), CHAR, NULL, 0}, {"ruid", "RUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_ruid), @@ -207,7 +207,7 @@ static VAR var[] = { NULL, 0}, {"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"vsize", "", "vsz", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, - {"vsz", "VSZ", NULL, 0, vsize, NULL, 5, 0, CHAR, NULL, 0}, + {"vsz", "VSZ", NULL, 0, vsize, NULL, 6, 0, CHAR, NULL, 0}, {"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6, 0, CHAR, NULL, 0}, {"xstat", "XSTAT", NULL, 0, kvar, NULL, 4, KOFF(ki_xstat), USHORT, "x", 0}, From 8691755dff5aa6e56a864e3bceee2bbf8ef57675 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 3 Nov 2009 11:19:05 +0000 Subject: [PATCH 475/646] MFp4: Improve reporting ATA Status error details. --- sys/cam/ata/ata_all.c | 179 ++++++++++++++++++++++++++++++++++++++++++ sys/cam/ata/ata_all.h | 8 ++ sys/cam/cam.c | 42 ++++++++-- sys/cam/cam.h | 6 ++ sys/cam/cam_periph.c | 1 + 5 files changed, 229 insertions(+), 7 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index b6f8e816f83..85548e337a9 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -68,6 +68,185 @@ ata_version(int ver) return 0; } +char * +ata_op_string(struct ata_cmd *cmd) +{ + + switch (cmd->command) { + case 0x00: return ("NOP"); + case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR"); + case 0x08: return ("DEVICE_RESET"); + case 0x20: return ("READ"); + case 0x24: return ("READ48"); + case 0x25: return ("READ_DMA48"); + case 0x26: return ("READ_DMA_QUEUED48"); + case 0x27: return ("READ_NATIVE_MAX_ADDRESS48"); + case 0x29: return ("READ_MUL48"); + case 0x2a: return ("READ_STREAM_DMA48"); + case 0x2b: return ("READ_STREAM48"); + case 0x2f: return ("READ_LOG_EXT"); + case 0x30: return ("WRITE"); + case 0x34: return ("WRITE48"); + case 0x35: return ("WRITE_DMA48"); + case 0x36: return ("WRITE_DMA_QUEUED48"); + case 0x37: return ("SET_MAX_ADDRESS48"); + case 0x39: return ("WRITE_MUL48"); + case 0x3a: return ("WRITE_STREAM_DMA48"); + case 0x3b: return ("WRITE_STREAM48"); + case 0x3d: return ("WRITE_DMA_FUA"); + case 0x3e: return ("WRITE_DMA_FUA48"); + case 0x3f: return ("WRITE_LOG_EXT"); + case 0x40: return ("READ_VERIFY"); + case 0x42: return ("READ_VERIFY48"); + case 0x51: return ("CONFIGURE_STREAM"); + case 0x60: return ("READ_FPDMA_QUEUED"); + case 0x61: return ("WRITE_FPDMA_QUEUED"); + case 0x70: return ("SEEK"); + case 0x87: return ("CFA_TRANSLATE_SECTOR"); + case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC"); + case 0x92: return ("DOWNLOAD_MICROCODE"); + case 0xa0: return ("PACKET"); + case 0xa1: return ("ATAPI_IDENTIFY"); + case 0xa2: return ("SERVICE"); + case 0xb0: return ("SMART"); + case 0xb1: return ("DEVICE CONFIGURATION"); + case 0xc0: return ("CFA_ERASE"); + case 0xc4: return ("READ_MUL"); + case 0xc5: return ("WRITE_MUL"); + case 0xc6: return ("SET_MULTI"); + case 0xc7: return ("READ_DMA_QUEUED"); + case 0xc8: return ("READ_DMA"); + case 0xca: return ("WRITE_DMA"); + case 0xcc: return ("WRITE_DMA_QUEUED"); + case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE"); + case 0xce: return ("WRITE_MULTIPLE_FUA48"); + case 0xd1: return ("CHECK_MEDIA_CARD_TYPE"); + case 0xda: return ("GET_MEDIA_STATUS"); + case 0xde: return ("MEDIA_LOCK"); + case 0xdf: return ("MEDIA_UNLOCK"); + case 0xe0: return ("STANDBY_IMMEDIATE"); + case 0xe1: return ("IDLE_IMMEDIATE"); + case 0xe2: return ("STANDBY"); + case 0xe3: return ("IDLE"); + case 0xe4: return ("READ_BUFFER/PM"); + case 0xe5: return ("CHECK_POWER_MODE"); + case 0xe6: return ("SLEEP"); + case 0xe7: return ("FLUSHCACHE"); + case 0xe8: return ("WRITE_PM"); + case 0xea: return ("FLUSHCACHE48"); + case 0xec: return ("ATA_IDENTIFY"); + case 0xed: return ("MEDIA_EJECT"); + case 0xef: + switch (cmd->features) { + case 0x03: return ("SETFEATURES SET TRANSFER MODE"); + case 0x02: return ("SETFEATURES ENABLE WCACHE"); + case 0x82: return ("SETFEATURES DISABLE WCACHE"); + case 0xaa: return ("SETFEATURES ENABLE RCACHE"); + case 0x55: return ("SETFEATURES DISABLE RCACHE"); + } + return "SETFEATURES"; + case 0xf1: return ("SECURITY_SET_PASSWORD"); + case 0xf2: return ("SECURITY_UNLOCK"); + case 0xf3: return ("SECURITY_ERASE_PREPARE"); + case 0xf4: return ("SECURITY_ERASE_UNIT"); + case 0xf5: return ("SECURITY_FREE_LOCK"); + case 0xf6: return ("SECURITY DISABLE PASSWORD"); + case 0xf8: return ("READ_NATIVE_MAX_ADDRESS"); + case 0xf9: return ("SET_MAX_ADDRESS"); + } + return "UNKNOWN"; +} + +char * +ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len) +{ + + snprintf(cmd_string, len, "%02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x", + cmd->command, cmd->features, + cmd->lba_low, cmd->lba_mid, cmd->lba_high, cmd->device, + cmd->lba_low_exp, cmd->lba_mid_exp, cmd->lba_high_exp, + cmd->features_exp, cmd->sector_count, cmd->sector_count_exp); + + return(cmd_string); +} + +char * +ata_res_string(struct ata_res *res, char *res_string, size_t len) +{ + + snprintf(res_string, len, "%02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x", + res->status, res->error, + res->lba_low, res->lba_mid, res->lba_high, res->device, + res->lba_low_exp, res->lba_mid_exp, res->lba_high_exp, + res->sector_count, res->sector_count_exp); + + return(res_string); +} + +/* + * ata_command_sbuf() returns 0 for success and -1 for failure. + */ +int +ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + char cmd_str[(12 * 3) + 1]; + + sbuf_printf(sb, "CMD: %s: %s", + ata_op_string(&ataio->cmd), + ata_cmd_string(&ataio->cmd, cmd_str, sizeof(cmd_str))); + + return(0); +} + +/* + * ata_status_abuf() returns 0 for success and -1 for failure. + */ +int +ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + + sbuf_printf(sb, "ATA Status: %02x (%s%s%s%s%s%s%s%s)", + ataio->res.status, + (ataio->res.status & 0x80) ? "BSY " : "", + (ataio->res.status & 0x40) ? "DRDY " : "", + (ataio->res.status & 0x20) ? "DF " : "", + (ataio->res.status & 0x10) ? "SERV " : "", + (ataio->res.status & 0x08) ? "DRQ " : "", + (ataio->res.status & 0x04) ? "CORR " : "", + (ataio->res.status & 0x02) ? "IDX " : "", + (ataio->res.status & 0x01) ? "ERR" : ""); + if (ataio->res.status & 1) { + sbuf_printf(sb, ", Error: %02x (%s%s%s%s%s%s%s%s)", + ataio->res.error, + (ataio->res.error & 0x80) ? "ICRC " : "", + (ataio->res.error & 0x40) ? "UNC " : "", + (ataio->res.error & 0x20) ? "MC " : "", + (ataio->res.error & 0x10) ? "IDNF " : "", + (ataio->res.error & 0x08) ? "MCR " : "", + (ataio->res.error & 0x04) ? "ABRT " : "", + (ataio->res.error & 0x02) ? "NM " : "", + (ataio->res.error & 0x01) ? "ILI" : ""); + } + + return(0); +} + +/* + * ata_res_sbuf() returns 0 for success and -1 for failure. + */ +int +ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + char res_str[(11 * 3) + 1]; + + sbuf_printf(sb, "RES: %s", + ata_res_string(&ataio->res, res_str, sizeof(res_str))); + + return(0); +} + void ata_print_ident(struct ata_params *ident_data) { diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index 748035f8602..404f817533d 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -81,6 +81,14 @@ struct ata_res { }; int ata_version(int ver); + +char * ata_op_string(struct ata_cmd *cmd); +char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len); +char * ata_res_string(struct ata_res *res, char *res_string, size_t len); +int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); +int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); +int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); + void ata_print_ident(struct ata_params *ident_data); void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, diff --git a/sys/cam/cam.c b/sys/cam/cam.c index 120050a5277..eff83a1ad13 100644 --- a/sys/cam/cam.c +++ b/sys/cam/cam.c @@ -229,6 +229,21 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, return(NULL); switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + switch (proto_flags & CAM_EPF_LEVEL_MASK) { + case CAM_EPF_NONE: + break; + case CAM_EPF_ALL: + case CAM_EPF_NORMAL: + proto_flags |= CAM_EAF_PRINT_RESULT; + /* FALLTHROUGH */ + case CAM_EPF_MINIMAL: + proto_flags |= CAM_EAF_PRINT_STATUS; + /* FALLTHROUGH */ + default: + break; + } + break; case XPT_SCSI_IO: switch (proto_flags & CAM_EPF_LEVEL_MASK) { case CAM_EPF_NONE: @@ -256,10 +271,12 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, sbuf_new(&sb, str, str_len, 0); if (flags & CAM_ESF_COMMAND) { - sbuf_cat(&sb, path_str); - switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + ata_command_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + break; case XPT_SCSI_IO: #ifdef _KERNEL scsi_command_string(&ccb->csio, &sb); @@ -267,7 +284,6 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, scsi_command_string(device, &ccb->csio, &sb); #endif /* _KERNEL/!_KERNEL */ sbuf_printf(&sb, "\n"); - break; default: break; @@ -295,6 +311,22 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, if (flags & CAM_ESF_PROTO_STATUS) { switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != + CAM_ATA_STATUS_ERROR) + break; + if (proto_flags & CAM_EAF_PRINT_STATUS) { + sbuf_cat(&sb, path_str); + ata_status_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + } + if (proto_flags & CAM_EAF_PRINT_RESULT) { + sbuf_cat(&sb, path_str); + ata_res_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + } + + break; case XPT_SCSI_IO: if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR) @@ -302,10 +334,6 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, if (proto_flags & CAM_ESF_PRINT_STATUS) { sbuf_cat(&sb, path_str); - /* - * Print out the SCSI status byte as long as - * the user wants some protocol output. - */ sbuf_printf(&sb, "SCSI Status: %s\n", scsi_status_string(&ccb->csio)); } diff --git a/sys/cam/cam.h b/sys/cam/cam.h index c26afb4600b..3d85264f4c5 100644 --- a/sys/cam/cam.h +++ b/sys/cam/cam.h @@ -184,6 +184,12 @@ typedef enum { CAM_ESF_PRINT_SENSE = 0x20 } cam_error_scsi_flags; +typedef enum { + CAM_EAF_PRINT_NONE = 0x00, + CAM_EAF_PRINT_STATUS = 0x10, + CAM_EAF_PRINT_RESULT = 0x20 +} cam_error_ata_flags; + struct cam_status_entry { cam_status status_code; diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 14b655d54c2..fd441b25564 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -1612,6 +1612,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, if (bootverbose && printed == 0) { xpt_print(ccb->ccb_h.path, "Request completed with CAM_ATA_STATUS_ERROR\n"); + cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); printed++; } /* FALLTHROUGH */ From 8f1c21a6e36ff94601e614252d5d2d9b3245c79c Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 3 Nov 2009 11:41:21 +0000 Subject: [PATCH 476/646] Just use devname(3) to print device names. Right now sysctl just prints the major/minor numbers of a device. Instead of rolling our own routine for this, we'd better just call devname(3) to perform a translation to a device name for us. --- sbin/sysctl/sysctl.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index 4810c6165b8..38c5038e3ce 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -419,14 +419,7 @@ T_dev_t(int l2, void *p) warnx("T_dev_T %d != %d", l2, sizeof(*d)); return (1); } - if ((int)(*d) != -1) { - if (minor(*d) > 255 || minor(*d) < 0) - printf("{ major = %d, minor = 0x%x }", - major(*d), minor(*d)); - else - printf("{ major = %d, minor = %d }", - major(*d), minor(*d)); - } + printf("%s", devname(*d, S_IFCHR)); return (0); } From a69552e4b6e6854176b250e7d82ce1a32538abce Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 3 Nov 2009 11:47:07 +0000 Subject: [PATCH 477/646] MFp4: - Handle timeouts and fatal errors with port hard-reset. The rest of recovery will be done by XPT on receiving async event. More gracefull per-device soft-reset recovery can be implemented later. - Add workaround for ATI SB600/SB700 PMP probe related bug, to speedup boot. --- sys/dev/ahci/ahci.c | 43 +++++++++++++++++++++++++++++++++++-------- sys/dev/ahci/ahci.h | 1 + 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 0a2472e7797..3e58cb5d49d 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1221,6 +1221,13 @@ ahci_execute_transaction(struct ahci_slot *slot) et = AHCI_ERR_TFE; break; } + /* Workaround for ATI SB600/SB700 chipsets. */ + if (ccb->ccb_h.target_id == 15 && + pci_get_vendor(device_get_parent(dev)) == 0x1002 && + (ATA_INL(ch->r_mem, AHCI_P_IS) & AHCI_P_IX_IPM)) { + et = AHCI_ERR_TIMEOUT; + break; + } } if (timeout && (count >= timeout)) { device_printf(ch->dev, @@ -1275,10 +1282,8 @@ ahci_timeout(struct ahci_slot *slot) ATA_INL(ch->r_mem, AHCI_P_IS), ATA_INL(ch->r_mem, AHCI_P_CI), ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD), ATA_INL(ch->r_mem, AHCI_P_SERR)); - /* Kick controller into sane state. */ - ahci_stop(ch->dev); - ahci_start(ch->dev); + ch->fatalerr = 1; /* Handle frozen command. */ if (ch->frozen) { union ccb *fccb = ch->frozen; @@ -1360,6 +1365,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ccb->csio.scsi_status = SCSI_STATUS_OK; break; case AHCI_ERR_INVALID: + ch->fatalerr = 1; ccb->ccb_h.status |= CAM_REQ_INVALID; break; case AHCI_ERR_INNOCENT: @@ -1375,6 +1381,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) } break; case AHCI_ERR_SATA: + ch->fatalerr = 1; if (!ch->readlog) { xpt_freeze_simq(ch->sim, 1); ccb->ccb_h.status &= ~CAM_STATUS_MASK; @@ -1383,6 +1390,10 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ccb->ccb_h.status |= CAM_UNCOR_PARITY; break; case AHCI_ERR_TIMEOUT: + /* Do no treat soft-reset timeout as fatal here. */ + if (ccb->ccb_h.func_code != XPT_ATA_IO || + !(ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) + ch->fatalerr = 1; if (!ch->readlog) { xpt_freeze_simq(ch->sim, 1); ccb->ccb_h.status &= ~CAM_STATUS_MASK; @@ -1391,6 +1402,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ccb->ccb_h.status |= CAM_CMD_TIMEOUT; break; default: + ch->fatalerr = 1; ccb->ccb_h.status |= CAM_REQ_CMP_ERR; } /* Free slot. */ @@ -1414,12 +1426,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ahci_begin_transaction(dev, ccb); return; } - /* If it was NCQ command error, put result on hold. */ - if (et == AHCI_ERR_NCQ) { - ch->hold[slot->slot] = ccb; - } else if (ch->readlog) /* If it was our READ LOG command - process it. */ + /* If it was our READ LOG command - process it. */ + if (ch->readlog) { ahci_process_read_log(dev, ccb); - else + /* If it was NCQ command error, put result on hold. */ + } else if (et == AHCI_ERR_NCQ) { + ch->hold[slot->slot] = ccb; + } else xpt_done(ccb); /* Unfreeze frozen command. */ if (ch->frozen && ch->numrslots == 0) { @@ -1428,6 +1441,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ahci_begin_transaction(dev, fccb); xpt_release_simq(ch->sim, TRUE); } + /* If we have no other active commands, ... */ + if (ch->rslots == 0) { + /* if there was fatal error - reset port. */ + if (ch->fatalerr) { + ahci_reset(dev); + } + } /* Start PM timer. */ if (ch->numrslots == 0 && ch->pm_level > 3) { callout_schedule(&ch->pm_timer, @@ -1674,6 +1694,13 @@ ahci_reset(device_t dev) /* XXX; Commands in loading state. */ ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT); } + for (i = 0; i < ch->numslots; i++) { + if (!ch->hold[i]) + continue; + xpt_done(ch->hold[i]); + ch->hold[i] = NULL; + } + ch->fatalerr = 0; /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); /* Disable port interrupts */ diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index df103ad658c..0686f6766c3 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -366,6 +366,7 @@ struct ahci_channel { int numrslots; /* Number of running slots */ int numtslots; /* Number of tagged slots */ int readlog; /* Our READ LOG active */ + int fatalerr; /* Fatal error happend */ int lastslot; /* Last used slot */ int taggedtarget; /* Last tagged target */ union ccb *frozen; /* Frozen command */ From 6f9a51c735977a131e61b8bed13f792f60ac491c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 3 Nov 2009 12:03:13 +0000 Subject: [PATCH 478/646] MFp4: - Rework timeout handling, to make it more graceful for devices sharing controller port (with PMP). Wait for other commands completion/timeout before initiating recovery. - Handle timeouts and fatal errors with port hard-reset. The rest of recovery will be done by XPT on receiving async event. More gracefull per-device soft-reset recovery can be implemented later. --- sys/dev/siis/siis.c | 150 ++++++++++++++++++++++++++++++-------------- sys/dev/siis/siis.h | 3 +- 2 files changed, 104 insertions(+), 49 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 0529f2a480c..8bd813e1fd8 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -511,7 +511,10 @@ siis_ch_resume(device_t dev) /* Get port out of reset state. */ ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET); ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT); - ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); + if (ch->pm_present) + ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); + else + ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); /* Enable port interrupts */ ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED); return (0); @@ -764,7 +767,7 @@ siis_ch_intr(void *data) estatus == SIIS_P_CMDERR_DATAFIS) { tslots = ch->numtslots[port]; for (i = 0; i < SIIS_MAX_SLOTS; i++) { - /* XXX: reqests in loading state. */ + /* XXX: requests in loading state. */ if (((ch->rslots >> i) & 1) == 0) continue; if (ch->slot[i].ccb->ccb_h.target_id != port) @@ -796,7 +799,7 @@ siis_ch_intr(void *data) } else et = SIIS_ERR_INVALID; for (i = 0; i < SIIS_MAX_SLOTS; i++) { - /* XXX: reqests in loading state. */ + /* XXX: requests in loading state. */ if (((ch->rslots >> i) & 1) == 0) continue; siis_end_transaction(&ch->slot[i], et); @@ -967,13 +970,33 @@ siis_execute_transaction(struct siis_slot *slot) return; } +/* Must be called with channel locked. */ +static void +siis_process_timeout(device_t dev) +{ + struct siis_channel *ch = device_get_softc(dev); + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + if (!ch->readlog && !ch->recovery) { + xpt_freeze_simq(ch->sim, ch->numrslots); + ch->recovery = 1; + } + /* Handle the rest of commands. */ + for (i = 0; i < SIIS_MAX_SLOTS; i++) { + /* Do we have a running request on slot? */ + if (ch->slot[i].state < SIIS_SLOT_RUNNING) + continue; + siis_end_transaction(&ch->slot[i], SIIS_ERR_TIMEOUT); + } +} + /* Locked by callout mechanism. */ static void siis_timeout(struct siis_slot *slot) { device_t dev = slot->dev; struct siis_channel *ch = device_get_softc(dev); - int i; mtx_assert(&ch->mtx, MA_OWNED); device_printf(dev, "Timeout on slot %d\n", slot->slot); @@ -981,32 +1004,15 @@ device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n", __func__, ATA_INL(ch->r_mem, SIIS_P_IS), ATA_INL(ch->r_mem, SIIS_P_SS), ch->rslots, ATA_INL(ch->r_mem, SIIS_P_CMDERR), ATA_INL(ch->r_mem, SIIS_P_STS), ATA_INL(ch->r_mem, SIIS_P_SERR)); - /* Kick controller into sane state. */ - siis_portinit(ch->dev); - if (!ch->readlog) - xpt_freeze_simq(ch->sim, ch->numrslots); - /* Handle frozen command. */ - if (ch->frozen) { - union ccb *fccb = ch->frozen; - ch->frozen = NULL; - fccb->ccb_h.status &= ~CAM_STATUS_MASK; - fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; - if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { - xpt_freeze_devq(fccb->ccb_h.path, 1); - fccb->ccb_h.status |= CAM_DEV_QFRZN; - } - xpt_done(fccb); - } - /* Handle command with timeout. */ - siis_end_transaction(&ch->slot[slot->slot], SIIS_ERR_TIMEOUT); - /* Handle the rest of commands. */ - for (i = 0; i < SIIS_MAX_SLOTS; i++) { - /* Do we have a running request on slot? */ - if (ch->slot[i].state < SIIS_SLOT_RUNNING) - continue; - siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT); - } + if (ch->toslots == 0) + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); + if ((ch->rslots & ~ch->toslots) == 0) + siis_process_timeout(dev); + else + device_printf(dev, " ... waiting for slots %08x\n", + ch->rslots & ~ch->toslots); } /* Must be called with channel locked. */ @@ -1071,6 +1077,7 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) ccb->csio.scsi_status = SCSI_STATUS_OK; break; case SIIS_ERR_INVALID: + ch->fatalerr = 1; ccb->ccb_h.status |= CAM_REQ_INVALID; break; case SIIS_ERR_INNOCENT: @@ -1086,9 +1093,11 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) } break; case SIIS_ERR_SATA: + ch->fatalerr = 1; ccb->ccb_h.status |= CAM_UNCOR_PARITY; break; case SIIS_ERR_TIMEOUT: + ch->fatalerr = 1; ccb->ccb_h.status |= CAM_CMD_TIMEOUT; break; default: @@ -1097,6 +1106,11 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) /* Free slot. */ ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); + if (et != SIIS_ERR_TIMEOUT) { + if (ch->toslots == (1 << slot->slot)) + xpt_release_simq(ch->sim, TRUE); + ch->toslots &= ~(1 << slot->slot); + } slot->state = SIIS_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1105,13 +1119,14 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots[ccb->ccb_h.target_id]--; } + /* If it was our READ LOG command - process it. */ + if (ch->readlog) { + siis_process_read_log(dev, ccb); /* If it was NCQ command error, put result on hold. */ - if (et == SIIS_ERR_NCQ) { + } else if (et == SIIS_ERR_NCQ) { ch->hold[slot->slot] = ccb; ch->numhslots++; - } else if (ch->readlog) /* If it was our READ LOG command - process it. */ - siis_process_read_log(dev, ccb); - else + } else xpt_done(ccb); /* Unfreeze frozen command. */ if (ch->frozen && ch->numrslots == 0) { @@ -1122,13 +1137,20 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) } /* If we have no other active commands, ... */ if (ch->rslots == 0) { - /* if we have slots in error, we can reinit port. */ - if (ch->eslots != 0) - siis_portinit(dev); - /* if there commands on hold, we can do READ LOG. */ - if (!ch->readlog && ch->numhslots) - siis_issue_read_log(dev); - } + /* if there were timeouts or fatal error - reset port. */ + if (ch->toslots != 0 || ch->fatalerr) { + siis_reset(dev); + } else { + /* if we have slots in error, we can reinit port. */ + if (ch->eslots != 0) + siis_portinit(dev); + /* if there commands on hold, we can do READ LOG. */ + if (!ch->readlog && ch->numhslots) + siis_issue_read_log(dev); + } + /* If all the reset of commands are in timeout - abort them. */ + } else if ((ch->rslots & ~ch->toslots) == 0) + siis_process_timeout(dev); } static void @@ -1296,13 +1318,14 @@ static void siis_reset(device_t dev) { struct siis_channel *ch = device_get_softc(dev); - int i; + int i, retry = 0; uint32_t val; if (bootverbose) device_printf(dev, "SIIS reset...\n"); - xpt_freeze_simq(ch->sim, ch->numrslots); - /* Requeue freezed command. */ + if (!ch->readlog && !ch->recovery) + xpt_freeze_simq(ch->sim, ch->numrslots); + /* Requeue frozen command. */ if (ch->frozen) { union ccb *fccb = ch->frozen; ch->frozen = NULL; @@ -1322,6 +1345,20 @@ siis_reset(device_t dev) /* XXX; Commands in loading state. */ siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT); } + /* Finish all holden commands as-is. */ + for (i = 0; i < SIIS_MAX_SLOTS; i++) { + if (!ch->hold[i]) + continue; + xpt_done(ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + if (ch->toslots != 0) + xpt_release_simq(ch->sim, TRUE); + ch->eslots = 0; + ch->recovery = 0; + ch->toslots = 0; + ch->fatalerr = 0; /* Disable port interrupts */ ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF); /* Set speed limit. */ @@ -1336,6 +1373,7 @@ siis_reset(device_t dev) ATA_OUTL(ch->r_mem, SIIS_P_SCTL, ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))); +retry: siis_devreset(dev); /* Reset and reconnect PHY, */ if (!siis_sata_connect(ch)) { @@ -1350,8 +1388,25 @@ siis_reset(device_t dev) return; } /* Wait for clearing busy status. */ - if (siis_wait_ready(dev, 10000)) + if (siis_wait_ready(dev, 10000)) { device_printf(dev, "device ready timeout\n"); + if (!retry) { + device_printf(dev, "trying full port reset ...\n"); + /* Get port to the reset state. */ + ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET); + DELAY(10000); + /* Get port out of reset state. */ + ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET); + ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT); + if (ch->pm_present) + ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); + else + ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); + siis_wait_ready(dev, 5000); + retry = 1; + goto retry; + } + } ch->devices = 1; /* Enable port interrupts */ ATA_OUTL(ch->r_mem, SIIS_P_IS, 0xFFFFFFFF); @@ -1487,7 +1542,8 @@ siisaction(struct cam_sim *sim, union ccb *ccb) struct ccb_trans_settings *cts = &ccb->cts; if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { - if (cts->xport_specific.sata.pm_present) + ch->pm_present = cts->xport_specific.sata.pm_present; + if (ch->pm_present) ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); else ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); @@ -1522,9 +1578,7 @@ siisaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.bitrate = 150000; cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; } - cts->xport_specific.sata.pm_present = - (ATA_INL(ch->r_mem, SIIS_P_STS) & SIIS_P_CTL_PME) ? - 1 : 0; + cts->xport_specific.sata.pm_present = ch->pm_present; cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h index 87a1d5d9994..ab18e6ed524 100644 --- a/sys/dev/siis/siis.h +++ b/sys/dev/siis/siis.h @@ -373,13 +373,14 @@ struct siis_channel { uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ uint32_t eslots; /* Slots in error */ + uint32_t toslots; /* Slots in timeout */ int numrslots; /* Number of running slots */ int numtslots[SIIS_MAX_SLOTS]; /* Number of tagged slots */ int numhslots; /* Number of holden slots */ int readlog; /* Our READ LOG active */ + int fatalerr; /* Fatal error happend */ int recovery; /* Some slots are in error */ int lastslot; /* Last used slot */ - int taggedtarget; /* Last tagged target */ union ccb *frozen; /* Frozen command */ }; From 1c89fc757aea8b62246d11b40c144d843dfd837d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 3 Nov 2009 12:52:35 +0000 Subject: [PATCH 479/646] If socket buffer space appears to be lower then sum of count of already prepared bytes and next portion of transfer, inner loop of kern_sendfile() aborts, not preparing next mbuf for socket buffer, and not modifying any outer loop invariants. The thread loops in the outer loop forever. Instead of breaking from inner loop, prepare only bytes that fit into the socket buffer space. In collaboration with: pho Reviewed by: bz PR: kern/138999 MFC after: 2 weeks --- sys/kern/uipc_syscalls.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 708cefcb6df..c00fd2d1236 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -2037,20 +2037,12 @@ retry_space: rem = obj->un_pager.vnp.vnp_size - uap->offset - fsbytes - loopbytes; xfsize = omin(rem, xfsize); + xfsize = omin(space - loopbytes, xfsize); if (xfsize <= 0) { VM_OBJECT_UNLOCK(obj); done = 1; /* all data sent */ break; } - /* - * Don't overflow the send buffer. - * Stop here and send out what we've - * already got. - */ - if (space < loopbytes + xfsize) { - VM_OBJECT_UNLOCK(obj); - break; - } /* * Attempt to look up the page. Allocate From 1b9d701feea709d06a3f85e0bf2d058aa5758b52 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 3 Nov 2009 16:46:52 +0000 Subject: [PATCH 480/646] Split P_NOLOAD into a per-thread flag (TDF_NOLOAD). This improvements aims for avoiding further cache-misses in scheduler specific functions which need to keep track of average thread running time and further locking in places setting for this flag. Reported by: jeff (originally), kris (currently) Reviewed by: jhb Tested by: Giuseppe Cocomazzi --- sys/kern/kern_idle.c | 3 +-- sys/kern/kern_intr.c | 10 +++++----- sys/kern/sched_4bsd.c | 16 ++++++++-------- sys/kern/sched_ule.c | 4 ++-- sys/sys/proc.h | 4 ++-- sys/vm/vm_zeroidle.c | 17 ++++++----------- 6 files changed, 24 insertions(+), 30 deletions(-) diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c index 1d9b3029778..af12d7dcf5a 100644 --- a/sys/kern/kern_idle.c +++ b/sys/kern/kern_idle.c @@ -74,10 +74,9 @@ idle_setup(void *dummy) if (error) panic("idle_setup: kproc_create error %d\n", error); - p->p_flag |= P_NOLOAD; thread_lock(td); TD_SET_CAN_RUN(td); - td->td_flags |= TDF_IDLETD; + td->td_flags |= TDF_IDLETD | TDF_NOLOAD; sched_class(td, PRI_IDLE); sched_prio(td, PRI_MAX_IDLE); thread_unlock(td); diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index d22bfeaa311..3554b9f4fbf 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -1061,6 +1061,7 @@ int swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, void *arg, int pri, enum intr_type flags, void **cookiep) { + struct thread *td; struct intr_event *ie; int error; @@ -1085,11 +1086,10 @@ swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, if (error) return (error); if (pri == SWI_CLOCK) { - struct proc *p; - p = ie->ie_thread->it_thread->td_proc; - PROC_LOCK(p); - p->p_flag |= P_NOLOAD; - PROC_UNLOCK(p); + td = ie->ie_thread->it_thread; + thread_lock(td); + td->td_flags |= TDF_NOLOAD; + thread_unlock(td); } return (0); } diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 4fe1c1415f2..e13cffc70d9 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -728,10 +728,10 @@ sched_exit_thread(struct thread *td, struct thread *child) thread_lock(td); td->td_estcpu = ESTCPULIM(td->td_estcpu + child->td_estcpu); thread_unlock(td); - mtx_lock_spin(&sched_lock); - if ((child->td_proc->p_flag & P_NOLOAD) == 0) + thread_lock(child); + if ((child->td_flags & TDF_NOLOAD) == 0) sched_load_rem(); - mtx_unlock_spin(&sched_lock); + thread_unlock(child); } void @@ -937,7 +937,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) thread_unlock(td); } - if ((p->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) sched_load_rem(); if (newtd) @@ -980,7 +980,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) ("trying to run inhibited thread")); newtd->td_flags |= TDF_DIDRUN; TD_SET_RUNNING(newtd); - if ((newtd->td_proc->p_flag & P_NOLOAD) == 0) + if ((newtd->td_flags & TDF_NOLOAD) == 0) sched_load_add(); } else { newtd = choosethread(); @@ -1289,7 +1289,7 @@ sched_add(struct thread *td, int flags) } } - if ((td->td_proc->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) sched_load_add(); runq_add(ts->ts_runq, td, flags); if (cpu != NOCPU) @@ -1338,7 +1338,7 @@ sched_add(struct thread *td, int flags) if (maybe_preempt(td)) return; } - if ((td->td_proc->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) sched_load_add(); runq_add(ts->ts_runq, td, flags); maybe_resched(td); @@ -1360,7 +1360,7 @@ sched_rem(struct thread *td) "prio:%d", td->td_priority, KTR_ATTR_LINKED, sched_tdname(curthread)); - if ((td->td_proc->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) sched_load_rem(); #ifdef SMP if (ts->ts_runq != &runq) diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index e0cff5f3647..1ebfda2da3c 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -495,7 +495,7 @@ tdq_load_add(struct tdq *tdq, struct thread *td) THREAD_LOCK_ASSERT(td, MA_OWNED); tdq->tdq_load++; - if ((td->td_proc->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) tdq->tdq_sysload++; KTR_COUNTER0(KTR_SCHED, "load", tdq->tdq_loadname, tdq->tdq_load); } @@ -514,7 +514,7 @@ tdq_load_rem(struct tdq *tdq, struct thread *td) ("tdq_load_rem: Removing with 0 load on queue %d", TDQ_ID(tdq))); tdq->tdq_load--; - if ((td->td_proc->p_flag & P_NOLOAD) == 0) + if ((td->td_flags & TDF_NOLOAD) == 0) tdq->tdq_sysload--; KTR_COUNTER0(KTR_SCHED, "load", tdq->tdq_loadname, tdq->tdq_load); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 6e5716788e9..384f2805ca0 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -322,7 +322,7 @@ do { \ #define TDF_NEEDSUSPCHK 0x00008000 /* Thread may need to suspend. */ #define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */ #define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */ -#define TDF_UNUSED18 0x00040000 /* --available-- */ +#define TDF_NOLOAD 0x00040000 /* Ignore during load avg calculations. */ #define TDF_UNUSED19 0x00080000 /* Thread is sleeping on a umtx. */ #define TDF_THRWAKEUP 0x00100000 /* Libthr thread must not suspend itself. */ #define TDF_UNUSED21 0x00200000 /* --available-- */ @@ -558,7 +558,7 @@ struct proc { #define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */ #define P_CONTROLT 0x00002 /* Has a controlling terminal. */ #define P_KTHREAD 0x00004 /* Kernel thread (*). */ -#define P_NOLOAD 0x00008 /* Ignore during load avg calculations. */ +#define P_UNUSED0 0x00008 /* available. */ #define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */ #define P_PROFIL 0x00020 /* Has started profiling. */ #define P_STOPPROF 0x00040 /* Has thread requesting to stop profiling. */ diff --git a/sys/vm/vm_zeroidle.c b/sys/vm/vm_zeroidle.c index a102e89a5c8..6ba96e1c006 100644 --- a/sys/vm/vm_zeroidle.c +++ b/sys/vm/vm_zeroidle.c @@ -139,26 +139,21 @@ vm_pagezero(void __unused *arg) } } -static struct proc *pagezero_proc; - static void pagezero_start(void __unused *arg) { int error; + struct proc *p; struct thread *td; - error = kproc_create(vm_pagezero, NULL, &pagezero_proc, RFSTOPPED, 0, - "pagezero"); + error = kproc_create(vm_pagezero, NULL, &p, RFSTOPPED, 0, "pagezero"); if (error) panic("pagezero_start: error %d\n", error); - /* - * We're an idle task, don't count us in the load. - */ - PROC_LOCK(pagezero_proc); - pagezero_proc->p_flag |= P_NOLOAD; - PROC_UNLOCK(pagezero_proc); - td = FIRST_THREAD_IN_PROC(pagezero_proc); + td = FIRST_THREAD_IN_PROC(p); thread_lock(td); + + /* We're an idle task, don't count us in the load. */ + td->td_flags |= TDF_NOLOAD; sched_class(td, PRI_IDLE); sched_prio(td, PRI_MAX_IDLE); sched_add(td, SRQ_BORING); From 86684848b6097c727e71954bd98b5350baf5d0b6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Nov 2009 17:15:15 +0000 Subject: [PATCH 481/646] Eliminate a bit of hackery from vm_fault(). The operations that this hackery sought to prevent are now properly supported by vm_map_protect(). (See r198505.) Reviewed by: kib --- sys/vm/vm_fault.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index de871834c4d..55b4173bb7c 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -264,17 +264,6 @@ RetryFault:; &fs.entry, &fs.first_object, &fs.first_pindex, &prot, &wired); if (result != KERN_SUCCESS) return (result); - - /* - * If we don't COW now, on a user wire, the user will never - * be able to write to the mapping. If we don't make this - * restriction, the bookkeeping would be nearly impossible. - * - * XXX The following assignment modifies the map without - * holding a write lock on it. - */ - if ((fs.entry->protection & VM_PROT_WRITE) == 0) - fs.entry->max_protection &= ~VM_PROT_WRITE; } map_generation = fs.map->timestamp; From 9144dd07ad6be6faa96d0c59a97df15d151beef7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 Nov 2009 18:40:42 +0000 Subject: [PATCH 482/646] Fix a couple of comment typos. MFC after: 1 week --- secure/usr.bin/bdes/bdes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/secure/usr.bin/bdes/bdes.c b/secure/usr.bin/bdes/bdes.c index 22df57af7c7..cbab5d76565 100644 --- a/secure/usr.bin/bdes/bdes.c +++ b/secure/usr.bin/bdes/bdes.c @@ -170,11 +170,11 @@ main(int argc, char *argv[]) int i; /* counter in a for loop */ char *p; /* used to obtain the key */ DES_cblock msgbuf; /* I/O buffer */ - int kflag; /* command-line encryptiooon key */ + int kflag; /* command-line encryption key */ setproctitle("-"); /* Hide command-line arguments */ - /* initialize the initialization vctor */ + /* initialize the initialization vector */ MEMZERO(ivec, 8); /* process the argument list */ From 4586315a7665712af5da18220337831ddfc7ce5d Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Tue, 3 Nov 2009 19:05:05 +0000 Subject: [PATCH 483/646] fdc(4) module unload fixes: - Tear down the interrupt handler before killing the worker thread. - Do geom withering as GEOM event to avoid acquiring the GEOM topology lock under Giant. PR: kern/104079 Reviewed by: joerg Approved by: trasz (mentor) --- sys/dev/fdc/fdc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 3ff31fd7c3b..458c839bff2 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -1734,6 +1734,10 @@ fdc_detach(device_t dev) if ((error = bus_generic_detach(dev))) return (error); + if (fdc->fdc_intr) + bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr); + fdc->fdc_intr = NULL; + /* kill worker thread */ mtx_lock(&fdc->fdc_mtx); fdc->flags |= FDC_KTHREAD_EXIT; @@ -2031,15 +2035,22 @@ fd_attach(device_t dev) return (0); } +static void +fd_detach_geom(void *arg, int flag) +{ + struct fd_data *fd = arg; + + g_topology_assert(); + g_wither_geom(fd->fd_geom, ENXIO); +} + static int fd_detach(device_t dev) { struct fd_data *fd; fd = device_get_softc(dev); - g_topology_lock(); - g_wither_geom(fd->fd_geom, ENXIO); - g_topology_unlock(); + g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL); while (device_get_state(dev) == DS_BUSY) tsleep(fd, PZERO, "fdd", hz/10); callout_drain(&fd->toffhandle); From 761eeb5fff4769159956c3ebe360a3515703c6e5 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 3 Nov 2009 20:22:09 +0000 Subject: [PATCH 484/646] Fix VESA color palette corruption: - VBE 3.0 says palette format resets to 6-bit mode when video mode changes. We simply set 8-bit mode when we switch modes if the adapter supports it. - VBE 3.0 also says if the mode is not VGA compatible, we must use VBE function to save/restore palette. Otherwise, VGA function may be used. Thus, reinstate the save/load palette functions only for non-VGA compatible modes regardless of its palette format. - Let vesa(4) set VESA modes even if vga(4) claims to support it. - Reset default palette if VESA pixel mode is set initially. - Fix more style nits. --- sys/dev/fb/vesa.c | 95 +++++++++++++++------------------------ sys/dev/syscons/syscons.c | 3 ++ sys/sys/fbio.h | 1 + 3 files changed, 40 insertions(+), 59 deletions(-) diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index 22213012440..c2521c5ad48 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -174,10 +174,8 @@ static int vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits); static int vesa_bios_load_palette(int start, int colors, u_char *palette, int bits); -#ifdef notyet static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits); -#endif #define STATE_SIZE 0 #define STATE_SAVE 1 #define STATE_LOAD 2 @@ -415,9 +413,9 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits) bits = 8 - bits; for (i = 0; i < colors; ++i) { - palette[i*3] = p[i*4 + 2] << bits; - palette[i*3 + 1] = p[i*4 + 1] << bits; - palette[i*3 + 2] = p[i*4] << bits; + palette[i * 3] = p[i * 4 + 2] << bits; + palette[i * 3 + 1] = p[i * 4 + 1] << bits; + palette[i * 3 + 2] = p[i * 4] << bits; } x86bios_free(p, colors * 4); @@ -455,9 +453,9 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, bits = 8 - bits; for (i = 0; i < colors; ++i) { - r[i] = p[i*4 + 2] << bits; - g[i] = p[i*4 + 1] << bits; - b[i] = p[i*4] << bits; + r[i] = p[i * 4 + 2] << bits; + g[i] = p[i * 4 + 1] << bits; + b[i] = p[i * 4] << bits; } x86bios_free(p, colors * 4); @@ -487,10 +485,10 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) bits = 8 - bits; for (i = 0; i < colors; ++i) { - p[i*4] = palette[i*3 + 2] >> bits; - p[i*4 + 1] = palette[i*3 + 1] >> bits; - p[i*4 + 2] = palette[i*3] >> bits; - p[i*4 + 3] = 0; + p[i * 4] = palette[i * 3 + 2] >> bits; + p[i * 4 + 1] = palette[i * 3 + 1] >> bits; + p[i * 4 + 2] = palette[i * 3] >> bits; + p[i * 4 + 3] = 0; } x86bios_intr(®s, 0x10); x86bios_free(p, colors * 4); @@ -498,7 +496,6 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) return (regs.R_AX != 0x004f); } -#ifdef notyet static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits) @@ -523,17 +520,16 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, bits = 8 - bits; for (i = 0; i < colors; ++i) { - p[i*4] = b[i] >> bits; - p[i*4 + 1] = g[i] >> bits; - p[i*4 + 2] = r[i] >> bits; - p[i*4 + 3] = 0; + p[i * 4] = b[i] >> bits; + p[i * 4 + 1] = g[i] >> bits; + p[i * 4 + 2] = r[i] >> bits; + p[i * 4 + 3] = 0; } x86bios_intr(®s, 0x10); x86bios_free(p, colors * 4); return (regs.R_AX != 0x004f); } -#endif static ssize_t vesa_bios_state_buf_size(void) @@ -702,6 +698,7 @@ vesa_translate_flags(u_int16_t vflags) { V_MODECOLOR, V_INFO_COLOR, 0 }, { V_MODEGRAPHICS, V_INFO_GRAPHICS, 0 }, { V_MODELFB, V_INFO_LINEAR, 0 }, + { V_MODENONVGA, V_INFO_NONVGA, 0 }, }; int flags; int i; @@ -1275,7 +1272,8 @@ vesa_set_mode(video_adapter_t *adp, int mode) * the new mode correctly. */ if (VESA_MODE(adp->va_mode)) { - if ((*prevvidsw->get_info)(adp, mode, &info) == 0) { + if (!VESA_MODE(mode) && + (*prevvidsw->get_info)(adp, mode, &info) == 0) { int10_set_mode(adp->va_initial_bios_mode); if (adp->va_info.vi_flags & V_INFO_LINEAR) vesa_unmap_buffer(adp->va_buffer, @@ -1288,7 +1286,7 @@ vesa_set_mode(video_adapter_t *adp, int mode) } /* we may not need to handle this mode after all... */ - if ((*prevvidsw->set_mode)(adp, mode) == 0) + if (!VESA_MODE(mode) && (*prevvidsw->set_mode)(adp, mode) == 0) return (0); /* is the new mode supported? */ @@ -1306,6 +1304,9 @@ vesa_set_mode(video_adapter_t *adp, int mode) if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0))) return (1); + if ((vesa_adp_info->v_flags & V_DAC8) != 0) + vesa_bios_set_dac(8); + if (adp->va_info.vi_flags & V_INFO_LINEAR) vesa_unmap_buffer(adp->va_buffer, vesa_adp_info->v_memsize*64*1024); @@ -1382,17 +1383,11 @@ static int vesa_save_palette(video_adapter_t *adp, u_char *palette) { int bits; - int error; - if ((adp == vesa_adp) && (vesa_adp_info->v_flags & V_DAC8) - && VESA_MODE(adp->va_mode)) { - bits = vesa_bios_get_dac(); - error = vesa_bios_save_palette(0, 256, palette, bits); - if (error == 0) - return (0); - if (bits != 6) - return (error); - } + if ((adp == vesa_adp) && + (adp->va_info.vi_flags & V_INFO_NONVGA) != 0 && + (bits = vesa_bios_get_dac()) >= 6) + return (vesa_bios_save_palette(0, 256, palette, bits)); return ((*prevvidsw->save_palette)(adp, palette)); } @@ -1400,19 +1395,12 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette) static int vesa_load_palette(video_adapter_t *adp, u_char *palette) { -#ifdef notyet int bits; - int error; - if ((adp == vesa_adp) && (vesa_adp_info->v_flags & V_DAC8) - && VESA_MODE(adp->va_mode) && ((bits = vesa_bios_set_dac(8)) > 6)) { - error = vesa_bios_load_palette(0, 256, palette, bits); - if (error == 0) - return (0); - if (vesa_bios_set_dac(6) != 6) - return (1); - } -#endif /* notyet */ + if ((adp == vesa_adp) && + (adp->va_info.vi_flags & V_INFO_NONVGA) != 0 && + (bits = vesa_bios_get_dac()) >= 6) + return (vesa_bios_load_palette(0, 256, palette, bits)); return ((*prevvidsw->load_palette)(adp, palette)); } @@ -1637,14 +1625,11 @@ get_palette(video_adapter_t *adp, int base, int count, return (1); if ((base + count) > 256) return (1); - if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)) + if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0 || + (bits = vesa_bios_get_dac()) < 6) return (1); - bits = vesa_bios_get_dac(); - if (bits <= 6) - return (1); - - r = malloc(count*3, M_DEVBUF, M_WAITOK); + r = malloc(count * 3, M_DEVBUF, M_WAITOK); g = r + count; b = g + count; error = vesa_bios_save_palette2(base, count, r, g, b, bits); @@ -1659,7 +1644,6 @@ get_palette(video_adapter_t *adp, int base, int count, } free(r, M_DEVBUF); - /* if error && bits != 6 at this point, we are in trouble... XXX */ return (error); } @@ -1667,8 +1651,6 @@ static int set_palette(video_adapter_t *adp, int base, int count, u_char *red, u_char *green, u_char *blue, u_char *trans) { - return (1); -#ifdef notyet u_char *r; u_char *g; u_char *b; @@ -1677,11 +1659,11 @@ set_palette(video_adapter_t *adp, int base, int count, if ((base < 0) || (base >= 256) || (base + count > 256)) return (1); - if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode) - || ((bits = vesa_bios_set_dac(8)) <= 6)) + if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0 || + (bits = vesa_bios_get_dac()) < 6) return (1); - r = malloc(count*3, M_DEVBUF, M_WAITOK); + r = malloc(count * 3, M_DEVBUF, M_WAITOK); g = r + count; b = g + count; copyin(red, r, count); @@ -1690,13 +1672,8 @@ set_palette(video_adapter_t *adp, int base, int count, error = vesa_bios_load_palette2(base, count, r, g, b, bits); free(r, M_DEVBUF); - if (error == 0) - return (0); - /* if the following call fails, we are in trouble... XXX */ - vesa_bios_set_dac(6); - return (1); -#endif /* notyet */ + return (error); } static int diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 9ea8a6b9fe6..836db55eb5c 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -414,6 +414,9 @@ sc_attach_unit(int unit, int flags) #endif sc_set_graphics_mode(scp, NULL, vmode); sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8); +#ifndef SC_NO_PALETTE_LOADING + vidd_save_palette(sc->adp, sc->palette); +#endif sc->initial_mode = vmode; #ifdef DEV_SPLASH /* put up the splash again! */ diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h index c7183dfc38c..415ad966911 100644 --- a/sys/sys/fbio.h +++ b/sys/sys/fbio.h @@ -269,6 +269,7 @@ struct video_info { #define V_INFO_GRAPHICS (1 << 1) #define V_INFO_LINEAR (1 << 2) #define V_INFO_VESA (1 << 3) +#define V_INFO_NONVGA (1 << 4) int vi_width; int vi_height; int vi_cwidth; From 21293e70168c37da3ea5095339ff18c3dc867f65 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Tue, 3 Nov 2009 21:06:19 +0000 Subject: [PATCH 485/646] Belatedly add an UPDATING message for the usb ethernet ifnet naming in r188412. MFC after: 3 days --- UPDATING | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UPDATING b/UPDATING index 009edae3f3c..5e49f4dd966 100644 --- a/UPDATING +++ b/UPDATING @@ -537,6 +537,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW: # Map old usb library to new one for usb2 stack libusb-0.1.so.8 libusb20.so.1 +20090209: + All USB ethernet devices now attach as interfaces under the name ueN + (eg. ue0). This is to provide a predictable name as vendors often + change usb chipsets in a product without notice. + 20090203: The ichsmb(4) driver has been changed to require SMBus slave addresses be left-justified (xxxxxxx0b) rather than right-justified. From ca1d2f657ac8942f180f7d1ab328400ae8524bf0 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 3 Nov 2009 21:06:19 +0000 Subject: [PATCH 486/646] Make /dev/klog and kern.msgbuf* MPSAFE. Normally msgbufp is locked using Giant. Switch it to use the msgbuf_lock. Instead of changing the tsleep() calls to msleep(), just convert it to condvar(9). In my opinion the locking around msgbuf_peekbytes() still remains questionable. It looks like locks are dropped while performing copies of multiple blocks to userspace, which may cause the msgbuf to be reset in the mean time. At least getting it underneath from Giant should make it a little easier for us to figure out how to solve that. Reminded by: rdivacky --- sys/kern/subr_log.c | 73 +++++++++++++++++++++++++-------------------- sys/kern/subr_prf.c | 21 +++++++++---- sys/sys/msgbuf.h | 1 + 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index 01a3acc9851..972f9f94185 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #define LOG_RDPRI (PZERO + 1) #define LOG_ASYNC 0x04 -#define LOG_RDWAIT 0x08 static d_open_t logopen; static d_close_t logclose; @@ -65,7 +64,6 @@ static void logtimeout(void *arg); static struct cdevsw log_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = logopen, .d_close = logclose, .d_read = logread, @@ -81,7 +79,10 @@ static struct logsoftc { struct callout sc_callout; /* callout to wakeup syslog */ } logsoftc; -int log_open; /* also used in log() */ +int log_open; /* also used in log() */ +static struct cv log_wakeup; +struct mtx msgbuf_lock; +MTX_SYSINIT(msgbuf_lock, &msgbuf_lock, "msgbuf lock", MTX_DEF); /* Times per second to check for a pending syslog wakeup. */ static int log_wakeups_per_second = 5; @@ -92,17 +93,23 @@ SYSCTL_INT(_kern, OID_AUTO, log_wakeups_per_second, CTLFLAG_RW, static int logopen(struct cdev *dev, int flags, int mode, struct thread *td) { - if (log_open) - return (EBUSY); - log_open = 1; - callout_init(&logsoftc.sc_callout, 0); - fsetown(td->td_proc->p_pid, &logsoftc.sc_sigio); /* signal process only */ + if (log_wakeups_per_second < 1) { printf("syslog wakeup is less than one. Adjusting to 1.\n"); log_wakeups_per_second = 1; } + + mtx_lock(&msgbuf_lock); + if (log_open) { + mtx_unlock(&msgbuf_lock); + return (EBUSY); + } + log_open = 1; callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second, logtimeout, NULL); + mtx_unlock(&msgbuf_lock); + + fsetown(td->td_proc->p_pid, &logsoftc.sc_sigio); /* signal process only */ return (0); } @@ -111,10 +118,14 @@ static int logclose(struct cdev *dev, int flag, int mode, struct thread *td) { - log_open = 0; + funsetown(&logsoftc.sc_sigio); + + mtx_lock(&msgbuf_lock); callout_stop(&logsoftc.sc_callout); logsoftc.sc_state = 0; - funsetown(&logsoftc.sc_sigio); + log_open = 0; + mtx_unlock(&msgbuf_lock); + return (0); } @@ -124,32 +135,32 @@ logread(struct cdev *dev, struct uio *uio, int flag) { char buf[128]; struct msgbuf *mbp = msgbufp; - int error = 0, l, s; + int error = 0, l; - s = splhigh(); + mtx_lock(&msgbuf_lock); while (msgbuf_getcount(mbp) == 0) { if (flag & IO_NDELAY) { - splx(s); + mtx_unlock(&msgbuf_lock); return (EWOULDBLOCK); } - logsoftc.sc_state |= LOG_RDWAIT; - if ((error = tsleep(mbp, LOG_RDPRI | PCATCH, "klog", 0))) { - splx(s); + if ((error = cv_wait_sig(&log_wakeup, &msgbuf_lock)) != 0) { + mtx_unlock(&msgbuf_lock); return (error); } } - splx(s); - logsoftc.sc_state &= ~LOG_RDWAIT; while (uio->uio_resid > 0) { l = imin(sizeof(buf), uio->uio_resid); l = msgbuf_getbytes(mbp, buf, l); if (l == 0) break; + mtx_unlock(&msgbuf_lock); error = uiomove(buf, l, uio); - if (error) - break; + if (error || uio->uio_resid == 0) + return (error); + mtx_lock(&msgbuf_lock); } + mtx_unlock(&msgbuf_lock); return (error); } @@ -157,18 +168,16 @@ logread(struct cdev *dev, struct uio *uio, int flag) static int logpoll(struct cdev *dev, int events, struct thread *td) { - int s; int revents = 0; - s = splhigh(); - if (events & (POLLIN | POLLRDNORM)) { + mtx_lock(&msgbuf_lock); if (msgbuf_getcount(msgbufp) > 0) revents |= events & (POLLIN | POLLRDNORM); else selrecord(td, &logsoftc.sc_selp); + mtx_unlock(&msgbuf_lock); } - splx(s); return (revents); } @@ -183,20 +192,16 @@ logtimeout(void *arg) log_wakeups_per_second = 1; } if (msgbuftrigger == 0) { - callout_reset(&logsoftc.sc_callout, - hz / log_wakeups_per_second, logtimeout, NULL); + callout_schedule(&logsoftc.sc_callout, + hz / log_wakeups_per_second); return; } msgbuftrigger = 0; selwakeuppri(&logsoftc.sc_selp, LOG_RDPRI); if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL) pgsigio(&logsoftc.sc_sigio, SIGIO, 0); - if (logsoftc.sc_state & LOG_RDWAIT) { - wakeup(msgbufp); - logsoftc.sc_state &= ~LOG_RDWAIT; - } - callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second, - logtimeout, NULL); + cv_broadcastpri(&log_wakeup, LOG_RDPRI); + callout_schedule(&logsoftc.sc_callout, hz / log_wakeups_per_second); } /*ARGSUSED*/ @@ -215,10 +220,12 @@ logioctl(struct cdev *dev, u_long com, caddr_t data, int flag, struct thread *td break; case FIOASYNC: + mtx_lock(&msgbuf_lock); if (*(int *)data) logsoftc.sc_state |= LOG_ASYNC; else logsoftc.sc_state &= ~LOG_ASYNC; + mtx_unlock(&msgbuf_lock); break; case FIOSETOWN: @@ -247,6 +254,8 @@ static void log_drvinit(void *unused) { + cv_init(&log_wakeup, "klog"); + callout_init_mtx(&logsoftc.sc_callout, &msgbuf_lock, 0); make_dev(&log_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "klog"); } diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 5c34f408751..30e92cba4dd 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -923,16 +923,24 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) } /* Read the whole buffer, one chunk at a time. */ + mtx_lock(&msgbuf_lock); msgbuf_peekbytes(msgbufp, NULL, 0, &seq); - while ((len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq)) > 0) { + for (;;) { + len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq); + mtx_unlock(&msgbuf_lock); + if (len == 0) + return (0); + error = sysctl_handle_opaque(oidp, buf, len, req); if (error) return (error); + + mtx_lock(&msgbuf_lock); } - return (0); } -SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD, +SYSCTL_PROC(_kern, OID_AUTO, msgbuf, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer"); static int msgbuf_clearflag; @@ -943,15 +951,18 @@ sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS) int error; error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); if (!error && req->newptr) { + mtx_lock(&msgbuf_lock); msgbuf_clear(msgbufp); + mtx_unlock(&msgbuf_lock); msgbuf_clearflag = 0; } return (error); } SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear, - CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clearflag, 0, - sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer"); + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, + &msgbuf_clearflag, 0, sysctl_kern_msgbuf_clear, "I", + "Clear kernel message buffer"); #ifdef DDB diff --git a/sys/sys/msgbuf.h b/sys/sys/msgbuf.h index 61c79a1b6f7..23bce08ceca 100644 --- a/sys/sys/msgbuf.h +++ b/sys/sys/msgbuf.h @@ -54,6 +54,7 @@ struct msgbuf { #ifdef _KERNEL extern int msgbuftrigger; extern struct msgbuf *msgbufp; +extern struct mtx msgbuf_lock; void msgbufinit(void *ptr, int size); void msgbuf_addchar(struct msgbuf *mbp, int c); From 35e8cd5f52e7c3fc5b162984d8553719bf0cb2f8 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Tue, 3 Nov 2009 21:47:07 +0000 Subject: [PATCH 487/646] fixes a typo that value should be 0 not 10. --- sys/dev/usb/wlan/if_urtw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 938107ae6dd..00789b89acc 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -1688,7 +1688,7 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, ieee80211_radiotap_tx(vap, m0); } - if ((wh->i_fc[10] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT || + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT || (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) { tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; rate = tp->mgmtrate; From 1f45f0733bc8f0637cbeb12c8c6a6cd9f413388d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 3 Nov 2009 23:26:58 +0000 Subject: [PATCH 488/646] Fix constants. --- sys/sys/ata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/sys/ata.h b/sys/sys/ata.h index fa91e3bdc98..91e3b534eff 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -207,8 +207,8 @@ struct ata_params { u_int16_t reserved104[2]; /*106*/ u_int16_t pss; #define ATA_PSS_LSPPS 0x000F -#define ATA_PSS_LSSABOVE512 0x2000 -#define ATA_PSS_MULTLS 0x4000 +#define ATA_PSS_LSSABOVE512 0x1000 +#define ATA_PSS_MULTLS 0x2000 /*107*/ u_int16_t isd; /*108*/ u_int16_t wwn[4]; u_int16_t reserved112[5]; From 7ac3e951e3947e3e78399bc98f11129ef96d0a1a Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 4 Nov 2009 00:58:20 +0000 Subject: [PATCH 489/646] Save/restore VGA color palette while suspending and resuming. --- sys/dev/fb/vgareg.h | 1 + sys/isa/vga_isa.c | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/sys/dev/fb/vgareg.h b/sys/dev/fb/vgareg.h index 0a73fbd5e1c..fa9d44eaef1 100644 --- a/sys/dev/fb/vgareg.h +++ b/sys/dev/fb/vgareg.h @@ -70,6 +70,7 @@ struct video_adapter; typedef struct vga_softc { struct video_adapter *adp; void *state_buf; + void *pal_buf; #ifdef FB_INSTALL_CDEV genfb_softc_t gensc; #endif diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index 3d7cd3ad9fd..d31df7e8c38 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -179,17 +179,33 @@ isavga_suspend(device_t dev) nbytes = vidd_save_state(sc->adp, NULL, 0); if (nbytes <= 0) return (0); - sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT | M_ZERO); - if (sc->state_buf == NULL) - return (0); - if (bootverbose) - device_printf(dev, "saving %d bytes of video state\n", nbytes); - if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { - device_printf(dev, "failed to save state (nbytes=%d)\n", - nbytes); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; + sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); + if (sc->state_buf != NULL) { + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", + nbytes); + if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { + device_printf(dev, "failed to save state (nbytes=%d)\n", + nbytes); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } } + + /* Save the color palette across the suspend. */ + if (sc->pal_buf != NULL) + free(sc->pal_buf, M_TEMP); + sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); + if (sc->pal_buf != NULL) { + if (bootverbose) + device_printf(dev, "saving color palette\n"); + if (vidd_save_palette(sc->adp, sc->pal_buf) != 0) { + device_printf(dev, "failed to save palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } + } + return (0); } @@ -205,6 +221,12 @@ isavga_resume(device_t dev) free(sc->state_buf, M_TEMP); sc->state_buf = NULL; } + if (sc->pal_buf != NULL) { + if (vidd_load_palette(sc->adp, sc->pal_buf) != 0) + device_printf(dev, "failed to reload palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } bus_generic_resume(dev); return 0; From 421cd2f2fbf74396056775a94394cdff1728ed39 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 4 Nov 2009 01:00:28 +0000 Subject: [PATCH 490/646] Restore color palette format if we reset video mode. --- sys/dev/fb/vesa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index c2521c5ad48..6d3ffcc172b 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -1470,6 +1470,8 @@ vesa_load_state(video_adapter_t *adp, void *p) (flags & V_INFO_LINEAR) != 0) mode |= 0x4000; (void)vesa_bios_set_mode(mode); + if ((vesa_adp_info->v_flags & V_DAC8) != 0) + (void)vesa_bios_set_dac(8); (void)(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); } From 06db609d4a0ad09f0590576003f7f1a7bef0d057 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Wed, 4 Nov 2009 01:32:59 +0000 Subject: [PATCH 491/646] Opteron rev E family of processor expose a bug where, in very rare ocassions, memory barriers semantic is not honoured by the hardware itself. As a result, some random breakage can happen in uninvestigable ways (for further explanation see at the content of the commit itself). As long as just a specific familly is bugged of an entire architecture is broken, a complete fix-up is impratical without harming to some extents the other correct cases. Considering that (and considering the frequency of the bug exposure) just print out a warning message if the affected machine is identified. Pointed out by: Samy Al Bahra Help on wordings by: jeff MFC: 3 days --- sys/amd64/amd64/identcpu.c | 18 ++++++++++++++++++ sys/i386/i386/identcpu.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index 766977df23d..b50c29b5651 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -607,6 +607,24 @@ print_AMD_info(void) printf(", %d lines/tag", (regs[2] >> 8) & 0x0f); print_AMD_l2_assoc((regs[2] >> 12) & 0x0f); } + + /* + * Opteron Rev E shows a bug as in very rare occasions a read memory + * barrier is not performed as expected if it is followed by a + * non-atomic read-modify-write instruction. + * As long as that bug pops up very rarely (intensive machine usage + * on other operating systems generally generates one unexplainable + * crash any 2 months) and as long as a model specific fix would be + * impratical at this stage, print out a warning string if the broken + * model and family are identified. + */ + if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && + CPUID_TO_MODEL(cpu_id) <= 0x3f) { + printf("WARNING: This architecture revision has known SMP " + "hardware bugs which may cause random instability\n"); + printf("WARNING: For details see: " + "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); + } } static void diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index 66c5fed5fa6..e8210c26528 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -1303,6 +1303,24 @@ print_AMD_info(void) (amd_whcr & 0x0100) ? "Enable" : "Disable"); } } + + /* + * Opteron Rev E shows a bug as in very rare occasions a read memory + * barrier is not performed as expected if it is followed by a + * non-atomic read-modify-write instruction. + * As long as that bug pops up very rarely (intensive machine usage + * on other operating systems generally generates one unexplainable + * crash any 2 months) and as long as a model specific fix would be + * impratical at this stage, print out a warning string if the broken + * model and family are identified. + */ + if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && + CPUID_TO_MODEL(cpu_id) <= 0x3f) { + printf("WARNING: This architecture revision has known SMP " + "hardware bugs which may cause random instability\n"); + printf("WARNING: For details see: " + "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); + } } static void From 2dd02f47734da959b1fae17bcbd6df34d19b0ff2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 4 Nov 2009 03:12:56 +0000 Subject: [PATCH 492/646] Eliminate an unnecessary #include. (This #include should have been removed in r188331 when vnode_pager_lock() was eliminated.) --- sys/vm/vm_fault.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 55b4173bb7c..b10270c9cb0 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -96,7 +96,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include /* XXX Temporary for VFS_LOCK_GIANT() */ From 9d44cd42c11a2d64b4dde1e2c47b38eb8c5be3de Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Wed, 4 Nov 2009 04:12:56 +0000 Subject: [PATCH 493/646] Fix typo (noded -> nodes). --- share/man/man3/tree.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man3/tree.3 b/share/man/man3/tree.3 index aa53eb134c7..46efbbba305 100644 --- a/share/man/man3/tree.3 +++ b/share/man/man3/tree.3 @@ -384,7 +384,7 @@ macros, but should be used only once. Finally, the .Fa CMP -argument is the name of a function used to compare tree noded +argument is the name of a function used to compare tree nodes with each other. The function takes two arguments of type .Vt "struct TYPE *" . From c346328f95027d94e50394c8009f6f201c00c265 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 4 Nov 2009 04:41:03 +0000 Subject: [PATCH 494/646] Eliminate an unnecessary vm include file. --- sys/arm/arm/machdep.c | 1 - sys/arm/at91/at91_machdep.c | 1 - sys/arm/mv/mv_machdep.c | 1 - sys/arm/sa11x0/assabet_machdep.c | 1 - 4 files changed, 4 deletions(-) diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index f49319e50b9..49af8e2cdf4 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index 8235000738c..1e63ee6a9ca 100644 --- a/sys/arm/at91/at91_machdep.c +++ b/sys/arm/at91/at91_machdep.c @@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c index 2dc20ceb08e..10890f7d16d 100644 --- a/sys/arm/mv/mv_machdep.c +++ b/sys/arm/mv/mv_machdep.c @@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/arm/sa11x0/assabet_machdep.c b/sys/arm/sa11x0/assabet_machdep.c index 521f3c309e6..c02595ffed6 100644 --- a/sys/arm/sa11x0/assabet_machdep.c +++ b/sys/arm/sa11x0/assabet_machdep.c @@ -82,7 +82,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include From 597954c813a7afdae481e233375f7494c4a7c1d2 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 4 Nov 2009 06:47:14 +0000 Subject: [PATCH 495/646] While VAPPEND without VWRITE makes sense for VOP_ACCESSX(9) (e.g. to check for the permission to create subdirectory (ACE4_ADD_SUBDIRECTORY)), it doesn't really make sense for VOP_ACCESS(9). Also, many VOP_ACCESS(9) implementations don't expect that. Make sure we don't confuse them. --- sys/kern/vfs_default.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index b80d03d0e9e..d37e0662f26 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -353,6 +353,14 @@ vop_stdaccessx(struct vop_accessx_args *ap) if (accmode == 0) return (0); + /* + * Many VOP_APPEND implementations don't expect VAPPEND without VWRITE + * being set, e.g. they check whether the filesystem is read-only only + * when VWRITE is set. Make sure we don't confuse them. + */ + if (accmode & VAPPEND) + accmode |= VWRITE; + return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td)); } From 8fafa5cecf776708e0cd5aa075d316eae17c3e46 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 4 Nov 2009 06:48:34 +0000 Subject: [PATCH 496/646] Make sure we don't end up with VAPPEND without VWRITE, if someone calls open(2) like this: open(..., O_APPEND). --- sys/kern/vfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 03e8d938bac..37f0200d6f1 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -213,7 +213,7 @@ restart: if (fmode & FEXEC) accmode |= VEXEC; if (fmode & O_APPEND) - accmode |= VAPPEND; + accmode |= VWRITE | VAPPEND; #ifdef MAC error = mac_vnode_check_open(cred, vp, accmode); if (error) From da9ce28ecbd36196e06ebc17a8d6a6c39c736b6d Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 4 Nov 2009 07:04:15 +0000 Subject: [PATCH 497/646] Style fixes. --- sys/kern/vfs_acl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index 2dd64f44e45..df4ee519058 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -213,7 +213,7 @@ vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, inkernelacl = acl_alloc(M_WAITOK); error = acl_copyin(aclp, inkernelacl, type); - if (error) + if (error != 0) goto out; error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error != 0) @@ -233,7 +233,7 @@ out_unlock: vn_finished_write(mp); out: acl_free(inkernelacl); - return(error); + return (error); } /* @@ -276,12 +276,12 @@ vacl_delete(struct thread *td, struct vnode *vp, acl_type_t type) int error; error = vn_start_write(vp, &mp, V_WAIT | PCATCH); - if (error) + if (error != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); #ifdef MAC error = mac_vnode_check_deleteacl(td->td_ucred, vp, type); - if (error) + if (error != 0) goto out; #endif error = VOP_SETACL(vp, acl_type_unold(type), 0, td->td_ucred, td); @@ -305,7 +305,7 @@ vacl_aclcheck(struct thread *td, struct vnode *vp, acl_type_t type, inkernelacl = acl_alloc(M_WAITOK); error = acl_copyin(aclp, inkernelacl, type); - if (error) + if (error != 0) goto out; error = VOP_ACLCHECK(vp, type, inkernelacl, td->td_ucred, td); out: @@ -501,7 +501,7 @@ __acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap) int __acl_aclcheck_file(struct thread *td, struct __acl_aclcheck_file_args *uap) { - struct nameidata nd; + struct nameidata nd; int vfslocked, error; NDINIT(&nd, LOOKUP, MPSAFE|FOLLOW, UIO_USERSPACE, uap->path, td); @@ -521,7 +521,7 @@ __acl_aclcheck_file(struct thread *td, struct __acl_aclcheck_file_args *uap) int __acl_aclcheck_link(struct thread *td, struct __acl_aclcheck_link_args *uap) { - struct nameidata nd; + struct nameidat nd; int vfslocked, error; NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td); From 3b1b09809ff8e566dd160de2132b703b5de03ce1 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 4 Nov 2009 07:14:16 +0000 Subject: [PATCH 498/646] Revert r198874, pending further discussion. --- sys/kern/vfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 37f0200d6f1..03e8d938bac 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -213,7 +213,7 @@ restart: if (fmode & FEXEC) accmode |= VEXEC; if (fmode & O_APPEND) - accmode |= VWRITE | VAPPEND; + accmode |= VAPPEND; #ifdef MAC error = mac_vnode_check_open(cred, vp, accmode); if (error) From 7a172809b5e3d8d5ed73db4c11115fdc4b189425 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 4 Nov 2009 08:25:58 +0000 Subject: [PATCH 499/646] Fix build. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Andrius Morkナォnas --- sys/kern/vfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index df4ee519058..a6a1ebfca77 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -521,7 +521,7 @@ __acl_aclcheck_file(struct thread *td, struct __acl_aclcheck_file_args *uap) int __acl_aclcheck_link(struct thread *td, struct __acl_aclcheck_link_args *uap) { - struct nameidat nd; + struct nameidata nd; int vfslocked, error; NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td); From c82b245af96d94a1781ff2249e414f565c49cc25 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 4 Nov 2009 15:10:46 +0000 Subject: [PATCH 500/646] Do not unarm callout on request completion and change slot selection algorithm as done in ahci(4). This saves some CPU time on high request rates. --- sys/dev/siis/siis.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 8bd813e1fd8..adc68e43301 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -641,6 +641,7 @@ siis_slotsfree(device_t dev) for (i = 0; i < SIIS_MAX_SLOTS; i++) { struct siis_slot *slot = &ch->slot[i]; + callout_drain(&slot->timeout); if (slot->dma.data_map) { bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); slot->dma.data_map = NULL; @@ -838,15 +839,11 @@ siis_begin_transaction(device_t dev, union ccb *ccb) mtx_assert(&ch->mtx, MA_OWNED); /* Choose empty slot. */ tag = ch->lastslot; - do { - tag++; - if (tag >= SIIS_MAX_SLOTS) + while (ch->slot[tag].state != SIIS_SLOT_EMPTY) { + if (++tag >= SIIS_MAX_SLOTS) tag = 0; - if (ch->slot[tag].state == SIIS_SLOT_EMPTY) - break; - } while (tag != ch->lastslot); - if (ch->slot[tag].state != SIIS_SLOT_EMPTY) - device_printf(ch->dev, "ALL SLOTS BUSY!\n"); + KASSERT(tag != ch->lastslot, ("siis: ALL SLOTS BUSY!")); + } ch->lastslot = tag; /* Occupy chosen slot. */ slot = &ch->slot[tag]; @@ -999,6 +996,9 @@ siis_timeout(struct siis_slot *slot) struct siis_channel *ch = device_get_softc(dev); mtx_assert(&ch->mtx, MA_OWNED); + /* Check for stale timeout. */ + if (slot->state < SIIS_SLOT_RUNNING) + return; device_printf(dev, "Timeout on slot %d\n", slot->slot); device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n", __func__, ATA_INL(ch->r_mem, SIIS_P_IS), ATA_INL(ch->r_mem, SIIS_P_SS), ch->rslots, @@ -1024,8 +1024,6 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) union ccb *ccb = slot->ccb; mtx_assert(&ch->mtx, MA_OWNED); - /* Cancel command execution timeout */ - callout_stop(&slot->timeout); bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, BUS_DMASYNC_POSTWRITE); /* Read result registers to the result struct From c1bd46c2d37b58621ee30075a6bb7262e83f2133 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 4 Nov 2009 15:24:32 +0000 Subject: [PATCH 501/646] MFp4: - Add support for sector size > 512 bytes and physical sector of several logical sectors, introduced by ATA-7 specification. - Remove some obsoleted code. --- sbin/camcontrol/camcontrol.c | 4 ++++ sys/cam/ata/ata_all.c | 32 +++++++++++++++++++++++++ sys/cam/ata/ata_all.h | 4 ++++ sys/cam/ata/ata_da.c | 46 +++++++++++++----------------------- sys/cam/ata/ata_xpt.c | 6 +++-- sys/sys/ata.h | 2 +- 6 files changed, 61 insertions(+), 33 deletions(-) diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index c0753e7b621..728b691c6dc 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -1061,6 +1061,10 @@ atacapprint(struct ata_params *parm) printf("cylinders %d\n", parm->cylinders); printf("heads %d\n", parm->heads); printf("sectors/track %d\n", parm->sectors); + printf("sector size logical %u, physical %lu, offset %lu\n", + ata_logical_sector_size(parm), + (unsigned long)ata_physical_sector_size(parm), + (unsigned long)ata_logical_sector_offset(parm)); if (parm->config == ATA_PROTO_CFA || (parm->support.command2 & ATA_SUPPORT_CFA)) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 85548e337a9..35b4ca257ed 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -271,6 +271,38 @@ ata_print_ident(struct ata_params *ident_data) printf(" device\n"); } +uint32_t +ata_logical_sector_size(struct ata_params *ident_data) +{ + if ((ident_data->pss & 0xc000) == 0x4000 && + (ident_data->pss & ATA_PSS_LSSABOVE512)) { + return ((u_int32_t)ident_data->lss_1 | + ((u_int32_t)ident_data->lss_2 << 16)); + } + return (512); +} + +uint64_t +ata_physical_sector_size(struct ata_params *ident_data) +{ + if ((ident_data->pss & 0xc000) == 0x4000 && + (ident_data->pss & ATA_PSS_MULTLS)) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (1 << (ident_data->pss & ATA_PSS_LSPPS))); + } + return (512); +} + +uint64_t +ata_logical_sector_offset(struct ata_params *ident_data) +{ + if ((ident_data->lsalign & 0xc000) == 0x4000) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (ident_data->lsalign & 0x3fff)); + } + return (0); +} + void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count) diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index 404f817533d..a86d348b2fc 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -91,6 +91,10 @@ int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); void ata_print_ident(struct ata_params *ident_data); +uint32_t ata_logical_sector_size(struct ata_params *ident_data); +uint64_t ata_physical_sector_size(struct ata_params *ident_data); +uint64_t ata_logical_sector_offset(struct ata_params *ident_data); + void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count); void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features, diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 76ed3d2b57f..f09713b0d0f 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -95,16 +95,14 @@ typedef enum { struct disk_params { u_int8_t heads; - u_int32_t cylinders; u_int8_t secs_per_track; - u_int32_t secsize; /* Number of bytes/sector */ - u_int64_t sectors; /* total number sectors */ + u_int32_t cylinders; + u_int32_t secsize; /* Number of bytes/logical sector */ + u_int64_t sectors; /* Total number sectors */ }; struct ada_softc { struct bio_queue_head bio_queue; - SLIST_ENTRY(ada_softc) links; - LIST_HEAD(, ccb_hdr) pending_ccbs; ada_state state; ada_flags flags; ada_quirks quirks; @@ -142,7 +140,7 @@ static void adadone(struct cam_periph *periph, union ccb *done_ccb); static int adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); -static void adasetgeom(struct cam_periph *periph, +static void adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd); static timeout_t adasendorderedtag; static void adashutdown(void *arg, int howto); @@ -613,7 +611,6 @@ adaregister(struct cam_periph *periph, void *arg) return(CAM_REQ_CMP_ERR); } - LIST_INIT(&softc->pending_ccbs); bioq_init(&softc->bio_queue); if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) @@ -658,6 +655,7 @@ adaregister(struct cam_periph *periph, void *arg) * Register this media as a disk */ mtx_unlock(periph->sim->mtx); + adagetparams(periph, cgd); softc->disk = disk_alloc(); softc->disk->d_open = adaopen; softc->disk->d_close = adaclose; @@ -671,9 +669,9 @@ adaregister(struct cam_periph *periph, void *arg) else if (maxio > MAXPHYS) maxio = MAXPHYS; /* for safety */ if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) - maxio = min(maxio, 65536 * 512); + maxio = min(maxio, 65536 * softc->params.secsize); else /* 28bit ATA command limit */ - maxio = min(maxio, 256 * 512); + maxio = min(maxio, 256 * softc->params.secsize); softc->disk->d_maxsize = maxio; softc->disk->d_unit = periph->unit_number; softc->disk->d_flags = 0; @@ -682,9 +680,12 @@ adaregister(struct cam_periph *periph, void *arg) strlcpy(softc->disk->d_ident, cgd->serial_num, MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1)); - adasetgeom(periph, cgd); softc->disk->d_sectorsize = softc->params.secsize; - softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; + softc->disk->d_mediasize = (off_t)softc->params.sectors * + softc->params.secsize; + softc->disk->d_stripesize = ata_physical_sector_size(&cgd->ident_data); + softc->disk->d_stripeoffset = softc->disk->d_stripesize - + ata_logical_sector_offset(&cgd->ident_data); /* XXX: these are not actually "firmware" values, so they may be wrong */ softc->disk->d_fwsectors = softc->params.secs_per_track; softc->disk->d_fwheads = softc->params.heads; @@ -852,19 +853,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) break; } start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO; - - /* - * Block out any asyncronous callbacks - * while we touch the pending ccb list. - */ - LIST_INSERT_HEAD(&softc->pending_ccbs, - &start_ccb->ccb_h, periph_links.le); - softc->outstanding_cmds++; - start_ccb->ccb_h.ccb_bp = bp; - bp = bioq_first(&softc->bio_queue); - + softc->outstanding_cmds++; xpt_action(start_ccb); + bp = bioq_first(&softc->bio_queue); } if (bp != NULL) { @@ -941,12 +933,6 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) if (ataio->resid > 0) bp->bio_flags |= BIO_ERROR; } - - /* - * Block out any asyncronous callbacks - * while we touch the pending ccb list. - */ - LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); softc->outstanding_cmds--; if (softc->outstanding_cmds == 0) softc->flags |= ADA_FLAG_WENT_IDLE; @@ -983,14 +969,14 @@ adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) } static void -adasetgeom(struct cam_periph *periph, struct ccb_getdev *cgd) +adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd) { struct ada_softc *softc = (struct ada_softc *)periph->softc; struct disk_params *dp = &softc->params; u_int64_t lbasize48; u_int32_t lbasize; - dp->secsize = 512; + dp->secsize = ata_logical_sector_size(&cgd->ident_data); if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) && cgd->ident_data.current_heads && cgd->ident_data.current_sectors) { dp->heads = cgd->ident_data.current_heads; diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 065f3ee70a9..56371ee52bd 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -363,10 +363,12 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { - cts.xport_specific.ata.bytecount = sectors * 512; + cts.xport_specific.ata.bytecount = sectors * + ata_logical_sector_size(ident_buf); cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; } else { - cts.xport_specific.sata.bytecount = sectors * 512; + cts.xport_specific.sata.bytecount = sectors * + ata_logical_sector_size(ident_buf); cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; } xpt_action((union ccb *)&cts); diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 91e3b534eff..e6dd2fe22ad 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -234,7 +234,7 @@ struct ata_params { /*176*/ u_int8_t media_serial[60]; /*206*/ u_int16_t sct; u_int16_t reserved206[2]; -/*209*/ u_int16_t lbalign; +/*209*/ u_int16_t lsalign; /*210*/ u_int16_t wrv_sectors_m3_1; u_int16_t wrv_sectors_m3_2; /*212*/ u_int16_t wrv_sectors_m2_1; From efa575b6be201f52e0956c4f4941554227557a56 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 4 Nov 2009 15:40:19 +0000 Subject: [PATCH 502/646] MFp4: - Remove CAM_PERIPH_POLLED flag. It is broken by design. Polling can't be periph flag. May be SIM, may be CCB, but now it works fine just without it. - Remove check unused for at least five years. If we will ever have non-BIO devices in CAM, this check is smallest of what we will need. - If several controllers complete requests same time, call swi_sched() only once. --- sys/cam/ata/ata_da.c | 2 -- sys/cam/cam_periph.h | 1 - sys/cam/cam_xpt.c | 31 ++++++++++++------------------- sys/cam/scsi/scsi_da.c | 3 --- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index f09713b0d0f..12719edc4dc 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -371,7 +371,6 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len } if (length > 0) { - periph->flags |= CAM_PERIPH_POLLED; xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); ccb.ccb_h.ccb_state = ADA_CCB_DUMP; cam_fill_ataio(&ccb.ataio, @@ -431,7 +430,6 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len /*timeout*/0, /*getcount_only*/0); } - periph->flags &= ~CAM_PERIPH_POLLED; cam_periph_unlock(periph); return (0); } diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index 258055f5bfc..07caf52d08a 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -117,7 +117,6 @@ struct cam_periph { #define CAM_PERIPH_INVALID 0x08 #define CAM_PERIPH_NEW_DEV_FOUND 0x10 #define CAM_PERIPH_RECOVERY_INPROG 0x20 -#define CAM_PERIPH_POLLED 0x40 u_int32_t immediate_priority; u_int32_t refcount; SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 8c568ecc452..e09308457a9 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -4238,6 +4238,7 @@ void xpt_done(union ccb *done_ccb) { struct cam_sim *sim; + int first; CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n")); if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) { @@ -4246,25 +4247,17 @@ xpt_done(union ccb *done_ccb) * any of the "non-immediate" type of ccbs. */ sim = done_ccb->ccb_h.path->bus->sim; - switch (done_ccb->ccb_h.path->periph->type) { - case CAM_PERIPH_BIO: - TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h, - sim_links.tqe); - done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX; - if ((sim->flags & CAM_SIM_ON_DONEQ) == 0) { - mtx_lock(&cam_simq_lock); - TAILQ_INSERT_TAIL(&cam_simq, sim, - links); - mtx_unlock(&cam_simq_lock); - sim->flags |= CAM_SIM_ON_DONEQ; - if ((done_ccb->ccb_h.path->periph->flags & - CAM_PERIPH_POLLED) == 0) - swi_sched(cambio_ih, 0); - } - break; - default: - panic("unknown periph type %d", - done_ccb->ccb_h.path->periph->type); + TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h, + sim_links.tqe); + done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX; + if ((sim->flags & CAM_SIM_ON_DONEQ) == 0) { + mtx_lock(&cam_simq_lock); + first = TAILQ_EMPTY(&cam_simq); + TAILQ_INSERT_TAIL(&cam_simq, sim, links); + mtx_unlock(&cam_simq_lock); + sim->flags |= CAM_SIM_ON_DONEQ; + if (first) + swi_sched(cambio_ih, 0); } } } diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 32ca51bb379..d05376ee295 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -859,7 +859,6 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng } if (length > 0) { - periph->flags |= CAM_PERIPH_POLLED; xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); csio.ccb_h.ccb_state = DA_CCB_DUMP; scsi_read_write(&csio, @@ -885,7 +884,6 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng else printf("status == 0x%x, scsi status == 0x%x\n", csio.ccb_h.status, csio.scsi_status); - periph->flags |= CAM_PERIPH_POLLED; return(EIO); } cam_periph_unlock(periph); @@ -929,7 +927,6 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng } } } - periph->flags &= ~CAM_PERIPH_POLLED; cam_periph_unlock(periph); return (0); } From fd2cc0bde8270266db0d8e874008c41c1e0fa517 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 4 Nov 2009 16:16:50 +0000 Subject: [PATCH 503/646] PMP commands use short format. PMP write doesn't return result. --- sys/cam/ata/ata_all.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 35b4ca257ed..266dc32ceab 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -368,30 +368,24 @@ void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port) { bzero(&ataio->cmd, sizeof(ataio->cmd)); - ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT; + ataio->cmd.flags = CAM_ATAIO_NEEDRESULT; ataio->cmd.command = ATA_READ_PM; ataio->cmd.features = reg; - ataio->cmd.features_exp = reg >> 8; ataio->cmd.device = port & 0x0f; } void -ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint64_t val) +ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val) { bzero(&ataio->cmd, sizeof(ataio->cmd)); - ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT; + ataio->cmd.flags = 0; ataio->cmd.command = ATA_WRITE_PM; ataio->cmd.features = reg; + ataio->cmd.sector_count = val; ataio->cmd.lba_low = val >> 8; ataio->cmd.lba_mid = val >> 16; ataio->cmd.lba_high = val >> 24; ataio->cmd.device = port & 0x0f; - ataio->cmd.lba_low_exp = val >> 40; - ataio->cmd.lba_mid_exp = val >> 48; - ataio->cmd.lba_high_exp = val >> 56; - ataio->cmd.features_exp = reg >> 8; - ataio->cmd.sector_count = val; - ataio->cmd.sector_count_exp = val >> 32; } void From 2a3510fd51c8d6d66a4d52827d6efbec1841b503 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 4 Nov 2009 16:37:13 +0000 Subject: [PATCH 504/646] Fix protype. --- sys/cam/ata/ata_all.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index a86d348b2fc..b711df7a8f0 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -103,7 +103,7 @@ void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint64_t lba, uint16_t sector_count); void ata_reset_cmd(struct ccb_ataio *ataio); void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port); -void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint64_t val); +void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val); void ata_bswap(int8_t *buf, int len); void ata_btrim(int8_t *buf, int len); From 00b9e39e685251fb367efd85142bb3dda8b90974 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 4 Nov 2009 17:30:48 +0000 Subject: [PATCH 505/646] Do not probe video mode if we are not going to use it. --- sys/dev/fb/vesa.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index 6d3ffcc172b..540335286bd 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -1450,10 +1450,11 @@ vesa_load_state(video_adapter_t *adp, void *p) * If the current mode is not the same, probably it was powered down. * Try BIOS POST to restore a sane state. */ - mode = vesa_bios_get_current_mode(); - if (mode >= 0 && (mode & 0x1ff) != adp->va_mode && - VESA_MODE(adp->va_mode)) - (void)vesa_bios_post(); + if (VESA_MODE(adp->va_mode)) { + mode = vesa_bios_get_current_mode(); + if (mode >= 0 && (mode & 0x1ff) != adp->va_mode) + (void)vesa_bios_post(); + } ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, vesa_state_buf_size); @@ -1461,9 +1462,10 @@ vesa_load_state(video_adapter_t *adp, void *p) /* * If the desired mode is not restored, force setting the mode. */ - mode = vesa_bios_get_current_mode(); - if (mode >= 0 && (mode & 0x1ff) != adp->va_mode && - VESA_MODE(adp->va_mode)) { + if (VESA_MODE(adp->va_mode)) { + mode = vesa_bios_get_current_mode(); + if (mode < 0 || (mode & 0x1ff) == adp->va_mode) + return (ret); mode = adp->va_mode; flags = adp->va_info.vi_flags; if ((flags & V_INFO_GRAPHICS) != 0 && From 4c061eaa531c4309b749e30ca82237834a6a6714 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Wed, 4 Nov 2009 18:40:05 +0000 Subject: [PATCH 506/646] Fix not only the grammar, but also the formatting that makes the gag --- games/fortune/datfiles/fortunes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes index 057bdeb1be1..d9ee0147d42 100644 --- a/games/fortune/datfiles/fortunes +++ b/games/fortune/datfiles/fortunes @@ -25228,7 +25228,8 @@ them scream. -- Sylvestre Matuschka, "the Hungarian Train Wreck Freak", escaped prison 1937, not heard from since % -Iam +I +am not very happy From a41504a9b19b289649ea3091402e144eaf45f0fb Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 4 Nov 2009 20:19:21 +0000 Subject: [PATCH 507/646] Use correct dma tag for jumbo buffer. --- sys/dev/bge/if_bge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 39990b00b72..24f8d5af717 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1031,7 +1031,7 @@ bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m) panic("%s: %d segments\n", __func__, nsegs); } - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_mtag_jumbo, sc->bge_cdata.bge_rx_jumbo_dmamap[i], BUS_DMASYNC_PREREAD); From a23634a1771448dbc24ff47b3e6e0e5cea5b1389 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 4 Nov 2009 20:40:38 +0000 Subject: [PATCH 508/646] Covert bge_newbuf_std to use bus_dmamap_load_mbuf_sg(9). Note, bge_newbuf_std still has a bug for handling dma map load failure under high network load. Just reusing mbuf is not enough as driver already unloaded the dma map of the mbuf. Graceful recovery needs more work. Ideally we can just update dma address part of a Rx descriptor because the controller never overwrite the Rx descriptor. This requires some Rx initialization code changes and it would be done later after fixing other incorrect bus_dma(9) usages. --- sys/dev/bge/if_bge.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 24f8d5af717..1e6dfa66d74 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -916,8 +916,8 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) { struct mbuf *m_new = NULL; struct bge_rx_bd *r; - struct bge_dmamap_arg ctx; - int error; + bus_dma_segment_t segs[1]; + int error, nsegs; if (m == NULL) { m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); @@ -932,24 +932,21 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0) m_adj(m_new, ETHER_ALIGN); - sc->bge_cdata.bge_rx_std_chain[i] = m_new; - r = &sc->bge_ldata.bge_rx_std_ring[i]; - ctx.bge_maxsegs = 1; - ctx.sc = sc; - error = bus_dmamap_load(sc->bge_cdata.bge_mtag, - sc->bge_cdata.bge_rx_std_dmamap[i], mtod(m_new, void *), - m_new->m_len, bge_dma_map_addr, &ctx, BUS_DMA_NOWAIT); - if (error || ctx.bge_maxsegs == 0) { + error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, + sc->bge_cdata.bge_rx_std_dmamap[i], m_new, segs, &nsegs, 0); + if (error != 0) { if (m == NULL) { sc->bge_cdata.bge_rx_std_chain[i] = NULL; m_freem(m_new); } - return (ENOMEM); + return (error); } - r->bge_addr.bge_addr_lo = BGE_ADDR_LO(ctx.bge_busaddr); - r->bge_addr.bge_addr_hi = BGE_ADDR_HI(ctx.bge_busaddr); + sc->bge_cdata.bge_rx_std_chain[i] = m_new; + r = &sc->bge_ldata.bge_rx_std_ring[i]; + r->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[0].ds_addr); + r->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[0].ds_addr); r->bge_flags = BGE_RXBDFLAG_END; - r->bge_len = m_new->m_len; + r->bge_len = segs[0].ds_len; r->bge_idx = i; bus_dmamap_sync(sc->bge_cdata.bge_mtag, From 0ac56796f7a2a74a1527668e0ccc17e93374e5a3 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 4 Nov 2009 20:57:52 +0000 Subject: [PATCH 509/646] Remove common DMA tag used for TX/RX mbufs and create Tx DMA tag and Rx DMA tag separately. Previously it used a common mbuf DMA tag for both Tx and Rx path but Rx buffer(standard ring case) should have a single DMA segment and maximum buffer size of the segment should be less than or equal to MCLBYTES. This change also make it possible to add TSO with minor changes. --- sys/dev/bge/if_bge.c | 64 +++++++++++++++++++++++++---------------- sys/dev/bge/if_bgereg.h | 5 ++-- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 1e6dfa66d74..92911669c37 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -932,7 +932,7 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0) m_adj(m_new, ETHER_ALIGN); - error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, + error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i], m_new, segs, &nsegs, 0); if (error != 0) { if (m == NULL) { @@ -949,7 +949,7 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) r->bge_len = segs[0].ds_len; r->bge_idx = i; - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i], BUS_DMASYNC_PREREAD); @@ -1068,10 +1068,10 @@ bge_free_rx_ring_std(struct bge_softc *sc) for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { if (sc->bge_cdata.bge_rx_std_chain[i] != NULL) { - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i], BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->bge_cdata.bge_mtag, + bus_dmamap_unload(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i]); m_freem(sc->bge_cdata.bge_rx_std_chain[i]); sc->bge_cdata.bge_rx_std_chain[i] = NULL; @@ -1138,10 +1138,10 @@ bge_free_tx_ring(struct bge_softc *sc) for (i = 0; i < BGE_TX_RING_CNT; i++) { if (sc->bge_cdata.bge_tx_chain[i] != NULL) { - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, sc->bge_cdata.bge_tx_dmamap[i], BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->bge_cdata.bge_mtag, + bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, sc->bge_cdata.bge_tx_dmamap[i]); m_freem(sc->bge_cdata.bge_tx_chain[i]); sc->bge_cdata.bge_tx_chain[i] = NULL; @@ -1976,7 +1976,7 @@ bge_dma_free(struct bge_softc *sc) /* Destroy DMA maps for RX buffers. */ for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { if (sc->bge_cdata.bge_rx_std_dmamap[i]) - bus_dmamap_destroy(sc->bge_cdata.bge_mtag, + bus_dmamap_destroy(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i]); } @@ -1990,12 +1990,14 @@ bge_dma_free(struct bge_softc *sc) /* Destroy DMA maps for TX buffers. */ for (i = 0; i < BGE_TX_RING_CNT; i++) { if (sc->bge_cdata.bge_tx_dmamap[i]) - bus_dmamap_destroy(sc->bge_cdata.bge_mtag, + bus_dmamap_destroy(sc->bge_cdata.bge_tx_mtag, sc->bge_cdata.bge_tx_dmamap[i]); } - if (sc->bge_cdata.bge_mtag) - bus_dma_tag_destroy(sc->bge_cdata.bge_mtag); + if (sc->bge_cdata.bge_rx_mtag) + bus_dma_tag_destroy(sc->bge_cdata.bge_rx_mtag); + if (sc->bge_cdata.bge_tx_mtag) + bus_dma_tag_destroy(sc->bge_cdata.bge_tx_mtag); /* Destroy standard RX ring. */ @@ -2106,21 +2108,33 @@ bge_dma_alloc(device_t dev) } /* - * Create tag for mbufs. + * Create tag for Tx mbufs. */ error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag, 1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * BGE_NSEG_NEW, BGE_NSEG_NEW, MCLBYTES, - BUS_DMA_ALLOCNOW, NULL, NULL, &sc->bge_cdata.bge_mtag); + BUS_DMA_ALLOCNOW, NULL, NULL, &sc->bge_cdata.bge_tx_mtag); if (error) { - device_printf(sc->bge_dev, "could not allocate dma tag\n"); + device_printf(sc->bge_dev, "could not allocate TX dma tag\n"); + return (ENOMEM); + } + + /* + * Create tag for Rx mbufs. + */ + error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag, 1, 0, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, + MCLBYTES, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->bge_cdata.bge_rx_mtag); + + if (error) { + device_printf(sc->bge_dev, "could not allocate RX dma tag\n"); return (ENOMEM); } /* Create DMA maps for RX buffers. */ for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { - error = bus_dmamap_create(sc->bge_cdata.bge_mtag, 0, + error = bus_dmamap_create(sc->bge_cdata.bge_rx_mtag, 0, &sc->bge_cdata.bge_rx_std_dmamap[i]); if (error) { device_printf(sc->bge_dev, @@ -2131,11 +2145,11 @@ bge_dma_alloc(device_t dev) /* Create DMA maps for TX buffers. */ for (i = 0; i < BGE_TX_RING_CNT; i++) { - error = bus_dmamap_create(sc->bge_cdata.bge_mtag, 0, + error = bus_dmamap_create(sc->bge_cdata.bge_tx_mtag, 0, &sc->bge_cdata.bge_tx_dmamap[i]); if (error) { device_printf(sc->bge_dev, - "can't create DMA map for RX\n"); + "can't create DMA map for TX\n"); return (ENOMEM); } } @@ -3173,10 +3187,10 @@ bge_rxeof(struct bge_softc *sc) } } else { BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[rxidx], BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->bge_cdata.bge_mtag, + bus_dmamap_unload(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[rxidx]); m = sc->bge_cdata.bge_rx_std_chain[rxidx]; sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL; @@ -3306,10 +3320,10 @@ bge_txeof(struct bge_softc *sc) if (cur_tx->bge_flags & BGE_TXBDFLAG_END) ifp->if_opackets++; if (sc->bge_cdata.bge_tx_chain[idx] != NULL) { - bus_dmamap_sync(sc->bge_cdata.bge_mtag, + bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, sc->bge_cdata.bge_tx_dmamap[idx], BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->bge_cdata.bge_mtag, + bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, sc->bge_cdata.bge_tx_dmamap[idx]); m_freem(sc->bge_cdata.bge_tx_chain[idx]); sc->bge_cdata.bge_tx_chain[idx] = NULL; @@ -3642,7 +3656,7 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx) } map = sc->bge_cdata.bge_tx_dmamap[idx]; - error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map, m, segs, + error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_tx_mtag, map, m, segs, &nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { m = m_collapse(m, M_DONTWAIT, BGE_NSEG_NEW); @@ -3652,8 +3666,8 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx) return (ENOBUFS); } *m_head = m; - error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map, m, - segs, &nsegs, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_tx_mtag, map, + m, segs, &nsegs, BUS_DMA_NOWAIT); if (error) { m_freem(m); *m_head = NULL; @@ -3667,11 +3681,11 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx) * of the end of the ring. */ if (nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) { - bus_dmamap_unload(sc->bge_cdata.bge_mtag, map); + bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map); return (ENOBUFS); } - bus_dmamap_sync(sc->bge_cdata.bge_mtag, map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map, BUS_DMASYNC_PREWRITE); for (i = 0; ; i++) { d = &sc->bge_ldata.bge_tx_ring[idx]; diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index ab336f44627..073c82e8c48 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -2543,8 +2543,9 @@ struct bge_chain_data { bus_dma_tag_t bge_tx_ring_tag; bus_dma_tag_t bge_status_tag; bus_dma_tag_t bge_stats_tag; - bus_dma_tag_t bge_mtag; /* mbuf mapping tag */ - bus_dma_tag_t bge_mtag_jumbo; /* mbuf mapping tag */ + bus_dma_tag_t bge_rx_mtag; /* Rx mbuf mapping tag */ + bus_dma_tag_t bge_tx_mtag; /* Tx mbuf mapping tag */ + bus_dma_tag_t bge_mtag_jumbo; /* Jumbo mbuf mapping tag */ bus_dmamap_t bge_tx_dmamap[BGE_TX_RING_CNT]; bus_dmamap_t bge_rx_std_dmamap[BGE_STD_RX_RING_CNT]; bus_dmamap_t bge_rx_jumbo_dmamap[BGE_JUMBO_RX_RING_CNT]; From 3ee5d7da8e9c62e7645aa22b184381d6c420b8e5 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 4 Nov 2009 21:06:54 +0000 Subject: [PATCH 510/646] Make bge_newbuf_std()/bge_newbuf_jumbo() returns actual error code for buffer allocation. If driver know we are out of Rx buffers let controller stop. This should fix panic when interface is run even if it had no configured Rx buffers. --- sys/dev/bge/if_bge.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 92911669c37..3832fadad6f 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1044,11 +1044,11 @@ bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m) static int bge_init_rx_ring_std(struct bge_softc *sc) { - int i; + int error, i; for (i = 0; i < BGE_SSLOTS; i++) { - if (bge_newbuf_std(sc, i, NULL) == ENOBUFS) - return (ENOBUFS); + if ((error = bge_newbuf_std(sc, i, NULL)) != 0) + return (error); }; bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, @@ -1085,11 +1085,11 @@ static int bge_init_rx_ring_jumbo(struct bge_softc *sc) { struct bge_rcb *rcb; - int i; + int error, i; for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { - if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS) - return (ENOBUFS); + if ((error = bge_newbuf_jumbo(sc, i, NULL)) != 0) + return (error); }; bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, @@ -3179,8 +3179,7 @@ bge_rxeof(struct bge_softc *sc) bge_newbuf_jumbo(sc, sc->bge_jumbo, m); continue; } - if (bge_newbuf_jumbo(sc, - sc->bge_jumbo, NULL) == ENOBUFS) { + if (bge_newbuf_jumbo(sc, sc->bge_jumbo, NULL) != 0) { ifp->if_ierrors++; bge_newbuf_jumbo(sc, sc->bge_jumbo, m); continue; @@ -3200,8 +3199,7 @@ bge_rxeof(struct bge_softc *sc) bge_newbuf_std(sc, sc->bge_std, m); continue; } - if (bge_newbuf_std(sc, sc->bge_std, - NULL) == ENOBUFS) { + if (bge_newbuf_std(sc, sc->bge_std, NULL) != 0) { ifp->if_ierrors++; bge_newbuf_std(sc, sc->bge_std, m); continue; @@ -3897,7 +3895,11 @@ bge_init_locked(struct bge_softc *sc) bge_setvlan(sc); /* Init RX ring. */ - bge_init_rx_ring_std(sc); + if (bge_init_rx_ring_std(sc) != 0) { + device_printf(sc->bge_dev, "no memory for std Rx buffers.\n"); + bge_stop(sc); + return; + } /* * Workaround for a bug in 5705 ASIC rev A0. Poll the NIC's @@ -3918,8 +3920,13 @@ bge_init_locked(struct bge_softc *sc) } /* Init jumbo RX ring. */ - if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) - bge_init_rx_ring_jumbo(sc); + if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) { + if (bge_init_rx_ring_jumbo(sc) != 0) { + device_printf(sc->bge_dev, "no memory for std Rx buffers.\n"); + bge_stop(sc); + return; + } + } /* Init our RX return ring index. */ sc->bge_rx_saved_considx = 0; From c2b1d5a3d67455a4dc6ffae7c1c41f74e8d162b0 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 4 Nov 2009 21:12:33 +0000 Subject: [PATCH 511/646] Include string.h for prototype of strcmp(). --- share/examples/ses/srcs/getencstat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/share/examples/ses/srcs/getencstat.c b/share/examples/ses/srcs/getencstat.c index bf45e576fb7..d9f5c6d68b1 100644 --- a/share/examples/ses/srcs/getencstat.c +++ b/share/examples/ses/srcs/getencstat.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include SESINC From 8fa0490a2e0875e6f66c0b6418061cb21ddc7922 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 4 Nov 2009 22:39:18 +0000 Subject: [PATCH 512/646] Tweak memory allocation for amd64 suspend/resume CPU context. --- sys/amd64/acpica/acpi_wakeup.c | 30 ++++++++++++++---------------- sys/amd64/amd64/mp_machdep.c | 6 +++--- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c index cfc960b3951..d53d8bb659e 100644 --- a/sys/amd64/acpica/acpi_wakeup.c +++ b/sys/amd64/acpica/acpi_wakeup.c @@ -65,9 +65,9 @@ extern int acpi_resume_beep; extern int acpi_reset_video; #ifdef SMP -extern struct xpcb *stopxpcbs; +extern struct xpcb **stopxpcbs; #else -static struct xpcb *stopxpcbs; +static struct xpcb **stopxpcbs; #endif int acpi_restorecpu(struct xpcb *, vm_offset_t); @@ -104,10 +104,10 @@ acpi_wakeup_ap(struct acpi_softc *sc, int cpu) int apic_id = cpu_apic_ids[cpu]; int ms; - WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, &stopxpcbs[cpu]); - WAKECODE_FIXUP(wakeup_gdt, uint16_t, stopxpcbs[cpu].xpcb_gdt.rd_limit); + WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, stopxpcbs[cpu]); + WAKECODE_FIXUP(wakeup_gdt, uint16_t, stopxpcbs[cpu]->xpcb_gdt.rd_limit); WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, - stopxpcbs[cpu].xpcb_gdt.rd_base); + stopxpcbs[cpu]->xpcb_gdt.rd_base); WAKECODE_FIXUP(wakeup_cpu, int, cpu); /* do an INIT IPI: assert RESET */ @@ -245,8 +245,8 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) cr3 = rcr3(); load_cr3(KPML4phys); - stopfpu = &stopxpcbs[0].xpcb_pcb.pcb_save; - if (acpi_savecpu(&stopxpcbs[0])) { + stopfpu = &stopxpcbs[0]->xpcb_pcb.pcb_save; + if (acpi_savecpu(stopxpcbs[0])) { fpugetregs(curthread, stopfpu); #ifdef SMP @@ -261,11 +261,11 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0)); WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0)); - WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, &stopxpcbs[0]); + WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, stopxpcbs[0]); WAKECODE_FIXUP(wakeup_gdt, uint16_t, - stopxpcbs[0].xpcb_gdt.rd_limit); + stopxpcbs[0]->xpcb_gdt.rd_limit); WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, - stopxpcbs[0].xpcb_gdt.rd_base); + stopxpcbs[0]->xpcb_gdt.rd_base); WAKECODE_FIXUP(wakeup_cpu, int, 0); /* Call ACPICA to enter the desired sleep state */ @@ -320,6 +320,7 @@ static void * acpi_alloc_wakeup_handler(void) { void *wakeaddr; + int i; /* * Specify the region for our wakeup code. We want it in the low 1 MB @@ -334,12 +335,9 @@ acpi_alloc_wakeup_handler(void) printf("%s: can't alloc wake memory\n", __func__); return (NULL); } - stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_NOWAIT); - if (stopxpcbs == NULL) { - contigfree(wakeaddr, 4 * PAGE_SIZE, M_DEVBUF); - printf("%s: can't alloc CPU state memory\n", __func__); - return (NULL); - } + stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_WAITOK); + for (i = 0; i < mp_ncpus; i++) + stopxpcbs[i] = malloc(sizeof(**stopxpcbs), M_DEVBUF, M_WAITOK); return (wakeaddr); } diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 0ef80173b28..f5b1351462e 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -105,7 +105,7 @@ extern pt_entry_t *KPTphys; extern pt_entry_t *SMPpt; struct pcb stoppcbs[MAXCPU]; -struct xpcb *stopxpcbs = NULL; +struct xpcb **stopxpcbs = NULL; /* Variables needed for SMP tlb shootdown. */ vm_offset_t smp_tlb_addr1; @@ -1256,8 +1256,8 @@ cpususpend_handler(void) rf = intr_disable(); cr3 = rcr3(); - stopfpu = &stopxpcbs[cpu].xpcb_pcb.pcb_save; - if (savectx2(&stopxpcbs[cpu])) { + stopfpu = &stopxpcbs[cpu]->xpcb_pcb.pcb_save; + if (savectx2(stopxpcbs[cpu])) { fpugetregs(curthread, stopfpu); wbinvd(); atomic_set_int(&stopped_cpus, cpumask); From 2804a96a502283a0b41449bcfe2b049dbfc6dbae Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 4 Nov 2009 23:36:23 +0000 Subject: [PATCH 513/646] Cleanup code to make it WARNS=6 clean: - ANSIfy prototypes; - Add __unused for parameters that is not being currently used; - Add a header for subrountines being called from other modules. Reviewed by: mjacob --- share/examples/ses/srcs/chpmon.c | 4 +--- share/examples/ses/srcs/eltsub.c | 12 ++++------ share/examples/ses/srcs/eltsub.h | 36 ++++++++++++++++++++++++++++ share/examples/ses/srcs/getencstat.c | 7 ++---- share/examples/ses/srcs/getnobj.c | 4 +--- share/examples/ses/srcs/getobjmap.c | 6 ++--- share/examples/ses/srcs/getobjstat.c | 4 +--- share/examples/ses/srcs/inienc.c | 4 +--- share/examples/ses/srcs/sesd.c | 9 +++---- share/examples/ses/srcs/setencstat.c | 4 +--- share/examples/ses/srcs/setobjstat.c | 4 +--- 11 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 share/examples/ses/srcs/eltsub.h diff --git a/share/examples/ses/srcs/chpmon.c b/share/examples/ses/srcs/chpmon.c index 1b537c7ba11..cb78f062f35 100644 --- a/share/examples/ses/srcs/chpmon.c +++ b/share/examples/ses/srcs/chpmon.c @@ -47,9 +47,7 @@ #define BADSTAT \ (SES_ENCSTAT_UNRECOV|SES_ENCSTAT_CRITICAL|SES_ENCSTAT_NONCRITICAL) int -main(a, v) - int a; - char **v; +main(int a, char **v) { int fd, delay, dev; ses_encstat stat, *carray; diff --git a/share/examples/ses/srcs/eltsub.c b/share/examples/ses/srcs/eltsub.c index 5fae6653d41..2acf982d2eb 100644 --- a/share/examples/ses/srcs/eltsub.c +++ b/share/examples/ses/srcs/eltsub.c @@ -38,9 +38,10 @@ #include #include SESINC +#include "eltsub.h" + char * -geteltnm(type) - int type; +geteltnm(int type) { static char rbuf[132]; @@ -116,8 +117,7 @@ geteltnm(type) } static char * -scode2ascii(code) - u_char code; +scode2ascii(u_char code) { static char rbuf[32]; switch (code & 0xf) { @@ -154,9 +154,7 @@ scode2ascii(code) char * -stat2ascii(eletype, cstat) - int eletype; - u_char *cstat; +stat2ascii(int eletype __unused, u_char *cstat) { static char ebuf[256], *scode; diff --git a/share/examples/ses/srcs/eltsub.h b/share/examples/ses/srcs/eltsub.h new file mode 100644 index 00000000000..3d98572352e --- /dev/null +++ b/share/examples/ses/srcs/eltsub.h @@ -0,0 +1,36 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 by Matthew Jacob + * 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, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * the GNU Public License ("GPL"). + * + * 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. + * + * Matthew Jacob + * Feral Software + * mjacob@feral.com + */ + +char * geteltnm(int); +char * stat2ascii(int, u_char *); diff --git a/share/examples/ses/srcs/getencstat.c b/share/examples/ses/srcs/getencstat.c index d9f5c6d68b1..3514fe4e77c 100644 --- a/share/examples/ses/srcs/getencstat.c +++ b/share/examples/ses/srcs/getencstat.c @@ -40,13 +40,10 @@ #include #include SESINC -extern char *geteltnm __P((int)); -extern char *stat2ascii __P((int, u_char *)); +#include "eltsub.h" int -main(a, v) - int a; - char **v; +main(int a, char **v) { ses_object *objp; ses_objstat ob; diff --git a/share/examples/ses/srcs/getnobj.c b/share/examples/ses/srcs/getnobj.c index 680a6cdbc17..17a26c62bd9 100644 --- a/share/examples/ses/srcs/getnobj.c +++ b/share/examples/ses/srcs/getnobj.c @@ -41,9 +41,7 @@ #include SESINC int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { unsigned int nobj; int fd; diff --git a/share/examples/ses/srcs/getobjmap.c b/share/examples/ses/srcs/getobjmap.c index 7f4d1b78374..9798b4c87ba 100644 --- a/share/examples/ses/srcs/getobjmap.c +++ b/share/examples/ses/srcs/getobjmap.c @@ -39,12 +39,10 @@ #include #include SESINC -extern char *geteltnm __P((int)); +#include "eltsub.h" int -main(a, v) - int a; - char **v; +main(int a, char **v) { ses_object *objp; int nobj, fd, i; diff --git a/share/examples/ses/srcs/getobjstat.c b/share/examples/ses/srcs/getobjstat.c index bf703cf47ff..99fb1854238 100644 --- a/share/examples/ses/srcs/getobjstat.c +++ b/share/examples/ses/srcs/getobjstat.c @@ -39,9 +39,7 @@ #include SESINC int -main(a, v) - int a; - char **v; +main(int a, char **v) { int fd; int i; diff --git a/share/examples/ses/srcs/inienc.c b/share/examples/ses/srcs/inienc.c index d6fb262ef7e..7d6cc220b51 100644 --- a/share/examples/ses/srcs/inienc.c +++ b/share/examples/ses/srcs/inienc.c @@ -40,9 +40,7 @@ #include SESINC int -main(a, v) - int a; - char **v; +main(int a, char **v) { int fd; diff --git a/share/examples/ses/srcs/sesd.c b/share/examples/ses/srcs/sesd.c index 5262b639bfd..0793077d210 100644 --- a/share/examples/ses/srcs/sesd.c +++ b/share/examples/ses/srcs/sesd.c @@ -49,13 +49,11 @@ */ int -main(a, v) - int a; - char **v; +main(int a, char **v) { - static char *usage = + static const char *usage = "usage: %s [ -d ] [ -t pollinterval ] device [ device ]\n"; - int fd, polltime, dev, devbase, nodaemon, bpri; + int fd, polltime, dev, devbase, nodaemon; ses_encstat stat, *carray; if (a < 2) { @@ -115,7 +113,6 @@ main(a, v) for (;;) { for (dev = devbase; dev < a; dev++) { - char buf[128]; fd = open(v[dev], O_RDWR); if (fd < 0) { syslog(LOG_ERR, "%s: %m", v[dev]); diff --git a/share/examples/ses/srcs/setencstat.c b/share/examples/ses/srcs/setencstat.c index 58e0dafc187..127f68fa4cf 100644 --- a/share/examples/ses/srcs/setencstat.c +++ b/share/examples/ses/srcs/setencstat.c @@ -40,9 +40,7 @@ #include SESINC int -main(a, v) - int a; - char **v; +main(int a, char **v) { int fd; long val; diff --git a/share/examples/ses/srcs/setobjstat.c b/share/examples/ses/srcs/setobjstat.c index 34e8ea65d97..08fdb7b4822 100644 --- a/share/examples/ses/srcs/setobjstat.c +++ b/share/examples/ses/srcs/setobjstat.c @@ -40,9 +40,7 @@ #include SESINC int -main(a, v) - int a; - char **v; +main(int a, char **v) { int fd; int i; From 5639f997b793c43361f7e824f70793ca405afb85 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Thu, 5 Nov 2009 04:51:38 +0000 Subject: [PATCH 514/646] File flags handling fixes for ext2fs: - Disallow setting of flags not supported by ext2fs. - Map EXT2_APPEND_FL to SF_APPEND. - Map EXT2_IMMUTABLE_FL to SF_IMMUTABLE. - Map EXT2_NODUMP_FL to UF_NODUMP. Note that ext2fs doesn't support user settable append and immutable flags. EXT2_NODUMP_FL is an user settable flag also on Linux. PR: kern/122047 Reported by: Ighighi Submitted by: Aditya Sarawgi (original version) Reviewed by: bde Approved by: trasz (mentor) --- sys/gnu/fs/ext2fs/ext2_inode_cnv.c | 10 ++++++---- sys/gnu/fs/ext2fs/ext2_vnops.c | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c b/sys/gnu/fs/ext2fs/ext2_inode_cnv.c index de30739fc51..412a47ccc00 100644 --- a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/gnu/fs/ext2fs/ext2_inode_cnv.c @@ -83,8 +83,9 @@ ext2_ei2i(ei, ip) ip->i_mtime = ei->i_mtime; ip->i_ctime = ei->i_ctime; ip->i_flags = 0; - ip->i_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0; - ip->i_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0; + ip->i_flags |= (ei->i_flags & EXT2_APPEND_FL) ? SF_APPEND : 0; + ip->i_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? SF_IMMUTABLE : 0; + ip->i_flags |= (ei->i_flags & EXT2_NODUMP_FL) ? UF_NODUMP : 0; ip->i_blocks = ei->i_blocks; ip->i_gen = ei->i_generation; ip->i_uid = ei->i_uid; @@ -121,8 +122,9 @@ ext2_i2ei(ip, ei) ei->i_ctime = ip->i_ctime; ei->i_flags = ip->i_flags; ei->i_flags = 0; - ei->i_flags |= (ip->i_flags & APPEND) ? EXT2_APPEND_FL: 0; - ei->i_flags |= (ip->i_flags & IMMUTABLE) ? EXT2_IMMUTABLE_FL: 0; + ei->i_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND_FL: 0; + ei->i_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE_FL: 0; + ei->i_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP_FL : 0; ei->i_blocks = ip->i_blocks; ei->i_generation = ip->i_gen; ei->i_uid = ip->i_uid; diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c index 41643e3e739..6b44b9b4547 100644 --- a/sys/gnu/fs/ext2fs/ext2_vnops.c +++ b/sys/gnu/fs/ext2fs/ext2_vnops.c @@ -391,6 +391,10 @@ ext2_setattr(ap) return (EINVAL); } if (vap->va_flags != VNOVAL) { + /* Disallow flags not supported by ext2fs. */ + if (vap->va_flags & ~(SF_APPEND | SF_IMMUTABLE | UF_NODUMP)) + return (EOPNOTSUPP); + if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); /* From c2ef543ba1cc60c2064d73b80f84a5ca2c5c9ac9 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 5 Nov 2009 06:08:04 +0000 Subject: [PATCH 515/646] IP_TTL is an IP socket option, not a TTL value. Use IPDEFTTL instead. --- lib/libstand/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libstand/udp.c b/lib/libstand/udp.c index a95cedebdf5..194f564531a 100644 --- a/lib/libstand/udp.c +++ b/lib/libstand/udp.c @@ -90,7 +90,7 @@ sendudp(d, pkt, len) ip->ip_hl = sizeof(*ip) >> 2; /* half-char */ ip->ip_len = htons(len); ip->ip_p = IPPROTO_UDP; /* char */ - ip->ip_ttl = IP_TTL; /* char */ + ip->ip_ttl = IPDEFTTL; /* char */ ip->ip_src = d->myip; ip->ip_dst = d->destip; ip->ip_sum = in_cksum(ip, sizeof(*ip)); /* short, but special */ From faa7ba7a3f82335b7d65d54b590131cca760b8eb Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 5 Nov 2009 06:23:02 +0000 Subject: [PATCH 516/646] Implement db_trace_self() by calling db_stack_trace_cmd() and not db_trace_thread(). --- sys/arm/arm/db_trace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index 6913df69beb..c1cb9984b71 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -207,5 +207,8 @@ db_trace_thread(struct thread *thr, int count) void db_trace_self(void) { - db_trace_thread(curthread, -1); + db_addr_t addr; + + addr = (db_addr_t)__builtin_frame_address(1); + db_stack_trace_cmd(addr, -1); } From 2ffa44209af6bdf6540e9f05534b2e2c49286da6 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 5 Nov 2009 06:27:46 +0000 Subject: [PATCH 517/646] Implement db_trace_thread() by calling db_stack_trace_cmd() and passing a frame pointer that comes from the thread context. This fixes DDB backtraces by not unwinding debugger functions first. --- sys/arm/arm/db_trace.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index c1cb9984b71..9bc3cbc6997 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -194,13 +194,10 @@ db_md_set_watchpoint(db_expr_t addr, db_expr_t size) int db_trace_thread(struct thread *thr, int count) { - uint32_t addr; + struct pcb *ctx; - if (thr == curthread) - addr = (uint32_t)__builtin_frame_address(0); - else - addr = thr->td_pcb->un_32.pcb32_r11; - db_stack_trace_cmd(addr, -1); + ctx = kdb_thr_ctx(thr); + db_stack_trace_cmd(ctx->un_32.pcb32_r11, -1); return (0); } From 4590f2282a421b9cddaed32cf1a0711c5c4ee087 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 5 Nov 2009 06:31:50 +0000 Subject: [PATCH 518/646] Fix gdb_cpu_getreg() to actually match GDB's register definition. --- sys/arm/arm/gdb_machdep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/arm/arm/gdb_machdep.c b/sys/arm/arm/gdb_machdep.c index a6fa7675e30..eefb046ef90 100644 --- a/sys/arm/arm/gdb_machdep.c +++ b/sys/arm/arm/gdb_machdep.c @@ -53,12 +53,15 @@ gdb_cpu_getreg(int regnum, size_t *regsz) *regsz = gdb_cpu_regsz(regnum); - if (kdb_thread == curthread) { - if (regnum < 16) - return (&kdb_frame->tf_r0 + 4 * regnum); + if (kdb_thread == curthread) { + if (regnum < 15) + return (&kdb_frame->tf_r0 + regnum); + if (regnum == 15) + return (&kdb_frame->tf_pc); if (regnum == 25) return (&kdb_frame->tf_spsr); } + switch (regnum) { case 8: return (&kdb_thrctx->un_32.pcb32_r8); case 9: return (&kdb_thrctx->un_32.pcb32_r9); @@ -78,6 +81,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz) return (&kdb_thrctx->un_32.pcb32_pc); } } + return (NULL); } From f3d62ac43dbafeef31f1de75fc40131cbb5657e6 Mon Sep 17 00:00:00 2001 From: Alexander Leidinger Date: Thu, 5 Nov 2009 07:37:48 +0000 Subject: [PATCH 519/646] Fix typo in kernel message. The fix is based upon the patch in the PR. PR: kern/140279 Submitted by: Alexander Best MFC after: 1 week --- sys/compat/linux/linux_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 0a46a058bfd..fbec94e9dd4 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -872,7 +872,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) case LINUX_SHM_LOCK: case LINUX_SHM_UNLOCK: default: - linux_msg(td, "ipc typ=%d not implemented", args->cmd & ~LINUX_IPC_64); + linux_msg(td, "ipc type %d not implemented", args->cmd & ~LINUX_IPC_64); return EINVAL; } } From 379ad35853ef7ea466f3c83fa4b6ac56ef9164a8 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 5 Nov 2009 08:55:24 +0000 Subject: [PATCH 520/646] MFp4: Implement device stats accounting for ATA commands. --- sys/cam/cam_periph.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index fd441b25564..70764c65c14 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -898,7 +898,8 @@ cam_periph_runccb(union ccb *ccb, * If the user has supplied a stats structure, and if we understand * this particular type of ccb, record the transaction start. */ - if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO)) + if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO || + ccb->ccb_h.func_code == XPT_ATA_IO)) devstat_start_transaction(ds, NULL); xpt_action(ccb); @@ -921,15 +922,27 @@ cam_periph_runccb(union ccb *ccb, /* timeout */0, /* getcount_only */ FALSE); - if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO)) - devstat_end_transaction(ds, + if (ds != NULL) { + if (ccb->ccb_h.func_code == XPT_SCSI_IO) { + devstat_end_transaction(ds, ccb->csio.dxfer_len, - ccb->csio.tag_action & 0xf, + ccb->csio.tag_action & 0x3, ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) ? DEVSTAT_NO_DATA : (ccb->ccb_h.flags & CAM_DIR_OUT) ? DEVSTAT_WRITE : DEVSTAT_READ, NULL, NULL); + } else if (ccb->ccb_h.func_code == XPT_ATA_IO) { + devstat_end_transaction(ds, + ccb->ataio.dxfer_len, + ccb->ataio.tag_action & 0x3, + ((ccb->ccb_h.flags & CAM_DIR_MASK) == + CAM_DIR_NONE) ? DEVSTAT_NO_DATA : + (ccb->ccb_h.flags & CAM_DIR_OUT) ? + DEVSTAT_WRITE : + DEVSTAT_READ, NULL, NULL); + } + } return(error); } From d638857a04ba583cc9a1e259eb30c5bb03933ff8 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Thu, 5 Nov 2009 10:01:15 +0000 Subject: [PATCH 521/646] Revert the spelling of Taiwan to be politically neutral in accordance with the policy published at http://www.freebsd.org/internal/i18n.html. Requested by: core (murray) --- share/misc/iso3166 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/share/misc/iso3166 b/share/misc/iso3166 index 8d06e7cd121..70ca84f497b 100644 --- a/share/misc/iso3166 +++ b/share/misc/iso3166 @@ -1,5 +1,8 @@ # $FreeBSD$ # +# Please consult with http://www.FreeBSD.org/internal/i18n.html before +# making changes to this file. +# # ISO 3166 country codes # This includes many places that are not legally independent countries, # but which is it convenient to refer to separately from their @@ -230,7 +233,7 @@ SZ SWZ 748 Swaziland SE SWE 752 Sweden CH CHE 756 Switzerland SY SYR 760 Syrian Arab Republic -TW TWN 158 Taiwan, Province of China +TW TWN 158 Taiwan TJ TJK 762 Tajikistan TZ TZA 834 Tanzania, United Republic of TH THA 764 Thailand From f1c892a33cc6954d6c54b0597cede5d82edc2eb3 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Thu, 5 Nov 2009 14:34:38 +0000 Subject: [PATCH 522/646] Strip from messages for users external URLs the project cannot directly control. Requested by: kib, rwatson --- sys/amd64/amd64/identcpu.c | 5 +---- sys/i386/i386/identcpu.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index b50c29b5651..420dd03cc76 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -619,12 +619,9 @@ print_AMD_info(void) * model and family are identified. */ if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && - CPUID_TO_MODEL(cpu_id) <= 0x3f) { + CPUID_TO_MODEL(cpu_id) <= 0x3f) printf("WARNING: This architecture revision has known SMP " "hardware bugs which may cause random instability\n"); - printf("WARNING: For details see: " - "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); - } } static void diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index e8210c26528..b0bcd094a5a 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -1315,12 +1315,9 @@ print_AMD_info(void) * model and family are identified. */ if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 && - CPUID_TO_MODEL(cpu_id) <= 0x3f) { + CPUID_TO_MODEL(cpu_id) <= 0x3f) printf("WARNING: This architecture revision has known SMP " "hardware bugs which may cause random instability\n"); - printf("WARNING: For details see: " - "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n"); - } } static void From f11ccc426ad715229a4c0b2dd8ee1cd9eb0273cd Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 5 Nov 2009 16:30:16 +0000 Subject: [PATCH 523/646] Fix two memory leaks in error cases. PR: 138378 Submitted by: Patroklos Argyroudis Approved by: mlaier MFC after: 1 week --- sys/contrib/altq/altq/altq_hfsc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/contrib/altq/altq/altq_hfsc.c b/sys/contrib/altq/altq/altq_hfsc.c index cc9a566b477..fa8bad13e99 100644 --- a/sys/contrib/altq/altq/altq_hfsc.c +++ b/sys/contrib/altq/altq/altq_hfsc.c @@ -1809,15 +1809,20 @@ hfsc_class_modify(cl, rsc, fsc, usc) cl->cl_fsc == NULL) { fsc_tmp = malloc(sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); - if (fsc_tmp == NULL) + if (fsc_tmp == NULL) { + free(rsc_tmp); return (ENOMEM); + } } if (usc != NULL && (usc->m1 != 0 || usc->m2 != 0) && cl->cl_usc == NULL) { usc_tmp = malloc(sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); - if (usc_tmp == NULL) + if (usc_tmp == NULL) { + free(rsc_tmp); + free(fsc_tmp); return (ENOMEM); + } } cur_time = read_machclk(); From 663c61a35bb456cd1763c52f988d4a2be6f56b7e Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Thu, 5 Nov 2009 20:44:39 +0000 Subject: [PATCH 524/646] sh: Fix memory leak when using a variable in arithmetic like $((x)). MFC after: 3 weeks --- bin/sh/arith_lex.l | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l index f0ed3d58617..f0d9cb34c41 100644 --- a/bin/sh/arith_lex.l +++ b/bin/sh/arith_lex.l @@ -51,6 +51,13 @@ __FBSDID("$FreeBSD$"); int yylex(void); +struct varname +{ + struct varname *next; + char name[1]; +}; +static struct varname *varnames; + #undef YY_INPUT #define YY_INPUT(buf,result,max) \ result = (*buf = *arith_buf++) ? 1 : YY_NULL; @@ -80,11 +87,14 @@ int yylex(void); * If variable doesn't exist, we should initialize * it to zero. */ - char *temp; + struct varname *temp; if (lookupvar(yytext) == NULL) setvarsafe(yytext, "0", 0); - temp = (char *)ckmalloc(strlen(yytext) + 1); - yylval.s_value = strcpy(temp, yytext); + temp = ckmalloc(sizeof(struct varname) + + strlen(yytext)); + temp->next = varnames; + varnames = temp; + yylval.s_value = strcpy(temp->name, yytext); return ARITH_VAR; } @@ -130,5 +140,15 @@ int yylex(void); void arith_lex_reset(void) { + struct varname *name, *next; + YY_NEW_FILE; + + name = varnames; + while (name != NULL) { + next = name->next; + ckfree(name); + name = next; + } + varnames = NULL; } From 2259d74c68f5e61add44f0f4483ab455ca945d41 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Thu, 5 Nov 2009 22:58:50 +0000 Subject: [PATCH 525/646] Save/restore VGA state from vga_pci.c instead of relying on vga_isa.c. It was not working because we were saving its state after the device was powered down. Simplify vesa_load_state() as the culprit is fixed now. --- sys/dev/fb/vesa.c | 54 +++------------------------- sys/dev/pci/vga_pci.c | 82 +++++++++++++++++++++++++++++++++++++++++-- sys/isa/vga_isa.c | 39 ++++++++++---------- 3 files changed, 104 insertions(+), 71 deletions(-) diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index 540335286bd..36b05f84bac 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -164,7 +164,6 @@ static char *vesa_revstr = NULL; static int int10_set_mode(int mode); static int vesa_bios_post(void); static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); -static int vesa_bios_get_current_mode(void); static int vesa_bios_set_mode(int mode); static int vesa_bios_get_dac(void); static int vesa_bios_set_dac(int bits); @@ -318,22 +317,6 @@ vesa_bios_get_mode(int mode, struct vesa_mode *vmode) return (0); } -static int -vesa_bios_get_current_mode(void) -{ - x86regs_t regs; - - x86bios_init_regs(®s); - regs.R_AX = 0x4f03; - - x86bios_intr(®s, 0x10); - - if (regs.R_AX != 0x004f) - return (-1); - - return (regs.R_BX); -} - static int vesa_bios_set_mode(int mode) { @@ -1438,7 +1421,6 @@ vesa_save_state(video_adapter_t *adp, void *p, size_t size) static int vesa_load_state(video_adapter_t *adp, void *p) { - int flags, mode, ret; if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG)) return ((*prevvidsw->load_state)(adp, p)); @@ -1446,38 +1428,12 @@ vesa_load_state(video_adapter_t *adp, void *p) if (vesa_state_buf_size <= 0) return (1); - /* - * If the current mode is not the same, probably it was powered down. - * Try BIOS POST to restore a sane state. - */ - if (VESA_MODE(adp->va_mode)) { - mode = vesa_bios_get_current_mode(); - if (mode >= 0 && (mode & 0x1ff) != adp->va_mode) - (void)vesa_bios_post(); - } + /* Try BIOS POST to restore a sane state. */ + (void)vesa_bios_post(); + (void)int10_set_mode(adp->va_initial_bios_mode); - ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, - vesa_state_buf_size); - - /* - * If the desired mode is not restored, force setting the mode. - */ - if (VESA_MODE(adp->va_mode)) { - mode = vesa_bios_get_current_mode(); - if (mode < 0 || (mode & 0x1ff) == adp->va_mode) - return (ret); - mode = adp->va_mode; - flags = adp->va_info.vi_flags; - if ((flags & V_INFO_GRAPHICS) != 0 && - (flags & V_INFO_LINEAR) != 0) - mode |= 0x4000; - (void)vesa_bios_set_mode(mode); - if ((vesa_adp_info->v_flags & V_DAC8) != 0) - (void)vesa_bios_set_dac(8); - (void)(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); - } - - return (ret); + return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, + vesa_state_buf_size)); } #if 0 diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 1467bbd116c..07b5ed0904f 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -40,12 +40,17 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include #include #include #include +#include +#include + #include #include @@ -63,7 +68,7 @@ SYSCTL_DECL(_hw_pci); int vga_pci_default_unit = -1; TUNABLE_INT("hw.pci.default_vgapci_unit", &vga_pci_default_unit); -SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RD, +SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RDTUN, &vga_pci_default_unit, -1, "Default VGA-compatible display"); static int @@ -112,13 +117,86 @@ vga_pci_attach(device_t dev) static int vga_pci_suspend(device_t dev) { + vga_softc_t *sc; + devclass_t dc; + int err, nbytes; - return (bus_generic_suspend(dev)); + err = bus_generic_suspend(dev); + if (err) + return (err); + + sc = NULL; + if (device_get_unit(dev) == vga_pci_default_unit) { + dc = devclass_find(VGA_DRIVER_NAME); + if (dc != NULL) + sc = devclass_get_softc(dc, 0); + } + if (sc == NULL) + return (0); + + /* Save the video state across the suspend. */ + if (sc->state_buf != NULL) + goto save_palette; + nbytes = vidd_save_state(sc->adp, NULL, 0); + if (nbytes <= 0) + goto save_palette; + sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); + if (sc->state_buf == NULL) + goto save_palette; + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", nbytes); + if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { + device_printf(dev, "failed to save state (nbytes=%d)\n", + nbytes); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } + +save_palette: + /* Save the color palette across the suspend. */ + if (sc->pal_buf != NULL) + return (0); + sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); + if (sc->pal_buf != NULL) { + if (bootverbose) + device_printf(dev, "saving color palette\n"); + if (vidd_save_palette(sc->adp, sc->pal_buf) != 0) { + device_printf(dev, "failed to save palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } + } + + return (0); } static int vga_pci_resume(device_t dev) { + vga_softc_t *sc; + devclass_t dc; + + sc = NULL; + if (device_get_unit(dev) == vga_pci_default_unit) { + dc = devclass_find(VGA_DRIVER_NAME); + if (dc != NULL) + sc = devclass_get_softc(dc, 0); + } + if (sc == NULL) + return (bus_generic_resume(dev)); + + if (sc->state_buf != NULL) { + if (vidd_load_state(sc->adp, sc->state_buf) != 0) + device_printf(dev, "failed to reload state\n"); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } + if (sc->pal_buf != NULL) { + if (vidd_load_palette(sc->adp, sc->pal_buf) != 0) + device_printf(dev, "failed to reload palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } return (bus_generic_resume(dev)); } diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index d31df7e8c38..cfb36ae97b6 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -166,35 +166,34 @@ isavga_suspend(device_t dev) vga_softc_t *sc; int err, nbytes; - sc = device_get_softc(dev); err = bus_generic_suspend(dev); if (err) return (err); + sc = device_get_softc(dev); + /* Save the video state across the suspend. */ - if (sc->state_buf != NULL) { + if (sc->state_buf != NULL) + goto save_palette; + nbytes = vidd_save_state(sc->adp, NULL, 0); + if (nbytes <= 0) + goto save_palette; + sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); + if (sc->state_buf == NULL) + goto save_palette; + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", nbytes); + if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { + device_printf(dev, "failed to save state (nbytes=%d)\n", + nbytes); free(sc->state_buf, M_TEMP); sc->state_buf = NULL; } - nbytes = vidd_save_state(sc->adp, NULL, 0); - if (nbytes <= 0) - return (0); - sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); - if (sc->state_buf != NULL) { - if (bootverbose) - device_printf(dev, "saving %d bytes of video state\n", - nbytes); - if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { - device_printf(dev, "failed to save state (nbytes=%d)\n", - nbytes); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } - } +save_palette: /* Save the color palette across the suspend. */ if (sc->pal_buf != NULL) - free(sc->pal_buf, M_TEMP); + return (0); sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); if (sc->pal_buf != NULL) { if (bootverbose) @@ -215,6 +214,7 @@ isavga_resume(device_t dev) vga_softc_t *sc; sc = device_get_softc(dev); + if (sc->state_buf != NULL) { if (vidd_load_state(sc->adp, sc->state_buf) != 0) device_printf(dev, "failed to reload state\n"); @@ -228,8 +228,7 @@ isavga_resume(device_t dev) sc->pal_buf = NULL; } - bus_generic_resume(dev); - return 0; + return (bus_generic_resume(dev)); } #ifdef FB_INSTALL_CDEV From c3bbfed43017b3611eb96463efa4826703816fd7 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 Nov 2009 01:11:59 +0000 Subject: [PATCH 526/646] Correct MSI mode register bits. --- sys/dev/bge/if_bgereg.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 073c82e8c48..4cf432a8b0c 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -1705,11 +1705,8 @@ /* MSI mode register */ #define BGE_MSIMODE_RESET 0x00000001 #define BGE_MSIMODE_ENABLE 0x00000002 -#define BGE_MSIMODE_PCI_TGT_ABRT_ATTN 0x00000004 -#define BGE_MSIMODE_PCI_MSTR_ABRT_ATTN 0x00000008 -#define BGE_MSIMODE_PCI_PERR_ATTN 0x00000010 -#define BGE_MSIMODE_MSI_FIFOUFLOW_ATTN 0x00000020 -#define BGE_MSIMODE_MSI_FIFOOFLOW_ATTN 0x00000040 +#define BGE_MSIMODE_ONE_SHOT_DISABLE 0x00000020 +#define BGE_MSIMODE_MULTIVEC_ENABLE 0x00000080 /* MSI status register */ #define BGE_MSISTAT_PCI_TGT_ABRT_ATTN 0x00000004 From 9da005c6927656d3716a409f7639abdedd830903 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 6 Nov 2009 06:09:04 +0000 Subject: [PATCH 527/646] Unbreak E500 builds. The inline assembly for the 970 CPUs is invalid when compiling for BookE. --- sys/powerpc/powerpc/cpu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index 1325207c574..b4224a4a673 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -118,7 +118,9 @@ static void cpu_print_speed(void); static void cpu_6xx_setup(int cpuid, uint16_t vers); static void cpu_6xx_print_cacheinfo(u_int, uint16_t); static void cpu_e500_setup(int cpuid, uint16_t vers); +#ifndef E500 static void cpu_970_setup(int cpuid, uint16_t vers); +#endif void cpu_setup(u_int cpuid) @@ -195,12 +197,14 @@ cpu_setup(u_int cpuid) cpu_6xx_setup(cpuid, vers); break; +#ifndef E500 case IBM970: case IBM970FX: case IBM970GX: case IBM970MP: cpu_970_setup(cpuid, vers); break; +#endif case FSL_E500v1: case FSL_E500v2: @@ -429,6 +433,7 @@ cpu_e500_setup(int cpuid, uint16_t vers) printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK); } +#ifndef E500 static void cpu_970_setup(int cpuid, uint16_t vers) { @@ -458,4 +463,4 @@ cpu_970_setup(int cpuid, uint16_t vers) : "=r" (hid0_hi) : "K" (SPR_HID0)); printf("cpu%d: HID0 %b", cpuid, (int)(hid0_hi), HID0_970_BITMASK); } - +#endif From 54a1c2b5aa417d49ad32ec056ecf2911e89822d4 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 6 Nov 2009 07:17:31 +0000 Subject: [PATCH 528/646] Add MAP_ANONYMOUS. Many operating systems also provide MAP_ANONYMOUS. It's not hard to support this ourselves, we'd better add it to make it more likely for applications to work out of the box. Reviewed by: alc (mman.h) --- lib/libc/sys/mmap.2 | 6 +++++- sys/sys/mman.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2 index e63274808d5..48499731b58 100644 --- a/lib/libc/sys/mmap.2 +++ b/lib/libc/sys/mmap.2 @@ -28,7 +28,7 @@ .\" @(#)mmap.2 8.4 (Berkeley) 5/11/95 .\" $FreeBSD$ .\" -.Dd July 26, 2009 +.Dd November 6, 2009 .Dt MMAP 2 .Os .Sh NAME @@ -108,6 +108,10 @@ The argument is ignored. .\".It Dv MAP_FILE .\"Mapped from a regular file or character-special device memory. +.It Dv MAP_ANONYMOUS +This flag is identical to +.Dv MAP_ANON +and is provided for compatibility. .It Dv MAP_FIXED Do not permit the system to select a different address than the one specified. diff --git a/sys/sys/mman.h b/sys/sys/mman.h index 9b64e8981cc..12c013383de 100644 --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -82,6 +82,9 @@ */ #define MAP_FILE 0x0000 /* map from file (default) */ #define MAP_ANON 0x1000 /* allocated from memory, swap space */ +#ifndef _KERNEL +#define MAP_ANONYMOUS MAP_ANON /* For compatibility. */ +#endif /* !_KERNEL */ /* * Extended flags From 2eb10edccb5ce17aaf65c9d76652142b64cbdb1c Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Fri, 6 Nov 2009 10:07:38 +0000 Subject: [PATCH 529/646] Don't call LLE_FREE() after nd6_free(). MFC after: 3 days --- sys/netinet6/nd6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index de1773ed669..30fad17e7f6 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -513,6 +513,7 @@ nd6_llinfo_timer(void *arg) if (ln->la_flags & LLE_DELETED) { (void)nd6_free(ln, 0); + ln = NULL; goto done; } From 1f02c0f7a9d3458fa0bdffc64f74a221f4c93e3d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 6 Nov 2009 11:17:33 +0000 Subject: [PATCH 530/646] Document support for more chips. --- share/man/man4/ata.4 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4 index a4cdfee29dc..f23a4d2be1a 100644 --- a/share/man/man4/ata.4 +++ b/share/man/man4/ata.4 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 24, 2009 +.Dd November 6, 2009 .Dt ATA 4 .Os .Sh NAME @@ -129,7 +129,7 @@ M5229, M5281, M5287, M5288, M5289. .It AMD: AMD756, AMD766, AMD768, AMD8111, CS5536. .It ATI: -IXP200, IXP300, IXP400. +IXP200, IXP300, IXP400, IXP600, IXP700, IXP800. .It CMD: CMD646, CMD646U2, CMD648, CMD649. .It Cypress: @@ -145,13 +145,15 @@ IT8211F, IT8212F, IT8213F. .It JMicron: JMB360, JMB361, JMB363, JMB365, JMB366, JMB368. .It Marvell -88SX5040, 88SX5041, 88SX5080, 88SX5081, 88SX6041, 88SX6081, 88SX6101, 88SX6141. +88SX5040, 88SX5041, 88SX5080, 88SX5081, 88SX6041, 88SX6042, 88SX6081, 88SX6101, +88SX6141, 88SX7042. .It National: SC1100. .It NetCell: NC3000, NC5000. .It nVidia: -nForce, nForce2, nForce2 MCP, nForce3, nForce3 MCP, nForce3 Pro, nForce4. +nForce, nForce2, nForce2 MCP, nForce3, nForce3 MCP, nForce3 Pro, nForce4, +MCP51, MCP55, MCP61, MCP65, MCP67, MCP73, MCP77, MCP79, MCP89. .It Promise: PDC20246, PDC20262, PDC20263, PDC20265, PDC20267, PDC20268, PDC20269, PDC20270, PDC20271, PDC20275, PDC20276, PDC20277, PDC20318, PDC20319, PDC20371, PDC20375, PDC20376, PDC20377, PDC20378, PDC20379, PDC20571, PDC20575, PDC20579, PDC20580, PDC20617, PDC20618, PDC20619, PDC20620, PDC20621, PDC20622, PDC40518, PDC40519, PDC40718, PDC40719. .It ServerWorks: From 50c3239e85f6708f6bd3f2177c713159240e6cf1 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 13:10:12 +0000 Subject: [PATCH 531/646] Fix a copy-paste bug when reading data from the last 3 (7 for PAE) bytes of a page mapped by a large page in the kernel. Submitted by: Dorr H. Clark dclark of engr.scu.edu MFC after: 1 week --- lib/libkvm/kvm_i386.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/libkvm/kvm_i386.c b/lib/libkvm/kvm_i386.c index 303b4af4ac3..ac86ba697c4 100644 --- a/lib/libkvm/kvm_i386.c +++ b/lib/libkvm/kvm_i386.c @@ -295,9 +295,9 @@ _kvm_vatop(kvm_t *kd, u_long va, off_t *pa) #define PG_FRAME4M (~PAGE4M_MASK) pde_pa = ((u_long)pde & PG_FRAME4M) + (va & PAGE4M_MASK); s = _kvm_pa2off(kd, pde_pa, &ofs); - if (s < sizeof pde) { - _kvm_syserr(kd, kd->program, - "_kvm_vatop: pde_pa not found"); + if (s == 0) { + _kvm_err(kd, kd->program, + "_kvm_vatop: 4MB page address not in dump"); goto invalid; } *pa = ofs; @@ -391,9 +391,9 @@ _kvm_vatop_pae(kvm_t *kd, u_long va, off_t *pa) #define PG_FRAME2M (~PAGE2M_MASK) pde_pa = ((u_long)pde & PG_FRAME2M) + (va & PAGE2M_MASK); s = _kvm_pa2off(kd, pde_pa, &ofs); - if (s < sizeof pde) { - _kvm_syserr(kd, kd->program, - "_kvm_vatop_pae: pde_pa not found"); + if (s == 0) { + _kvm_err(kd, kd->program, + "_kvm_vatop: 2MB page address not in dump"); goto invalid; } *pa = ofs; From f1b211841d6c1455b797ac92ac7382c95ca543f7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 14:52:37 +0000 Subject: [PATCH 532/646] Use device_printf() and if_printf() instead of printf() with an explicit unit number and remove 'unit' members from softc. --- sys/dev/an/if_an.c | 129 ++++++++++++++++----------------- sys/dev/an/if_anreg.h | 2 - sys/dev/ixgb/if_ixgb.c | 156 +++++++++++++++++++--------------------- sys/dev/ixgb/if_ixgb.h | 1 - sys/dev/vge/if_vge.c | 15 ++-- sys/dev/vge/if_vgevar.h | 1 - 6 files changed, 142 insertions(+), 162 deletions(-) diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index 1d22322d8f7..7f8a2c27503 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -349,7 +349,6 @@ an_probe(device_t dev) */ sc->an_bhandle = rman_get_bushandle(sc->port_res); sc->an_btag = rman_get_bustag(sc->port_res); - sc->an_unit = device_get_unit(dev); ssid.an_len = sizeof(ssid); ssid.an_type = AN_RID_SSIDLIST; @@ -600,8 +599,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_RX_DESC_OFFSET; cmd_struct.an_parm2 = AN_MAX_RX_DESC; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate RX descriptor\n", - sc->an_unit); + if_printf(sc->an_ifp, "failed to allocate RX descriptor\n"); return(EIO); } @@ -629,8 +627,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_TX_DESC_OFFSET; cmd_struct.an_parm2 = AN_MAX_TX_DESC; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate TX descriptor\n", - sc->an_unit); + if_printf(sc->an_ifp, "failed to allocate TX descriptor\n"); return(EIO); } @@ -659,8 +656,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_HOST_DESC_OFFSET; cmd_struct.an_parm2 = 1; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate host descriptor\n", - sc->an_unit); + if_printf(sc->an_ifp, "failed to allocate host descriptor\n"); return(EIO); } @@ -687,7 +683,7 @@ an_attach(struct an_softc *sc, int unit, int flags) ifp = sc->an_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - printf("an%d: can not if_alloc()\n", sc->an_unit); + device_printf(sc->an_dev, "can not if_alloc()\n"); goto fail; } @@ -708,7 +704,7 @@ an_attach(struct an_softc *sc, int unit, int flags) /* Load factory config */ if (an_cmd(sc, AN_CMD_READCFG, 0)) { - printf("an%d: failed to load config data\n", sc->an_unit); + device_printf(sc->an_dev, "failed to load config data\n"); goto fail; } @@ -716,7 +712,7 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_config.an_type = AN_RID_GENCONFIG; sc->an_config.an_len = sizeof(struct an_ltv_genconfig); if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) { - printf("an%d: read record failed\n", sc->an_unit); + device_printf(sc->an_dev, "read record failed\n"); goto fail; } @@ -724,7 +720,7 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_caps.an_type = AN_RID_CAPABILITIES; sc->an_caps.an_len = sizeof(struct an_ltv_caps); if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) { - printf("an%d: read record failed\n", sc->an_unit); + device_printf(sc->an_dev, "read record failed\n"); goto fail; } @@ -732,7 +728,7 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_ssidlist.an_type = AN_RID_SSIDLIST; sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new); if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { - printf("an%d: read record failed\n", sc->an_unit); + device_printf(sc->an_dev, "read record failed\n"); goto fail; } @@ -740,7 +736,7 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_aplist.an_type = AN_RID_APLIST; sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { - printf("an%d: read record failed\n", sc->an_unit); + device_printf(sc->an_dev, "read record failed\n"); goto fail; } @@ -751,19 +747,19 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_rssimap.an_type = AN_RID_RSSI_MAP; sc->an_rssimap.an_len = sizeof(struct an_ltv_rssi_map); if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_rssimap)) { - printf("an%d: unable to get RSSI <-> dBM map\n", sc->an_unit); + device_printf(sc->an_dev, + "unable to get RSSI <-> dBM map\n"); } else { - printf("an%d: got RSSI <-> dBM map\n", sc->an_unit); + device_printf(sc->an_dev, "got RSSI <-> dBM map\n"); sc->an_have_rssimap = 1; } } else { - printf("an%d: no RSSI <-> dBM map\n", sc->an_unit); + device_printf(sc->an_dev, "no RSSI <-> dBM map\n"); } #endif AN_UNLOCK(sc); ifp->if_softc = sc; - sc->an_unit = unit; if_initname(ifp, device_get_name(sc->an_dev), device_get_unit(sc->an_dev)); ifp->if_mtu = ETHERMTU; @@ -907,9 +903,9 @@ an_rxeof(struct an_softc *sc) + sizeof(rx_frame); /* Check for insane frame length */ if (len > sizeof(sc->buf_802_11)) { - printf("an%d: oversized packet " + if_printf(ifp, "oversized packet " "received (%d, %d)\n", - sc->an_unit, len, MCLBYTES); + len, MCLBYTES); ifp->if_ierrors++; return; } @@ -933,9 +929,9 @@ an_rxeof(struct an_softc *sc) + ieee80211_header_len; /* Check for insane frame length */ if (len > sizeof(sc->buf_802_11)) { - printf("an%d: oversized packet " + if_printf(ifp, "oversized packet " "received (%d, %d)\n", - sc->an_unit, len, MCLBYTES); + len, MCLBYTES); ifp->if_ierrors++; return; } @@ -993,9 +989,9 @@ an_rxeof(struct an_softc *sc) len = rx_frame_802_3.an_rx_802_3_payload_len; if (len > sizeof(sc->buf_802_11)) { m_freem(m); - printf("an%d: oversized packet " + if_printf(ifp, "oversized packet " "received (%d, %d)\n", - sc->an_unit, len, MCLBYTES); + len, MCLBYTES); ifp->if_ierrors++; return; } @@ -1073,9 +1069,9 @@ an_rxeof(struct an_softc *sc) len = an_rx_desc.an_len + 12; if (len > MCLBYTES) { m_freem(m); - printf("an%d: oversized packet " + if_printf(ifp, "oversized packet " "received (%d, %d)\n", - sc->an_unit, len, MCLBYTES); + len, MCLBYTES); ifp->if_ierrors++; return; } @@ -1116,9 +1112,8 @@ an_rxeof(struct an_softc *sc) ((u_int32_t *)(void *)&an_rx_desc)[i]); } else { - printf("an%d: Didn't get valid RX packet " + if_printf(ifp, "Didn't get valid RX packet " "%x %x %d\n", - sc->an_unit, an_rx_desc.an_done, an_rx_desc.an_valid, an_rx_desc.an_len); } @@ -1393,7 +1388,7 @@ an_reset(struct an_softc *sc) an_cmd(sc, AN_CMD_NOOP2, 0); if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) - printf("an%d: reset failed\n", sc->an_unit); + if_printf(sc->an_ifp, "reset failed\n"); an_cmd(sc, AN_CMD_DISABLE, 0); @@ -1410,6 +1405,7 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) struct an_card_rid_desc an_rid_desc; struct an_command cmd; struct an_reply reply; + struct ifnet *ifp; u_int16_t *ptr; u_int8_t *ptr2; int i, len; @@ -1418,16 +1414,17 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) if (ltv->an_len < 4 || ltv->an_type == 0) return(EINVAL); + ifp = sc->an_ifp; if (!sc->mpi350){ /* Tell the NIC to enter record read mode. */ if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) { - printf("an%d: RID access failed\n", sc->an_unit); + if_printf(ifp, "RID access failed\n"); return(EIO); } /* Seek to the record. */ if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) { - printf("an%d: seek to record failed\n", sc->an_unit); + if_printf(ifp, "seek to record failed\n"); return(EIO); } @@ -1439,8 +1436,8 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) */ len = CSR_READ_2(sc, AN_DATA1); if (len > (ltv->an_len - 2)) { - printf("an%d: record length mismatch -- expected %d, " - "got %d for Rid %x\n", sc->an_unit, + if_printf(ifp, "record length mismatch -- expected %d, " + "got %d for Rid %x\n", ltv->an_len - 2, len, ltv->an_type); len = ltv->an_len - 2; } else { @@ -1476,8 +1473,8 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) if (an_cmd_struct(sc, &cmd, &reply) || reply.an_status & AN_CMD_QUAL_MASK) { - printf("an%d: failed to read RID %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + if_printf(ifp, "failed to read RID %x %x %x %x %x, %d\n", + ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1493,8 +1490,8 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) len = an_rid_desc.an_len; if (len > (ltv->an_len - 2)) { - printf("an%d: record length mismatch -- expected %d, " - "got %d for Rid %x\n", sc->an_unit, + if_printf(ifp, "record length mismatch -- expected %d, " + "got %d for Rid %x\n", ltv->an_len - 2, len, ltv->an_type); len = ltv->an_len - 2; } else { @@ -1586,8 +1583,9 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) DELAY(100000); if ((i = an_cmd_struct(sc, &cmd, &reply))) { - printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + if_printf(sc->an_ifp, + "failed to write RID 1 %x %x %x %x %x, %d\n", + ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1598,8 +1596,9 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) if (reply.an_status & AN_CMD_QUAL_MASK) { - printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + if_printf(sc->an_ifp, + "failed to write RID 2 %x %x %x %x %x, %d\n", + ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1623,11 +1622,11 @@ an_dump_record(struct an_softc *sc, struct an_ltv_gen *ltv, char *string) char buf[17], temp; len = ltv->an_len - 4; - printf("an%d: RID %4x, Length %4d, Mode %s\n", - sc->an_unit, ltv->an_type, ltv->an_len - 4, string); + if_printf(sc->an_ifp, "RID %4x, Length %4d, Mode %s\n", + ltv->an_type, ltv->an_len - 4, string); if (an_dump == 1 || (an_dump == ltv->an_type)) { - printf("an%d:\t", sc->an_unit); + if_printf(sc->an_ifp, "\t"); bzero(buf,sizeof(buf)); ptr2 = (u_int8_t *)<v->an_val; @@ -1642,7 +1641,7 @@ an_dump_record(struct an_softc *sc, struct an_ltv_gen *ltv, char *string) if (++count == 16) { count = 0; printf("%s\n",buf); - printf("an%d:\t", sc->an_unit); + if_printf(sc->an_ifp, "\t"); bzero(buf,sizeof(buf)); } } @@ -1669,7 +1668,7 @@ an_seek(struct an_softc *sc, int id, int off, int chan) offreg = AN_OFF1; break; default: - printf("an%d: invalid data path: %x\n", sc->an_unit, chan); + if_printf(sc->an_ifp, "invalid data path: %x\n", chan); return(EIO); } @@ -1743,8 +1742,8 @@ an_alloc_nicmem(struct an_softc *sc, int len, int *id) int i; if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { - printf("an%d: failed to allocate %d bytes on NIC\n", - sc->an_unit, len); + if_printf(sc->an_ifp, "failed to allocate %d bytes on NIC\n", + len); return(ENOMEM); } @@ -1863,7 +1862,7 @@ an_setdef(struct an_softc *sc, struct an_req *areq) } break; default: - printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); + if_printf(ifp, "unknown RID: %x\n", areq->an_type); return; } @@ -2653,8 +2652,7 @@ an_init(void *xsc) if (sc->mpi350) an_init_mpi350_desc(sc); if (an_init_tx_ring(sc)) { - printf("an%d: tx buffer allocation " - "failed\n", sc->an_unit); + if_printf(ifp, "tx buffer allocation failed\n"); AN_UNLOCK(sc); return; } @@ -2695,7 +2693,7 @@ an_init(void *xsc) sc->an_ssidlist.an_type = AN_RID_SSIDLIST; sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new); if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { - printf("an%d: failed to set ssid list\n", sc->an_unit); + if_printf(ifp, "failed to set ssid list\n"); AN_UNLOCK(sc); return; } @@ -2704,7 +2702,7 @@ an_init(void *xsc) sc->an_aplist.an_type = AN_RID_APLIST; sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { - printf("an%d: failed to set AP list\n", sc->an_unit); + if_printf(ifp, "failed to set AP list\n"); AN_UNLOCK(sc); return; } @@ -2713,14 +2711,14 @@ an_init(void *xsc) sc->an_config.an_len = sizeof(struct an_ltv_genconfig); sc->an_config.an_type = AN_RID_GENCONFIG; if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { - printf("an%d: failed to set configuration\n", sc->an_unit); + if_printf(ifp, "failed to set configuration\n"); AN_UNLOCK(sc); return; } /* Enable the MAC */ if (an_cmd(sc, AN_CMD_ENABLE, 0)) { - printf("an%d: failed to enable MAC\n", sc->an_unit); + if_printf(ifp, "failed to enable MAC\n"); AN_UNLOCK(sc); return; } @@ -2827,7 +2825,7 @@ an_start(struct ifnet *ifp) sc->an_rdata.an_tx_ring[idx] = id; if (an_cmd(sc, AN_CMD_TX, id)) - printf("an%d: xmit failed\n", sc->an_unit); + if_printf(ifp, "xmit failed\n"); AN_INC(idx, AN_TX_RING_CNT); @@ -2976,7 +2974,7 @@ an_watchdog(struct ifnet *ifp) return; } - printf("an%d: device timeout\n", sc->an_unit); + if_printf(ifp, "device timeout\n"); an_reset(sc); if (sc->mpi350) @@ -3127,7 +3125,7 @@ an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m, } #ifdef SIGDEBUG - printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", + if_printf(sc->an_ifp, "q value %x (MSB=0x%x, LSB=0x%x) \n", rx_rssi & 0xffff, rx_rssi >> 8, rx_rssi & 0xff); #endif @@ -3567,8 +3565,7 @@ cmdreset(struct ifnet *ifp) an_cmd(sc, AN_CMD_DISABLE, 0); if (!(status = WaitBusy(ifp, AN_TIMEOUT))) { - printf("an%d: Waitbusy hang b4 RESET =%d\n", - sc->an_unit, status); + if_printf(ifp, "Waitbusy hang b4 RESET =%d\n", status); AN_UNLOCK(sc); return -EBUSY; } @@ -3578,8 +3575,7 @@ cmdreset(struct ifnet *ifp) if (!(status = WaitBusy(ifp, 100))) { - printf("an%d: Waitbusy hang AFTER RESET =%d\n", - sc->an_unit, status); + if_printf(ifp, "Waitbusy hang AFTER RESET =%d\n", status); AN_UNLOCK(sc); return -EBUSY; } @@ -3687,8 +3683,7 @@ flashpchar(struct ifnet *ifp, int byte, int dwelltime) /* timeout for busy clear wait */ if (waittime <= 0) { - printf("an%d: flash putchar busywait timeout! \n", - sc->an_unit); + if_printf(ifp, "flash putchar busywait timeout!\n"); return -1; } /* @@ -3774,8 +3769,7 @@ flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) sc = ifp->if_softc; if (sc->mpi350) { - printf("an%d: flashing not supported on MPI 350 yet\n", - sc->an_unit); + if_printf(ifp, "flashing not supported on MPI 350 yet\n"); return(-1); } status = l_ioctl->command; @@ -3820,7 +3814,7 @@ flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) break; case AIROFLPUTBUF: /* Send 32k to card */ if (l_ioctl->len > FLASH_SIZE) { - printf("an%d: Buffer to big, %x %x\n", sc->an_unit, + if_printf(ifp, "Buffer to big, %x %x\n", l_ioctl->len, FLASH_SIZE); return -EINVAL; } @@ -3837,8 +3831,7 @@ flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) break; case AIRORESTART: if ((status = flashrestart(ifp)) != 0) { - printf("an%d: FLASHRESTART returned %d\n", - sc->an_unit, status); + if_printf(ifp, "FLASHRESTART returned %d\n", status); return -EIO; } else return 0; diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h index ec0ad2bc4a8..3378d2ccb0a 100644 --- a/sys/dev/an/if_anreg.h +++ b/sys/dev/an/if_anreg.h @@ -442,8 +442,6 @@ struct an_tx_ring_data { struct an_softc { struct ifnet *an_ifp; - int an_unit; - int port_rid; /* resource id for port range */ struct resource* port_res; /* resource for port range */ int mem_rid; /* resource id for memory range */ diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c index 90b3c91cf7f..21d0bf02aa0 100644 --- a/sys/dev/ixgb/if_ixgb.c +++ b/sys/dev/ixgb/if_ixgb.c @@ -249,18 +249,17 @@ ixgb_attach(device_t dev) int tsize, rsize; int error = 0; - printf("ixgb%d: %s\n", device_get_unit(dev), ixgb_copyright); + device_printf(dev, "%s\n", ixgb_copyright); INIT_DEBUGOUT("ixgb_attach: begin"); /* Allocate, clear, and link in our adapter structure */ if (!(adapter = device_get_softc(dev))) { - printf("ixgb: adapter structure allocation failed\n"); + device_printf(dev, "adapter structure allocation failed\n"); return (ENOMEM); } bzero(adapter, sizeof(struct adapter)); adapter->dev = dev; adapter->osdep.dev = dev; - adapter->unit = device_get_unit(dev); IXGB_LOCK_INIT(adapter, device_get_nameunit(dev)); if (ixgb_adapter_list != NULL) @@ -299,8 +298,7 @@ ixgb_attach(device_t dev) ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN; if (ixgb_allocate_pci_resources(adapter)) { - printf("ixgb%d: Allocation of PCI resources failed\n", - adapter->unit); + device_printf(dev, "Allocation of PCI resources failed\n"); error = ENXIO; goto err_pci; } @@ -309,8 +307,7 @@ ixgb_attach(device_t dev) /* Allocate Transmit Descriptor ring */ if (ixgb_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) { - printf("ixgb%d: Unable to allocate TxDescriptor memory\n", - adapter->unit); + device_printf(dev, "Unable to allocate TxDescriptor memory\n"); error = ENOMEM; goto err_tx_desc; } @@ -321,8 +318,7 @@ ixgb_attach(device_t dev) /* Allocate Receive Descriptor ring */ if (ixgb_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) { - printf("ixgb%d: Unable to allocate rx_desc memory\n", - adapter->unit); + device_printf(dev, "Unable to allocate rx_desc memory\n"); error = ENOMEM; goto err_rx_desc; } @@ -330,8 +326,7 @@ ixgb_attach(device_t dev) /* Initialize the hardware */ if (ixgb_hardware_init(adapter)) { - printf("ixgb%d: Unable to initialize the hardware\n", - adapter->unit); + device_printf(dev, "Unable to initialize the hardware\n"); error = EIO; goto err_hw_init; } @@ -628,7 +623,7 @@ ixgb_watchdog(struct ifnet * ifp) ifp->if_timer = IXGB_TX_TIMEOUT; return; } - printf("ixgb%d: watchdog timeout -- resetting\n", adapter->unit); + if_printf(ifp, "watchdog timeout -- resetting\n"); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; @@ -663,23 +658,22 @@ ixgb_init_locked(struct adapter *adapter) IXGB_LOCK_ASSERT(adapter); ixgb_stop(adapter); + ifp = adapter->ifp; /* Get the latest mac address, User can use a LAA */ - bcopy(IF_LLADDR(adapter->ifp), adapter->hw.curr_mac_addr, - IXGB_ETH_LENGTH_OF_ADDRESS); + bcopy(IF_LLADDR(ifp), adapter->hw.curr_mac_addr, + IXGB_ETH_LENGTH_OF_ADDRESS); /* Initialize the hardware */ if (ixgb_hardware_init(adapter)) { - printf("ixgb%d: Unable to initialize the hardware\n", - adapter->unit); + if_printf(ifp, "Unable to initialize the hardware\n"); return; } ixgb_enable_vlans(adapter); /* Prepare transmit descriptors and buffers */ if (ixgb_setup_transmit_structures(adapter)) { - printf("ixgb%d: Could not setup transmit structures\n", - adapter->unit); + if_printf(ifp, "Could not setup transmit structures\n"); ixgb_stop(adapter); return; } @@ -690,8 +684,7 @@ ixgb_init_locked(struct adapter *adapter) /* Prepare receive descriptors and buffers */ if (ixgb_setup_receive_structures(adapter)) { - printf("ixgb%d: Could not setup receive structures\n", - adapter->unit); + if_printf(ifp, "Could not setup receive structures\n"); ixgb_stop(adapter); return; } @@ -959,8 +952,8 @@ ixgb_encap(struct adapter * adapter, struct mbuf * m_head) &nsegs, BUS_DMA_NOWAIT); if (error != 0) { adapter->no_tx_dma_setup++; - printf("ixgb%d: ixgb_encap: bus_dmamap_load_mbuf failed; " - "error %u\n", adapter->unit, error); + if_printf(ifp, "ixgb_encap: bus_dmamap_load_mbuf failed; " + "error %u\n", error); bus_dmamap_destroy(adapter->txtag, map); return (error); } @@ -1149,15 +1142,14 @@ ixgb_print_link_status(struct adapter * adapter) { if (adapter->hw.link_up) { if (!adapter->link_active) { - printf("ixgb%d: Link is up %d Mbps %s \n", - adapter->unit, + if_printf(adapter->ifp, "Link is up %d Mbps %s \n", 10000, "Full Duplex"); adapter->link_active = 1; } } else { if (adapter->link_active) { - printf("ixgb%d: Link is Down \n", adapter->unit); + if_printf(adapter->ifp, "Link is Down \n"); adapter->link_active = 0; } } @@ -1213,8 +1205,8 @@ ixgb_identify_hardware(struct adapter * adapter) adapter->hw.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2); if (!((adapter->hw.pci_cmd_word & PCIM_CMD_BUSMASTEREN) && (adapter->hw.pci_cmd_word & PCIM_CMD_MEMEN))) { - printf("ixgb%d: Memory Access and/or Bus Master bits were not set!\n", - adapter->unit); + device_printf(dev, + "Memory Access and/or Bus Master bits were not set!\n"); adapter->hw.pci_cmd_word |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); pci_write_config(dev, PCIR_COMMAND, adapter->hw.pci_cmd_word, 2); @@ -1234,7 +1226,8 @@ ixgb_identify_hardware(struct adapter * adapter) break; default: INIT_DEBUGOUT1("Unknown device if 0x%x", adapter->hw.device_id); - printf("ixgb%d: unsupported device id 0x%x\n", adapter->unit, adapter->hw.device_id); + device_printf(dev, "unsupported device id 0x%x\n", + adapter->hw.device_id); } return; @@ -1251,8 +1244,7 @@ ixgb_allocate_pci_resources(struct adapter * adapter) &rid, 0, ~0, 1, RF_ACTIVE); if (!(adapter->res_memory)) { - printf("ixgb%d: Unable to allocate bus resource: memory\n", - adapter->unit); + device_printf(dev, "Unable to allocate bus resource: memory\n"); return (ENXIO); } adapter->osdep.mem_bus_space_tag = @@ -1266,16 +1258,15 @@ ixgb_allocate_pci_resources(struct adapter * adapter) &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); if (!(adapter->res_interrupt)) { - printf("ixgb%d: Unable to allocate bus resource: interrupt\n", - adapter->unit); + device_printf(dev, + "Unable to allocate bus resource: interrupt\n"); return (ENXIO); } if (bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_NET | INTR_MPSAFE, NULL, (void (*) (void *))ixgb_intr, adapter, &adapter->int_handler_tag)) { - printf("ixgb%d: Error registering interrupt handler!\n", - adapter->unit); + device_printf(dev, "Error registering interrupt handler!\n"); return (ENXIO); } adapter->hw.back = &adapter->osdep; @@ -1322,13 +1313,12 @@ ixgb_hardware_init(struct adapter * adapter) /* Make sure we have a good EEPROM before we read from it */ if (!ixgb_validate_eeprom_checksum(&adapter->hw)) { - printf("ixgb%d: The EEPROM Checksum Is Not Valid\n", - adapter->unit); + device_printf(adapter->dev, + "The EEPROM Checksum Is Not Valid\n"); return (EIO); } if (!ixgb_init_hw(&adapter->hw)) { - printf("ixgb%d: Hardware Initialization Failed", - adapter->unit); + device_printf(adapter->dev, "Hardware Initialization Failed"); return (EIO); } @@ -1352,7 +1342,7 @@ ixgb_setup_interface(device_t dev, struct adapter * adapter) #if __FreeBSD_version >= 502000 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); #else - ifp->if_unit = adapter->unit; + ifp->if_unit = device_get_unit(dev); ifp->if_name = "ixgb"; #endif ifp->if_mtu = ETHERMTU; @@ -1420,8 +1410,10 @@ static int ixgb_dma_malloc(struct adapter * adapter, bus_size_t size, struct ixgb_dma_alloc * dma, int mapflags) { + device_t dev; int r; + dev = adapter->dev; r = bus_dma_tag_create(NULL, /* parent */ PAGE_SIZE, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ @@ -1437,15 +1429,15 @@ ixgb_dma_malloc(struct adapter * adapter, bus_size_t size, #endif &dma->dma_tag); if (r != 0) { - printf("ixgb%d: ixgb_dma_malloc: bus_dma_tag_create failed; " - "error %u\n", adapter->unit, r); + device_printf(dev, "ixgb_dma_malloc: bus_dma_tag_create failed; " + "error %u\n", r); goto fail_0; } r = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr, BUS_DMA_NOWAIT, &dma->dma_map); if (r != 0) { - printf("ixgb%d: ixgb_dma_malloc: bus_dmamem_alloc failed; " - "error %u\n", adapter->unit, r); + device_printf(dev, "ixgb_dma_malloc: bus_dmamem_alloc failed; " + "error %u\n", r); goto fail_1; } r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, @@ -1454,8 +1446,8 @@ ixgb_dma_malloc(struct adapter * adapter, bus_size_t size, &dma->dma_paddr, mapflags | BUS_DMA_NOWAIT); if (r != 0) { - printf("ixgb%d: ixgb_dma_malloc: bus_dmamap_load failed; " - "error %u\n", adapter->unit, r); + device_printf(dev, "ixgb_dma_malloc: bus_dmamap_load failed; " + "error %u\n", r); goto fail_2; } dma->dma_size = size; @@ -1493,8 +1485,8 @@ ixgb_allocate_transmit_structures(struct adapter * adapter) (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) * adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) { - printf("ixgb%d: Unable to allocate tx_buffer memory\n", - adapter->unit); + device_printf(adapter->dev, + "Unable to allocate tx_buffer memory\n"); return ENOMEM; } bzero(adapter->tx_buffer_area, @@ -1528,7 +1520,7 @@ ixgb_setup_transmit_structures(struct adapter * adapter) NULL, /* lockfuncarg */ #endif &adapter->txtag)) { - printf("ixgb%d: Unable to allocate TX DMA tag\n", adapter->unit); + device_printf(adapter->dev, "Unable to allocate TX DMA tag\n"); return (ENOMEM); } if (ixgb_allocate_transmit_structures(adapter)) @@ -1845,8 +1837,8 @@ ixgb_allocate_receive_structures(struct adapter * adapter) (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) * adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) { - printf("ixgb%d: Unable to allocate rx_buffer memory\n", - adapter->unit); + device_printf(adapter->dev, + "Unable to allocate rx_buffer memory\n"); return (ENOMEM); } bzero(adapter->rx_buffer_area, @@ -1867,9 +1859,9 @@ ixgb_allocate_receive_structures(struct adapter * adapter) #endif &adapter->rxtag); if (error != 0) { - printf("ixgb%d: ixgb_allocate_receive_structures: " + device_printf(adapter->dev, "ixgb_allocate_receive_structures: " "bus_dma_tag_create failed; error %u\n", - adapter->unit, error); + error); goto fail_0; } rx_buffer = adapter->rx_buffer_area; @@ -1877,9 +1869,10 @@ ixgb_allocate_receive_structures(struct adapter * adapter) error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT, &rx_buffer->map); if (error != 0) { - printf("ixgb%d: ixgb_allocate_receive_structures: " + device_printf(adapter->dev, + "ixgb_allocate_receive_structures: " "bus_dmamap_create failed; error %u\n", - adapter->unit, error); + error); goto fail_1; } } @@ -2431,20 +2424,21 @@ ixgb_print_hw_stats(struct adapter * adapter) char buf_speed[100], buf_type[100]; ixgb_bus_speed bus_speed; ixgb_bus_type bus_type; - int unit = adapter->unit; + device_t dev; + dev = adapter->dev; #ifdef _SV_ - printf("ixgb%d: Packets not Avail = %ld\n", unit, + device_printf(dev, "Packets not Avail = %ld\n", adapter->no_pkts_avail); - printf("ixgb%d: CleanTxInterrupts = %ld\n", unit, + device_printf(dev, "CleanTxInterrupts = %ld\n", adapter->clean_tx_interrupts); - printf("ixgb%d: ICR RXDMT0 = %lld\n", unit, + device_printf(dev, "ICR RXDMT0 = %lld\n", (long long)adapter->sv_stats.icr_rxdmt0); - printf("ixgb%d: ICR RXO = %lld\n", unit, + device_printf(dev, "ICR RXO = %lld\n", (long long)adapter->sv_stats.icr_rxo); - printf("ixgb%d: ICR RXT0 = %lld\n", unit, + device_printf(dev, "ICR RXT0 = %lld\n", (long long)adapter->sv_stats.icr_rxt0); - printf("ixgb%d: ICR TXDW = %lld\n", unit, + device_printf(dev, "ICR TXDW = %lld\n", (long long)adapter->sv_stats.icr_TXDW); #endif /* _SV_ */ @@ -2456,55 +2450,55 @@ ixgb_print_hw_stats(struct adapter * adapter) bus_speed == ixgb_bus_speed_100 ? "100MHz" : bus_speed == ixgb_bus_speed_133 ? "133MHz" : "UNKNOWN"); - printf("ixgb%d: PCI_Bus_Speed = %s\n", unit, + device_printf(dev, "PCI_Bus_Speed = %s\n", buf_speed); sprintf(buf_type, bus_type == ixgb_bus_type_pci ? "PCI" : bus_type == ixgb_bus_type_pcix ? "PCI-X" : "UNKNOWN"); - printf("ixgb%d: PCI_Bus_Type = %s\n", unit, + device_printf(dev, "PCI_Bus_Type = %s\n", buf_type); - printf("ixgb%d: Tx Descriptors not Avail1 = %ld\n", unit, + device_printf(dev, "Tx Descriptors not Avail1 = %ld\n", adapter->no_tx_desc_avail1); - printf("ixgb%d: Tx Descriptors not Avail2 = %ld\n", unit, + device_printf(dev, "Tx Descriptors not Avail2 = %ld\n", adapter->no_tx_desc_avail2); - printf("ixgb%d: Std Mbuf Failed = %ld\n", unit, + device_printf(dev, "Std Mbuf Failed = %ld\n", adapter->mbuf_alloc_failed); - printf("ixgb%d: Std Cluster Failed = %ld\n", unit, + device_printf(dev, "Std Cluster Failed = %ld\n", adapter->mbuf_cluster_failed); - printf("ixgb%d: Defer count = %lld\n", unit, + device_printf(dev, "Defer count = %lld\n", (long long)adapter->stats.dc); - printf("ixgb%d: Missed Packets = %lld\n", unit, + device_printf(dev, "Missed Packets = %lld\n", (long long)adapter->stats.mpc); - printf("ixgb%d: Receive No Buffers = %lld\n", unit, + device_printf(dev, "Receive No Buffers = %lld\n", (long long)adapter->stats.rnbc); - printf("ixgb%d: Receive length errors = %lld\n", unit, + device_printf(dev, "Receive length errors = %lld\n", (long long)adapter->stats.rlec); - printf("ixgb%d: Crc errors = %lld\n", unit, + device_printf(dev, "Crc errors = %lld\n", (long long)adapter->stats.crcerrs); - printf("ixgb%d: Driver dropped packets = %ld\n", unit, + device_printf(dev, "Driver dropped packets = %ld\n", adapter->dropped_pkts); - printf("ixgb%d: XON Rcvd = %lld\n", unit, + device_printf(dev, "XON Rcvd = %lld\n", (long long)adapter->stats.xonrxc); - printf("ixgb%d: XON Xmtd = %lld\n", unit, + device_printf(dev, "XON Xmtd = %lld\n", (long long)adapter->stats.xontxc); - printf("ixgb%d: XOFF Rcvd = %lld\n", unit, + device_printf(dev, "XOFF Rcvd = %lld\n", (long long)adapter->stats.xoffrxc); - printf("ixgb%d: XOFF Xmtd = %lld\n", unit, + device_printf(dev, "XOFF Xmtd = %lld\n", (long long)adapter->stats.xofftxc); - printf("ixgb%d: Good Packets Rcvd = %lld\n", unit, + device_printf(dev, "Good Packets Rcvd = %lld\n", (long long)adapter->stats.gprcl); - printf("ixgb%d: Good Packets Xmtd = %lld\n", unit, + device_printf(dev, "Good Packets Xmtd = %lld\n", (long long)adapter->stats.gptcl); - printf("ixgb%d: Jumbo frames recvd = %lld\n", unit, + device_printf(dev, "Jumbo frames recvd = %lld\n", (long long)adapter->stats.jprcl); - printf("ixgb%d: Jumbo frames Xmtd = %lld\n", unit, + device_printf(dev, "Jumbo frames Xmtd = %lld\n", (long long)adapter->stats.jptcl); return; diff --git a/sys/dev/ixgb/if_ixgb.h b/sys/dev/ixgb/if_ixgb.h index c2f0acffee8..cef9b55e08c 100644 --- a/sys/dev/ixgb/if_ixgb.h +++ b/sys/dev/ixgb/if_ixgb.h @@ -284,7 +284,6 @@ struct adapter { struct ifmedia media; struct callout timer; int io_rid; - u_int8_t unit; struct mtx mtx; /* Info about the board itself */ diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c index f08f8a267f3..a2457695e8e 100644 --- a/sys/dev/vge/if_vge.c +++ b/sys/dev/vge/if_vge.c @@ -967,8 +967,6 @@ vge_attach(dev) */ vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0); - sc->vge_unit = unit; - /* * Allocate the parent bus DMA tag appropriate for PCI. */ @@ -993,7 +991,7 @@ vge_attach(dev) ifp = sc->vge_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - printf("vge%d: can not if_alloc()\n", sc->vge_unit); + device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; goto fail; } @@ -1001,7 +999,7 @@ vge_attach(dev) /* Do MII setup */ if (mii_phy_probe(dev, &sc->vge_miibus, vge_ifmedia_upd, vge_ifmedia_sts)) { - printf("vge%d: MII without any phy!\n", sc->vge_unit); + device_printf(dev, "MII without any phy!\n"); error = ENXIO; goto fail; } @@ -1736,8 +1734,7 @@ vge_encap(sc, m_head, idx) m_head, vge_dma_map_tx_desc, &arg, BUS_DMA_NOWAIT); if (error && error != EFBIG) { - printf("vge%d: can't map mbuf (error %d)\n", - sc->vge_unit, error); + if_printf(sc->vge_ifp, "can't map mbuf (error %d)\n", error); return (ENOBUFS); } @@ -1758,8 +1755,8 @@ vge_encap(sc, m_head, idx) error = bus_dmamap_load_mbuf(sc->vge_ldata.vge_mtag, map, m_head, vge_dma_map_tx_desc, &arg, BUS_DMA_NOWAIT); if (error) { - printf("vge%d: can't map mbuf (error %d)\n", - sc->vge_unit, error); + if_printf(sc->vge_ifp, "can't map mbuf (error %d)\n", + error); return (EFBIG); } } @@ -2254,7 +2251,7 @@ vge_watchdog(ifp) sc = ifp->if_softc; VGE_LOCK(sc); - printf("vge%d: watchdog timeout\n", sc->vge_unit); + if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; vge_txeof(sc); diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h index 5d240a33a9e..aab52281b7f 100644 --- a/sys/dev/vge/if_vgevar.h +++ b/sys/dev/vge/if_vgevar.h @@ -108,7 +108,6 @@ struct vge_softc { device_t vge_miibus; bus_dma_tag_t vge_parent_tag; bus_dma_tag_t vge_tag; - u_int8_t vge_unit; /* interface number */ u_int8_t vge_type; int vge_if_flags; int vge_rx_consumed; From e1b17582f4b6633faf7f42f4e6b98cdedc53744c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 14:55:01 +0000 Subject: [PATCH 533/646] Take a step towards removing if_watchdog/if_timer. Don't explicitly set if_watchdog/if_timer to NULL/0 when initializing an ifnet. if_alloc() sets those members to NULL/0 already. --- sys/dev/ath/if_ath.c | 1 - sys/dev/cxgb/cxgb_main.c | 4 ---- sys/dev/hatm/if_hatm.c | 1 - sys/dev/ixgbe/ixgbe.c | 2 -- sys/dev/nfe/if_nfe.c | 1 - sys/dev/patm/if_patm_attach.c | 2 -- sys/dev/sk/if_sk.c | 2 -- sys/dev/stge/if_stge.c | 2 -- sys/net/if_ef.c | 1 - sys/net80211/ieee80211.c | 1 - sys/netgraph/ng_eiface.c | 1 - sys/netgraph/ng_fec.c | 1 - sys/netgraph/ng_iface.c | 1 - sys/netgraph/ng_sppp.c | 1 - 14 files changed, 21 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index b6fbaf857d6..97784f4676a 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -560,7 +560,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) ifp->if_softc = sc; ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_start = ath_start; - ifp->if_watchdog = NULL; ifp->if_ioctl = ath_ioctl; ifp->if_init = ath_init; IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 26d4b508c0a..58ea2f78426 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -1054,10 +1054,6 @@ cxgb_port_attach(device_t dev) ifp->if_ioctl = cxgb_ioctl; ifp->if_start = cxgb_start; - - ifp->if_timer = 0; /* Disable ifnet watchdog */ - ifp->if_watchdog = NULL; - ifp->if_snd.ifq_drv_maxlen = cxgb_snd_queue_len; IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); IFQ_SET_READY(&ifp->if_snd); diff --git a/sys/dev/hatm/if_hatm.c b/sys/dev/hatm/if_hatm.c index 85327643ba3..325e5325c76 100644 --- a/sys/dev/hatm/if_hatm.c +++ b/sys/dev/hatm/if_hatm.c @@ -1928,7 +1928,6 @@ hatm_attach(device_t dev) ifp->if_flags = IFF_SIMPLEX; ifp->if_ioctl = hatm_ioctl; ifp->if_start = hatm_start; - ifp->if_watchdog = NULL; ifp->if_init = hatm_init; utopia_attach(&sc->utopia, IFP2IFATM(sc->ifp), &sc->media, &sc->mtx, diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index fb5ea519768..d994529ea46 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -2508,8 +2508,6 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter) ifp->if_transmit = ixgbe_mq_start; ifp->if_qflush = ixgbe_qflush; #endif - ifp->if_timer = 0; - ifp->if_watchdog = NULL; ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2; ether_ifattach(ifp, adapter->hw.mac.addr); diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c index 67d48710f5f..5d0bfd268f6 100644 --- a/sys/dev/nfe/if_nfe.c +++ b/sys/dev/nfe/if_nfe.c @@ -567,7 +567,6 @@ nfe_attach(device_t dev) ifp->if_start = nfe_start; ifp->if_hwassist = 0; ifp->if_capabilities = 0; - ifp->if_watchdog = NULL; ifp->if_init = nfe_init; IFQ_SET_MAXLEN(&ifp->if_snd, NFE_TX_RING_COUNT - 1); ifp->if_snd.ifq_drv_maxlen = NFE_TX_RING_COUNT - 1; diff --git a/sys/dev/patm/if_patm_attach.c b/sys/dev/patm/if_patm_attach.c index 940d0ac3009..12dfa1498cc 100644 --- a/sys/dev/patm/if_patm_attach.c +++ b/sys/dev/patm/if_patm_attach.c @@ -197,11 +197,9 @@ patm_attach(device_t dev) ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_SIMPLEX; - ifp->if_watchdog = NULL; ifp->if_init = patm_init; ifp->if_ioctl = patm_ioctl; ifp->if_start = patm_start; - ifp->if_watchdog = NULL; /* do this early so we can destroy unconditionally */ mtx_init(&sc->mtx, device_get_nameunit(dev), diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c index b9ca1cf5aa7..0f5d2b15101 100644 --- a/sys/dev/sk/if_sk.c +++ b/sys/dev/sk/if_sk.c @@ -1372,8 +1372,6 @@ sk_attach(dev) ifp->if_capenable = ifp->if_capabilities; ifp->if_ioctl = sk_ioctl; ifp->if_start = sk_start; - ifp->if_timer = 0; - ifp->if_watchdog = NULL; ifp->if_init = sk_init; IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1); ifp->if_snd.ifq_drv_maxlen = SK_TX_RING_CNT - 1; diff --git a/sys/dev/stge/if_stge.c b/sys/dev/stge/if_stge.c index dac4da6d5db..271790d3a2d 100644 --- a/sys/dev/stge/if_stge.c +++ b/sys/dev/stge/if_stge.c @@ -722,8 +722,6 @@ stge_attach(device_t dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = stge_ioctl; ifp->if_start = stge_start; - ifp->if_timer = 0; - ifp->if_watchdog = NULL; ifp->if_init = stge_init; ifp->if_mtu = ETHERMTU; ifp->if_snd.ifq_drv_maxlen = STGE_TX_RING_CNT - 1; diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index 2af3a177204..94fb03d13a4 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -128,7 +128,6 @@ ef_attach(struct efnet *sc) struct ifnet *ifp = sc->ef_ifp; ifp->if_start = ef_start; - ifp->if_watchdog = NULL; ifp->if_init = ef_init; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index b14f13f90fe..d0fc692dc2e 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -391,7 +391,6 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_start = ieee80211_start; ifp->if_ioctl = ieee80211_ioctl; - ifp->if_watchdog = NULL; /* NB: no watchdog routine */ ifp->if_init = ieee80211_init; /* NB: input+output filled in by ether_ifattach */ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c index ce23683c59b..5c91b81a0a6 100644 --- a/sys/netgraph/ng_eiface.c +++ b/sys/netgraph/ng_eiface.c @@ -369,7 +369,6 @@ ng_eiface_constructor(node_p node) ifp->if_output = ether_output; ifp->if_start = ng_eiface_start; ifp->if_ioctl = ng_eiface_ioctl; - ifp->if_watchdog = NULL; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST); diff --git a/sys/netgraph/ng_fec.c b/sys/netgraph/ng_fec.c index e694dd8de1d..c1760d1cc3e 100644 --- a/sys/netgraph/ng_fec.c +++ b/sys/netgraph/ng_fec.c @@ -1226,7 +1226,6 @@ ng_fec_constructor(node_p node) ifp->if_start = ng_fec_start; ifp->if_ioctl = ng_fec_ioctl; ifp->if_init = ng_fec_init; - ifp->if_watchdog = NULL; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; ifp->if_mtu = NG_FEC_MTU_DEFAULT; ifp->if_flags = (IFF_SIMPLEX|IFF_BROADCAST|IFF_MULTICAST); diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 209ac77fbd3..d53bf768b10 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -558,7 +558,6 @@ ng_iface_constructor(node_p node) ifp->if_output = ng_iface_output; ifp->if_start = ng_iface_start; ifp->if_ioctl = ng_iface_ioctl; - ifp->if_watchdog = NULL; ifp->if_mtu = NG_IFACE_MTU_DEFAULT; ifp->if_flags = (IFF_SIMPLEX|IFF_POINTOPOINT|IFF_NOARP|IFF_MULTICAST); ifp->if_type = IFT_PROPVIRTUAL; /* XXX */ diff --git a/sys/netgraph/ng_sppp.c b/sys/netgraph/ng_sppp.c index 5276f4f9bec..6b30ed61f8e 100644 --- a/sys/netgraph/ng_sppp.c +++ b/sys/netgraph/ng_sppp.c @@ -279,7 +279,6 @@ ng_sppp_constructor (node_p node) if_initname (SP2IFP(pp), NG_SPPP_IFACE_NAME, priv->unit); ifp->if_start = ng_sppp_start; ifp->if_ioctl = ng_sppp_ioctl; - ifp->if_watchdog = NULL; ifp->if_flags = (IFF_POINTOPOINT|IFF_MULTICAST); /* Give this node the same name as the interface (if possible) */ From c6d948051918afdab9ab520dbc20f4297f2504b9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 16:55:05 +0000 Subject: [PATCH 534/646] Several years ago a feature was added to TCP that casued soreceive() to send an ACK right away if data was drained from a TCP socket that had previously advertised a zero-sized window. The current code requires the receive window to be exactly zero for this to kick in. If window scaling is enabled and the window is smaller than the scale, then the effective window that is advertised is zero. However, in that case the zero-sized window handling is not enabled because the window is not exactly zero. The fix changes the code to check the raw window value against zero. Reviewed by: bz MFC after: 1 week --- sys/netinet/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index ee33ea2de73..ebe5e36ee3f 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -992,7 +992,7 @@ send: * to read more data than can be buffered prior to transmitting on * the connection. */ - if (recwin == 0) + if (th->th_win == 0) tp->t_flags |= TF_RXWIN0SENT; else tp->t_flags &= ~TF_RXWIN0SENT; From 287e3cb475a17d3cfa9e9d0435bbb58532f286cd Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Fri, 6 Nov 2009 17:34:26 +0000 Subject: [PATCH 535/646] Make nd6_llinfo_timer() does its job, again. ln->la_expire was greater than time_second, in most cases. MFC after: 3 days --- sys/netinet6/nd6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 30fad17e7f6..77dcf9cee04 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -507,7 +507,7 @@ nd6_llinfo_timer(void *arg) ndi = ND_IFINFO(ifp); dst = &L3_ADDR_SIN6(ln)->sin6_addr; - if ((ln->la_flags & LLE_STATIC) || (ln->la_expire > time_second)) { + if (ln->la_flags & LLE_STATIC) { goto done; } From 775a636b110849b9d9ec3c5afb6a81df9353acab Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 18:28:13 +0000 Subject: [PATCH 536/646] - Use device_printf() instead of printf() with an explicit unit number in the PCI attach routine. - Simplify PCI probe. - Remove no-longer-used 'unit' from an_attach() parameters. PR: kern/126924 Submitted by: gavin --- sys/dev/an/if_an.c | 2 +- sys/dev/an/if_an_isa.c | 2 +- sys/dev/an/if_an_pccard.c | 2 +- sys/dev/an/if_an_pci.c | 27 ++++++++++++--------------- sys/dev/an/if_anreg.h | 2 +- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index 7f8a2c27503..0cbda3d51b3 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -674,7 +674,7 @@ an_init_mpi350_desc(struct an_softc *sc) } int -an_attach(struct an_softc *sc, int unit, int flags) +an_attach(struct an_softc *sc, int flags) { struct ifnet *ifp; int error = EIO; diff --git a/sys/dev/an/if_an_isa.c b/sys/dev/an/if_an_isa.c index 80933b18ada..5c1f0eb8770 100644 --- a/sys/dev/an/if_an_isa.c +++ b/sys/dev/an/if_an_isa.c @@ -115,7 +115,7 @@ an_attach_isa(device_t dev) sc->an_btag = rman_get_bustag(sc->port_res); sc->an_dev = dev; - error = an_attach(sc, device_get_unit(dev), flags); + error = an_attach(sc, flags); if (error) { an_release_resources(dev); return (error); diff --git a/sys/dev/an/if_an_pccard.c b/sys/dev/an/if_an_pccard.c index b475265d84b..cfb20f36822 100644 --- a/sys/dev/an/if_an_pccard.c +++ b/sys/dev/an/if_an_pccard.c @@ -145,7 +145,7 @@ an_pccard_attach(device_t dev) sc->an_btag = rman_get_bustag(sc->port_res); sc->an_dev = dev; - error = an_attach(sc, device_get_unit(dev), flags); + error = an_attach(sc, flags); if (error) goto fail; diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c index d13e3ab5971..1efc494814f 100644 --- a/sys/dev/an/if_an_pci.c +++ b/sys/dev/an/if_an_pci.c @@ -103,6 +103,7 @@ struct an_type { static struct an_type an_devs[] = { { AIRONET_VENDORID, AIRONET_DEVICEID_35x, "Cisco Aironet 350 Series" }, + { AIRONET_VENDORID, AIRONET_DEVICEID_MPI350, "Cisco Aironet MPI350" }, { AIRONET_VENDORID, AIRONET_DEVICEID_4500, "Aironet PCI4500" }, { AIRONET_VENDORID, AIRONET_DEVICEID_4800, "Aironet PCI4800" }, { AIRONET_VENDORID, AIRONET_DEVICEID_4xxx, "Aironet PCI4500/PCI4800" }, @@ -133,13 +134,6 @@ an_probe_pci(device_t dev) t++; } - if (pci_get_vendor(dev) == AIRONET_VENDORID && - pci_get_device(dev) == AIRONET_DEVICEID_MPI350) { - device_set_desc(dev, "Cisco Aironet MPI350"); - an_pci_probe(dev); - return(BUS_PROBE_DEFAULT); - } - return(ENXIO); } @@ -149,10 +143,9 @@ an_attach_pci(dev) { u_int32_t command; struct an_softc *sc; - int unit, flags, error = 0; + int flags, error = 0; sc = device_get_softc(dev); - unit = device_get_unit(dev); flags = device_get_flags(dev); if (pci_get_vendor(dev) == AIRONET_VENDORID && @@ -169,7 +162,7 @@ an_attach_pci(dev) command = pci_read_config(dev, PCIR_COMMAND, 4); if (!(command & PCIM_CMD_PORTEN)) { - printf("an%d: failed to enable I/O ports!\n", unit); + device_printf(dev, "failed to enable I/O ports!\n"); error = ENXIO; goto fail; } @@ -178,7 +171,7 @@ an_attach_pci(dev) error = an_alloc_port(dev, sc->port_rid, 1); if (error) { - printf("an%d: couldn't map ports\n", unit); + device_printf(dev, "couldn't map ports\n"); goto fail; } @@ -191,7 +184,7 @@ an_attach_pci(dev) sc->mem_rid = PCIR_BAR(1); error = an_alloc_memory(dev, sc->mem_rid, 1); if (error) { - printf("an%d: couldn't map memory\n", unit); + device_printf(dev, "couldn't map memory\n"); goto fail; } sc->an_mem_btag = rman_get_bustag(sc->mem_res); @@ -202,7 +195,7 @@ an_attach_pci(dev) error = an_alloc_aux_memory(dev, sc->mem_aux_rid, AN_AUX_MEM_SIZE); if (error) { - printf("an%d: couldn't map aux memory\n", unit); + device_printf(dev, "couldn't map aux memory\n"); goto fail; } sc->an_mem_aux_btag = rman_get_bustag(sc->mem_aux_res); @@ -222,7 +215,7 @@ an_attach_pci(dev) NULL, /* lockarg */ &sc->an_dtag); if (error) { - printf("an%d: couldn't get DMA region\n", unit); + device_printf(dev, "couldn't get DMA region\n"); goto fail; } } @@ -230,12 +223,14 @@ an_attach_pci(dev) /* Allocate interrupt */ error = an_alloc_irq(dev, 0, RF_SHAREABLE); if (error) { + device_printf(dev, "couldn't get interrupt\n"); goto fail; } sc->an_dev = dev; - error = an_attach(sc, device_get_unit(dev), flags); + error = an_attach(sc, flags); if (error) { + device_printf(dev, "couldn't attach\n"); goto fail; } @@ -244,6 +239,8 @@ an_attach_pci(dev) */ error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, NULL, an_intr, sc, &sc->irq_handle); + if (error) + device_printf(dev, "couldn't setup interrupt\n"); fail: if (error) diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h index 3378d2ccb0a..7b1484c4f60 100644 --- a/sys/dev/an/if_anreg.h +++ b/sys/dev/an/if_anreg.h @@ -511,7 +511,7 @@ int an_pci_probe (device_t); int an_probe (device_t); int an_shutdown (device_t); void an_resume (device_t); -int an_attach (struct an_softc *, int, int); +int an_attach (struct an_softc *, int); int an_detach (device_t); void an_stop (struct an_softc *); From 56964c4c9feea9a5491ded8af95316e2443a8674 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 Nov 2009 18:36:09 +0000 Subject: [PATCH 537/646] Remove unnecessary header file. --- sys/dev/msk/if_msk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 912eaeb498c..cdb65b66f7a 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -137,7 +137,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include From ff0802165762e70b456a18179120865e5f62891f Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 Nov 2009 18:51:05 +0000 Subject: [PATCH 538/646] It's normal to see Rx FIFO overruns under high network load and showing the message creates other side-effects. Remove the Rx FIFO overrun message in interrupt handler. msk(4) should recover from the FIFO overruns without any user intervention. Users can still check the Rx FIFO overrun counter from MAC MIB statistics maintained in driver(dev.msk.0.stats.rx.overflows). --- sys/dev/msk/if_msk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index cdb65b66f7a..061d8c79d46 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -3217,11 +3217,9 @@ msk_intr_gmac(struct msk_if_softc *sc_if) status = CSR_READ_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_SRC)); /* GMAC Rx FIFO overrun. */ - if ((status & GM_IS_RX_FF_OR) != 0) { + if ((status & GM_IS_RX_FF_OR) != 0) CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_CLI_RX_FO); - device_printf(sc_if->msk_if_dev, "Rx FIFO overrun!\n"); - } /* GMAC Tx FIFO underrun. */ if ((status & GM_IS_TX_FF_UR) != 0) { CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), From f802264db19951b367dc8d42e50dd418970bea7d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 6 Nov 2009 20:07:16 +0000 Subject: [PATCH 539/646] Take a step towards removing if_watchdog/if_timer. Don't explicitly set if_watchdog/if_timer to NULL/0 when initializing an ifnet. if_alloc() sets those members to NULL/0 already. (Missed this driver in the earlier commit.) --- sys/dev/msk/if_msk.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 061d8c79d46..6585d78339e 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1518,8 +1518,6 @@ msk_attach(device_t dev) ifp->if_capenable = ifp->if_capabilities; ifp->if_ioctl = msk_ioctl; ifp->if_start = msk_start; - ifp->if_timer = 0; - ifp->if_watchdog = NULL; ifp->if_init = msk_init; IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1); ifp->if_snd.ifq_drv_maxlen = MSK_TX_RING_CNT - 1; From b66e2b8e50cd7b4da46c23ac0933f2bb6e6acc14 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Fri, 6 Nov 2009 20:32:26 +0000 Subject: [PATCH 540/646] Remove duplicate suspend/resume code from vga_pci.c and let vga(4) register itself to an associated PCI device if it exists. It is little bit hackish but it should fix build without frame buffer driver since r198964. Fix some style(9) nits in vga_isa.c while we are here. --- sys/dev/fb/vgareg.h | 1 + sys/dev/pci/vga_pci.c | 85 +++++-------------------------------------- sys/isa/vga_isa.c | 72 ++++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 94 deletions(-) diff --git a/sys/dev/fb/vgareg.h b/sys/dev/fb/vgareg.h index fa9d44eaef1..8f23a83caac 100644 --- a/sys/dev/fb/vgareg.h +++ b/sys/dev/fb/vgareg.h @@ -69,6 +69,7 @@ struct video_adapter; typedef struct vga_softc { struct video_adapter *adp; + device_t pci_dev; void *state_buf; void *pal_buf; #ifdef FB_INSTALL_CDEV diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 07b5ed0904f..9f6a449d955 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -40,15 +40,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include -#include #include #include #include #include -#include #include #include @@ -60,6 +57,7 @@ struct vga_resource { }; struct vga_pci_softc { + device_t vga_isa_dev; /* Sister isavga driver. */ device_t vga_msi_child; /* Child driver using MSI. */ struct vga_resource vga_res[PCIR_MAX_BAR_0 + 1]; }; @@ -117,86 +115,23 @@ vga_pci_attach(device_t dev) static int vga_pci_suspend(device_t dev) { - vga_softc_t *sc; - devclass_t dc; - int err, nbytes; + struct vga_pci_softc *sc; - err = bus_generic_suspend(dev); - if (err) - return (err); + sc = device_get_softc(dev); + if (sc->vga_isa_dev != NULL) + (void)DEVICE_SUSPEND(sc->vga_isa_dev); - sc = NULL; - if (device_get_unit(dev) == vga_pci_default_unit) { - dc = devclass_find(VGA_DRIVER_NAME); - if (dc != NULL) - sc = devclass_get_softc(dc, 0); - } - if (sc == NULL) - return (0); - - /* Save the video state across the suspend. */ - if (sc->state_buf != NULL) - goto save_palette; - nbytes = vidd_save_state(sc->adp, NULL, 0); - if (nbytes <= 0) - goto save_palette; - sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); - if (sc->state_buf == NULL) - goto save_palette; - if (bootverbose) - device_printf(dev, "saving %d bytes of video state\n", nbytes); - if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { - device_printf(dev, "failed to save state (nbytes=%d)\n", - nbytes); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } - -save_palette: - /* Save the color palette across the suspend. */ - if (sc->pal_buf != NULL) - return (0); - sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); - if (sc->pal_buf != NULL) { - if (bootverbose) - device_printf(dev, "saving color palette\n"); - if (vidd_save_palette(sc->adp, sc->pal_buf) != 0) { - device_printf(dev, "failed to save palette\n"); - free(sc->pal_buf, M_TEMP); - sc->pal_buf = NULL; - } - } - - return (0); + return (bus_generic_suspend(dev)); } static int vga_pci_resume(device_t dev) { - vga_softc_t *sc; - devclass_t dc; + struct vga_pci_softc *sc; - sc = NULL; - if (device_get_unit(dev) == vga_pci_default_unit) { - dc = devclass_find(VGA_DRIVER_NAME); - if (dc != NULL) - sc = devclass_get_softc(dc, 0); - } - if (sc == NULL) - return (bus_generic_resume(dev)); - - if (sc->state_buf != NULL) { - if (vidd_load_state(sc->adp, sc->state_buf) != 0) - device_printf(dev, "failed to reload state\n"); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } - if (sc->pal_buf != NULL) { - if (vidd_load_palette(sc->adp, sc->pal_buf) != 0) - device_printf(dev, "failed to reload palette\n"); - free(sc->pal_buf, M_TEMP); - sc->pal_buf = NULL; - } + sc = device_get_softc(dev); + if (sc->vga_isa_dev != NULL) + (void)DEVICE_RESUME(sc->vga_isa_dev); return (bus_generic_resume(dev)); } diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index cfb36ae97b6..e86ee4680a3 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -117,13 +117,17 @@ isavga_probe(device_t dev) isa_set_msize(dev, adp.va_mem_size); #endif } - return error; + return (error); } static int isavga_attach(device_t dev) { vga_softc_t *sc; + devclass_t dc; + device_t *devs; + void *vgapci_sc; + int count, i; int unit; int rid; int error; @@ -140,13 +144,13 @@ isavga_attach(device_t dev) error = vga_attach_unit(unit, sc, device_get_flags(dev)); if (error) - return error; + return (error); #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ error = fb_attach(VGA_MKMINOR(unit), sc->adp, &isavga_cdevsw); if (error) - return error; + return (error); #endif /* FB_INSTALL_CDEV */ if (0 && bootverbose) @@ -157,20 +161,43 @@ isavga_attach(device_t dev) bus_generic_attach(dev); #endif - return 0; + /* Find the matching PCI video controller. */ + if (unit == 0) { + dc = devclass_find("vgapci"); + if (dc != NULL && + devclass_get_devices(dc, &devs, &count) == 0) { + for (i = 0; i < count; i++) + if (device_get_flags(devs[i]) != 0) { + sc->pci_dev = devs[i]; + break; + } + free(devs, M_TEMP); + } + if (sc->pci_dev != NULL) { + vgapci_sc = device_get_softc(sc->pci_dev); + *(device_t *)vgapci_sc = dev; + device_printf(dev, "associated with %s\n", + device_get_nameunit(sc->pci_dev)); + } + } + + return (0); } static int isavga_suspend(device_t dev) { vga_softc_t *sc; + device_t isa_dev; int err, nbytes; - err = bus_generic_suspend(dev); - if (err) - return (err); - - sc = device_get_softc(dev); + err = 0; + isa_dev = dev; + sc = device_get_softc(isa_dev); + if (sc->pci_dev != NULL) + dev = sc->pci_dev; + else + err = bus_generic_suspend(isa_dev); /* Save the video state across the suspend. */ if (sc->state_buf != NULL) @@ -193,7 +220,7 @@ isavga_suspend(device_t dev) save_palette: /* Save the color palette across the suspend. */ if (sc->pal_buf != NULL) - return (0); + return (err); sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); if (sc->pal_buf != NULL) { if (bootverbose) @@ -205,15 +232,19 @@ save_palette: } } - return (0); + return (err); } static int isavga_resume(device_t dev) { vga_softc_t *sc; + device_t isa_dev; - sc = device_get_softc(dev); + isa_dev = dev; + sc = device_get_softc(isa_dev); + if (sc->pci_dev != NULL) + dev = sc->pci_dev; if (sc->state_buf != NULL) { if (vidd_load_state(sc->adp, sc->state_buf) != 0) @@ -228,7 +259,10 @@ isavga_resume(device_t dev) sc->pal_buf = NULL; } - return (bus_generic_resume(dev)); + if (isa_dev != dev) + return (0); + + return (bus_generic_resume(isa_dev)); } #ifdef FB_INSTALL_CDEV @@ -236,37 +270,37 @@ isavga_resume(device_t dev) static int isavga_open(struct cdev *dev, int flag, int mode, struct thread *td) { - return vga_open(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td); + return (vga_open(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td)); } static int isavga_close(struct cdev *dev, int flag, int mode, struct thread *td) { - return vga_close(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td); + return (vga_close(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td)); } static int isavga_read(struct cdev *dev, struct uio *uio, int flag) { - return vga_read(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag); + return (vga_read(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag)); } static int isavga_write(struct cdev *dev, struct uio *uio, int flag) { - return vga_write(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag); + return (vga_write(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag)); } static int isavga_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { - return vga_ioctl(dev, VGA_SOFTC(VGA_UNIT(dev)), cmd, arg, flag, td); + return (vga_ioctl(dev, VGA_SOFTC(VGA_UNIT(dev)), cmd, arg, flag, td)); } static int isavga_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot) { - return vga_mmap(dev, VGA_SOFTC(VGA_UNIT(dev)), offset, paddr, prot); + return (vga_mmap(dev, VGA_SOFTC(VGA_UNIT(dev)), offset, paddr, prot)); } #endif /* FB_INSTALL_CDEV */ From 9c7664086808e7cacc9158c505f09515e8ddd942 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 6 Nov 2009 22:29:46 +0000 Subject: [PATCH 541/646] - Improve comments about locking of the "struct fifoinfo" which is a bit unclear. - Fix a memory leak [0] [0] Diagnosed by: Dorr H. Clark MFC: 1 week --- sys/fs/fifofs/fifo_vnops.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index c930d928048..e339a8ac853 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -78,6 +78,10 @@ struct fileops fifo_ops_f = { /* * This structure is associated with the FIFO vnode and stores * the state associated with the FIFO. + * Notes about locking: + * - fi_readsock and fi_writesock are invariant since init time. + * - fi_readers and fi_writers are vnode lock protected. + * - fi_wgen is fif_mtx lock protected. */ struct fifoinfo { struct socket *fi_readsock; @@ -223,14 +227,9 @@ fail1: } /* - * General access to fi_readers and fi_writers is protected using - * the vnode lock. - * - * Protect the increment of fi_readers and fi_writers and the - * associated calls to wakeup() with the fifo mutex in addition - * to the vnode lock. This allows the vnode lock to be dropped - * for the msleep() calls below, and using the fifo mutex with - * msleep() prevents the wakeup from being missed. + * Use the fifo_mtx lock here, in addition to the vnode lock, + * in order to allow vnode lock dropping before msleep() calls + * and still avoiding missed wakeups. */ mtx_lock(&fifo_mtx); if (ap->a_mode & FREAD) { @@ -249,6 +248,8 @@ fail1: if (ap->a_mode & FWRITE) { if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { mtx_unlock(&fifo_mtx); + if (fip->fi_writers == 0) + fifo_cleanup(vp); return (ENXIO); } fip->fi_writers++; From 337c5ff4fc66af3ff4c339cc9fb3fbf8bdb69323 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 6 Nov 2009 22:33:03 +0000 Subject: [PATCH 542/646] Save the sack when doing a lockmgr_disown() call. Requested by: kib MFC: 3 days --- sys/kern/kern_lock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 60b51f7b315..90df2fcb634 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1086,6 +1086,7 @@ _lockmgr_disown(struct lock *lk, const char *file, int line) LOCK_LOG_LOCK("XDISOWN", &lk->lock_object, 0, 0, file, line); WITNESS_UNLOCK(&lk->lock_object, LOP_EXCLUSIVE, file, line); TD_LOCKS_DEC(curthread); + STACK_SAVE(lk); /* * In order to preserve waiters flags, just spin. From a669a81f0bda69a38e75943bfa4735cbd4aee3af Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 Nov 2009 22:37:29 +0000 Subject: [PATCH 543/646] bge(4) already switched to use UMA backed page allocator and local memory allocator for jumbo frame was removed long time ago. Remove no more used macros. --- sys/dev/bge/if_bgereg.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 4cf432a8b0c..5223dbedbea 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -2481,13 +2481,6 @@ struct bge_gib { #define BGE_MSLOTS 256 #define BGE_JSLOTS 384 -#define BGE_JRAWLEN (BGE_JUMBO_FRAMELEN + ETHER_ALIGN) -#define BGE_JLEN (BGE_JRAWLEN + (sizeof(uint64_t) - \ - (BGE_JRAWLEN % sizeof(uint64_t)))) -#define BGE_JPAGESZ PAGE_SIZE -#define BGE_RESID (BGE_JPAGESZ - (BGE_JLEN * BGE_JSLOTS) % BGE_JPAGESZ) -#define BGE_JMEM ((BGE_JLEN * BGE_JSLOTS) + BGE_RESID) - #define BGE_NSEG_JUMBO 4 #define BGE_NSEG_NEW 32 From c215fd771d34c5798db0d98fe6b652852322d02d Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 6 Nov 2009 23:49:20 +0000 Subject: [PATCH 544/646] Do bus_dmamap_sync call only if frame size is greater than standard buffer size. If controller is not capable of handling jumbo frame, interface MTU couldn't be larger than standard MTU which in turn the received should be fit in standard buffer. This fixes bus_dmamap_sync call for jumbo ring is called even if interface is configured to use standard MTU. Also if total frame size could be fit into standard buffer don't use jumbo buffers. --- sys/dev/bge/if_bge.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 3832fadad6f..04874960487 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3134,7 +3134,8 @@ bge_rxeof(struct bge_softc *sc) sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTREAD); bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTWRITE); - if (BGE_IS_JUMBO_CAPABLE(sc)) + if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > + (MCLBYTES - ETHER_ALIGN)) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTWRITE); @@ -3266,7 +3267,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE); - if (BGE_IS_JUMBO_CAPABLE(sc) && jumbocnt > 0) + if (jumbocnt > 0) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE); @@ -3920,7 +3921,8 @@ bge_init_locked(struct bge_softc *sc) } /* Init jumbo RX ring. */ - if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) { + if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > + (MCLBYTES - ETHER_ALIGN)) { if (bge_init_rx_ring_jumbo(sc) != 0) { device_printf(sc->bge_dev, "no memory for std Rx buffers.\n"); bge_stop(sc); From 943787f3a7dd420213c42250331ccfe994bbfee2 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 Nov 2009 01:01:33 +0000 Subject: [PATCH 545/646] Reimplement Rx buffer allocation to handle dma map load failure. Introduce two spare dma maps for standard buffer and jumbo buffer respectively. If loading a dma map failed reuse previously loaded dma map. This should fix unloaded dma map is used in case of dma map load failure. Also don't blindly unload dma map and defer dma map sync and unloading operation until we know dma map for new buffer is successfully loaded. This change saves unnecessary dma load/unload operation. Previously bge(4) tried to reuse mbuf with unloaded dma map which is really bad thing in bus_dma(9) perspective. While I'm here update if_iqdrops if we can't allocate Rx buffers. --- sys/dev/bge/if_bge.c | 166 +++++++++++++++++++++------------------- sys/dev/bge/if_bgereg.h | 2 + 2 files changed, 88 insertions(+), 80 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 04874960487..584cce696f0 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -393,8 +393,8 @@ static void bge_setpromisc(struct bge_softc *); static void bge_setmulti(struct bge_softc *); static void bge_setvlan(struct bge_softc *); -static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *); -static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *); +static int bge_newbuf_std(struct bge_softc *, int); +static int bge_newbuf_jumbo(struct bge_softc *, int); static int bge_init_rx_ring_std(struct bge_softc *); static void bge_free_rx_ring_std(struct bge_softc *); static int bge_init_rx_ring_jumbo(struct bge_softc *); @@ -912,37 +912,38 @@ bge_miibus_statchg(device_t dev) * Intialize a standard receive ring descriptor. */ static int -bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) +bge_newbuf_std(struct bge_softc *sc, int i) { - struct mbuf *m_new = NULL; + struct mbuf *m; struct bge_rx_bd *r; bus_dma_segment_t segs[1]; + bus_dmamap_t map; int error, nsegs; - if (m == NULL) { - m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m_new == NULL) - return (ENOBUFS); - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - } else { - m_new = m; - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - m_new->m_data = m_new->m_ext.ext_buf; - } - + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MCLBYTES; if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0) - m_adj(m_new, ETHER_ALIGN); + m_adj(m, ETHER_ALIGN); + error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_rx_mtag, - sc->bge_cdata.bge_rx_std_dmamap[i], m_new, segs, &nsegs, 0); + sc->bge_cdata.bge_rx_std_sparemap, m, segs, &nsegs, 0); if (error != 0) { - if (m == NULL) { - sc->bge_cdata.bge_rx_std_chain[i] = NULL; - m_freem(m_new); - } + m_freem(m); return (error); } - sc->bge_cdata.bge_rx_std_chain[i] = m_new; - r = &sc->bge_ldata.bge_rx_std_ring[i]; + if (sc->bge_cdata.bge_rx_std_chain[i] != NULL) { + bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, + sc->bge_cdata.bge_rx_std_dmamap[i], BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->bge_cdata.bge_rx_mtag, + sc->bge_cdata.bge_rx_std_dmamap[i]); + } + map = sc->bge_cdata.bge_rx_std_dmamap[i]; + sc->bge_cdata.bge_rx_std_dmamap[i] = sc->bge_cdata.bge_rx_std_sparemap; + sc->bge_cdata.bge_rx_std_sparemap = map; + sc->bge_cdata.bge_rx_std_chain[i] = m; + r = &sc->bge_ldata.bge_rx_std_ring[sc->bge_std]; r->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[0].ds_addr); r->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[0].ds_addr); r->bge_flags = BGE_RXBDFLAG_END; @@ -950,8 +951,7 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) r->bge_idx = i; bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, - sc->bge_cdata.bge_rx_std_dmamap[i], - BUS_DMASYNC_PREREAD); + sc->bge_cdata.bge_rx_std_dmamap[i], BUS_DMASYNC_PREREAD); return (0); } @@ -961,48 +961,49 @@ bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m) * a jumbo buffer from the pool managed internally by the driver. */ static int -bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m) +bge_newbuf_jumbo(struct bge_softc *sc, int i) { bus_dma_segment_t segs[BGE_NSEG_JUMBO]; + bus_dmamap_t map; struct bge_extrx_bd *r; - struct mbuf *m_new = NULL; - int nsegs; - int error; + struct mbuf *m; + int error, nsegs; - if (m == NULL) { - MGETHDR(m_new, M_DONTWAIT, MT_DATA); - if (m_new == NULL) - return (ENOBUFS); + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) + return (ENOBUFS); - m_cljget(m_new, M_DONTWAIT, MJUM9BYTES); - if (!(m_new->m_flags & M_EXT)) { - m_freem(m_new); - return (ENOBUFS); - } - m_new->m_len = m_new->m_pkthdr.len = MJUM9BYTES; - } else { - m_new = m; - m_new->m_len = m_new->m_pkthdr.len = MJUM9BYTES; - m_new->m_data = m_new->m_ext.ext_buf; + m_cljget(m, M_DONTWAIT, MJUM9BYTES); + if (!(m->m_flags & M_EXT)) { + m_freem(m); + return (ENOBUFS); } - + m->m_len = m->m_pkthdr.len = MJUM9BYTES; if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0) - m_adj(m_new, ETHER_ALIGN); + m_adj(m, ETHER_ALIGN); error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag_jumbo, - sc->bge_cdata.bge_rx_jumbo_dmamap[i], - m_new, segs, &nsegs, BUS_DMA_NOWAIT); - if (error) { - if (m == NULL) - m_freem(m_new); + sc->bge_cdata.bge_rx_jumbo_sparemap, m, segs, &nsegs, 0); + if (error != 0) { + m_freem(m); return (error); } - sc->bge_cdata.bge_rx_jumbo_chain[i] = m_new; + if (sc->bge_cdata.bge_rx_jumbo_chain[i] == NULL) { + bus_dmamap_sync(sc->bge_cdata.bge_mtag_jumbo, + sc->bge_cdata.bge_rx_jumbo_dmamap[i], BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->bge_cdata.bge_mtag_jumbo, + sc->bge_cdata.bge_rx_jumbo_dmamap[i]); + } + map = sc->bge_cdata.bge_rx_jumbo_dmamap[i]; + sc->bge_cdata.bge_rx_jumbo_dmamap[i] = + sc->bge_cdata.bge_rx_jumbo_sparemap; + sc->bge_cdata.bge_rx_jumbo_sparemap = map; + sc->bge_cdata.bge_rx_jumbo_chain[i] = m; /* * Fill in the extended RX buffer descriptor. */ - r = &sc->bge_ldata.bge_rx_jumbo_ring[i]; + r = &sc->bge_ldata.bge_rx_jumbo_ring[sc->bge_jumbo]; r->bge_flags = BGE_RXBDFLAG_JUMBO_RING | BGE_RXBDFLAG_END; r->bge_idx = i; r->bge_len3 = r->bge_len2 = r->bge_len1 = 0; @@ -1029,8 +1030,7 @@ bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m) } bus_dmamap_sync(sc->bge_cdata.bge_mtag_jumbo, - sc->bge_cdata.bge_rx_jumbo_dmamap[i], - BUS_DMASYNC_PREREAD); + sc->bge_cdata.bge_rx_jumbo_dmamap[i], BUS_DMASYNC_PREREAD); return (0); } @@ -1047,7 +1047,7 @@ bge_init_rx_ring_std(struct bge_softc *sc) int error, i; for (i = 0; i < BGE_SSLOTS; i++) { - if ((error = bge_newbuf_std(sc, i, NULL)) != 0) + if ((error = bge_newbuf_std(sc, i)) != 0) return (error); }; @@ -1088,7 +1088,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc) int error, i; for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { - if ((error = bge_newbuf_jumbo(sc, i, NULL)) != 0) + if ((error = bge_newbuf_jumbo(sc, i)) != 0) return (error); }; @@ -1979,6 +1979,9 @@ bge_dma_free(struct bge_softc *sc) bus_dmamap_destroy(sc->bge_cdata.bge_rx_mtag, sc->bge_cdata.bge_rx_std_dmamap[i]); } + if (sc->bge_cdata.bge_rx_std_sparemap) + bus_dmamap_destroy(sc->bge_cdata.bge_rx_mtag, + sc->bge_cdata.bge_rx_std_sparemap); /* Destroy DMA maps for jumbo RX buffers. */ for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { @@ -1986,6 +1989,9 @@ bge_dma_free(struct bge_softc *sc) bus_dmamap_destroy(sc->bge_cdata.bge_mtag_jumbo, sc->bge_cdata.bge_rx_jumbo_dmamap[i]); } + if (sc->bge_cdata.bge_rx_jumbo_sparemap) + bus_dmamap_destroy(sc->bge_cdata.bge_mtag_jumbo, + sc->bge_cdata.bge_rx_jumbo_sparemap); /* Destroy DMA maps for TX buffers. */ for (i = 0; i < BGE_TX_RING_CNT; i++) { @@ -2133,6 +2139,13 @@ bge_dma_alloc(device_t dev) } /* Create DMA maps for RX buffers. */ + error = bus_dmamap_create(sc->bge_cdata.bge_rx_mtag, 0, + &sc->bge_cdata.bge_rx_std_sparemap); + if (error) { + device_printf(sc->bge_dev, + "can't create spare DMA map for RX\n"); + return (ENOMEM); + } for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { error = bus_dmamap_create(sc->bge_cdata.bge_rx_mtag, 0, &sc->bge_cdata.bge_rx_std_dmamap[i]); @@ -2234,6 +2247,13 @@ bge_dma_alloc(device_t dev) sc->bge_ldata.bge_rx_jumbo_ring_paddr = ctx.bge_busaddr; /* Create DMA maps for jumbo RX buffers. */ + error = bus_dmamap_create(sc->bge_cdata.bge_mtag_jumbo, + 0, &sc->bge_cdata.bge_rx_jumbo_sparemap); + if (error) { + device_printf(sc->bge_dev, + "can't create sapre DMA map for jumbo RX\n"); + return (ENOMEM); + } for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { error = bus_dmamap_create(sc->bge_cdata.bge_mtag_jumbo, 0, &sc->bge_cdata.bge_rx_jumbo_dmamap[i]); @@ -3166,43 +3186,29 @@ bge_rxeof(struct bge_softc *sc) } if (cur_rx->bge_flags & BGE_RXBDFLAG_JUMBO_RING) { - BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); - bus_dmamap_sync(sc->bge_cdata.bge_mtag_jumbo, - sc->bge_cdata.bge_rx_jumbo_dmamap[rxidx], - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->bge_cdata.bge_mtag_jumbo, - sc->bge_cdata.bge_rx_jumbo_dmamap[rxidx]); - m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx]; - sc->bge_cdata.bge_rx_jumbo_chain[rxidx] = NULL; jumbocnt++; + m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx]; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { + BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); ifp->if_ierrors++; - bge_newbuf_jumbo(sc, sc->bge_jumbo, m); continue; } - if (bge_newbuf_jumbo(sc, sc->bge_jumbo, NULL) != 0) { - ifp->if_ierrors++; - bge_newbuf_jumbo(sc, sc->bge_jumbo, m); + if (bge_newbuf_jumbo(sc, rxidx) != 0) { + BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); + ifp->if_iqdrops++; continue; } } else { - BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); - bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag, - sc->bge_cdata.bge_rx_std_dmamap[rxidx], - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->bge_cdata.bge_rx_mtag, - sc->bge_cdata.bge_rx_std_dmamap[rxidx]); - m = sc->bge_cdata.bge_rx_std_chain[rxidx]; - sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL; stdcnt++; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); ifp->if_ierrors++; - bge_newbuf_std(sc, sc->bge_std, m); continue; } - if (bge_newbuf_std(sc, sc->bge_std, NULL) != 0) { - ifp->if_ierrors++; - bge_newbuf_std(sc, sc->bge_std, m); + m = sc->bge_cdata.bge_rx_std_chain[rxidx]; + if (bge_newbuf_std(sc, rxidx) != 0) { + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); + ifp->if_iqdrops++; continue; } } diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 5223dbedbea..99f0d4b3c9a 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -2537,7 +2537,9 @@ struct bge_chain_data { bus_dma_tag_t bge_tx_mtag; /* Tx mbuf mapping tag */ bus_dma_tag_t bge_mtag_jumbo; /* Jumbo mbuf mapping tag */ bus_dmamap_t bge_tx_dmamap[BGE_TX_RING_CNT]; + bus_dmamap_t bge_rx_std_sparemap; bus_dmamap_t bge_rx_std_dmamap[BGE_STD_RX_RING_CNT]; + bus_dmamap_t bge_rx_jumbo_sparemap; bus_dmamap_t bge_rx_jumbo_dmamap[BGE_JUMBO_RX_RING_CNT]; bus_dmamap_t bge_rx_std_ring_map; bus_dmamap_t bge_rx_jumbo_ring_map; From 76202a160199e392926e003a3c64b132913abe6f Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 Nov 2009 01:14:09 +0000 Subject: [PATCH 546/646] Add preliminary Yukon Ultra 2 support(88E8057). The controller looks very similar to Yukon EC Ultra. Tested by: kalin m ( kalin <> el dot net ) --- sys/dev/msk/if_msk.c | 14 ++++++++++++-- sys/dev/msk/if_mskreg.h | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 6585d78339e..fbde7b73b19 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -222,6 +222,8 @@ static struct msk_product { "Marvell Yukon 88E8071 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_436C, "Marvell Yukon 88E8072 Gigabit Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_4380, + "Marvell Yukon 88E8057 Gigabit Ethernet" }, { VENDORID_DLINK, DEVICEID_DLINK_DGE550SX, "D-Link 550SX Gigabit Ethernet" }, { VENDORID_DLINK, DEVICEID_DLINK_DGE560SX, @@ -236,7 +238,9 @@ static const char *model_name[] = { "Yukon EX", "Yukon EC", "Yukon FE", - "Yukon FE+" + "Yukon FE+", + "Yukon Supreme", + "Yukon Ultra 2" }; static int mskc_probe(device_t); @@ -1143,6 +1147,7 @@ msk_phy_power(struct msk_softc *sc, int mode) case CHIP_ID_YUKON_EC_U: case CHIP_ID_YUKON_EX: case CHIP_ID_YUKON_FE_P: + case CHIP_ID_YUKON_UL_2: CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF); /* Enable all clocks. */ @@ -1644,7 +1649,8 @@ mskc_attach(device_t dev) sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f; /* Bail out if chip is not recognized. */ if (sc->msk_hw_id < CHIP_ID_YUKON_XL || - sc->msk_hw_id > CHIP_ID_YUKON_FE_P) { + sc->msk_hw_id > CHIP_ID_YUKON_UL_2 || + sc->msk_hw_id == CHIP_ID_YUKON_SUPR) { device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n", sc->msk_hw_id, sc->msk_hw_rev); mtx_destroy(&sc->msk_mtx); @@ -1743,6 +1749,10 @@ mskc_attach(device_t dev) sc->msk_clock = 156; /* 156 Mhz */ sc->msk_pflags |= MSK_FLAG_JUMBO; break; + case CHIP_ID_YUKON_UL_2: + sc->msk_clock = 156; /* 156 Mhz */ + sc->msk_pflags |= MSK_FLAG_JUMBO; + break; default: sc->msk_clock = 156; /* 156 Mhz */ break; diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index b42a01fe1a5..2f4e2164584 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -144,6 +144,7 @@ #define DEVICEID_MRVL_436A 0x436A #define DEVICEID_MRVL_436B 0x436B #define DEVICEID_MRVL_436C 0x436C +#define DEVICEID_MRVL_4380 0x4380 /* * D-Link gigabit ethernet device ID @@ -891,6 +892,8 @@ #define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */ #define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */ #define CHIP_ID_YUKON_FE_P 0xb8 /* Chip ID for YUKON-2 FE+ */ +#define CHIP_ID_YUKON_SUPR 0xb9 /* Chip ID for YUKON-2 Supreme */ +#define CHIP_ID_YUKON_UL_2 0xba /* Chip ID for YUKON-2 Ultra 2 */ #define CHIP_REV_YU_XL_A0 0 /* Chip Rev. for Yukon-2 A0 */ #define CHIP_REV_YU_XL_A1 1 /* Chip Rev. for Yukon-2 A1 */ From 710460e8afd3f824962b23315ae202374b441837 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 Nov 2009 01:18:03 +0000 Subject: [PATCH 547/646] 88E8057(Ultra 2) is now supported. --- share/man/man4/msk.4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4 index e6200478afe..f0991e996e7 100644 --- a/share/man/man4/msk.4 +++ b/share/man/man4/msk.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 28, 2009 +.Dd November 6, 2009 .Dt MSK 4 .Os .Sh NAME @@ -204,6 +204,8 @@ Marvell Yukon 88E8055 Gigabit Ethernet .It Marvell Yukon 88E8056 Gigabit Ethernet .It +Marvell Yukon 88E8057 Gigabit Ethernet +.It Marvell Yukon 88E8058 Gigabit Ethernet .It Marvell Yukon 88E8070 Gigabit Ethernet From 03e78bd096d16aa401a981a8ee4bf281b64a59be Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 Nov 2009 02:10:59 +0000 Subject: [PATCH 548/646] Fix I mssied in r199011. Rx ring index also should be updated. If we fill Rx ring full instead of half we can simplify this logic but this requires more experimentation. --- sys/dev/bge/if_bge.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 584cce696f0..7913fd57426 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1046,9 +1046,11 @@ bge_init_rx_ring_std(struct bge_softc *sc) { int error, i; + sc->bge_std = 0; for (i = 0; i < BGE_SSLOTS; i++) { if ((error = bge_newbuf_std(sc, i)) != 0) return (error); + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); }; bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, @@ -1087,9 +1089,11 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc) struct bge_rcb *rcb; int error, i; + sc->bge_jumbo = 0; for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { if ((error = bge_newbuf_jumbo(sc, i)) != 0) return (error); + BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); }; bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, @@ -3198,6 +3202,7 @@ bge_rxeof(struct bge_softc *sc) ifp->if_iqdrops++; continue; } + BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); } else { stdcnt++; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { @@ -3211,6 +3216,7 @@ bge_rxeof(struct bge_softc *sc) ifp->if_iqdrops++; continue; } + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); } ifp->if_ipackets++; From ede807c429aef9b2e1b418955205297345db8127 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 7 Nov 2009 11:41:23 +0000 Subject: [PATCH 549/646] ichwd: don't attach to isa pnp device(s) by accident Reviewed by: imp, des MFC after: 1 week --- sys/dev/ichwd/ichwd.c | 5 ++++- sys/modules/ichwd/Makefile | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c index 78d9816f156..028c50e9842 100644 --- a/sys/dev/ichwd/ichwd.c +++ b/sys/dev/ichwd/ichwd.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -393,7 +394,9 @@ static int ichwd_probe(device_t dev) { - (void)dev; + /* Do not claim some ISA PnP device by accident. */ + if (isa_get_logicalid(dev) != 0) + return (ENXIO); return (0); } diff --git a/sys/modules/ichwd/Makefile b/sys/modules/ichwd/Makefile index 880ec82a28e..21c143073cf 100644 --- a/sys/modules/ichwd/Makefile +++ b/sys/modules/ichwd/Makefile @@ -3,6 +3,6 @@ .PATH: ${.CURDIR}/../../dev/ichwd KMOD= ichwd -SRCS= ichwd.c device_if.h bus_if.h pci_if.h +SRCS= ichwd.c device_if.h bus_if.h pci_if.h isa_if.h .include From f6eb382c794e02a4003b62b1753724b2da2feb9a Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 7 Nov 2009 11:46:38 +0000 Subject: [PATCH 550/646] acpi: remove 'magic' ivar o acpi_hpet: auto-added 'wildcard' devices can be identified by non-NULL handle attribute. o acpi_ec: auto-add 'wildcard' devices can be identified by unset (NULL) private attribute. o acpi_cpu: use private instead of magic to store cpu id. Reviewed by: jhb Silence from: acpi@ MFC after: 2 weeks X-MFC-Note: perhaps the ivar should stay for ABI stability --- sys/dev/acpica/acpi.c | 6 ------ sys/dev/acpica/acpi_cpu.c | 4 ++-- sys/dev/acpica/acpi_ec.c | 14 ++++++-------- sys/dev/acpica/acpi_hpet.c | 6 +----- sys/dev/acpica/acpivar.h | 4 +--- 5 files changed, 10 insertions(+), 24 deletions(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 9fe823a0825..6679ebf4070 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -900,9 +900,6 @@ acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) case ACPI_IVAR_HANDLE: *(ACPI_HANDLE *)result = ad->ad_handle; break; - case ACPI_IVAR_MAGIC: - *(uintptr_t *)result = ad->ad_magic; - break; case ACPI_IVAR_PRIVATE: *(void **)result = ad->ad_private; break; @@ -938,9 +935,6 @@ acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value) case ACPI_IVAR_HANDLE: ad->ad_handle = (ACPI_HANDLE)value; break; - case ACPI_IVAR_MAGIC: - ad->ad_magic = (uintptr_t)value; - break; case ACPI_IVAR_PRIVATE: ad->ad_private = (void *)value; break; diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 8fe9de6f61c..c16dcb17416 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -255,7 +255,7 @@ acpi_cpu_probe(device_t dev) /* Mark this processor as in-use and save our derived id for attach. */ cpu_softc[cpu_id] = (void *)1; - acpi_set_magic(dev, cpu_id); + acpi_set_private(dev, (void*)(intptr_t)cpu_id); device_set_desc(dev, "ACPI CPU"); return (0); @@ -286,7 +286,7 @@ acpi_cpu_attach(device_t dev) sc = device_get_softc(dev); sc->cpu_dev = dev; sc->cpu_handle = acpi_get_handle(dev); - cpu_id = acpi_get_magic(dev); + cpu_id = (int)(intptr_t)acpi_get_private(dev); cpu_softc[cpu_id] = sc; pcpu_data = pcpu_find(cpu_id); pcpu_data->pc_device = dev; diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c index a5a81dc632f..b339ba10ed0 100644 --- a/sys/dev/acpica/acpi_ec.c +++ b/sys/dev/acpica/acpi_ec.c @@ -129,9 +129,6 @@ struct acpi_ec_params { int uid; }; -/* Indicate that this device has already been probed via ECDT. */ -#define DEV_ECDT(x) (acpi_get_magic(x) == (uintptr_t)&acpi_ec_devclass) - /* * Driver softc. */ @@ -332,7 +329,6 @@ acpi_ec_ecdt_probe(device_t parent) params->uid = ecdt->Uid; acpi_GetInteger(h, "_GLK", ¶ms->glk); acpi_set_private(child, params); - acpi_set_magic(child, (uintptr_t)&acpi_ec_devclass); /* Finish the attach process. */ if (device_probe_and_attach(child) != 0) @@ -348,6 +344,7 @@ acpi_ec_probe(device_t dev) ACPI_STATUS status; device_t peer; char desc[64]; + int ecdt; int ret; struct acpi_ec_params *params; static char *ec_ids[] = { "PNP0C09", NULL }; @@ -362,11 +359,12 @@ acpi_ec_probe(device_t dev) * duplicate probe. */ ret = ENXIO; - params = NULL; + ecdt = 0; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; - if (DEV_ECDT(dev)) { - params = acpi_get_private(dev); + params = acpi_get_private(dev); + if (params != NULL) { + ecdt = 1; ret = 0; } else if (!acpi_disabled("ec") && ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) { @@ -439,7 +437,7 @@ out: if (ret == 0) { snprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", params->gpe_bit, (params->glk) ? ", GLK" : "", - DEV_ECDT(dev) ? ", ECDT" : ""); + ecdt ? ", ECDT" : ""); device_set_desc_copy(dev, desc); } diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c index a4186954368..ee346b7ddff 100644 --- a/sys/dev/acpica/acpi_hpet.c +++ b/sys/dev/acpica/acpi_hpet.c @@ -61,8 +61,6 @@ static void acpi_hpet_test(struct acpi_hpet_softc *sc); static char *hpet_ids[] = { "PNP0103", NULL }; -#define DEV_HPET(x) (acpi_get_magic(x) == (uintptr_t)&acpi_hpet_devclass) - struct timecounter hpet_timecounter = { .tc_get_timecount = hpet_get_timecount, .tc_counter_mask = ~0u, @@ -133,8 +131,6 @@ acpi_hpet_identify(driver_t *driver, device_t parent) return; } - /* Record a magic value so we can detect this device later. */ - acpi_set_magic(child, (uintptr_t)&acpi_hpet_devclass); bus_set_resource(child, SYS_RES_MEMORY, 0, hpet->Address.Address, HPET_MEM_WIDTH); } @@ -146,7 +142,7 @@ acpi_hpet_probe(device_t dev) if (acpi_disabled("hpet")) return (ENXIO); - if (!DEV_HPET(dev) && + if (acpi_get_handle(dev) != NULL && (ACPI_ID_PROBE(device_get_parent(dev), dev, hpet_ids) == NULL || device_get_unit(dev) != 0)) return (ENXIO); diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index f4d27e4738c..abfaa8b1f2b 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -88,7 +88,6 @@ struct acpi_softc { struct acpi_device { /* ACPI ivars */ ACPI_HANDLE ad_handle; - uintptr_t ad_magic; void *ad_private; int ad_flags; @@ -224,7 +223,7 @@ extern int acpi_quirks; * attach to ACPI. */ #define ACPI_IVAR_HANDLE 0x100 -#define ACPI_IVAR_MAGIC 0x101 +#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */ #define ACPI_IVAR_PRIVATE 0x102 #define ACPI_IVAR_FLAGS 0x103 @@ -250,7 +249,6 @@ static __inline void varp ## _set_ ## var(device_t dev, type t) \ } __ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE) -__ACPI_BUS_ACCESSOR(acpi, magic, ACPI, MAGIC, uintptr_t) __ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *) __ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int) From 1c2dee3cc97ddec00e1f21b034adf3cd4c11c2de Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 7 Nov 2009 17:29:03 +0000 Subject: [PATCH 551/646] Fix handling of GPT headers when size is > 92 bytes. It is valid for an on-disk GPT header to report a header size which is greater than 92 bytes. Previously, we would read in the sector and copy only the 92 bytes that we know how to deal with before calculating the checksum for comparison. This meant that when we did the checksum, we overshot the buffer and took in random memory, so the checksum would fail. We now determine the size of the header and allocate enough space to preserve the entire on-disk contents. This allows us to be correctly calculate the checksum and be able to modify and write the header back to the disk, while preserving data that we might not understand. Reported by: Kris Weston Approved by: marcel@ MFC after: 2 weeks --- sys/geom/part/g_part_gpt.c | 159 +++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 67 deletions(-) diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index f62b46774f5..aabbec1cde8 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -73,7 +73,7 @@ enum gpt_state { struct g_part_gpt_table { struct g_part_table base; u_char mbr[MBRSIZE]; - struct gpt_hdr hdr; + struct gpt_hdr *hdr; quad_t lba[GPT_ELT_COUNT]; enum gpt_state state[GPT_ELT_COUNT]; }; @@ -143,13 +143,12 @@ static struct uuid gpt_uuid_linux_swap = GPT_ENT_TYPE_LINUX_SWAP; static struct uuid gpt_uuid_mbr = GPT_ENT_TYPE_MBR; static struct uuid gpt_uuid_unused = GPT_ENT_TYPE_UNUSED; -static void +static struct gpt_hdr * gpt_read_hdr(struct g_part_gpt_table *table, struct g_consumer *cp, - enum gpt_elt elt, struct gpt_hdr *hdr) + enum gpt_elt elt) { - struct uuid uuid; + struct gpt_hdr *buf, *hdr; struct g_provider *pp; - char *buf; quad_t lba, last; int error; uint32_t crc, sz; @@ -161,63 +160,75 @@ gpt_read_hdr(struct g_part_gpt_table *table, struct g_consumer *cp, buf = g_read_data(cp, table->lba[elt] * pp->sectorsize, pp->sectorsize, &error); if (buf == NULL) - return; - bcopy(buf, hdr, sizeof(*hdr)); - if (memcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0) - return; + return (NULL); + hdr = NULL; + if (memcmp(buf->hdr_sig, GPT_HDR_SIG, sizeof(buf->hdr_sig)) != 0) + goto fail; table->state[elt] = GPT_STATE_CORRUPT; - sz = le32toh(hdr->hdr_size); + sz = le32toh(buf->hdr_size); if (sz < 92 || sz > pp->sectorsize) - return; - crc = le32toh(hdr->hdr_crc_self); - hdr->hdr_crc_self = 0; - if (crc32(hdr, sz) != crc) - return; + goto fail; + + hdr = g_malloc(sz, M_WAITOK | M_ZERO); + bcopy(buf, hdr, sz); hdr->hdr_size = sz; + + crc = le32toh(buf->hdr_crc_self); + buf->hdr_crc_self = 0; + if (crc32(buf, sz) != crc) + goto fail; hdr->hdr_crc_self = crc; table->state[elt] = GPT_STATE_INVALID; - hdr->hdr_revision = le32toh(hdr->hdr_revision); + hdr->hdr_revision = le32toh(buf->hdr_revision); if (hdr->hdr_revision < 0x00010000) - return; - hdr->hdr_lba_self = le64toh(hdr->hdr_lba_self); + goto fail; + hdr->hdr_lba_self = le64toh(buf->hdr_lba_self); if (hdr->hdr_lba_self != table->lba[elt]) - return; - hdr->hdr_lba_alt = le64toh(hdr->hdr_lba_alt); + goto fail; + hdr->hdr_lba_alt = le64toh(buf->hdr_lba_alt); /* Check the managed area. */ - hdr->hdr_lba_start = le64toh(hdr->hdr_lba_start); + hdr->hdr_lba_start = le64toh(buf->hdr_lba_start); if (hdr->hdr_lba_start < 2 || hdr->hdr_lba_start >= last) - return; - hdr->hdr_lba_end = le64toh(hdr->hdr_lba_end); + goto fail; + hdr->hdr_lba_end = le64toh(buf->hdr_lba_end); if (hdr->hdr_lba_end < hdr->hdr_lba_start || hdr->hdr_lba_end >= last) - return; + goto fail; /* Check the table location and size of the table. */ - hdr->hdr_entries = le32toh(hdr->hdr_entries); - hdr->hdr_entsz = le32toh(hdr->hdr_entsz); + hdr->hdr_entries = le32toh(buf->hdr_entries); + hdr->hdr_entsz = le32toh(buf->hdr_entsz); if (hdr->hdr_entries == 0 || hdr->hdr_entsz < 128 || (hdr->hdr_entsz & 7) != 0) - return; - hdr->hdr_lba_table = le64toh(hdr->hdr_lba_table); + goto fail; + hdr->hdr_lba_table = le64toh(buf->hdr_lba_table); if (hdr->hdr_lba_table < 2 || hdr->hdr_lba_table >= last) - return; + goto fail; if (hdr->hdr_lba_table >= hdr->hdr_lba_start && hdr->hdr_lba_table <= hdr->hdr_lba_end) - return; + goto fail; lba = hdr->hdr_lba_table + (hdr->hdr_entries * hdr->hdr_entsz + pp->sectorsize - 1) / pp->sectorsize - 1; if (lba >= last) - return; + goto fail; if (lba >= hdr->hdr_lba_start && lba <= hdr->hdr_lba_end) - return; + goto fail; table->state[elt] = GPT_STATE_OK; - le_uuid_dec(&hdr->hdr_uuid, &uuid); - hdr->hdr_uuid = uuid; - hdr->hdr_crc_table = le32toh(hdr->hdr_crc_table); + le_uuid_dec(&buf->hdr_uuid, &hdr->hdr_uuid); + hdr->hdr_crc_table = le32toh(buf->hdr_crc_table); + + g_free(buf); + return (hdr); + + fail: + if (hdr != NULL) + g_free(hdr); + g_free(buf); + return (NULL); } static struct gpt_ent * @@ -230,6 +241,9 @@ gpt_read_tbl(struct g_part_gpt_table *table, struct g_consumer *cp, unsigned int idx, sectors, tblsz; int error; + if (hdr == NULL) + return (NULL); + pp = cp->provider; table->lba[elt] = hdr->hdr_lba_table; @@ -271,6 +285,9 @@ static int gpt_matched_hdrs(struct gpt_hdr *pri, struct gpt_hdr *sec) { + if (pri == NULL || sec == NULL) + return (0); + if (!EQUUID(&pri->hdr_uuid, &sec->hdr_uuid)) return (0); return ((pri->hdr_revision == sec->hdr_revision && @@ -427,17 +444,17 @@ g_part_gpt_create(struct g_part_table *basetable, struct g_part_parms *gpp) table->lba[GPT_ELT_SECHDR] = last; table->lba[GPT_ELT_SECTBL] = last - tblsz; - bcopy(GPT_HDR_SIG, table->hdr.hdr_sig, sizeof(table->hdr.hdr_sig)); - table->hdr.hdr_revision = GPT_HDR_REVISION; - table->hdr.hdr_size = offsetof(struct gpt_hdr, padding); - table->hdr.hdr_lba_start = 2 + tblsz; - table->hdr.hdr_lba_end = last - tblsz - 1; - kern_uuidgen(&table->hdr.hdr_uuid, 1); - table->hdr.hdr_entries = basetable->gpt_entries; - table->hdr.hdr_entsz = sizeof(struct gpt_ent); + bcopy(GPT_HDR_SIG, table->hdr->hdr_sig, sizeof(table->hdr->hdr_sig)); + table->hdr->hdr_revision = GPT_HDR_REVISION; + table->hdr->hdr_size = offsetof(struct gpt_hdr, padding); + table->hdr->hdr_lba_start = 2 + tblsz; + table->hdr->hdr_lba_end = last - tblsz - 1; + kern_uuidgen(&table->hdr->hdr_uuid, 1); + table->hdr->hdr_entries = basetable->gpt_entries; + table->hdr->hdr_entsz = sizeof(struct gpt_ent); - basetable->gpt_first = table->hdr.hdr_lba_start; - basetable->gpt_last = table->hdr.hdr_lba_end; + basetable->gpt_first = table->hdr->hdr_lba_start; + basetable->gpt_last = table->hdr->hdr_lba_end; return (0); } @@ -582,7 +599,7 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) static int g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp) { - struct gpt_hdr prihdr, sechdr; + struct gpt_hdr *prihdr, *sechdr; struct gpt_ent *tbl, *pritbl, *sectbl; struct g_provider *pp; struct g_part_gpt_table *table; @@ -601,18 +618,18 @@ g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp) g_free(buf); /* Read the primary header and table. */ - gpt_read_hdr(table, cp, GPT_ELT_PRIHDR, &prihdr); + prihdr = gpt_read_hdr(table, cp, GPT_ELT_PRIHDR); if (table->state[GPT_ELT_PRIHDR] == GPT_STATE_OK) { - pritbl = gpt_read_tbl(table, cp, GPT_ELT_PRITBL, &prihdr); + pritbl = gpt_read_tbl(table, cp, GPT_ELT_PRITBL, prihdr); } else { table->state[GPT_ELT_PRITBL] = GPT_STATE_MISSING; pritbl = NULL; } /* Read the secondary header and table. */ - gpt_read_hdr(table, cp, GPT_ELT_SECHDR, &sechdr); + sechdr = gpt_read_hdr(table, cp, GPT_ELT_SECHDR); if (table->state[GPT_ELT_SECHDR] == GPT_STATE_OK) { - sectbl = gpt_read_tbl(table, cp, GPT_ELT_SECTBL, &sechdr); + sectbl = gpt_read_tbl(table, cp, GPT_ELT_SECTBL, sechdr); } else { table->state[GPT_ELT_SECTBL] = GPT_STATE_MISSING; sectbl = NULL; @@ -635,13 +652,17 @@ g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp) */ if (table->state[GPT_ELT_PRIHDR] == GPT_STATE_OK && table->state[GPT_ELT_SECHDR] == GPT_STATE_OK && - !gpt_matched_hdrs(&prihdr, &sechdr)) { + !gpt_matched_hdrs(prihdr, sechdr)) { if (table->state[GPT_ELT_PRITBL] == GPT_STATE_OK) { table->state[GPT_ELT_SECHDR] = GPT_STATE_INVALID; table->state[GPT_ELT_SECTBL] = GPT_STATE_MISSING; + g_free(sechdr); + sechdr = NULL; } else { table->state[GPT_ELT_PRIHDR] = GPT_STATE_INVALID; table->state[GPT_ELT_PRITBL] = GPT_STATE_MISSING; + g_free(prihdr); + prihdr = NULL; } } @@ -651,6 +672,8 @@ g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp) printf("GEOM: %s: using the secondary instead -- recovery " "strongly advised.\n", pp->name); table->hdr = sechdr; + if (prihdr != NULL) + g_free(prihdr); tbl = sectbl; if (pritbl != NULL) g_free(pritbl); @@ -662,14 +685,16 @@ g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp) "suggested.\n", pp->name); } table->hdr = prihdr; + if (sechdr != NULL) + g_free(sechdr); tbl = pritbl; if (sectbl != NULL) g_free(sectbl); } - basetable->gpt_first = table->hdr.hdr_lba_start; - basetable->gpt_last = table->hdr.hdr_lba_end; - basetable->gpt_entries = table->hdr.hdr_entries; + basetable->gpt_first = table->hdr->hdr_lba_start; + basetable->gpt_last = table->hdr->hdr_lba_end; + basetable->gpt_entries = table->hdr->hdr_entries; for (index = basetable->gpt_entries - 1; index >= 0; index--) { if (EQUUID(&tbl[index].ent_type, &gpt_uuid_unused)) @@ -727,7 +752,7 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp) pp = cp->provider; table = (struct g_part_gpt_table *)basetable; - tlbsz = (table->hdr.hdr_entries * table->hdr.hdr_entsz + + tlbsz = (table->hdr->hdr_entries * table->hdr->hdr_entsz + pp->sectorsize - 1) / pp->sectorsize; /* Write the PMBR */ @@ -741,21 +766,21 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp) /* Allocate space for the header and entries. */ buf = g_malloc((tlbsz + 1) * pp->sectorsize, M_WAITOK | M_ZERO); - memcpy(buf, table->hdr.hdr_sig, sizeof(table->hdr.hdr_sig)); - le32enc(buf + 8, table->hdr.hdr_revision); - le32enc(buf + 12, table->hdr.hdr_size); - le64enc(buf + 40, table->hdr.hdr_lba_start); - le64enc(buf + 48, table->hdr.hdr_lba_end); - le_uuid_enc(buf + 56, &table->hdr.hdr_uuid); - le32enc(buf + 80, table->hdr.hdr_entries); - le32enc(buf + 84, table->hdr.hdr_entsz); + memcpy(buf, table->hdr->hdr_sig, sizeof(table->hdr->hdr_sig)); + le32enc(buf + 8, table->hdr->hdr_revision); + le32enc(buf + 12, table->hdr->hdr_size); + le64enc(buf + 40, table->hdr->hdr_lba_start); + le64enc(buf + 48, table->hdr->hdr_lba_end); + le_uuid_enc(buf + 56, &table->hdr->hdr_uuid); + le32enc(buf + 80, table->hdr->hdr_entries); + le32enc(buf + 84, table->hdr->hdr_entsz); LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) { if (baseentry->gpe_deleted) continue; entry = (struct g_part_gpt_entry *)baseentry; index = baseentry->gpe_index - 1; - bp = buf + pp->sectorsize + table->hdr.hdr_entsz * index; + bp = buf + pp->sectorsize + table->hdr->hdr_entsz * index; le_uuid_enc(bp, &entry->ent.ent_type); le_uuid_enc(bp + 16, &entry->ent.ent_uuid); le64enc(bp + 32, entry->ent.ent_lba_start); @@ -766,7 +791,7 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp) } crc = crc32(buf + pp->sectorsize, - table->hdr.hdr_entries * table->hdr.hdr_entsz); + table->hdr->hdr_entries * table->hdr->hdr_entsz); le32enc(buf + 88, crc); /* Write primary meta-data. */ @@ -774,7 +799,7 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp) le64enc(buf + 24, table->lba[GPT_ELT_PRIHDR]); /* hdr_lba_self. */ le64enc(buf + 32, table->lba[GPT_ELT_SECHDR]); /* hdr_lba_alt. */ le64enc(buf + 72, table->lba[GPT_ELT_PRITBL]); /* hdr_lba_table. */ - crc = crc32(buf, table->hdr.hdr_size); + crc = crc32(buf, table->hdr->hdr_size); le32enc(buf + 16, crc); error = g_write_data(cp, table->lba[GPT_ELT_PRITBL] * pp->sectorsize, @@ -791,7 +816,7 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp) le64enc(buf + 24, table->lba[GPT_ELT_SECHDR]); /* hdr_lba_self. */ le64enc(buf + 32, table->lba[GPT_ELT_PRIHDR]); /* hdr_lba_alt. */ le64enc(buf + 72, table->lba[GPT_ELT_SECTBL]); /* hdr_lba_table. */ - crc = crc32(buf, table->hdr.hdr_size); + crc = crc32(buf, table->hdr->hdr_size); le32enc(buf + 16, crc); error = g_write_data(cp, table->lba[GPT_ELT_SECTBL] * pp->sectorsize, From 5c670c33fc4574daa9a316afd2b10e05aa23d880 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 7 Nov 2009 18:42:53 +0000 Subject: [PATCH 552/646] Turn off WPI_DEBUG by default as the driver seems sufficiently stable at this point. Reviewed by: benjsc, thompsa --- sys/dev/wpi/if_wpi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index af51f60269c..2ef4865e2b5 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -103,8 +103,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define WPI_DEBUG - #ifdef WPI_DEBUG #define DPRINTF(x) do { if (wpi_debug != 0) printf x; } while (0) #define DPRINTFN(n, x) do { if (wpi_debug & n) printf x; } while (0) From 48a84955743976049efea885d247724e42e8eff8 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 7 Nov 2009 18:55:39 +0000 Subject: [PATCH 553/646] Wrap some socket handling code in a !NULL bow This patch or something similar will likely be included in a future BIND release. PR: bin/138061 Submitted by: Michael Baker Original patch submitted by: Volker Patch reviewed and tweaked by: ISC --- contrib/bind9/bin/dig/dighost.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c index 470261cb2da..73264e6c2ce 100644 --- a/contrib/bind9/bin/dig/dighost.c +++ b/contrib/bind9/bin/dig/dighost.c @@ -2604,10 +2604,12 @@ connect_done(isc_task_t *task, isc_event_t *event) { if (sevent->result == ISC_R_CANCELED) { debug("in cancel handler"); - isc_socket_detach(&query->sock); - sockcount--; - INSIST(sockcount >= 0); - debug("sockcount=%d", sockcount); + if (query->sock != NULL) { + isc_socket_detach(&query->sock); + sockcount--; + INSIST(sockcount >= 0); + debug("sockcount=%d", sockcount); + } query->waiting_connect = ISC_FALSE; isc_event_free(&event); l = query->lookup; From 61ccb9da43a54153a6c752b44534389d0ee7fe81 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 7 Nov 2009 20:37:38 +0000 Subject: [PATCH 554/646] Tell upper layer we support long frames. ether_ifattach() initializes it to ETHER_HDR_LEN so we have to override it after calling ether_ifattch(). While I'm here remove setting if_mtu value, it's initialized in ether_ifattach(). --- sys/dev/bge/if_bge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 7913fd57426..ba2073e59b8 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2723,7 +2723,6 @@ bge_attach(device_t dev) ifp->if_ioctl = bge_ioctl; ifp->if_start = bge_start; ifp->if_init = bge_init; - ifp->if_mtu = ETHERMTU; ifp->if_snd.ifq_drv_maxlen = BGE_TX_RING_CNT - 1; IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); IFQ_SET_READY(&ifp->if_snd); @@ -2838,6 +2837,9 @@ again: ether_ifattach(ifp, eaddr); callout_init_mtx(&sc->bge_stat_ch, &sc->bge_mtx, 0); + /* Tell upper layer we support long frames. */ + ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); + /* * Hookup IRQ last. */ From 355179569c55f0639a3b2cdd7c7f8a52cec39a2c Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 7 Nov 2009 21:02:40 +0000 Subject: [PATCH 555/646] Remove the svn:executable property from this file --- games/fortune/datfiles/gerrold.limerick | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 games/fortune/datfiles/gerrold.limerick diff --git a/games/fortune/datfiles/gerrold.limerick b/games/fortune/datfiles/gerrold.limerick old mode 100755 new mode 100644 From 152f5570db0a9ed4bf9b6e312e4792981d8df9e7 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 7 Nov 2009 21:28:21 +0000 Subject: [PATCH 556/646] Move Warner's very funny comparison of VCS to anal sex into fortunes-o --- games/fortune/datfiles/fortunes | 6 ------ games/fortune/datfiles/fortunes-o.real | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes index d9ee0147d42..22d77d1ce2b 100644 --- a/games/fortune/datfiles/fortunes +++ b/games/fortune/datfiles/fortunes @@ -2515,12 +2515,6 @@ which is why you should do them yourself. There is no point in paying other people to screw things up when you can easily screw them up yourself for far less money. This article can help you. -- Dave Barry, "The Taming of the Screw" -% - I'd say that VCS is more like the anal sex of the software -world: Everybody talks about it, some people do it, some people enjoy -it, but typically only vague implications about the best techniques -are ever voiced in public. - -- Warner Losh, on Version Control Systems % "I'll tell you what I know, then," he decided. "The pin I'm wearing means I'm a member of the IA. That's Inamorati Anonymous. An inamorato is diff --git a/games/fortune/datfiles/fortunes-o.real b/games/fortune/datfiles/fortunes-o.real index 3238af46093..dbfafcae703 100644 --- a/games/fortune/datfiles/fortunes-o.real +++ b/games/fortune/datfiles/fortunes-o.real @@ -1152,6 +1152,12 @@ and stuck it in my back." "Not my remains, Al!" "Gabriel's trumpet will produce you from the ass of a pig." -- Al Swearingen, E. B. Farnum, _Deadwood_ +% + I'd say that VCS is more like the anal sex of the software +world: Everybody talks about it, some people do it, some people enjoy +it, but typically only vague implications about the best techniques +are ever voiced in public. + -- Warner Losh, on Version Control Systems % "I'll tell ya, Jeb," Wilbur said to his friend, "the tractor business ain't doin' too well. I ain't sold one all month. From 48f6dd8a8ca53595c936686cdeb613b37bc181ab Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 7 Nov 2009 21:46:34 +0000 Subject: [PATCH 557/646] Use a safety belt for cases where corrupted narg can be passed to the ktrsyscall(). print_number() does decrement the number of arguments, leading to infinite loops for negative values. Reported by: Patrick Lamaiziere , Jonathan Pascal Submitted by: jh PR: bin/120055, kern/119564 MFC: 1 week --- usr.bin/kdump/kdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 3d8b93a6101..60ce05f4f2d 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -799,7 +799,7 @@ ktrsyscall(struct ktr_syscall *ktr) narg--; } } - while (narg) { + while (narg > 0) { print_number(ip,narg,c); } (void)putchar(')'); From 79b871ac8a37e92b0d8012b307611ee2b7031009 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 7 Nov 2009 22:13:29 +0000 Subject: [PATCH 558/646] Properly sort a math fortune after the changes in r193486 Properly sort fortunes added in r174879 and r174959 --- games/fortune/datfiles/fortunes | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes index 22d77d1ce2b..7458fdaac66 100644 --- a/games/fortune/datfiles/fortunes +++ b/games/fortune/datfiles/fortunes @@ -68,6 +68,17 @@ the damage. Having a bootable tape (for larger machines) is not a bad idea either. If you need some help, give us a call. -- CommUNIXque 1:1, ASCAR Business Systems +% + 1/2 + 12 + 144 + 20 + 3*4 2 + ---------------------- + 5 * 11 = 9 + 0 + 7 + +A dozen, a gross and a score, +Plus three times the square root of four, + Divided by seven, + Plus five times eleven, +Equals nine squared plus zero, no more! % -- Gifts for Children -- @@ -673,17 +684,6 @@ Liza Minnelli. -- Dave Barry, "In Search of Excellence" % ... with liberty and justice for all who can afford it. -% - 1/2 - 12 + 144 + 20 + 3*4 2 - ---------------------- + 5 * 11 = 9 + 0 - 7 - -A dozen, a gross and a score, -Plus three times the square root of four, - Divided by seven, - Plus five times eleven, -Equals nine squared plus zero, no more! % 7,140 pounds on the Sun 97 pounds on Mercury or Mars @@ -33065,6 +33065,10 @@ versions of songs from The Wizard of Oz. % May a Misguided Platypus lay its Eggs in your Jockey Shorts % +May all your Emus lay soft boiled eggs, and may all your +Kangaroos be born with iPods already fitted. + -- Aussie New Years wish, found on hasselbladinfo.com +% May all your PUSHes be POPped. % May Euell Gibbons eat your only copy of the manual! @@ -59764,6 +59768,17 @@ You've been telling me to relax all the way here, and now you're telling me just to be myself? -- The Return of the Secaucus Seven % +You've decked the halls with a dozen miles' length of electric lights. +Your front lawn is a gleaming testament of incandescent wonder. The neighbors +wear sunglasses 24/7, and orbiting satellites have officially picked up +and pinpointed your house as the brightest spot on earth. + +You've finally put together the Christmas wonderland of your dreams... now +if only you could get a good picture of it. + +Photographing holiday lights is no easy task. + -- from an email sent by photojojo.com +% You've got to have a gimmick if your band sucks. -- Gary Giddens % @@ -59804,18 +59819,3 @@ since I first called my brother's father dad. Zymurgy's Law of Volunteer Labor: People are always available for work in the past tense. % -You've decked the halls with a dozen miles' length of electric lights. -Your front lawn is a gleaming testament of incandescent wonder. The neighbors -wear sunglasses 24/7, and orbiting satellites have officially picked up -and pinpointed your house as the brightest spot on earth. - -You've finally put together the Christmas wonderland of your dreams... now -if only you could get a good picture of it. - -Photographing holiday lights is no easy task. - -- from an email sent by photojojo.com -% -May all your Emus lay soft boiled eggs, and may all your -Kangaroos be born with iPods already fitted. - -- Aussie New Years wish, found on hasselbladinfo.com -% From 25dc84f22ff0ff57e6503db1b100710dfadbd9f8 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 8 Nov 2009 01:13:38 +0000 Subject: [PATCH 559/646] Don't count input errors twice, we always read input errors from MAC in bge_tick. Previously it used to show more number of input errors. I noticed actual input errors were less than 8% even for 64 bytes UDP frames generated by netperf. Since we always access BGE_RXLP_LOCSTAT_IFIN_DROPS register in bge_tick, remove useless code protected by #ifdef notyet. --- sys/dev/bge/if_bge.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index ba2073e59b8..830880137d0 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3196,7 +3196,6 @@ bge_rxeof(struct bge_softc *sc) m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx]; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); - ifp->if_ierrors++; continue; } if (bge_newbuf_jumbo(sc, rxidx) != 0) { @@ -3209,7 +3208,6 @@ bge_rxeof(struct bge_softc *sc) stdcnt++; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); - ifp->if_ierrors++; continue; } m = sc->bge_cdata.bge_rx_std_chain[rxidx]; @@ -3291,14 +3289,6 @@ bge_rxeof(struct bge_softc *sc) bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); if (jumbocnt) bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); -#ifdef notyet - /* - * This register wraps very quickly under heavy packet drops. - * If you need correct statistics, you can enable this check. - */ - if (BGE_IS_5705_PLUS(sc)) - ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); -#endif return (rx_npkts); } From e238d4ead114ad0e8a4af71bfc50cade4eb841f0 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 8 Nov 2009 01:30:35 +0000 Subject: [PATCH 560/646] Count number of inbound packets which were chosen to be discarded as input errors. Also count out of receive BDs as input errors. --- sys/dev/bge/if_bge.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 830880137d0..f2352a968ff 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3547,7 +3547,9 @@ bge_stats_update_regs(struct bge_softc *sc) ifp->if_collisions += CSR_READ_4(sc, BGE_MAC_STATS + offsetof(struct bge_mac_stats_regs, etherStatsCollisions)); + ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_OUT_OF_BDS); ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); + ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS); } static void From afe0ec0027c9b1e7dc9ff95258d72484cb3dac46 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sun, 8 Nov 2009 02:33:33 +0000 Subject: [PATCH 561/646] Properly turn off debugging LART applied (gently) by: sam --- sys/dev/wpi/if_wpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 2ef4865e2b5..85812375218 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -103,6 +103,8 @@ __FBSDID("$FreeBSD$"); #include #include +#define WPI_DEBUG + #ifdef WPI_DEBUG #define DPRINTF(x) do { if (wpi_debug != 0) printf x; } while (0) #define DPRINTFN(n, x) do { if (wpi_debug & n) printf x; } while (0) @@ -124,7 +126,7 @@ enum { WPI_DEBUG_ANY = 0xffffffff }; -static int wpi_debug = 1; +static int wpi_debug = 0; SYSCTL_INT(_debug, OID_AUTO, wpi, CTLFLAG_RW, &wpi_debug, 0, "wpi debug level"); TUNABLE_INT("debug.wpi", &wpi_debug); From ce837c4a0f795fd6511466bcc23420cab8d2e402 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Sun, 8 Nov 2009 08:59:40 +0000 Subject: [PATCH 562/646] create an SMP kernel by default in picobsd --- release/picobsd/bridge/PICOBSD | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD index 150a44d38e7..6aeac14da11 100644 --- a/release/picobsd/bridge/PICOBSD +++ b/release/picobsd/bridge/PICOBSD @@ -11,11 +11,14 @@ hints "PICOBSD.hints" # values accessible through getenv() # env "PICOBSD.env" -cpu I486_CPU +#cpu I486_CPU cpu I586_CPU cpu I686_CPU ident PICOBSD +options SMP +device apic + options SCHED_4BSD # mandatory to have one scheduler #options MATH_EMULATE #Support for x87 emulation options INET #InterNETworking From 7ba889b8f4fff5d2363a8a9fa9160e7694d940f0 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 8 Nov 2009 09:54:25 +0000 Subject: [PATCH 563/646] Add suggestion for zfs root. --- sys/kern/vfs_mount.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 15899ce1f0b..71084f5069b 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1892,6 +1892,7 @@ vfs_mountroot_ask(void) freeenv(options); printf("\nManual root filesystem specification:\n"); printf(" : Mount using filesystem \n"); + printf(" eg. zfs:tank\n"); printf(" eg. ufs:/dev/da0s1a\n"); printf(" eg. cd9660:/dev/acd0\n"); printf(" This is equivalent to: "); From 88260ae6147ec915429d0998c00a7c28b60b66b9 Mon Sep 17 00:00:00 2001 From: Gabor Kovesdan Date: Sun, 8 Nov 2009 11:32:39 +0000 Subject: [PATCH 564/646] - Update Ukranian catalog Submitted by: Alex Kozlov (via private mail) --- lib/libc/nls/uk_UA.UTF-8.msg | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/libc/nls/uk_UA.UTF-8.msg b/lib/libc/nls/uk_UA.UTF-8.msg index e6ea2f7748a..2b7b02f74a4 100644 --- a/lib/libc/nls/uk_UA.UTF-8.msg +++ b/lib/libc/nls/uk_UA.UTF-8.msg @@ -181,6 +181,16 @@ $ ENOATTR 87 ミ績びミクミアムτ ミスミオ ミキミスミーミケミエミオミスミセ $ EDOOFUS 88 ミ渙セミシミクミサミコミー ミソムミセミウムミーミシムσイミーミスミスム +$ EBADMSG +89 ミ渙セミウミーミスミクミケ ムミセムミシミーム ミソミセミイム孟エミセミシミサミオミスミスム +$ EMULTIHOP XXX +90 ミ。ミソムミセミアミー ミシムσサムび毛ミセミソム +$ ENOLINK +91 ミ慴オムミオミカミセミイミクミケ ミコミーミスミーミサ ムミセミキム毛ミイミーミスミセ +$ EPROTO +92 ミ渙セミシミクミサミコミー ミソムミセムひセミコミセミサム +$ ENOTCAPABLE +93 ミ慴セミカミサミクミイミセムムび ミスミオミエミセムムひームひスム $ $ strsignal() support catalog $ From c43ee8876420263f97fc34a847525aa3858e1732 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 8 Nov 2009 11:33:51 +0000 Subject: [PATCH 565/646] Introduce hw.hptrr.attach_generic loader tunable to deny hptrr driver attach chips with generic Marvell (non-HighPoint) PCI identification. These chips are also supported by ata(4). Some vendors, like Supermicro, are using same chips without providing HPT RAID BIOS. PR: kern/120842, kern/136750 --- share/man/man4/hptrr.4 | 11 ++++++++++- sys/dev/hptrr/hptrr_osm_bsd.c | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/share/man/man4/hptrr.4 b/share/man/man4/hptrr.4 index 24943445ce5..847d86db7c0 100644 --- a/share/man/man4/hptrr.4 +++ b/share/man/man4/hptrr.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 14, 2007 +.Dd November 8, 2009 .Dt HPTRR 4 .Os .Sh NAME @@ -46,6 +46,14 @@ module at boot time, place the following line in .Bd -literal -offset indent hptrr_load="YES" .Ed +.Pp +The following tunables are settable from the loader: +.Bl -ohang +.It Va hw.hptrr.attach_generic +set to 0 to deny driver attach to chips with generic Marvell (non-HighPoint) +PCI identification. These chips are also supported by ata(4). +Some vendors are using same chips, but without providing RAID BIOS. +.El .Sh DESCRIPTION The .Nm @@ -101,6 +109,7 @@ manual page for details on support. .Pp This driver supersedes the older rr232x driver. .Sh SEE ALSO +.Xr ata 4 , .Xr cam 4 , .Xr hptmv 4 , .Xr loader 8 diff --git a/sys/dev/hptrr/hptrr_osm_bsd.c b/sys/dev/hptrr/hptrr_osm_bsd.c index eae952e1228..78c8b60fe2e 100644 --- a/sys/dev/hptrr/hptrr_osm_bsd.c +++ b/sys/dev/hptrr/hptrr_osm_bsd.c @@ -34,6 +34,9 @@ #include #include +static int attach_generic = 1; +TUNABLE_INT("hw.hptrr.attach_generic", &attach_generic); + static int hpt_probe(device_t dev) { PCI_ID pci_id; @@ -41,6 +44,9 @@ static int hpt_probe(device_t dev) int i; PHBA hba; + /* Some of supported chips are used not only by HPT. */ + if (pci_get_vendor(dev) != 0x1103 && !attach_generic) + return (ENXIO); for (him = him_list; him; him = him->next) { for (i=0; him->get_supported_device_id(i, &pci_id); i++) { if ((pci_get_vendor(dev) == pci_id.vid) && From f93a16d57d1b53f54fc3927a1485aa601afa57bd Mon Sep 17 00:00:00 2001 From: Gabor Kovesdan Date: Sun, 8 Nov 2009 11:55:03 +0000 Subject: [PATCH 566/646] - Strip trailing CRs Requested by: Alex Kozlov (via private mail) --- lib/libc/nls/uk_UA.UTF-8.msg | 518 +++++++++++++++++------------------ 1 file changed, 259 insertions(+), 259 deletions(-) diff --git a/lib/libc/nls/uk_UA.UTF-8.msg b/lib/libc/nls/uk_UA.UTF-8.msg index 2b7b02f74a4..af871d94276 100644 --- a/lib/libc/nls/uk_UA.UTF-8.msg +++ b/lib/libc/nls/uk_UA.UTF-8.msg @@ -1,259 +1,259 @@ -$ $FreeBSD$ -$ -$ Message catalog for uk_UA.UTF-8 locale -$ -$ strerror() support catalog -$ -$set 1 -$ EPERM -1 ミ榧ソミオムミームム毛 ミスミオ ミエミセミキミイミセミサミオミスミー -$ ENOENT -2 ミ斷オミシミーム ムひーミコミセミウミセ ムミーミケミサム ミーミアミセ ミコミームひーミサミセミウム -$ ESRCH -3 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミセムミオムム -$ EINTR -4 ミ渙オムミオムミイミーミスミセ ミイミクミコミサミクミコ ムムσスミコムム毛 -$ EIO -5 ミ渙セミシミクミサミコミー ミイミイミセミエム-ミイミクミイミセミエム -$ ENXIO -6 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミクムムびミセム ミーミアミセ ミーミエムミオムミク -$ E2BIG -7 ミ渙オムミオミサム孟コ ミームミウムσシミオミスムび孟イ ミスミーミエムひセ ミエミセミイミウミクミケ -$ ENOEXEC -8 ミ渙セミシミクミサミコミー ムミセムミシミームび ミイミクミコミセミスムσイミーミスミセミウミセ ムミーミケミサム -$ EBADF -9 ミ斷オミイム毛ミスミクミケ ミエミオムミコムミクミソムひセム ムミーミケミサム -$ ECHILD -10 ミ斷オミシミーム ミエミセムム毛ミスム糊セミウミセ ミソムミセムミオムム -$ EDEADLK -11 ミ」ミスミクミコミスムτひセ ミイミキミーム頒シミスミオ ミアミサミセミコムσイミーミスミスム ムミオムムτムム孟イ -$ ENOMEM -12 ミ斷オ ミエミセムムひームひスム糊セ ミソミーミシ'ム肖び -$ EACCES -13 ミ柘孟エミシミセミイミー ム ミエミセムムびσソム -$ EFAULT -14 ミ斷オミイム毛ミスミー ミーミエムミオムミー -$ ENOTBLK -15 ミ渙セムびム孟アミオミス ミアミサミセムミスミクミケ ミソムミクムムびム孟ケ -$ EBUSY -16 ミミオムムτム ミキミーミケミスム肖ひクミケ -$ EEXIST -17 ミ、ミーミケミサ ミイミカミオ ム毛ミスムτ -$ EXDEV -18 ミ渙セムミクミサミーミスミスム ミキミー ミシミオミカム ミソムミクムムびミセム -$ ENODEV -19 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミクムムびミセム -$ ENOTDIR -20 ミヲミオ ミスミオ ミコミームひーミサミセミウ -$ EISDIR -21 ミヲミオ ミコミームひーミサミセミウ -$ EINVAL -22 ミ斷オミエミセミキミイミセミサミオミスミクミケ ミームミウムσシミオミスム -$ ENFILE -23 ミ厘ーミアミーミウミームひセ ミイム孟エミコムミクムひクム ムミーミケミサム孟イ ム ムミクムムひオミシム -$ EMFILE -24 ミ厘ーミアミーミウミームひセ ミイム孟エミコムミクムひクム ムミーミケミサム孟イ -$ ENOTTY -25 ミヲミオ ミスミオ ムひオムミシム孟スミーミサ -$ ETXTBSY -26 ミ「ミオミコムムひセミイミクミケ ムミーミケミサ ミキミーミケミスム肖ひクミケ -$ EFBIG -27 ミ、ミーミケミサ ミスミーミエムひセ ミイミオミサミクミコミクミケ -$ ENOSPC -28 ミ斷オ ミキミーミサミクム威クミサミセムム ミシム毛ムム ミスミー ミソムミクムムびミセム -$ ESPIPE -29 ミ斷オミエミセミキミイミセミサミオミスミオ ミソミセミキミクムム孟セミスムσイミーミスミスム -$ EROFS -30 ミ、ミーミケミサミセミイミー ムミクムムひオミシミー ミサミクム威オ ミエミサム ムミクムひーミスミスム -$ EMLINK -31 ミ厘ーミアミーミウミームひセ ミソミセムミクミサミーミスム -$ EPIPE -32 ミ墟ーミスミーミサ ミキムムσケミスミセミイミーミスミセ -$ EDOM -33 ミ渙セミシミクミサミコミー ミセミアミサミームムび ミイミクミキミスミームミオミスミスム -$ ERANGE -34 ミミオミキムσサム袴ひーム ミスミーミエムひセ ミイミオミサミクミコミクミケ -$ EAGAIN, EWOULDBLOCK -35 ミミオムムτム ムひクミシムミームミセミイミセ ミスミオ ミエミセムムびσソミスミクミケ -$ EINPROGRESS -36 ミ榧ソミオムミームム毛 ム ミソムミセムミオムム ミイミクミコミセミスミーミスミスム -$ EALREADY -37 ミ榧ソミオムミームム毛 ミイミカミオ ミイミクミコミセミスムτ飯び袴ム -$ ENOTSOCK -38 ミヲミオ ミスミオ ムミセミコミオム -$ EDESTADDRREQ -39 ミ斷オミセミアムム孟エミスミー ミーミエムミオムミー ミソムミクミキミスミームミオミスミスム -$ EMSGSIZE -40 ミ渙セミイム孟エミセミシミサミオミスミスム ミスミーミエムひセ ミエミセミイミウミオ -$ EPROTOTYPE -41 ミ渙セミシミクミサミコミセミイミクミケ ムひクミソ ミソムミセムひセミコミセミサム ミエミサム ムミセミコミオムび -$ ENOPROTOOPT -42 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミセムひセミコミセミサム -$ EPROTONOSUPPORT -43 ミ湲ミセムひセミコミセミサ ミスミオ ミソム孟エムびミクミシムτ飯び袴ム -$ ESOCKTNOSUPPORT -44 ミヲミオミケ ムひクミソ ムミセミコミオムび ミスミオ ミソム孟エムびミクミシムτ飯び袴ム -$ EOPNOTSUPP -45 ミ榧ソミオムミームム毛 ミスミオ ミソム孟エムびミクミシムτ飯び袴ム -$ EPFNOSUPPORT -46 ミミセミエミクミスミー ミソムミセムひセミコミセミサム孟イ ミスミオ ミソム孟エムびミクミシムτ飯び袴ム -$ EAFNOSUPPORT -47 ミミセミエミクミスミー ミーミエムミオム ミスミオ ミソム孟エムびミクミシムτ飯び袴ム ミソムミセムひセミコミセミサミセミシ -$ EADDRINUSE -48 ミ籍エムミオムミー ミイミカミオ ミイミクミコミセムミクムムひセミイムτ飯び袴ム -$ EADDRNOTAVAIL -49 ミ籍エムミオムミー ミスミオミエミセムム紹カミスミー -$ ENETDOWN -50 ミ慴オムミオミカミー ミスミオ ミソムミームム紗 -$ ENETUNREACH -51 ミ慴オムミオミカミー ミスミオミエミセムム紹カミスミー -$ ENETRESET -52 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ ミシミオムミオミカミオム -$ ECONNABORTED -53 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ -$ ECONNRESET -54 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ ミソムミセムひクミサミオミカミスミセム ムムひセムミセミスミセム -$ ENOBUFS -55 ミ斷オミシミーム ミイム孟サム糊スミクム ミアムτミオムム孟イ -$ EISCONN -56 ミ。ミセミコミオム ミイミカミオ ミソム孟エ'ム頒エミスミーミスミセ -$ ENOTCONN -57 ミ。ミセミコミオム ミスミオ ミソム孟エ'ム頒エミスミーミスミセ -$ ESHUTDOWN -58 ミ斷オ ミシミセミカム ミイム孟エム毛ミサミームひク ミソム毛ミサム ミキミーミコムミクムびび ムミセミコミオムび ミソムミセムひクミサミオミカミスミセム ムムひセムミセミスミセム -$ ETOOMANYREFS -59 ミ厘ーミアミーミウミームひセ ミソミセムミクミサミーミスム: ミスミオ ミシミセミカム ミキ'ム頒エミスミームひク -$ ETIMEDOUT -60 ミ漬クミケム威セミイ ミサム孟シム毛 ムミームム ミエミサム ミキ'ム頒エミスミーミスミスム -$ ECONNREFUSED -61 ミ柘孟エミシミセミイミー ム ミキ'ム頒エミスミーミスミスム -$ ELOOP -62 ミ厘ーミアミーミウミームひセ ムム孟イミスム孟イ ムミクミシミイミセミサム毛ミスミクム ミソミセムミクミサミーミスム -$ ENAMETOOLONG -63 ミミシ'ム ムミーミケミサム ミスミーミエムひセ ミエミセミイミウミオ -$ EHOSTDOWN -64 ミ・ミセムム ミスミオ ミソムミームム紗 -$ EHOSTUNREACH -65 ミ・ミセムム ミスミオミエミセムム紹カミスミクミケ -$ ENOTEMPTY -66 ミ墟ームひーミサミセミウ ミスミオ ミソミセムミセミカミスム孟ケ -$ EPROCLIM -67 ミ厘ーミアミーミウミームひセ ミソムミセムミオムム孟イ -$ EUSERS -68 ミ厘ーミアミーミウミームひセ ミコミセムミクムムびσイミームム孟イ -$ EDQUOT -69 ミ渙オムミオミイミクム禍オミスミー ミエミクムミコミセミイミー ミコミイミセムひー -$ ESTALE -70 ミ厘ームムひームム孟サミクミケ ミエミオムミコムミクミソムひセム ムミーミケミサム NFS -$ EREMOTE -71 ミ柘孟エミエミーミサミオミスミクミケ ミセミア'ム頒コム -$ EBADRPC -72 ミ渙セミウミーミスミー ムムびムσコムびτミー RPC -$ ERPCMISMATCH -73 ミ斷オミイム毛ミスミー ミイミオムムム毛 RPC -$ EPROGUNAVAIL -74 ミ湲ミセミウムミーミシミー RPC ミスミオミエミセムム紹カミスミー -$ EPROGMISMATCH -75 ミ斷オミイム毛ミスミー ミイミオムムム毛 ミソムミセミウムミーミシミク -$ EPROCUNAVAIL -76 ミ渙セミウミーミスミー ミソムミセムミオミエムτミー ミエミサム ミソムミセミウムミーミシミク -$ ENOLCK -77 ミ岱サミセミコムσイミーミスミスム ミスミオ ミエミセムムびσソミスミオ -$ ENOSYS -78 ミ、ムσスミコムム毛 ミスミオ ムミオミーミサム孟キミセミイミーミスミセ -$ EFTYPE -79 ミ斷オミソムミクミエミームひスミクミケ ムひクミソ ムミク ムミセムミシミーム ムミーミケミサム -$ EAUTH -80 ミ渙セミシミクミサミコミー ミームτひオミスムひクムム孟コミームム毛 -$ ENEEDAUTH -81 ミ渙セムびム孟アミスミー ミームτひオミスムひクムム孟コミームム毛 -$ EIDRM -82 ミミエミオミスムひクムム孟コミームひセム ミイミクミサムτミオミスミセ -$ ENOMSG -83 ミ斷オミシミーム ミソミセミイム孟エミセミシミサミオミスミスム ミアミーミカミーミスミセミウミセ ムひクミソム -$ EOVERFLOW -84 ミ厘ーミイミオミサミクミコミオ ミキミスミームミオミスミスム ミエミサム ムム糊セミウミセ ムひクミソム ミエミーミスミクム -$ ECANCELED -85 ミ榧ソミオムミームム毛 ムミコミームミセミイミーミスミセ -$ EILSEQ -86 ミ斷オミエミセミキミイミセミサミオミスミー ミソミセムミサム孟エミセミイミスム毛ムび ミアミーミケムび孟イ -$ ENOATTR -87 ミ績びミクミアムτ ミスミオ ミキミスミーミケミエミオミスミセ -$ EDOOFUS -88 ミ渙セミシミクミサミコミー ミソムミセミウムミーミシムσイミーミスミスム -$ EBADMSG -89 ミ渙セミウミーミスミクミケ ムミセムミシミーム ミソミセミイム孟エミセミシミサミオミスミスム -$ EMULTIHOP XXX -90 ミ。ミソムミセミアミー ミシムσサムび毛ミセミソム -$ ENOLINK -91 ミ慴オムミオミカミセミイミクミケ ミコミーミスミーミサ ムミセミキム毛ミイミーミスミセ -$ EPROTO -92 ミ渙セミシミクミサミコミー ミソムミセムひセミコミセミサム -$ ENOTCAPABLE -93 ミ慴セミカミサミクミイミセムムび ミスミオミエミセムムひームひスム -$ -$ strsignal() support catalog -$ -$set 2 -$ SIGHUP -1 ミ柘孟エミコミサム紗ミオミスミスム -$ SIGINT -2 ミ渙オムミオムミクミイミーミスミスム -$ SIGQUIT -3 ミ漬クムム孟エ -$ SIGILL -4 ミ斷オミソムミクミソムτムひクミシミー ム孟スムムびムσコムム毛 -$ SIGTRAP -5 ミ渙ームムひコミー ムびミームムσイミーミスミスム -$ SIGABRT -6 ミ籍イミームム孟ケミスミオ ミキミーミイミオムム威オミスミスム -$ SIGEMT -7 ミ渙オムミオムミセミソミサミオミスミスム ミオミシムσサム糊セミイミーミスミセム ム孟スムムびムσコムム毛 -$ SIGFPE -8 ミ渙セミシミクミサミコミー ムミセミアミセムひク ミキ ミソミサミーミイミーム紗ミセム ミコムミーミソミコミセム -$ SIGKILL -9 ミ漬アミクムひセ -$ SIGBUS -10 ミ渙セミシミクミサミコミー ム威クミスミク -$ SIGSEGV -11 ミ渙セムムτ威オミスミスム ムミオミウミシミオミスムひームム毛 -$ SIGSYS -12 ミ渙セミウミーミスミクミケ ムミクムムひオミシミスミクミケ ミイミクミコミサミクミコ -$ SIGPIPE -13 ミ墟ーミスミーミサ ミキムムσケミスミセミイミーミスミセ -$ SIGALRM -14 ミ「ミーミケミシミオム ミイミクムミオムミソミーミスミセ -$ SIGTERM -15 ミ厘ーミイミオムム威オミスミスム -$ SIGURG -16 ミ斷オミイム孟エミコミサミーミエミスミクミケ ムムひーミス ミスミー ムミセミコミオムび -$ SIGSTOP -17 ミ湲ミクミキムσソミクミスミオミスミセ (ムミクミウミスミーミサ) -$ SIGTSTP -18 ミ湲ミクミキムσソミクミスミオミスミセ -$ SIGCONT -19 ミ湲ミセミエミセミイミカミオミスミスム ムミセミアミセムひク -$ SIGCHLD -20 ミ厘シム孟スミー ムムひームびτム ミエミセムム毛ミスム糊セミウミセ ミソムミセムミオムム -$ SIGTTIN -21 ミ林σソミクミスミオミスミセ (ミイミイム孟エ ミキ ムひオムミシム孟スミーミサム) -$ SIGTTOU -22 ミ林σソミクミスミオミスミセ (ミイミクミイム孟エ ミスミー ムひオムミシム孟スミーミサ) -$ SIGIO -23 ミ漬イム孟エ-ミイミクミイム孟エ ミシミセミカミサミクミイミクミケ -$ SIGXCPU -24 ミ渙オムミオミイミクム禍オミスミセ ミサム孟シム毛 ミソムミセムミオムミセムミスミセミウミセ ムミームム -$ SIGXFSZ -25 ミ渙オムミオミイミクム禍オミスミセ ミサム孟シム毛 ミシミーミコムミクミシミーミサム糊スミセミウミセ ムミセミキミシム毛ム ムミーミケミサミー -$ SIGVTALRM -26 ミ柘毛ムびσーミサム糊スミクミケ ムひーミケミシミオム ミイミクムミオムミソミーミスミセ -$ SIGPROF -27 ミ「ミーミケミシミオム ミソムミセムム孟サム社イミーミスミスム ミイミクムミオムミソミーミスミセ -$ SIGWINCH -28 ミミセミキミシム毛 ミイム孟コミスミー ミキミシム孟スミオミスミセ -$ SIGINFO -29 ミ厘ーミソミクム ム孟スムミセムミシミームム毛 -$ SIGUSR1 -30 ミ。ミクミウミスミーミサ ミコミセムミクムムびσイミームミー 1 -$ SIGUSR2 -31 ミ。ミクミウミスミーミサ ミコミセムミクムムびσイミームミー 2 +$ $FreeBSD$ +$ +$ Message catalog for uk_UA.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 ミ榧ソミオムミームム毛 ミスミオ ミエミセミキミイミセミサミオミスミー +$ ENOENT +2 ミ斷オミシミーム ムひーミコミセミウミセ ムミーミケミサム ミーミアミセ ミコミームひーミサミセミウム +$ ESRCH +3 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミセムミオムム +$ EINTR +4 ミ渙オムミオムミイミーミスミセ ミイミクミコミサミクミコ ムムσスミコムム毛 +$ EIO +5 ミ渙セミシミクミサミコミー ミイミイミセミエム-ミイミクミイミセミエム +$ ENXIO +6 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミクムムびミセム ミーミアミセ ミーミエムミオムミク +$ E2BIG +7 ミ渙オムミオミサム孟コ ミームミウムσシミオミスムび孟イ ミスミーミエムひセ ミエミセミイミウミクミケ +$ ENOEXEC +8 ミ渙セミシミクミサミコミー ムミセムミシミームび ミイミクミコミセミスムσイミーミスミセミウミセ ムミーミケミサム +$ EBADF +9 ミ斷オミイム毛ミスミクミケ ミエミオムミコムミクミソムひセム ムミーミケミサム +$ ECHILD +10 ミ斷オミシミーム ミエミセムム毛ミスム糊セミウミセ ミソムミセムミオムム +$ EDEADLK +11 ミ」ミスミクミコミスムτひセ ミイミキミーム頒シミスミオ ミアミサミセミコムσイミーミスミスム ムミオムムτムム孟イ +$ ENOMEM +12 ミ斷オ ミエミセムムひームひスム糊セ ミソミーミシ'ム肖び +$ EACCES +13 ミ柘孟エミシミセミイミー ム ミエミセムムびσソム +$ EFAULT +14 ミ斷オミイム毛ミスミー ミーミエムミオムミー +$ ENOTBLK +15 ミ渙セムびム孟アミオミス ミアミサミセムミスミクミケ ミソムミクムムびム孟ケ +$ EBUSY +16 ミミオムムτム ミキミーミケミスム肖ひクミケ +$ EEXIST +17 ミ、ミーミケミサ ミイミカミオ ム毛ミスムτ +$ EXDEV +18 ミ渙セムミクミサミーミスミスム ミキミー ミシミオミカム ミソムミクムムびミセム +$ ENODEV +19 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミクムムびミセム +$ ENOTDIR +20 ミヲミオ ミスミオ ミコミームひーミサミセミウ +$ EISDIR +21 ミヲミオ ミコミームひーミサミセミウ +$ EINVAL +22 ミ斷オミエミセミキミイミセミサミオミスミクミケ ミームミウムσシミオミスム +$ ENFILE +23 ミ厘ーミアミーミウミームひセ ミイム孟エミコムミクムひクム ムミーミケミサム孟イ ム ムミクムムひオミシム +$ EMFILE +24 ミ厘ーミアミーミウミームひセ ミイム孟エミコムミクムひクム ムミーミケミサム孟イ +$ ENOTTY +25 ミヲミオ ミスミオ ムひオムミシム孟スミーミサ +$ ETXTBSY +26 ミ「ミオミコムムひセミイミクミケ ムミーミケミサ ミキミーミケミスム肖ひクミケ +$ EFBIG +27 ミ、ミーミケミサ ミスミーミエムひセ ミイミオミサミクミコミクミケ +$ ENOSPC +28 ミ斷オ ミキミーミサミクム威クミサミセムム ミシム毛ムム ミスミー ミソムミクムムびミセム +$ ESPIPE +29 ミ斷オミエミセミキミイミセミサミオミスミオ ミソミセミキミクムム孟セミスムσイミーミスミスム +$ EROFS +30 ミ、ミーミケミサミセミイミー ムミクムムひオミシミー ミサミクム威オ ミエミサム ムミクムひーミスミスム +$ EMLINK +31 ミ厘ーミアミーミウミームひセ ミソミセムミクミサミーミスム +$ EPIPE +32 ミ墟ーミスミーミサ ミキムムσケミスミセミイミーミスミセ +$ EDOM +33 ミ渙セミシミクミサミコミー ミセミアミサミームムび ミイミクミキミスミームミオミスミスム +$ ERANGE +34 ミミオミキムσサム袴ひーム ミスミーミエムひセ ミイミオミサミクミコミクミケ +$ EAGAIN, EWOULDBLOCK +35 ミミオムムτム ムひクミシムミームミセミイミセ ミスミオ ミエミセムムびσソミスミクミケ +$ EINPROGRESS +36 ミ榧ソミオムミームム毛 ム ミソムミセムミオムム ミイミクミコミセミスミーミスミスム +$ EALREADY +37 ミ榧ソミオムミームム毛 ミイミカミオ ミイミクミコミセミスムτ飯び袴ム +$ ENOTSOCK +38 ミヲミオ ミスミオ ムミセミコミオム +$ EDESTADDRREQ +39 ミ斷オミセミアムム孟エミスミー ミーミエムミオムミー ミソムミクミキミスミームミオミスミスム +$ EMSGSIZE +40 ミ渙セミイム孟エミセミシミサミオミスミスム ミスミーミエムひセ ミエミセミイミウミオ +$ EPROTOTYPE +41 ミ渙セミシミクミサミコミセミイミクミケ ムひクミソ ミソムミセムひセミコミセミサム ミエミサム ムミセミコミオムび +$ ENOPROTOOPT +42 ミ斷オミシミーム ムひーミコミセミウミセ ミソムミセムひセミコミセミサム +$ EPROTONOSUPPORT +43 ミ湲ミセムひセミコミセミサ ミスミオ ミソム孟エムびミクミシムτ飯び袴ム +$ ESOCKTNOSUPPORT +44 ミヲミオミケ ムひクミソ ムミセミコミオムび ミスミオ ミソム孟エムびミクミシムτ飯び袴ム +$ EOPNOTSUPP +45 ミ榧ソミオムミームム毛 ミスミオ ミソム孟エムびミクミシムτ飯び袴ム +$ EPFNOSUPPORT +46 ミミセミエミクミスミー ミソムミセムひセミコミセミサム孟イ ミスミオ ミソム孟エムびミクミシムτ飯び袴ム +$ EAFNOSUPPORT +47 ミミセミエミクミスミー ミーミエムミオム ミスミオ ミソム孟エムびミクミシムτ飯び袴ム ミソムミセムひセミコミセミサミセミシ +$ EADDRINUSE +48 ミ籍エムミオムミー ミイミカミオ ミイミクミコミセムミクムムひセミイムτ飯び袴ム +$ EADDRNOTAVAIL +49 ミ籍エムミオムミー ミスミオミエミセムム紹カミスミー +$ ENETDOWN +50 ミ慴オムミオミカミー ミスミオ ミソムミームム紗 +$ ENETUNREACH +51 ミ慴オムミオミカミー ミスミオミエミセムム紹カミスミー +$ ENETRESET +52 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ ミシミオムミオミカミオム +$ ECONNABORTED +53 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ +$ ECONNRESET +54 ミ'ム頒エミスミーミスミスム ミソムミクミソミクミスミオミスミセ ミソムミセムひクミサミオミカミスミセム ムムひセムミセミスミセム +$ ENOBUFS +55 ミ斷オミシミーム ミイム孟サム糊スミクム ミアムτミオムム孟イ +$ EISCONN +56 ミ。ミセミコミオム ミイミカミオ ミソム孟エ'ム頒エミスミーミスミセ +$ ENOTCONN +57 ミ。ミセミコミオム ミスミオ ミソム孟エ'ム頒エミスミーミスミセ +$ ESHUTDOWN +58 ミ斷オ ミシミセミカム ミイム孟エム毛ミサミームひク ミソム毛ミサム ミキミーミコムミクムびび ムミセミコミオムび ミソムミセムひクミサミオミカミスミセム ムムひセムミセミスミセム +$ ETOOMANYREFS +59 ミ厘ーミアミーミウミームひセ ミソミセムミクミサミーミスム: ミスミオ ミシミセミカム ミキ'ム頒エミスミームひク +$ ETIMEDOUT +60 ミ漬クミケム威セミイ ミサム孟シム毛 ムミームム ミエミサム ミキ'ム頒エミスミーミスミスム +$ ECONNREFUSED +61 ミ柘孟エミシミセミイミー ム ミキ'ム頒エミスミーミスミスム +$ ELOOP +62 ミ厘ーミアミーミウミームひセ ムム孟イミスム孟イ ムミクミシミイミセミサム毛ミスミクム ミソミセムミクミサミーミスム +$ ENAMETOOLONG +63 ミミシ'ム ムミーミケミサム ミスミーミエムひセ ミエミセミイミウミオ +$ EHOSTDOWN +64 ミ・ミセムム ミスミオ ミソムミームム紗 +$ EHOSTUNREACH +65 ミ・ミセムム ミスミオミエミセムム紹カミスミクミケ +$ ENOTEMPTY +66 ミ墟ームひーミサミセミウ ミスミオ ミソミセムミセミカミスム孟ケ +$ EPROCLIM +67 ミ厘ーミアミーミウミームひセ ミソムミセムミオムム孟イ +$ EUSERS +68 ミ厘ーミアミーミウミームひセ ミコミセムミクムムびσイミームム孟イ +$ EDQUOT +69 ミ渙オムミオミイミクム禍オミスミー ミエミクムミコミセミイミー ミコミイミセムひー +$ ESTALE +70 ミ厘ームムひームム孟サミクミケ ミエミオムミコムミクミソムひセム ムミーミケミサム NFS +$ EREMOTE +71 ミ柘孟エミエミーミサミオミスミクミケ ミセミア'ム頒コム +$ EBADRPC +72 ミ渙セミウミーミスミー ムムびムσコムびτミー RPC +$ ERPCMISMATCH +73 ミ斷オミイム毛ミスミー ミイミオムムム毛 RPC +$ EPROGUNAVAIL +74 ミ湲ミセミウムミーミシミー RPC ミスミオミエミセムム紹カミスミー +$ EPROGMISMATCH +75 ミ斷オミイム毛ミスミー ミイミオムムム毛 ミソムミセミウムミーミシミク +$ EPROCUNAVAIL +76 ミ渙セミウミーミスミー ミソムミセムミオミエムτミー ミエミサム ミソムミセミウムミーミシミク +$ ENOLCK +77 ミ岱サミセミコムσイミーミスミスム ミスミオ ミエミセムムびσソミスミオ +$ ENOSYS +78 ミ、ムσスミコムム毛 ミスミオ ムミオミーミサム孟キミセミイミーミスミセ +$ EFTYPE +79 ミ斷オミソムミクミエミームひスミクミケ ムひクミソ ムミク ムミセムミシミーム ムミーミケミサム +$ EAUTH +80 ミ渙セミシミクミサミコミー ミームτひオミスムひクムム孟コミームム毛 +$ ENEEDAUTH +81 ミ渙セムびム孟アミスミー ミームτひオミスムひクムム孟コミームム毛 +$ EIDRM +82 ミミエミオミスムひクムム孟コミームひセム ミイミクミサムτミオミスミセ +$ ENOMSG +83 ミ斷オミシミーム ミソミセミイム孟エミセミシミサミオミスミスム ミアミーミカミーミスミセミウミセ ムひクミソム +$ EOVERFLOW +84 ミ厘ーミイミオミサミクミコミオ ミキミスミームミオミスミスム ミエミサム ムム糊セミウミセ ムひクミソム ミエミーミスミクム +$ ECANCELED +85 ミ榧ソミオムミームム毛 ムミコミームミセミイミーミスミセ +$ EILSEQ +86 ミ斷オミエミセミキミイミセミサミオミスミー ミソミセムミサム孟エミセミイミスム毛ムび ミアミーミケムび孟イ +$ ENOATTR +87 ミ績びミクミアムτ ミスミオ ミキミスミーミケミエミオミスミセ +$ EDOOFUS +88 ミ渙セミシミクミサミコミー ミソムミセミウムミーミシムσイミーミスミスム +$ EBADMSG +89 ミ渙セミウミーミスミクミケ ムミセムミシミーム ミソミセミイム孟エミセミシミサミオミスミスム +$ EMULTIHOP XXX +90 ミ。ミソムミセミアミー ミシムσサムび毛ミセミソム +$ ENOLINK +91 ミ慴オムミオミカミセミイミクミケ ミコミーミスミーミサ ムミセミキム毛ミイミーミスミセ +$ EPROTO +92 ミ渙セミシミクミサミコミー ミソムミセムひセミコミセミサム +$ ENOTCAPABLE +93 ミ慴セミカミサミクミイミセムムび ミスミオミエミセムムひームひスム +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 ミ柘孟エミコミサム紗ミオミスミスム +$ SIGINT +2 ミ渙オムミオムミクミイミーミスミスム +$ SIGQUIT +3 ミ漬クムム孟エ +$ SIGILL +4 ミ斷オミソムミクミソムτムひクミシミー ム孟スムムびムσコムム毛 +$ SIGTRAP +5 ミ渙ームムひコミー ムびミームムσイミーミスミスム +$ SIGABRT +6 ミ籍イミームム孟ケミスミオ ミキミーミイミオムム威オミスミスム +$ SIGEMT +7 ミ渙オムミオムミセミソミサミオミスミスム ミオミシムσサム糊セミイミーミスミセム ム孟スムムびムσコムム毛 +$ SIGFPE +8 ミ渙セミシミクミサミコミー ムミセミアミセムひク ミキ ミソミサミーミイミーム紗ミセム ミコムミーミソミコミセム +$ SIGKILL +9 ミ漬アミクムひセ +$ SIGBUS +10 ミ渙セミシミクミサミコミー ム威クミスミク +$ SIGSEGV +11 ミ渙セムムτ威オミスミスム ムミオミウミシミオミスムひームム毛 +$ SIGSYS +12 ミ渙セミウミーミスミクミケ ムミクムムひオミシミスミクミケ ミイミクミコミサミクミコ +$ SIGPIPE +13 ミ墟ーミスミーミサ ミキムムσケミスミセミイミーミスミセ +$ SIGALRM +14 ミ「ミーミケミシミオム ミイミクムミオムミソミーミスミセ +$ SIGTERM +15 ミ厘ーミイミオムム威オミスミスム +$ SIGURG +16 ミ斷オミイム孟エミコミサミーミエミスミクミケ ムムひーミス ミスミー ムミセミコミオムび +$ SIGSTOP +17 ミ湲ミクミキムσソミクミスミオミスミセ (ムミクミウミスミーミサ) +$ SIGTSTP +18 ミ湲ミクミキムσソミクミスミオミスミセ +$ SIGCONT +19 ミ湲ミセミエミセミイミカミオミスミスム ムミセミアミセムひク +$ SIGCHLD +20 ミ厘シム孟スミー ムムひームびτム ミエミセムム毛ミスム糊セミウミセ ミソムミセムミオムム +$ SIGTTIN +21 ミ林σソミクミスミオミスミセ (ミイミイム孟エ ミキ ムひオムミシム孟スミーミサム) +$ SIGTTOU +22 ミ林σソミクミスミオミスミセ (ミイミクミイム孟エ ミスミー ムひオムミシム孟スミーミサ) +$ SIGIO +23 ミ漬イム孟エ-ミイミクミイム孟エ ミシミセミカミサミクミイミクミケ +$ SIGXCPU +24 ミ渙オムミオミイミクム禍オミスミセ ミサム孟シム毛 ミソムミセムミオムミセムミスミセミウミセ ムミームム +$ SIGXFSZ +25 ミ渙オムミオミイミクム禍オミスミセ ミサム孟シム毛 ミシミーミコムミクミシミーミサム糊スミセミウミセ ムミセミキミシム毛ム ムミーミケミサミー +$ SIGVTALRM +26 ミ柘毛ムびσーミサム糊スミクミケ ムひーミケミシミオム ミイミクムミオムミソミーミスミセ +$ SIGPROF +27 ミ「ミーミケミシミオム ミソムミセムム孟サム社イミーミスミスム ミイミクムミオムミソミーミスミセ +$ SIGWINCH +28 ミミセミキミシム毛 ミイム孟コミスミー ミキミシム孟スミオミスミセ +$ SIGINFO +29 ミ厘ーミソミクム ム孟スムミセムミシミームム毛 +$ SIGUSR1 +30 ミ。ミクミウミスミーミサ ミコミセムミクムムびσイミームミー 1 +$ SIGUSR2 +31 ミ。ミクミウミスミーミサ ミコミセムミクムムびσイミームミー 2 From 36ba9f409d639b3adcd1d2ab9672764f86f76d6b Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 8 Nov 2009 14:02:54 +0000 Subject: [PATCH 567/646] Fix a copy+paste error by checking the correct variable against MM_NULLACT. PR: 140386 Submitted by: soulcatcher Date: Sun, 8 Nov 2009 14:33:19 +0000 Subject: [PATCH 568/646] Introduce define and kernel option ATA_REQUEST_TIMEOUT to control ATA(4) command timeout. Submitted by: keramida --- sys/conf/NOTES | 3 +++ sys/conf/options | 1 + sys/dev/ata/ata-all.h | 4 ++++ sys/dev/ata/ata-disk.c | 10 +++++----- sys/dev/ata/ata-queue.c | 6 +++--- sys/dev/ata/ata-raid.c | 6 +++--- sys/dev/ata/atapi-cd.c | 2 +- 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 71115808ccf..7c4208d7cfc 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1715,8 +1715,11 @@ hint.ata.1.irq="15" # # ATA_STATIC_ID: controller numbering is static ie depends on location # else the device numbers are dynamically allocated. +# ATA_REQUEST_TIMEOUT: the number of seconds to wait for an ATA request +# before timing out. options ATA_STATIC_ID +#options ATA_REQUEST_TIMEOUT=10 # # Standard floppy disk controllers and floppy tapes, supports diff --git a/sys/conf/options b/sys/conf/options index b1e62c33d09..5c146c8765f 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -350,6 +350,7 @@ ISCSI_INITIATOR_DEBUG opt_iscsi_initiator.h # Options used in the 'ata' ATA/ATAPI driver ATA_STATIC_ID opt_ata.h ATA_NOPCI opt_ata.h +ATA_REQUEST_TIMEOUT opt_ata.h # Net stuff. ACCEPT_FILTER_DATA diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 2bc89369159..f832505f36b 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -345,6 +345,10 @@ struct ata_ahci_cmd_list { #define ATA_OP_FINISHED 1 #define ATA_MAX_28BIT_LBA 268435455UL +#ifndef ATA_REQUEST_TIMEOUT +#define ATA_REQUEST_TIMEOUT 10 +#endif + /* structure used for composite atomic operations */ #define MAX_COMPOSITES 32 /* u_int32_t bits */ struct ata_composite { diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 58f2245aa0b..22be3543c7d 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -230,7 +230,7 @@ ad_spindown(void *priv) } request->dev = dev; request->flags = ATA_R_CONTROL; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 1; request->callback = ad_power_callback; request->u.ata.command = ATA_STANDBY_IMMEDIATE; @@ -262,10 +262,10 @@ ad_strategy(struct bio *bp) if (atadev->spindown_state) { device_printf(dev, "request while spun down, starting.\n"); atadev->spindown_state = 0; - request->timeout = 31; + request->timeout = MAX(ATA_REQUEST_TIMEOUT, 31); } else { - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; } request->retries = 2; request->data = bp->bio_data; @@ -468,7 +468,7 @@ ad_set_geometry(device_t dev) request->u.ata.count = 0; request->u.ata.feature = 0; request->flags = ATA_R_CONTROL | ATA_R_QUIET; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 0; ata_queue_request(request); if (request->status & ATA_S_ERROR) @@ -487,7 +487,7 @@ ad_set_geometry(device_t dev) request->u.ata.count = 1; request->u.ata.feature = 0; request->flags = ATA_R_CONTROL; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 0; ata_queue_request(request); if (request->status & ATA_S_ERROR) diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index eeb7a1a4805..c0487787144 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -141,9 +141,9 @@ ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, if (atadev->spindown_state) { device_printf(dev, "request while spun down, starting.\n"); atadev->spindown_state = 0; - request->timeout = 31; + request->timeout = MAX(ATA_REQUEST_TIMEOUT, 31); } else { - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; } request->retries = 0; ata_queue_request(request); @@ -397,7 +397,7 @@ ata_completed(void *context, int dummy) request->bytecount = sizeof(struct atapi_sense); request->donecount = 0; request->transfersize = sizeof(struct atapi_sense); - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->flags &= (ATA_R_ATAPI | ATA_R_QUIET | ATA_R_DEBUG); request->flags |= (ATA_R_READ | ATA_R_AT_HEAD | ATA_R_REQUEUE); ATA_DEBUG_RQ(request, "autoissue request sense"); diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index a88284bc3ec..7bc88b51e5f 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -273,7 +273,7 @@ ata_raid_flush(struct bio *bp) request->u.ata.lba = 0; request->u.ata.count = 0; request->u.ata.feature = 0; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 0; request->flags |= ATA_R_ORDERED | ATA_R_DIRECT; ata_queue_request(request); @@ -4371,7 +4371,7 @@ ata_raid_init_request(device_t dev, struct ar_softc *rdp, struct bio *bio) return NULL; } request->dev = dev; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 2; request->callback = ata_raid_done; request->driver = rdp; @@ -4445,7 +4445,7 @@ ata_raid_rw(device_t dev, u_int64_t lba, void *data, u_int bcount, int flags) /* setup request */ request->dev = dev; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; request->retries = 0; request->data = data; request->bytecount = bcount; diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 7e23db6956e..a021e005492 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -700,7 +700,7 @@ acd_geom_access(struct g_provider *pp, int dr, int dw, int de) request->dev = dev; bcopy(ccb, request->u.atapi.ccb, 16); request->flags = ATA_R_ATAPI; - request->timeout = 10; + request->timeout = ATA_REQUEST_TIMEOUT; ata_queue_request(request); if (!request->error && (request->u.atapi.sense.key == 2 || From f9917533212e10a3dea23dbd65f95398be6dd889 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 8 Nov 2009 19:02:13 +0000 Subject: [PATCH 569/646] Add a check for the connection being shut down to the krpc client just before queuing a request for the connection. The code already had a check for the connection being shut down while the request was queued, but not one for the shut down having been initiated by the server before the request was in the queue. This appears to fix the problem of slow reconnects against an NFS server that drops inactive connections reported by Olaf Seibert, but does not fix the case where the FreeBSD client generates RST segments at about the same time as ACKs. This is still a problem that is being investigated. This patch does not cause a regression for this case. Tested by: Olaf Seibert, Daniel Braniss Reviewed by: dfr MFC after: 5 days --- sys/rpc/clnt_vc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index 85e89abe5c3..2e5fe41f1b9 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -413,6 +413,22 @@ call_again: cr->cr_xid = xid; mtx_lock(&ct->ct_lock); + /* + * Check to see if the other end has already started to close down + * the connection. The upcall will have set ct_error.re_status + * to RPC_CANTRECV if this is the case. + * If the other end starts to close down the connection after this + * point, it will be detected later when cr_error is checked, + * since the request is in the ct_pending queue. + */ + if (ct->ct_error.re_status == RPC_CANTRECV) { + if (errp != &ct->ct_error) { + errp->re_errno = ct->ct_error.re_errno; + errp->re_status = RPC_CANTRECV; + } + stat = RPC_CANTRECV; + goto out; + } TAILQ_INSERT_TAIL(&ct->ct_pending, cr, cr_link); mtx_unlock(&ct->ct_lock); From f5a034f95a3eb1e4c66310499d671929d89b3b43 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 8 Nov 2009 19:59:54 +0000 Subject: [PATCH 570/646] Partially revert r199035. Revision 1.158 says only lower ten bits of BGE_RXLP_LOCSTAT_IFIN_DROPS register is valid. For BCM5761 case it seems the controller maintains 16bits value for the register. However 16bits are still too small to count all dropped packets happened in a second. To get a correct counter we have to read the register in bge_rxeof() which would be too expensive. Pointed out by: bde --- sys/dev/bge/if_bge.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index f2352a968ff..c0ef5dc1971 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3289,6 +3289,14 @@ bge_rxeof(struct bge_softc *sc) bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); if (jumbocnt) bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); +#ifdef notyet + /* + * This register wraps very quickly under heavy packet drops. + * If you need correct statistics, you can enable this check. + */ + if (BGE_IS_5705_PLUS(sc)) + ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); +#endif return (rx_npkts); } From ccef4ddf40fee777575fe227405159a2b6d11dee Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 20:03:52 +0000 Subject: [PATCH 571/646] - fix refcounting error during data transfer - fix a memory leak on the USB backend - fix invalid pointer computations (in one case memory outside the allocated area was written in LibUSB v1.0) - make sure memory is always initialised, also in failing cases - add missing functions from v1.0.4 PR: usb/140325 Reported by: Robert Jenssen Submitted by: Hans Petter Selasky MFC After: 3 days --- lib/libusb/libusb.h | 37 ++++++-- lib/libusb/libusb10.c | 26 +++++- lib/libusb/libusb10_desc.c | 34 ++++--- lib/libusb/libusb10_io.c | 172 +++++++++++++++++++++++++++++++++-- lib/libusb/libusb20.c | 8 +- lib/libusb/libusb20_desc.c | 3 + lib/libusb/libusb20_ugen20.c | 6 ++ 7 files changed, 251 insertions(+), 35 deletions(-) diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index f65b57a5039..bdf281265dd 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -271,9 +271,11 @@ typedef struct libusb_control_setup { uint16_t wLength; } libusb_control_setup; +#define LIBUSB_CONTROL_SETUP_SIZE 8 /* bytes */ + typedef struct libusb_iso_packet_descriptor { - unsigned int length; - unsigned int actual_length; + uint32_t length; + uint32_t actual_length; enum libusb_transfer_status status; } libusb_iso_packet_descriptor __aligned(sizeof(void *)); @@ -282,9 +284,9 @@ typedef void (*libusb_transfer_cb_fn) (struct libusb_transfer *transfer); typedef struct libusb_transfer { libusb_device_handle *dev_handle; uint8_t flags; - unsigned int endpoint; + uint32_t endpoint; uint8_t type; - unsigned int timeout; + uint32_t timeout; enum libusb_transfer_status status; int length; int actual_length; @@ -320,7 +322,7 @@ int libusb_get_configuration(libusb_device_handle * devh, int *config); int libusb_set_configuration(libusb_device_handle * devh, int configuration); int libusb_claim_interface(libusb_device_handle * devh, int interface_number); int libusb_release_interface(libusb_device_handle * devh, int interface_number); -int libusb_reset_device(libusb_device_handle * dev); +int libusb_reset_device(libusb_device_handle * devh); int libusb_kernel_driver_active(libusb_device_handle * devh, int interface); int libusb_detach_kernel_driver(libusb_device_handle * devh, int interface); int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface); @@ -333,7 +335,8 @@ int libusb_get_active_config_descriptor(libusb_device * dev, struct libusb_confi int libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index, struct libusb_config_descriptor **config); int libusb_get_config_descriptor_by_value(libusb_device * dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config); void libusb_free_config_descriptor(struct libusb_config_descriptor *config); -int libusb_get_string_descriptor_ascii(libusb_device_handle * dev, uint8_t desc_index, uint8_t *data, int length); +int libusb_get_string_descriptor_ascii(libusb_device_handle * devh, uint8_t desc_index, uint8_t *data, int length); +int libusb_get_descriptor(libusb_device_handle * devh, uint8_t desc_type, uint8_t desc_index, uint8_t *data, int length); /* Asynchronous device I/O */ @@ -341,7 +344,16 @@ struct libusb_transfer *libusb_alloc_transfer(int iso_packets); void libusb_free_transfer(struct libusb_transfer *transfer); int libusb_submit_transfer(struct libusb_transfer *transfer); int libusb_cancel_transfer(struct libusb_transfer *transfer); -uint8_t *libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, unsigned int packet); +uint8_t *libusb_get_iso_packet_buffer(struct libusb_transfer *transfer, uint32_t index); +uint8_t *libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, uint32_t index); +void libusb_set_iso_packet_lengths(struct libusb_transfer *transfer, uint32_t length); +uint8_t *libusb_control_transfer_get_data(struct libusb_transfer *transfer); +struct libusb_control_setup *libusb_control_transfer_get_setup(struct libusb_transfer *transfer); +void libusb_fill_control_setup(uint8_t *buf, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength); +void libusb_fill_control_transfer(struct libusb_transfer *transfer, libusb_device_handle *devh, uint8_t *buf, libusb_transfer_cb_fn callback, void *user_data, uint32_t timeout); +void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, int length, libusb_transfer_cb_fn callback, void *user_data, uint32_t timeout); +void libusb_fill_interrupt_transfer(struct libusb_transfer *transfer, libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, int length, libusb_transfer_cb_fn callback, void *user_data, uint32_t timeout); +void libusb_fill_iso_transfer(struct libusb_transfer *transfer, libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, int length, int npacket, libusb_transfer_cb_fn callback, void *user_data, uint32_t timeout); /* Polling and timing */ @@ -362,9 +374,14 @@ struct libusb_pollfd **libusb_get_pollfds(libusb_context * ctx); /* Synchronous device I/O */ -int libusb_control_transfer(libusb_device_handle * devh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength, unsigned int timeout); -int libusb_bulk_transfer(libusb_device_handle *devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, unsigned int timeout); -int libusb_interrupt_transfer(libusb_device_handle *devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, unsigned int timeout); +int libusb_control_transfer(libusb_device_handle * devh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength, uint32_t timeout); +int libusb_bulk_transfer(libusb_device_handle * devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, uint32_t timeout); +int libusb_interrupt_transfer(libusb_device_handle * devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, uint32_t timeout); + +/* Byte-order */ + +uint16_t libusb_cpu_to_le16(uint16_t x); +uint16_t libusb_le16_to_cpu(uint16_t x); #if 0 { /* indent fix */ diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index fa9130d7e53..55ee1c509e7 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "libusb20.h" #include "libusb20_desc.h" @@ -185,8 +186,6 @@ libusb_get_device_list(libusb_context *ctx, libusb_device ***list) /* create libusb v1.0 compliant devices */ i = 0; while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { - /* get device into libUSB v1.0 list */ - libusb20_be_dequeue_device(usb_backend, pdev); dev = malloc(sizeof(*dev)); if (dev == NULL) { @@ -199,6 +198,10 @@ libusb_get_device_list(libusb_context *ctx, libusb_device ***list) libusb20_be_free(usb_backend); return (LIBUSB_ERROR_NO_MEM); } + + /* get device into libUSB v1.0 list */ + libusb20_be_dequeue_device(usb_backend, pdev); + memset(dev, 0, sizeof(*dev)); /* init transfer queues */ @@ -416,6 +419,8 @@ libusb_close(struct libusb20_device *pdev) libusb10_remove_pollfd(ctx, &dev->dev_poll); libusb20_dev_close(pdev); + + /* unref will free the "pdev" when the refcount reaches zero */ libusb_unref_device(dev); /* make sure our event loop detects the closed device */ @@ -1195,7 +1200,7 @@ libusb_submit_transfer(struct libusb_transfer *uxfer) struct libusb20_transfer *pxfer1; struct libusb_super_transfer *sxfer; struct libusb_device *dev; - unsigned int endpoint; + uint32_t endpoint; int err; if (uxfer == NULL) @@ -1252,7 +1257,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer) struct libusb20_transfer *pxfer1; struct libusb_super_transfer *sxfer; struct libusb_device *dev; - unsigned int endpoint; + uint32_t endpoint; if (uxfer == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -1312,3 +1317,16 @@ libusb10_cancel_all_transfer(libusb_device *dev) { /* TODO */ } + +uint16_t +libusb_cpu_to_le16(uint16_t x) +{ + return (htole16(x)); +} + +uint16_t +libusb_le16_to_cpu(uint16_t x) +{ + return (le16toh(x)); +} + diff --git a/lib/libusb/libusb10_desc.c b/lib/libusb/libusb10_desc.c index c43443af939..0215bceef00 100644 --- a/lib/libusb/libusb10_desc.c +++ b/lib/libusb/libusb10_desc.c @@ -35,6 +35,8 @@ #include "libusb.h" #include "libusb10.h" +#define N_ALIGN(n) (-((-(n)) & (-8UL))) + /* USB descriptors */ int @@ -114,17 +116,17 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, nalt = nif = pconf->num_interface; nep = 0; - nextra = pconf->extra.len; + nextra = N_ALIGN(pconf->extra.len); for (i = 0; i < nif; i++) { pinf = pconf->interface + i; - nextra += pinf->extra.len; + nextra += N_ALIGN(pinf->extra.len); nep += pinf->num_endpoints; k = pinf->num_endpoints; pend = pinf->endpoints; while (k--) { - nextra += pend->extra.len; + nextra += N_ALIGN(pend->extra.len); pend++; } @@ -132,12 +134,12 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, nalt += pinf->num_altsetting; pinf = pinf->altsetting; while (j--) { - nextra += pinf->extra.len; + nextra += N_ALIGN(pinf->extra.len); nep += pinf->num_endpoints; k = pinf->num_endpoints; pend = pinf->endpoints; while (k--) { - nextra += pend->extra.len; + nextra += N_ALIGN(pend->extra.len); pend++; } pinf++; @@ -150,17 +152,18 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, (nalt * sizeof(libusb_interface_descriptor)) + (nep * sizeof(libusb_endpoint_descriptor)); + nextra = N_ALIGN(nextra); + pconfd = malloc(nextra); if (pconfd == NULL) { free(pconf); return (LIBUSB_ERROR_NO_MEM); } - /* make sure memory is clean */ + /* make sure memory is initialised */ memset(pconfd, 0, nextra); - pconfd->interface = (libusb_interface *) (pconfd + - sizeof(libusb_config_descriptor)); + pconfd->interface = (libusb_interface *) (pconfd + 1); ifd = (libusb_interface_descriptor *) (pconfd->interface + nif); endd = (libusb_endpoint_descriptor *) (ifd + nalt); @@ -181,7 +184,7 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, pconfd->extra_length = pconf->extra.len; pconfd->extra = pextra; memcpy(pextra, pconf->extra.ptr, pconfd->extra_length); - pextra += pconfd->extra_length; + pextra += N_ALIGN(pconfd->extra_length); } /* setup all interface and endpoint pointers */ @@ -221,7 +224,7 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, ifd->extra_length = pinf->extra.len; ifd->extra = pextra; memcpy(pextra, pinf->extra.ptr, pinf->extra.len); - pextra += pinf->extra.len; + pextra += N_ALIGN(pinf->extra.len); } for (k = 0; k < pinf->num_endpoints; k++) { pend = &pinf->endpoints[k]; @@ -238,7 +241,7 @@ libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, endd->extra_length = pend->extra.len; endd->extra = pextra; memcpy(pextra, pend->extra.ptr, pend->extra.len); - pextra += pend->extra.len; + pextra += N_ALIGN(pend->extra.len); } } } @@ -304,3 +307,12 @@ libusb_get_string_descriptor_ascii(libusb_device_handle *pdev, return (LIBUSB_ERROR_OTHER); } + +int +libusb_get_descriptor(libusb_device_handle * devh, uint8_t desc_type, + uint8_t desc_index, uint8_t *data, int length) +{ + return (libusb_control_transfer(devh, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (desc_type << 8) | desc_index, 0, data, + length, 1000)); +} diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c index a5bb85fc528..3d6daefbc24 100644 --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "libusb20.h" #include "libusb20_desc.h" @@ -148,19 +149,19 @@ libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv) goto do_done; } for (i = 0; i != nfds; i++) { - if (fds[i].revents == 0) - continue; if (ppdev[i] != NULL) { dev = libusb_get_device(ppdev[i]); - err = libusb20_dev_process(ppdev[i]); + if (fds[i].revents == 0) + err = 0; /* nothing to do */ + else + err = libusb20_dev_process(ppdev[i]); + if (err) { /* cancel all transfers - device is gone */ libusb10_cancel_all_transfer(dev); - /* - * make sure we don't go into an infinite - * loop - */ + + /* remove USB device from polling loop */ libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); } CTX_UNLOCK(ctx); @@ -573,3 +574,160 @@ libusb_interrupt_transfer(libusb_device_handle *devh, DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave"); return (ret); } + +uint8_t * +libusb_get_iso_packet_buffer(struct libusb_transfer *transfer, uint32_t index) +{ + uint8_t *ptr; + uint32_t n; + + if (transfer->num_iso_packets < 0) + return (NULL); + + if (index >= (uint32_t)transfer->num_iso_packets) + return (NULL); + + ptr = transfer->buffer; + if (ptr == NULL) + return (NULL); + + for (n = 0; n != index; n++) { + ptr += transfer->iso_packet_desc[n].length; + } + return (ptr); +} + +uint8_t * +libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, uint32_t index) +{ + uint8_t *ptr; + + if (transfer->num_iso_packets < 0) + return (NULL); + + if (index >= (uint32_t)transfer->num_iso_packets) + return (NULL); + + ptr = transfer->buffer; + if (ptr == NULL) + return (NULL); + + ptr += transfer->iso_packet_desc[0].length * index; + + return (ptr); +} + +void +libusb_set_iso_packet_lengths(struct libusb_transfer *transfer, uint32_t length) +{ + int n; + + if (transfer->num_iso_packets < 0) + return; + + for (n = 0; n != transfer->num_iso_packets; n++) + transfer->iso_packet_desc[n].length = length; +} + +uint8_t * +libusb_control_transfer_get_data(struct libusb_transfer *transfer) +{ + if (transfer->buffer == NULL) + return (NULL); + + return (transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE); +} + +struct libusb_control_setup * +libusb_control_transfer_get_setup(struct libusb_transfer *transfer) +{ + return ((struct libusb_control_setup *)transfer->buffer); +} + +void +libusb_fill_control_setup(uint8_t *buf, uint8_t bmRequestType, + uint8_t bRequest, uint16_t wValue, + uint16_t wIndex, uint16_t wLength) +{ + struct libusb_control_setup *req = (struct libusb_control_setup *)buf; + + /* The alignment is OK for all fields below. */ + req->bmRequestType = bmRequestType; + req->bRequest = bRequest; + req->wValue = htole16(wValue); + req->wIndex = htole16(wIndex); + req->wLength = htole16(wLength); +} + +void +libusb_fill_control_transfer(struct libusb_transfer *transfer, + libusb_device_handle *devh, uint8_t *buf, + libusb_transfer_cb_fn callback, void *user_data, + uint32_t timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)buf; + + transfer->dev_handle = devh; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buf; + if (setup != NULL) + transfer->length = LIBUSB_CONTROL_SETUP_SIZE + + le16toh(setup->wLength); + else + transfer->length = 0; + transfer->user_data = user_data; + transfer->callback = callback; + +} + +void +libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, + int length, libusb_transfer_cb_fn callback, void *user_data, + uint32_t timeout) +{ + transfer->dev_handle = devh; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buf; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +void +libusb_fill_interrupt_transfer(struct libusb_transfer *transfer, + libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, + int length, libusb_transfer_cb_fn callback, void *user_data, + uint32_t timeout) +{ + transfer->dev_handle = devh; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buf; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +void +libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, + int length, int npacket, libusb_transfer_cb_fn callback, + void *user_data, uint32_t timeout) +{ + transfer->dev_handle = devh; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buf; + transfer->length = length; + transfer->num_iso_packets = npacket; + transfer->user_data = user_data; + transfer->callback = callback; +} + diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c index 6e0ec476f3d..1a338052c93 100644 --- a/lib/libusb/libusb20.c +++ b/lib/libusb/libusb20.c @@ -630,6 +630,9 @@ libusb20_dev_req_string_sync(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED req; int error; + /* make sure memory is initialised */ + memset(ptr, 0, len); + if (len < 4) { /* invalid length */ return (LIBUSB20_ERROR_INVALID_PARAM); @@ -1093,7 +1096,8 @@ libusb20_be_free(struct libusb20_backend *pbe) if (pbe->methods->exit_backend) { pbe->methods->exit_backend(pbe); } - return; + /* free backend */ + free(pbe); } void @@ -1101,7 +1105,6 @@ libusb20_be_enqueue_device(struct libusb20_backend *pbe, struct libusb20_device { pdev->beMethods = pbe->methods; /* copy backend methods */ TAILQ_INSERT_TAIL(&(pbe->usb_devs), pdev, dev_entry); - return; } void @@ -1109,5 +1112,4 @@ libusb20_be_dequeue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev) { TAILQ_REMOVE(&(pbe->usb_devs), pdev, dev_entry); - return; } diff --git a/lib/libusb/libusb20_desc.c b/lib/libusb/libusb20_desc.c index e0d2c54b908..5206cf45757 100644 --- a/lib/libusb/libusb20_desc.c +++ b/lib/libusb/libusb20_desc.c @@ -118,6 +118,9 @@ libusb20_parse_config_desc(const void *config_desc) if (lub_config == NULL) { return (NULL); /* out of memory */ } + /* make sure memory is initialised */ + memset(lub_config, 0, size); + lub_interface = (void *)(lub_config + 1); lub_alt_interface = (void *)(lub_interface + niface_no_alt); lub_endpoint = (void *)(lub_interface + niface); diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c index f9f36891a03..efcca63a209 100644 --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -449,6 +449,8 @@ ugen20_get_config_desc_full(struct libusb20_device *pdev, uint16_t len; int error; + /* make sure memory is initialised */ + memset(&cdesc, 0, sizeof(cdesc)); memset(&gen_desc, 0, sizeof(gen_desc)); gen_desc.ugd_data = &cdesc; @@ -468,6 +470,10 @@ ugen20_get_config_desc_full(struct libusb20_device *pdev, if (!ptr) { return (LIBUSB20_ERROR_NO_MEM); } + + /* make sure memory is initialised */ + memset(ptr, 0, len); + gen_desc.ugd_data = ptr; gen_desc.ugd_maxlen = len; From 10454ab70026cb1bda81b839cad4ca5d4693835c Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 20:44:55 +0000 Subject: [PATCH 572/646] ehci_init() will do reset and set the usbrev flag. Fix problem where ehci_reset() was called before ehci_init(). PR: usb/140242 Submitted by: Sebastian Huber --- sys/dev/usb/controller/ehci_ixp4xx.c | 3 --- sys/dev/usb/controller/ehci_mbus.c | 2 -- sys/dev/usb/controller/ehci_pci.c | 4 +--- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sys/dev/usb/controller/ehci_ixp4xx.c b/sys/dev/usb/controller/ehci_ixp4xx.c index 9f866149c14..3a2b6e46e56 100644 --- a/sys/dev/usb/controller/ehci_ixp4xx.c +++ b/sys/dev/usb/controller/ehci_ixp4xx.c @@ -157,8 +157,6 @@ ehci_ixp_attach(device_t self) return (ENOMEM); } - sc->sc_bus.usbrev = USB_REV_2_0; - /* NB: hints fix the memory location and irq */ rid = 0; @@ -230,7 +228,6 @@ ehci_ixp_attach(device_t self) | EHCI_SCFLG_BIGEMMIO | EHCI_SCFLG_NORESTERM ; - (void) ehci_reset(sc); err = ehci_init(sc); if (!err) { diff --git a/sys/dev/usb/controller/ehci_mbus.c b/sys/dev/usb/controller/ehci_mbus.c index d3c0f4c45aa..368e3e57494 100644 --- a/sys/dev/usb/controller/ehci_mbus.c +++ b/sys/dev/usb/controller/ehci_mbus.c @@ -166,8 +166,6 @@ ehci_mbus_attach(device_t self) return (ENOMEM); } - sc->sc_bus.usbrev = USB_REV_2_0; - rid = 0; sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_io_res) { diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c index fc2035bd297..d1440c10259 100644 --- a/sys/dev/usb/controller/ehci_pci.c +++ b/sys/dev/usb/controller/ehci_pci.c @@ -318,13 +318,11 @@ ehci_pci_attach(device_t self) device_printf(self, "pre-2.0 USB revision (ignored)\n"); /* fallthrough */ case PCI_USB_REV_2_0: - sc->sc_bus.usbrev = USB_REV_2_0; break; default: /* Quirk for Parallels Desktop 4.0 */ device_printf(self, "USB revision is unknown. Assuming v2.0.\n"); - sc->sc_bus.usbrev = USB_REV_2_0; - break; + break; } rid = PCI_CBMEM; From 30b22abe403bbdfaff8d284da85a60352c71a47d Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 20:51:15 +0000 Subject: [PATCH 573/646] Integrate lost interrupts patch from the old USB stack. Some EHCI chips from VIA / ATI seem to trigger interrupts before writing back the qTD status, or miss signalling occasionally under heavy load. If the host machine is too fast, we can miss transaction completion - when we scan the active list the transaction still seems to be active. This generally exhibits itself as a umass stall that never recovers. We work around this behaviour by setting up this callback after any softintr that completes with transactions still pending, giving us another chance to check for completion after the writeback has taken place Submitted by: Alexander Nedotsuko MFC after: 3 days --- sys/dev/usb/controller/ehci.c | 40 +++++++++++++++++++++++++++---- sys/dev/usb/controller/ehci.h | 2 ++ sys/dev/usb/controller/ehci_pci.c | 13 ++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 42b78c360a6..28be7ab6326 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -113,10 +113,12 @@ extern struct usb_pipe_methods ehci_device_intr_methods; extern struct usb_pipe_methods ehci_device_isoc_fs_methods; extern struct usb_pipe_methods ehci_device_isoc_hs_methods; -static void ehci_do_poll(struct usb_bus *bus); -static void ehci_device_done(struct usb_xfer *xfer, usb_error_t error); -static uint8_t ehci_check_transfer(struct usb_xfer *xfer); -static void ehci_timeout(void *arg); +static void ehci_do_poll(struct usb_bus *); +static void ehci_device_done(struct usb_xfer *, usb_error_t); +static uint8_t ehci_check_transfer(struct usb_xfer *); +static void ehci_timeout(void *); +static void ehci_poll_timeout(void *); + static void ehci_root_intr(ehci_softc_t *sc); struct ehci_std_temp { @@ -243,6 +245,7 @@ ehci_init(ehci_softc_t *sc) DPRINTF("start\n"); usb_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0); + usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0); #if USB_DEBUG if (ehcidebug > 2) { @@ -520,6 +523,7 @@ ehci_detach(ehci_softc_t *sc) USB_BUS_LOCK(&sc->sc_bus); usb_callout_stop(&sc->sc_tmo_pcd); + usb_callout_stop(&sc->sc_tmo_poll); EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); USB_BUS_UNLOCK(&sc->sc_bus); @@ -532,6 +536,7 @@ ehci_detach(ehci_softc_t *sc) usb_pause_mtx(NULL, hz / 20); usb_callout_drain(&sc->sc_tmo_pcd); + usb_callout_drain(&sc->sc_tmo_poll); } void @@ -1472,6 +1477,28 @@ repeat: } } +/* + * Some EHCI chips from VIA / ATI seem to trigger interrupts before + * writing back the qTD status, or miss signalling occasionally under + * heavy load. If the host machine is too fast, we can miss + * transaction completion - when we scan the active list the + * transaction still seems to be active. This generally exhibits + * itself as a umass stall that never recovers. + * + * We work around this behaviour by setting up this callback after any + * softintr that completes with transactions still pending, giving us + * another chance to check for completion after the writeback has + * taken place. + */ +static void +ehci_poll_timeout(void *arg) +{ + ehci_softc_t *sc = arg; + + DPRINTFN(3, "\n"); + ehci_interrupt_poll(sc); +} + /*------------------------------------------------------------------------* * ehci_interrupt - EHCI interrupt handler * @@ -1539,6 +1566,11 @@ ehci_interrupt(ehci_softc_t *sc) /* poll all the USB transfers */ ehci_interrupt_poll(sc); + if (sc->sc_flags & EHCI_SCFLG_LOSTINTRBUG) { + usb_callout_reset(&sc->sc_tmo_poll, hz / 128, + (void *)&ehci_poll_timeout, sc); + } + done: USB_BUS_UNLOCK(&sc->sc_bus); } diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h index 32c08356a3b..a3d84063c84 100644 --- a/sys/dev/usb/controller/ehci.h +++ b/sys/dev/usb/controller/ehci.h @@ -321,6 +321,7 @@ typedef struct ehci_softc { struct ehci_hw_softc sc_hw; struct usb_bus sc_bus; /* base device */ struct usb_callout sc_tmo_pcd; + struct usb_callout sc_tmo_poll; union ehci_hub_desc sc_hub_desc; struct usb_device *sc_devices[EHCI_MAX_DEVICES]; @@ -348,6 +349,7 @@ typedef struct ehci_softc { #define EHCI_SCFLG_BIGEDESC 0x0008 /* big-endian byte order descriptors */ #define EHCI_SCFLG_BIGEMMIO 0x0010 /* big-endian byte order MMIO */ #define EHCI_SCFLG_TT 0x0020 /* transaction translator present */ +#define EHCI_SCFLG_LOSTINTRBUG 0x0040 /* workaround for VIA / ATI chipsets */ uint8_t sc_offs; /* offset to operational registers */ uint8_t sc_doorbell_disable; /* set on doorbell failure */ diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c index d1440c10259..ec6f3f73fce 100644 --- a/sys/dev/usb/controller/ehci_pci.c +++ b/sys/dev/usb/controller/ehci_pci.c @@ -439,6 +439,19 @@ ehci_pci_attach(device_t self) break; } + /* Dropped interrupts workaround */ + switch (pci_get_vendor(self)) { + case PCI_EHCI_VENDORID_ATI: + case PCI_EHCI_VENDORID_VIA: + sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG; + if (bootverbose) + device_printf(self, + "Dropped interrupts workaround enabled\n"); + break; + default: + break; + } + err = ehci_init(sc); if (!err) { err = device_probe_and_attach(sc->sc_bus.bdev); From 883bb300228d7c1741af6a79af154b7ecf3486e2 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 20:54:03 +0000 Subject: [PATCH 574/646] improve support for high speed isochronous endpoints which does not run 1:1, but needs intervalling 1:2, 1:4 or 1:8 Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/ehci.c | 93 +++++++++++++++++++++++++---------- sys/dev/usb/usb_core.h | 1 + sys/dev/usb/usb_transfer.c | 23 +++++++++ sys/dev/usb/usbdi.h | 1 + 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 28be7ab6326..5cc9b29aea7 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -2140,7 +2140,7 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer) DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n", xfer, xfer->endpoint); - while (nframes--) { + while (nframes) { if (td == NULL) { panic("%s:%d: out of TD's\n", __FUNCTION__, __LINE__); @@ -2162,21 +2162,26 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer) DPRINTFN(2, "status=0x%08x, len=%u\n", status, len); - if (*plen >= len) { - /* - * The length is valid. NOTE: The complete - * length is written back into the status - * field, and not the remainder like with - * other transfer descriptor types. - */ - } else { - /* Invalid length - truncate */ - len = 0; + if (xfer->usb_smask & (1 << td_no)) { + + if (*plen >= len) { + /* + * The length is valid. NOTE: The + * complete length is written back + * into the status field, and not the + * remainder like with other transfer + * descriptor types. + */ + } else { + /* Invalid length - truncate */ + len = 0; + } + + *plen = len; + plen++; + nframes--; } - *plen = len; - - plen++; td_no++; if ((td_no == 8) || (nframes == 0)) { @@ -2393,10 +2398,9 @@ static void ehci_device_intr_close(struct usb_xfer *xfer) { ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - uint8_t slot; - slot = usb_intr_schedule_adjust - (xfer->xroot->udev, -(xfer->max_frame_size), xfer->usb_uframe); + usb_intr_schedule_adjust(xfer->xroot->udev, + -(xfer->max_frame_size), xfer->usb_uframe); sc->sc_intr_stat[xfer->qh_pos]--; @@ -2722,6 +2726,28 @@ ehci_device_isoc_hs_open(struct usb_xfer *xfer) ehci_itd_t *td; uint32_t temp; uint8_t ds; + uint8_t slot; + + slot = usb_intr_schedule_adjust(xfer->xroot->udev, xfer->max_frame_size, + USB_HS_MICRO_FRAMES_MAX); + + xfer->usb_uframe = slot; + xfer->usb_cmask = 0; + + switch (usbd_xfer_get_fps_shift(xfer)) { + case 0: + xfer->usb_smask = 0xFF; + break; + case 1: + xfer->usb_smask = 0x55 << (slot & 1); + break; + case 2: + xfer->usb_smask = 0x11 << (slot & 3); + break; + default: + xfer->usb_smask = 0x01 << (slot & 7); + break; + } /* initialize all TD's */ @@ -2765,6 +2791,10 @@ ehci_device_isoc_hs_open(struct usb_xfer *xfer) static void ehci_device_isoc_hs_close(struct usb_xfer *xfer) { + + usb_intr_schedule_adjust(xfer->xroot->udev, + -(xfer->max_frame_size), xfer->usb_uframe); + ehci_device_done(xfer, USB_ERR_CANCELLED); } @@ -2854,7 +2884,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer) xfer->qh_pos = xfer->endpoint->isoc_next; - while (nframes--) { + while (nframes) { if (td == NULL) { panic("%s:%d: out of TD's\n", __FUNCTION__, __LINE__); @@ -2874,13 +2904,21 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer) #endif *plen = xfer->max_frame_size; } - status = (EHCI_ITD_SET_LEN(*plen) | - EHCI_ITD_ACTIVE | - EHCI_ITD_SET_PG(0)); - td->itd_status[td_no] = htohc32(sc, status); - itd_offset[td_no] = buf_offset; - buf_offset += *plen; - plen++; + + if (xfer->usb_smask & (1 << td_no)) { + status = (EHCI_ITD_SET_LEN(*plen) | + EHCI_ITD_ACTIVE | + EHCI_ITD_SET_PG(0)); + td->itd_status[td_no] = htohc32(sc, status); + itd_offset[td_no] = buf_offset; + buf_offset += *plen; + plen++; + nframes --; + } else { + td->itd_status[td_no] = 0; /* not active */ + itd_offset[td_no] = buf_offset; + } + td_no++; if ((td_no == 8) || (nframes == 0)) { @@ -2937,7 +2975,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer) } /* set IOC bit if we are complete */ if (nframes == 0) { - td->itd_status[7] |= htohc32(sc, EHCI_ITD_IOC); + td->itd_status[td_no - 1] |= htohc32(sc, EHCI_ITD_IOC); } usb_pc_cpu_flush(td->page_cache); #if USB_DEBUG @@ -3583,7 +3621,8 @@ ehci_xfer_setup(struct usb_setup_params *parm) usbd_transfer_setup_sub(parm); - nitd = (xfer->nframes + 7) / 8; + nitd = ((xfer->nframes + 7) / 8) << + usbd_xfer_get_fps_shift(xfer); } else { diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index a9d273d427f..7541adbc703 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -165,6 +165,7 @@ struct usb_xfer { uint8_t usb_cmask; uint8_t usb_uframe; uint8_t usb_state; + uint8_t fps_shift; /* down shift of FPS, 0..3 */ usb_error_t error; diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index bfb6430085f..4169ac8b5af 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -416,9 +416,15 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) case USB_SPEED_LOW: case USB_SPEED_FULL: frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER; + xfer->fps_shift = 0; break; default: frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER; + xfer->fps_shift = edesc->bInterval; + if (xfer->fps_shift > 0) + xfer->fps_shift--; + if (xfer->fps_shift > 3) + xfer->fps_shift = 3; break; } @@ -1826,6 +1832,23 @@ usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex) return (&xfer->frbuffers[frindex]); } +/*------------------------------------------------------------------------* + * usbd_xfer_get_fps_shift + * + * The following function is only useful for isochronous transfers. It + * returns how many times the frame execution rate has been shifted + * down. + * + * Return value: + * Success: 0..3 + * Failure: 0 + *------------------------------------------------------------------------*/ +uint8_t +usbd_xfer_get_fps_shift(struct usb_xfer *xfer) +{ + return (xfer->fps_shift); +} + usb_frlength_t usbd_xfer_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex) { diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 0042c97ccff..46747d7baf0 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -478,6 +478,7 @@ void usbd_xfer_set_frame_offset(struct usb_xfer *xfer, usb_frlength_t offset, usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer); usb_frlength_t usbd_xfer_max_framelen(struct usb_xfer *xfer); usb_frcount_t usbd_xfer_max_frames(struct usb_xfer *xfer); +uint8_t usbd_xfer_get_fps_shift(struct usb_xfer *xfer); usb_frlength_t usbd_xfer_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex); void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, From b029f6bb9561d7bf18d78e8f0e1baab6a7d58cb9 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 21:00:50 +0000 Subject: [PATCH 575/646] Improve support for High-speed USB audio devices. - fix issues regarding the mixer, where the interface number was not set in time. - fix wrong use of resolution parameter. Submitted by: Hans Petter Selasky --- sys/dev/sound/usb/uaudio.c | 241 ++++++++++++++++++------------------- 1 file changed, 120 insertions(+), 121 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index f5d47406391..2ac8766e828 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -105,10 +105,9 @@ SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RW, &uaudio_default_channels, 0, "uaudio default sample channels"); #endif -#define UAUDIO_MINFRAMES 16 /* must be factor of 8 due HS-USB */ +#define UAUDIO_NFRAMES 64 /* must be factor of 8 due HS-USB */ #define UAUDIO_NCHANBUFS 2 /* number of outstanding request */ #define UAUDIO_RECURSE_LIMIT 24 /* rounds */ -#define UAUDIO_MINFRAMES_ALIGN(x) ((x) & ~(UAUDIO_MINFRAMES - 1)) #define MAKE_WORD(h,l) (((h) << 8) | (l)) #define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1) @@ -119,7 +118,7 @@ struct uaudio_mixer_node { int32_t maxval; #define MIX_MAX_CHAN 8 int32_t wValue[MIX_MAX_CHAN]; /* using nchan */ - uint32_t delta; + uint32_t mod; /* modulus */ uint32_t mul; uint32_t ctl; @@ -169,7 +168,7 @@ struct uaudio_chan { * buffer */ uint32_t intr_size; /* in bytes */ - uint32_t block_size; + uint32_t intr_frames; /* in units */ uint32_t sample_rate; uint32_t format; uint32_t pcm_format[2]; @@ -410,7 +409,7 @@ static const struct usb_config .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ - .frames = UAUDIO_MINFRAMES, + .frames = UAUDIO_NFRAMES, .flags = {.short_xfer_ok = 1,}, .callback = &uaudio_chan_record_callback, }, @@ -420,7 +419,7 @@ static const struct usb_config .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ - .frames = UAUDIO_MINFRAMES, + .frames = UAUDIO_NFRAMES, .flags = {.short_xfer_ok = 1,}, .callback = &uaudio_chan_record_callback, }, @@ -433,7 +432,7 @@ static const struct usb_config .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ - .frames = UAUDIO_MINFRAMES, + .frames = UAUDIO_NFRAMES, .flags = {.short_xfer_ok = 1,}, .callback = &uaudio_chan_play_callback, }, @@ -443,7 +442,7 @@ static const struct usb_config .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ - .frames = UAUDIO_MINFRAMES, + .frames = UAUDIO_NFRAMES, .flags = {.short_xfer_ok = 1,}, .callback = &uaudio_chan_play_callback, }, @@ -506,7 +505,6 @@ static const struct usb_config .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(struct usb_device_request), - .flags = {}, .callback = &umidi_write_clear_stall_callback, .timeout = 1000, /* 1 second */ .interval = 50, /* 50ms */ @@ -517,7 +515,6 @@ static const struct usb_config .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(struct usb_device_request), - .flags = {}, .callback = &umidi_read_clear_stall_callback, .timeout = 1000, /* 1 second */ .interval = 50, /* 50ms */ @@ -577,6 +574,8 @@ uaudio_attach(device_t dev) sc->sc_play_chan.priv_sc = sc; sc->sc_rec_chan.priv_sc = sc; sc->sc_udev = uaa->device; + sc->sc_mixer_iface_index = uaa->info.bIfaceIndex; + sc->sc_mixer_iface_no = uaa->info.bIfaceNum; if (usb_test_quirk(uaa, UQ_AUDIO_SWAP_LR)) sc->sc_uq_audio_swap_lr = 1; @@ -600,9 +599,6 @@ uaudio_attach(device_t dev) uaudio_mixer_fill_info(sc, uaa->device, id); - sc->sc_mixer_iface_index = uaa->info.bIfaceIndex; - sc->sc_mixer_iface_no = uaa->info.bIfaceNum; - DPRINTF("audio rev %d.%02x\n", sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); @@ -1119,34 +1115,11 @@ done: * next audio transfer. */ static void -uaudio_setup_blockcount(struct uaudio_chan *ch, usb_frcount_t max_frames, +uaudio_setup_blockcount(struct uaudio_chan *ch, uint32_t *total, uint32_t *blockcount) { - uint32_t temp; - uint32_t isiz; - - /* allow dynamic sizing of play buffer */ - isiz = ch->intr_size; - - /* allow dynamic sizing of play buffer */ - temp = isiz / ch->bytes_per_frame; - - /* align units */ - temp = UAUDIO_MINFRAMES_ALIGN(temp); - - /* range check - min */ - if (temp == 0) - temp = UAUDIO_MINFRAMES; - - /* range check - max */ - if (temp > max_frames) - temp = max_frames; - - /* store blockcount */ - *blockcount = temp; - - /* compute the total length */ - *total = temp * ch->bytes_per_frame; + *total = ch->intr_size; + *blockcount = ch->intr_frames; } static void @@ -1162,8 +1135,12 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); - uaudio_setup_blockcount(ch, usbd_xfer_max_frames(xfer), - &total, &blockcount); + uaudio_setup_blockcount(ch, &total, &blockcount); + + if (ch->end == ch->start) { + DPRINTF("no buffer!\n"); + return; + } switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -1187,10 +1164,6 @@ tr_transferred: for (n = 0; n != blockcount; n++) usbd_xfer_set_frame_len(xfer, n, ch->bytes_per_frame); - if (ch->end == ch->start) { - DPRINTF("no buffer!\n"); - break; - } DPRINTFN(6, "transfer %d bytes\n", total); offset = 0; @@ -1235,17 +1208,23 @@ uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error) uint32_t blockcount; uint32_t offset0; uint32_t offset1; + uint32_t mfl; int len; - int actlen, nframes; + int actlen; + int nframes; usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes); + mfl = usbd_xfer_max_framelen(xfer); - uaudio_setup_blockcount(ch, usbd_xfer_max_frames(xfer), - &total, &blockcount); + uaudio_setup_blockcount(ch, &total, &blockcount); + + if (ch->end == ch->start) { + DPRINTF("no buffer!\n"); + return; + } switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: -tr_transferred: if (actlen < total) { DPRINTF("short transfer, " "%d of %d bytes\n", actlen, total); @@ -1254,11 +1233,11 @@ tr_transferred: } offset0 = 0; + pc = usbd_xfer_get_frame(xfer, 0); for (n = 0; n != nframes; n++) { offset1 = offset0; - pc = usbd_xfer_get_frame(xfer, 0); len = usbd_xfer_frame_len(xfer, n); while (len > 0) { @@ -1279,36 +1258,26 @@ tr_transferred: } } - offset0 += ch->bytes_per_frame; + offset0 += mfl; } chn_intr(ch->pcm_ch); case USB_ST_SETUP: - if (ch->bytes_per_frame > usbd_xfer_max_framelen(xfer)) { - DPRINTF("bytes per transfer, %d, " - "exceeds maximum, %d!\n", - ch->bytes_per_frame, - usbd_xfer_max_framelen(xfer)); - return; - } +tr_setup: usbd_xfer_set_frames(xfer, blockcount); for (n = 0; n < blockcount; n++) { - usbd_xfer_set_frame_len(xfer, n, ch->bytes_per_frame); + usbd_xfer_set_frame_len(xfer, n, mfl); } - if (ch->end == ch->start) { - DPRINTF("no buffer!\n"); - return; - } usbd_transfer_submit(xfer); - return; + break; default: /* Error */ if (error == USB_ERR_CANCELLED) { - return; + break; } - goto tr_transferred; + goto tr_setup; } } @@ -1319,38 +1288,26 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ? &sc->sc_play_chan : &sc->sc_rec_chan); uint32_t buf_size; + uint32_t frames; uint8_t endpoint; + uint8_t blocks; uint8_t iface_index; uint8_t alt_index; + uint8_t fps_shift; usb_error_t err; + if (usbd_get_isoc_fps(sc->sc_udev) < 8000) { + /* FULL speed USB */ + frames = 8; + } else { + /* HIGH speed USB */ + frames = UAUDIO_NFRAMES; + } + /* compute required buffer size */ - buf_size = (ch->bytes_per_frame * UAUDIO_MINFRAMES); - /* setup interrupt interval */ - ch->intr_size = buf_size; + buf_size = (ch->bytes_per_frame * frames); - /* double buffering */ - buf_size *= 2; - - ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO); - if (ch->buf == NULL) { - goto error; - } - if (sndbuf_setup(b, ch->buf, buf_size) != 0) { - goto error; - } - ch->start = ch->buf; - ch->end = ch->buf + buf_size; - ch->cur = ch->buf; - ch->pcm_ch = c; - ch->pcm_mtx = c->lock; - ch->pcm_buf = b; - - if (ch->pcm_mtx == NULL) { - DPRINTF("ERROR: PCM channels does not have a mutex!\n"); - goto error; - } /* setup play/record format */ ch->pcm_cap.fmtlist = ch->pcm_format; @@ -1370,7 +1327,6 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, ch->pcm_cap.fmtlist[1] = 0; - /* set alternate interface corresponding to the mode */ endpoint = ch->p_ed1->bEndpointAddress; @@ -1407,6 +1363,43 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, DPRINTF("could not allocate USB transfers!\n"); goto error; } + + fps_shift = usbd_xfer_get_fps_shift(ch->xfer[0]); + + /* setup frame sizes */ + ch->intr_size = buf_size; + ch->intr_frames = (frames >> fps_shift); + ch->bytes_per_frame <<= fps_shift; + + if (ch->intr_frames == 0) { + DPRINTF("frame shift is too high!\n"); + goto error; + } + + /* setup double buffering */ + buf_size *= 2; + blocks = 2; + + ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO); + if (ch->buf == NULL) + goto error; + if (sndbuf_setup(b, ch->buf, buf_size) != 0) + goto error; + if (sndbuf_resize(b, blocks, ch->intr_size)) + goto error; + + ch->start = ch->buf; + ch->end = ch->buf + buf_size; + ch->cur = ch->buf; + ch->pcm_ch = c; + ch->pcm_mtx = c->lock; + ch->pcm_buf = b; + + if (ch->pcm_mtx == NULL) { + DPRINTF("ERROR: PCM channels does not have a mutex!\n"); + goto error; + } + return (ch); error: @@ -1431,30 +1424,13 @@ uaudio_chan_free(struct uaudio_chan *ch) int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize) { - uaudio_chan_set_param_fragments(ch, blocksize, 0 - 1); - - return (ch->block_size); + return (ch->intr_size); } int uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize, uint32_t blockcount) { - /* we only support one size */ - blocksize = ch->intr_size; - blockcount = 2; - - if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) || - (sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) { - DPRINTFN(1, "resizing to %u x " - "%u bytes\n", blockcount, blocksize); - if (sndbuf_resize(ch->pcm_buf, blockcount, blocksize)) { - DPRINTFN(0, "failed to resize sound buffer, count=%u, " - "size=%u\n", blockcount, blocksize); - } - } - ch->block_size = sndbuf_getblksz(ch->pcm_buf); - return (1); } @@ -1591,12 +1567,12 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) DPRINTF("adding %d\n", mc->ctl); } - mc->delta = 0; if (mc->type == MIX_ON_OFF) { mc->minval = 0; mc->maxval = 1; + mc->mod = 1; } else if (mc->type == MIX_SELECTOR) { - + mc->mod = 1; } else { /* determine min and max values */ @@ -1607,21 +1583,30 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) mc->maxval = uaudio_mixer_get(sc->sc_udev, GET_MAX, mc); - mc->maxval = 1 + uaudio_mixer_signext(mc->type, mc->maxval); + mc->maxval = uaudio_mixer_signext(mc->type, mc->maxval); + /* check if max and min was swapped */ + + if (mc->maxval < mc->minval) { + res = mc->maxval; + mc->maxval = mc->minval; + mc->minval = res; + } + + /* compute value range */ mc->mul = mc->maxval - mc->minval; - if (mc->mul == 0) { + if (mc->mul == 0) mc->mul = 1; - } + + /* compute value alignment */ res = uaudio_mixer_get(sc->sc_udev, GET_RES, mc); - if (res > 0) { - mc->delta = ((res * 255) + (mc->mul / 2)) / mc->mul; - } + if (res == 0) + res = 1; + mc->mod = mc->mul / res; + if (mc->mod == 0) + mc->mod = 1; } - if (mc->maxval < mc->minval) { - mc->maxval = mc->minval; - } uaudio_mixer_add_ctl_sub(sc, mc); #if USB_DEBUG @@ -3108,7 +3093,21 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val) val = mc->minval; } } else { - val = (((val + (mc->delta / 2)) * mc->mul) / 255) + mc->minval; + + /* compute actual volume */ + val = (val * mc->mul) / 255; + + /* align volume level */ + val = val - (val % mc->mod); + + /* add lower offset */ + val = val + mc->minval; + + /* make sure we don't write a value out of range */ + if (val > mc->maxval) + val = mc->maxval; + else if (val < mc->minval) + val = mc->minval; } DPRINTFN(6, "type=0x%03x val=%d min=%d max=%d val=%d\n", From 9dac8e0ed2fdec3544e76b2491f2001385b52665 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 21:07:47 +0000 Subject: [PATCH 576/646] Add missing mtx_destroy(). Submitted by: Sebastian Huber --- sys/dev/usb/storage/umass.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 914a36e9903..9321516097a 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -1669,6 +1669,7 @@ umass_detach(device_t dev) #if (__FreeBSD_version >= 700037) mtx_unlock(&sc->sc_mtx); #endif + mtx_destroy(&sc->sc_mtx); return (0); /* success */ } From a1f7c632cccbee7ac429622ba8d02f73b0ff6f04 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 8 Nov 2009 21:08:50 +0000 Subject: [PATCH 577/646] Correct Olympus quirk. Submitted by: Pavel Gubin --- sys/dev/usb/storage/umass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 9321516097a..18756c97cf9 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -679,7 +679,7 @@ static const struct umass_devdescr umass_devdescr[] = { WRONG_CSWSIG }, {USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, RID_WILDCARD, - UMASS_PROTO_SCSI, + UMASS_PROTO_DEFAULT, NO_GETMAXLUN }, {USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD, From 4d3a629c65d20d7f5023fb344a54f32929ead30c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 9 Nov 2009 00:16:50 +0000 Subject: [PATCH 578/646] Correct disabling checksum offloading for BCM5700 B0. --- sys/dev/bge/if_bge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index c0ef5dc1971..9a27d31e55b 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2743,7 +2743,7 @@ bge_attach(device_t dev) */ if (sc->bge_chipid == BGE_CHIPID_BCM5700_B0) { ifp->if_capabilities &= ~IFCAP_HWCSUM; - ifp->if_capenable &= IFCAP_HWCSUM; + ifp->if_capenable &= ~IFCAP_HWCSUM; ifp->if_hwassist = 0; } From 0c10c611ffe51a800d510220c61192a73e250631 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 9 Nov 2009 02:37:02 +0000 Subject: [PATCH 579/646] Apply a NetBSD fix (revision 1.12) to handle multi-session bzip2 files as created by pbzip2. Submitted by: mrg (NetBSD.org) MFC after: 1 week --- usr.bin/gzip/unbzip2.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c index e8990d7b984..4835325a6d2 100644 --- a/usr.bin/gzip/unbzip2.c +++ b/usr.bin/gzip/unbzip2.c @@ -1,4 +1,4 @@ -/* $NetBSD: unbzip2.c,v 1.11 2008/04/28 20:24:13 martin Exp $ */ +/* $NetBSD: unbzip2.c,v 1.12 2009/10/11 05:17:20 mrg Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) if (bytes_in) *bytes_in = prelen; - while (ret >= BZ_OK && ret != BZ_STREAM_END) { + while (ret == BZ_OK) { if (bzs.avail_in == 0 && !end_of_file) { ssize_t n; @@ -88,7 +88,7 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) case BZ_OK: if (ret == BZ_OK && end_of_file) maybe_err("read"); - if (!tflag) { + if (!tflag && bzs.avail_out != BUFLEN) { ssize_t n; n = write(out, outbuf, BUFLEN - bzs.avail_out); @@ -96,7 +96,13 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) maybe_err("write"); bytes_out += n; } - break; + if (ret == BZ_STREAM_END && !end_of_file) { + if (BZ2_bzDecompressEnd(&bzs) != BZ_OK || + BZ2_bzDecompressInit(&bzs, 0, 0) != BZ_OK) + maybe_errx("bzip2 re-init"); + ret = BZ_OK; + } + break; case BZ_DATA_ERROR: maybe_warnx("bzip2 data integrity error"); @@ -109,7 +115,10 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) case BZ_MEM_ERROR: maybe_warnx("bzip2 out of memory"); break; - + + default: + maybe_warnx("unknown bzip2 error: %d", ret); + break; } } From 6f5c96c41dcbefb5ef8785fdf2ed0611d0a60c40 Mon Sep 17 00:00:00 2001 From: Jun Kuriyama Date: Mon, 9 Nov 2009 02:54:16 +0000 Subject: [PATCH 580/646] - Add hw.clflush_disable loader tunable to avoid panic (trap 9) at map_invalidate_cache_range() even if CPU is not Intel. - This tunable can be set to -1 (default), 0 and 1. -1 is same as current behavior, which automatically disable CLFLUSH on Intel CPUs without CPUID_SS (should be occured on Xen only). You can specify 1 when this panic happened on non-Intel CPUs (such as AMD's). Because disabling CLFLUSH may reduce performance, you can try with setting 0 on Intel CPUs without SS to use CLFLUSH feature. Reviewed by: kib Reported by: karl, kuriyama Related to: kern/138863 --- sys/amd64/amd64/initcpu.c | 19 ++++++++++++++++++- sys/i386/i386/initcpu.c | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c index 7aaff821463..0753306282d 100644 --- a/sys/amd64/amd64/initcpu.c +++ b/sys/amd64/amd64/initcpu.c @@ -47,6 +47,13 @@ __FBSDID("$FreeBSD$"); static int hw_instruction_sse; SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD, &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU"); +/* + * -1: automatic (default) + * 0: keep enable CLFLUSH + * 1: force disable CLFLUSH + */ +static int hw_clflush_disable = -1; +TUNABLE_INT("hw.clflush_disable", &hw_clflush_disable); int cpu; /* Are we 386, 386sx, 486, etc? */ u_int cpu_feature; /* Feature flags */ @@ -169,6 +176,16 @@ initializecpu(void) * XXXKIB: (temporary) hack to work around traps generated when * CLFLUSHing APIC registers window. */ - if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS)) + TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable); + if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS) && + hw_clflush_disable == -1) cpu_feature &= ~CPUID_CLFSH; + /* + * Allow to disable CLFLUSH feature manually by + * hw.clflush_disable tunable. This may help Xen guest on some AMD + * CPUs. + */ + if (hw_clflush_disable == 1) { + cpu_feature &= ~CPUID_CLFSH; + } } diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c index dc8da0b0f2a..bcd9922b089 100644 --- a/sys/i386/i386/initcpu.c +++ b/sys/i386/i386/initcpu.c @@ -75,6 +75,13 @@ static void init_mendocino(void); static int hw_instruction_sse; SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD, &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU"); +/* + * -1: automatic (default) + * 0: keep enable CLFLUSH + * 1: force disable CLFLUSH + */ +static int hw_clflush_disable = -1; +TUNABLE_INT("hw.clflush_disable", &hw_clflush_disable); /* Must *NOT* be BSS or locore will bzero these after setting them */ int cpu = 0; /* Are we 386, 386sx, 486, etc? */ @@ -721,8 +728,18 @@ initializecpu(void) * XXXKIB: (temporary) hack to work around traps generated when * CLFLUSHing APIC registers window. */ - if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS)) + TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable); + if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS) && + hw_clflush_disable == -1) cpu_feature &= ~CPUID_CLFSH; + /* + * Allow to disable CLFLUSH feature manually by + * hw.clflush_disable tunable. This may help Xen guest on some AMD + * CPUs. + */ + if (hw_clflush_disable == 1) { + cpu_feature &= ~CPUID_CLFSH; + } #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) /* From 641182ba045afd04f34fc85f560e56b341dc2a22 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 9 Nov 2009 07:28:29 +0000 Subject: [PATCH 581/646] Initialize the whole message unit's DMA buffer to zero, this fixes a panic during boot when ARC1200 is being used with certain motherboard models. This commit brings the driver to the same state of vendor's 1.20.00.16 release. Many thanks to Areca for their continued support to FreeBSD. Reported by: Jirka Mikulas Submitted by: Erich Chen (Areca) Obtained from: ftp://ftp.areca.com.tw/RaidCards/AP_Drivers/FreeBSD/DRIVER/SourceCode/arcmsr-freebsd-1.20.00.16-91010.zip MFC after: 3 days --- sys/dev/arcmsr/arcmsr.c | 4 +++- sys/dev/arcmsr/arcmsr.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 09bce1b9455..0e6acbf190b 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -55,6 +55,8 @@ ** 1.20.00.14 02/05/2007 Erich Chen bug fix for incorrect ccb_h.status report ** and cause g_vfs_done() read write error ** 1.20.00.15 10/10/2007 Erich Chen support new RAID adapter type ARC120x +** 1.20.00.16 10/10/2009 Erich Chen Bug fix for RAID adapter type ARC120x +** bus_dmamem_alloc() with BUS_DMA_ZERO ****************************************************************************************** * $FreeBSD$ */ @@ -2903,7 +2905,7 @@ static u_int32_t arcmsr_initialize(device_t dev) } /* Allocation for our srbs */ if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr - , BUS_DMA_WAITOK | BUS_DMA_COHERENT, &acb->srb_dmamap) != 0) { + , BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &acb->srb_dmamap) != 0) { bus_dma_tag_destroy(acb->srb_dmat); bus_dma_tag_destroy(acb->dm_segs_dmat); bus_dma_tag_destroy(acb->parent_dmat); diff --git a/sys/dev/arcmsr/arcmsr.h b/sys/dev/arcmsr/arcmsr.h index 0b573816a18..7d8e24bcbdd 100644 --- a/sys/dev/arcmsr/arcmsr.h +++ b/sys/dev/arcmsr/arcmsr.h @@ -37,7 +37,7 @@ ************************************************************************** * $FreeBSD$ */ -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007-10-07" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.16 2009-10-10" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_DEV_SECTOR_SIZE 512 #define ARCMSR_MAX_XFER_SECTORS 4096 From 57edc1bbf38a20e9a80593b441e15182ca7152a9 Mon Sep 17 00:00:00 2001 From: Oleg Bulyzhin Date: Mon, 9 Nov 2009 09:12:45 +0000 Subject: [PATCH 582/646] style(9): add missing parentheses --- sys/netinet/ipfw/ip_dummynet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c index 3de27a1ca11..e961a55e817 100644 --- a/sys/netinet/ipfw/ip_dummynet.c +++ b/sys/netinet/ipfw/ip_dummynet.c @@ -252,7 +252,7 @@ static int dummynet_io(struct mbuf **, int , struct ip_fw_args *); #define QUEUE_IS_IDLE(q) ((q)->head == NULL && (q)->S == (q)->F + 1 && \ curr_time > (q)->idle_time + 1 && \ ((q)->numbytes + (curr_time - (q)->idle_time - 1) * \ - (q)->fs->pipe->bandwidth >= q->fs->pipe->burst)) + (q)->fs->pipe->bandwidth >= (q)->fs->pipe->burst)) /* * Heap management functions. From fb549e86e7cebb9d958b090276f8cdc04b0a57f3 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 9 Nov 2009 09:27:09 +0000 Subject: [PATCH 583/646] Add more ICH10 chip IDs. Submitted by: Dmitry S. Luhtionov --- sys/dev/ata/ata-pci.h | 4 ++++ sys/dev/ata/chipsets/ata-intel.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 7d7a08eb520..66a25c4be87 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -196,6 +196,10 @@ struct ata_pci_controller { #define ATA_I82801JD_AH 0x3a028086 #define ATA_I82801JD_R1 0x3a058086 #define ATA_I82801JD_S2 0x3a068086 +#define ATA_I82801JI_S1 0x3a208086 +#define ATA_I82801JI_AH 0x3a228086 +#define ATA_I82801JI_R1 0x3a258086 +#define ATA_I82801JI_S2 0x3a268086 #define ATA_I31244 0x32008086 #define ATA_ITE_ID 0x1283 diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c index 38c296b1f4b..a19de8bec5c 100644 --- a/sys/dev/ata/chipsets/ata-intel.c +++ b/sys/dev/ata/chipsets/ata-intel.c @@ -135,6 +135,10 @@ ata_intel_probe(device_t dev) { ATA_I82801JD_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I82801JD_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I82801JD_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JI_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JI_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JI_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JI_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I31244, 0, 0, 2, ATA_SA150, "31244" }, { 0, 0, 0, 0, 0, 0}}; From d28e9c146aa54d16f03eae2c545fdb2b8de371a5 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 9 Nov 2009 11:23:37 +0000 Subject: [PATCH 584/646] The isr_intval in ieee80211req_scan_result structure should be 16 bit. This makes ifconfig list scan display the correct beacon interval (previously it would int overflow). As a side effect, this makes the ieee80211req_scan_result word aligned. Submitted by: Paul B Mahol --- sys/net80211/ieee80211_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index 89d8fe53fcf..7215a5edd9f 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -790,7 +790,7 @@ struct ieee80211req_scan_result { uint16_t isr_flags; /* channel flags */ int8_t isr_noise; int8_t isr_rssi; - uint8_t isr_intval; /* beacon interval */ + uint16_t isr_intval; /* beacon interval */ uint8_t isr_capinfo; /* capabilities */ uint8_t isr_erp; /* ERP element */ uint8_t isr_bssid[IEEE80211_ADDR_LEN]; From 50c9a27603f682c99815b360938610d25f761168 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 9 Nov 2009 11:39:51 +0000 Subject: [PATCH 585/646] Add support for ATA Power Management. --- sbin/camcontrol/camcontrol.8 | 25 +++++++- sbin/camcontrol/camcontrol.c | 112 ++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 3 deletions(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index b987cad2e07..a0871ac7f3f 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 4, 2009 +.Dd November 9, 2009 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -165,6 +165,20 @@ .Op Fl w .Op Fl y .Nm +.Ic idle +.Op device id +.Op generic args +.Op Fl t Ar time +.Nm +.Ic standby +.Op device id +.Op generic args +.Op Fl t Ar time +.Nm +.Ic sleep +.Op device id +.Op generic args +.Nm .Ic help .Sh DESCRIPTION The @@ -821,6 +835,15 @@ The user will not be asked about the timeout if a timeout is specified on the command line. .El +.It Ic idle +Put ATA device into IDLE state. Optional parameter specifies automatic +idle timer value in seconds. +.It Ic standby +Put ATA device into STANDBY state. Optional parameter specifies automatic +standby timer value in seconds. +.It Ic sleep +Put ATA device into SLEEP state. Note that the only way get device out of +this state may be reset. .It Ic help Print out verbose usage information. .El diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 728b691c6dc..1638a5dbaf5 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -74,7 +74,10 @@ typedef enum { CAM_CMD_DETACH = 0x00000010, CAM_CMD_REPORTLUNS = 0x00000011, CAM_CMD_READCAP = 0x00000012, - CAM_CMD_IDENTIFY = 0x00000013 + CAM_CMD_IDENTIFY = 0x00000013, + CAM_CMD_IDLE = 0x00000014, + CAM_CMD_STANDBY = 0x00000015, + CAM_CMD_SLEEP = 0x00000016 } cam_cmdmask; typedef enum { @@ -154,6 +157,9 @@ struct camcontrol_opts option_table[] = { {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"}, {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, + {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, + {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, + {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, #endif /* MINIMALISTIC */ {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, @@ -217,6 +223,8 @@ static int scsireportluns(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int scsireadcapacity(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); +static int atapm(struct cam_device *device, int argc, char **argv, + char *combinedopt, int retry_count, int timeout); #endif /* MINIMALISTIC */ camcontrol_optret @@ -4128,6 +4136,91 @@ bailout: return (retval); } +static int +atapm(struct cam_device *device, int argc, char **argv, + char *combinedopt, int retry_count, int timeout) +{ + union ccb *ccb; + int retval = 0; + int t = -1; + char c; + u_char cmd, sc; + + ccb = cam_getccb(device); + + if (ccb == NULL) { + warnx("%s: error allocating ccb", __func__); + return (1); + } + + while ((c = getopt(argc, argv, combinedopt)) != -1) { + switch (c) { + case 't': + t = atoi(optarg); + break; + default: + break; + } + } + if (strcmp(argv[1], "idle") == 0) { + if (t == -1) + cmd = ATA_IDLE_IMMEDIATE; + else + cmd = ATA_IDLE_CMD; + } else if (strcmp(argv[1], "standby") == 0) { + if (t == -1) + cmd = ATA_STANDBY_IMMEDIATE; + else + cmd = ATA_STANDBY_CMD; + } else { + cmd = ATA_SLEEP; + t = -1; + } + if (t < 0) + sc = 0; + else if (t <= (240 * 5)) + sc = t / 5; + else if (t <= (11 * 30 * 60)) + sc = t / (30 * 60) + 241; + else + sc = 253; + cam_fill_ataio(&ccb->ataio, + retry_count, + NULL, + /*flags*/CAM_DIR_NONE, + MSG_SIMPLE_Q_TAG, + /*data_ptr*/NULL, + /*dxfer_len*/0, + timeout ? timeout : 30 * 1000); + ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (arglist & CAM_ARG_ERR_RECOVER) + ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; + + if (cam_send_ccb(device, ccb) < 0) { + warn("error sending command"); + + if (arglist & CAM_ARG_VERBOSE) + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + + retval = 1; + goto bailout; + } + + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); + retval = 1; + goto bailout; + } +bailout: + cam_freeccb(ccb); + return (retval); +} + #endif /* MINIMALISTIC */ void @@ -4166,6 +4259,9 @@ usage(int verbose) " [-R syncrate][-v][-T ]\n" " [-U][-W bus_width]\n" " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" +" camcontrol idle [dev_id][generic args][-t time]\n" +" camcontrol standby [dev_id][generic args][-t time]\n" +" camcontrol sleep [dev_id][generic args]\n" #endif /* MINIMALISTIC */ " camcontrol help\n"); if (!verbose) @@ -4193,6 +4289,9 @@ usage(int verbose) "tags report or set the number of transaction slots for a device\n" "negotiate report or set device negotiation parameters\n" "format send the SCSI FORMAT UNIT command to the named device\n" +"idle send the ATA IDLE command to the named device\n" +"standby send the ATA STANDBY command to the named device\n" +"sleep send the ATA SLEEP command to the named device\n" "help this message\n" "Device Identifiers:\n" "bus:target specify the bus and target, lun defaults to 0\n" @@ -4259,7 +4358,9 @@ usage(int verbose) "-q be quiet, don't print status messages\n" "-r run in report only mode\n" "-w don't send immediate format command\n" -"-y don't ask any questions\n"); +"-y don't ask any questions\n" +"idle/standby arguments:\n" +"-t number of seconds before respective state.\n"); #endif /* MINIMALISTIC */ } @@ -4555,6 +4656,13 @@ main(int argc, char **argv) combinedopt, retry_count, timeout); break; + case CAM_CMD_IDLE: + case CAM_CMD_STANDBY: + case CAM_CMD_SLEEP: + error = atapm(cam_dev, argc, argv, + combinedopt, retry_count, + timeout); + break; #endif /* MINIMALISTIC */ case CAM_CMD_USAGE: usage(1); From 6bf41ac159cc3160a8b5610677e3657916887310 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 9 Nov 2009 12:28:59 +0000 Subject: [PATCH 586/646] Add ja_JP.UTF-8 catalog. Reviewed by: hrs, nork, takawata MFC after: 1 week --- lib/libc/nls/Makefile.inc | 1 + lib/libc/nls/ja_JP.UTF-8.msg | 249 +++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 lib/libc/nls/ja_JP.UTF-8.msg diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc index 234c850cf4b..9b7148f4a36 100644 --- a/lib/libc/nls/Makefile.inc +++ b/lib/libc/nls/Makefile.inc @@ -23,6 +23,7 @@ NLS+= fr_FR.ISO8859-1 NLS+= gl_ES.ISO8859-1 NLS+= hu_HU.ISO8859-2 NLS+= it_IT.ISO8859-15 +NLS+= ja_JP.UTF-8 NLS+= ko_KR.UTF-8 NLS+= ko_KR.eucKR NLS+= mn_MN.UTF-8 diff --git a/lib/libc/nls/ja_JP.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg new file mode 100644 index 00000000000..940f7b9923c --- /dev/null +++ b/lib/libc/nls/ja_JP.UTF-8.msg @@ -0,0 +1,249 @@ +$ $FreeBSD$ +$ +$ Message catalog for C locale (template) +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 險ア蜿ッ縺輔l縺ヲ縺縺ェ縺謫堺ス懊〒縺 +$ ENOENT +2 縺昴ョ繧医≧縺ェ繝輔ぃ繧、繝ォ縺セ縺溘ッ繝繧」繝ャ繧ッ繝医Μ縺ッ縺ゅj縺セ縺帙s +$ ESRCH +3 縺昴ョ繧医≧縺ェ繝励Ο繧サ繧ケ縺ッ縺ゅj縺セ縺帙s +$ EINTR +4 繧キ繧ケ繝繝繧ウ繝シ繝ォ縺御クュ譁ュ縺輔l縺セ縺励◆ +$ EIO +5 蜈・蜃コ蜉帙お繝ゥ繝シ縺ァ縺 +$ ENXIO +6 繝繝舌う繧ケ縺梧コ門y縺輔l縺ヲ縺縺セ縺帙s +$ E2BIG +7 蠑墓焚縺ョ繝ェ繧ケ繝医′髟キ縺吶℃縺セ縺 +$ ENOEXEC +8 辟。蜉ケ縺ェ螳溯。悟ス「蠑上〒縺 +$ EBADF +9 辟。蜉ケ縺ェ繝輔ぃ繧、繝ォ險倩ソー蟄舌〒縺 +$ ECHILD +10 蟄舌励Ο繧サ繧ケ縺後≠繧翫∪縺帙s +$ EDEADLK +11 繝ェ繧ス繝シ繧ケ繝繝繝峨Ο繝繧ッ繧貞屓驕ソ縺励∪縺励◆ +$ ENOMEM +12 繝。繝「繝ェ縺ョ蜑イ繧雁ス薙※縺後〒縺阪∪縺帙s +$ EACCES +13 繝代シ繝溘ャ繧キ繝ァ繝ウ縺梧拠邨カ縺輔l縺セ縺励◆ +$ EFAULT +14 辟。蜉ケ縺ェ繧「繝峨Ξ繧ケ縺ァ縺 +$ ENOTBLK +15 繝悶Ο繝繧ッ繝繝舌う繧ケ縺瑚ヲ∵アゅ&繧後※縺縺セ縺 +$ EBUSY +16 繝繝舌う繧ケ縺後ン繧ク繝シ迥カ諷九〒縺 +$ EEXIST +17 繝輔ぃ繧、繝ォ縺悟ュ伜惠縺励∪縺 +$ EXDEV +18 繝繝舌う繧ケ繧偵∪縺溘$繝ェ繝ウ繧ッ縺ァ縺 +$ ENODEV +19 繝繝舌う繧ケ縺悟ッセ蠢懊@縺ヲ縺ェ縺謫堺ス懊〒縺 +$ ENOTDIR +20 繝繧」繝ャ繧ッ繝医Μ縺ァ縺ッ縺ゅj縺セ縺帙s +$ EISDIR +21 繝繧」繝ャ繧ッ繝医Μ縺ァ縺 +$ EINVAL +22 辟。蜉ケ縺ェ蠑墓焚縺ァ縺 +$ ENFILE +23 繧キ繧ケ繝繝蜀縺ァ繧ェ繝シ繝励Φ縺輔l縺ヲ縺繧九ヵ繧。繧、繝ォ縺悟、壹☆縺弱∪縺 +$ EMFILE +24 繧ェ繝シ繝励Φ縺励※縺繧九ヵ繧。繧、繝ォ縺悟、壹☆縺弱∪縺 +$ ENOTTY +25 繝繝舌う繧ケ縺悟ッセ蠢懊@縺ヲ縺縺ェ縺 ioctl 縺ァ縺 +$ ETXTBSY +26 繝繧ュ繧ケ繝医ヵ繧。繧、繝ォ縺後ン繧ク繝シ迥カ諷九〒縺 +$ EFBIG +27 繝輔ぃ繧、繝ォ縺悟、ァ縺阪☆縺弱∪縺 +$ ENOSPC +28 繝繝舌う繧ケ縺ョ遨コ縺埼伜沺荳崎カウ縺ァ縺 +$ ESPIPE +29 辟。蜉ケ縺ェ繧キ繝シ繧ッ縺ァ縺 +$ EROFS +30 隱ュ縺ソ霎シ縺ソ蟆ら畑繝輔ぃ繧、繝ォ繧キ繧ケ繝繝縺ァ縺 +$ EMLINK +31 繝ェ繝ウ繧ッ謨ー縺悟、壹☆縺弱∪縺 +$ EPIPE +32 繝代う繝励′遐エ螢翫&繧後※縺セ縺励◆ +$ EDOM +33 謨ー蛟、蠑墓焚縺檎ッ蝗イ螟悶〒縺 +$ ERANGE +34 邨先棡縺悟、ァ縺埼℃縺弱∪縺 +$ EAGAIN, EWOULDBLOCK +35 繝ェ繧ス繝シ繧ケ縺御ク譎ら噪縺ォ蛻ゥ逕ィ縺ァ縺阪∪縺帙s +$ EINPROGRESS +36 謫堺ス懊′迴セ蝨ィ騾イ陦御クュ縺ァ縺 +$ EALREADY +37 謫堺ス懊ッ譌「縺ォ騾イ陦御クュ縺ァ縺 +$ ENOTSOCK +38 繧ス繧ア繝繝医〒縺ェ縺繧ゅョ縺ォ縺、縺縺ヲ繧ス繧ア繝繝域桃菴懊r陦後>縺セ縺励◆ +$ EDESTADDRREQ +39 螳帛医い繝峨Ξ繧ケ縺瑚ヲ∵アゅ&繧後※縺縺セ縺 +$ EMSGSIZE +40 繝。繝繧サ繝シ繧ク縺碁聞縺吶℃縺セ縺 +$ EPROTOTYPE +41 繧ス繧ア繝繝医′蟇セ蠢懊@縺ヲ縺縺ェ縺繝励Ο繝医さ繝ォ繧ソ繧、繝励〒縺 +$ ENOPROTOOPT +42 蛻ゥ逕ィ縺ァ縺阪↑縺繝励Ο繝医さ繝ォ縺ァ縺 +$ EPROTONOSUPPORT +43 蟇セ蠢懊@縺ヲ縺縺ェ縺繝励Ο繝医さ繝ォ縺ァ縺 +$ ESOCKTNOSUPPORT +44 蟇セ蠢懊@縺ヲ縺縺ェ縺繧ス繧ア繝繝医ち繧、繝励〒縺 +$ EOPNOTSUPP +45 蟇セ蠢懊@縺ヲ縺縺ェ縺謫堺ス懊〒縺 +$ EPFNOSUPPORT +46 蟇セ蠢懊@縺ヲ縺縺ェ縺繝励Ο繝医さ繝ォ繝輔ぃ繝溘Μ縺ァ縺 +$ EAFNOSUPPORT +47 繝励Ο繝医さ繝ォ繝輔ぃ繝溘Μ縺悟ッセ蠢懊@縺ヲ縺縺ェ縺繧「繝峨Ξ繧ケ繝輔ぃ繝溘Μ縺梧欠螳壹&繧後∪縺励◆ +$ EADDRINUSE +48 繧「繝峨Ξ繧ケ縺梧里縺ォ菴ソ逕ィ荳ュ縺ァ縺 +$ EADDRNOTAVAIL +49 隕∵アゅ&繧後◆繧「繝峨Ξ繧ケ繧貞牡繧雁ス薙※縺ァ縺阪∪縺帙s +$ ENETDOWN +50 繝阪ャ繝医Ρ繝シ繧ッ縺後ム繧ヲ繝ウ縺励※縺縺セ縺 +$ ENETUNREACH +51 繝阪ャ繝医Ρ繝シ繧ッ縺ォ蛻ー驕斐〒縺阪∪縺帙s +$ ENETRESET +52 繝ェ繧サ繝繝医↓繧医j繝阪ャ繝医Ρ繝シ繧ッ縺ョ謗・邯壹′螟ア繧上l縺セ縺励◆ +$ ECONNABORTED +53 繧ス繝輔ヨ繧ヲ繧ァ繧「縺ォ繧医▲縺ヲ謗・邯壹′蛻譁ュ縺輔l縺セ縺励◆ +$ ECONNRESET +54 謗・邯壹′騾壻ソ。逶ク謇九↓繧医▲縺ヲ繝ェ繧サ繝繝医&繧後∪縺励◆ +$ ENOBUFS +55 繝舌ャ繝輔ぃ縺ョ螳ケ驥丈ク崎カウ縺ァ縺 +$ EISCONN +56 繧ス繧ア繝繝医ッ譌「縺ォ謗・邯壹&繧後※縺縺セ縺 +$ ENOTCONN +57 繧ス繧ア繝繝医ッ謗・邯壹&繧後※縺縺セ縺帙s +$ ESHUTDOWN +58 繧ス繧ア繝繝医ョ繧キ繝」繝繝医ム繧ヲ繝ウ縺ョ蠕後〒騾∽ソ。縺後〒縺阪∪縺帙s +$ ETOOMANYREFS +59 蜃ヲ逅髯千阜繧定カ縺医k螟夐榊盾辣ァ縺ァ縺 +$ ETIMEDOUT +60 謫堺ス懊′繧ソ繧、繝繧「繧ヲ繝医@縺セ縺励◆ +$ ECONNREFUSED +61 謗・邯壹′諡堤オカ縺輔l縺セ縺励◆ +$ ELOOP +62 蜃ヲ逅髯千阜繧定カ縺医k繧キ繝ウ繝懊Μ繝繧ッ繝ェ繝ウ繧ッ繝ャ繝吶Ν縺ァ縺 +$ ENAMETOOLONG +63 繝輔ぃ繧、繝ォ蜷阪′髟キ縺吶℃縺セ縺 +$ EHOSTDOWN +64 繝帙せ繝医′繝繧ヲ繝ウ縺励※縺縺セ縺 +$ EHOSTUNREACH +65 繝帙せ繝医∈縺ョ邨瑚キッ縺後≠繧翫∪縺帙s +$ ENOTEMPTY +66 繝繧」繝ャ繧ッ繝医Μ縺檎ゥコ縺ァ縺ッ縺ゅj縺セ縺帙s +$ EPROCLIM +67 繝励Ο繧サ繧ケ縺悟、壹☆縺弱∪縺 +$ EUSERS +68 繝ヲ繝シ繧カ縺悟、壹☆縺弱∪縺 +$ EDQUOT +69 繝繧」繧ケ繧ッ繧ッ繧ゥ繝シ繧ソ縺瑚カ驕弱@縺セ縺励◆ +$ ESTALE +70 螟ア蜉ケ縺励◆ NFS 繝輔ぃ繧、繝ォ繝上Φ繝峨Ν縺ァ縺 +$ EREMOTE +71 繝代せ荳ュ縺ョ繝ェ繝「繝シ繝医ョ繝ャ繝吶Ν縺悟、壹☆縺弱∪縺 +$ EBADRPC +72 辟。蜉ケ縺ェ RPC 讒矩菴薙〒縺 +$ ERPCMISMATCH +73 RPC 繝舌シ繧ク繝ァ繝ウ縺碁俣驕輔▲縺ヲ縺縺セ縺 +$ EPROGUNAVAIL +74 RPC 繝励Ο繧ー繝ゥ繝縺悟茜逕ィ縺ァ縺阪∪縺帙s +$ EPROGMISMATCH +75 繝励Ο繧ー繝ゥ繝縺ョ繝舌シ繧ク繝ァ繝ウ縺悟粋縺」縺ヲ縺縺セ縺帙s +$ EPROCUNAVAIL +76 繝励Ο繧ー繝ゥ繝縺ァ縺ッ蛻ゥ逕ィ縺ァ縺阪↑縺 procedure 縺ァ縺 +$ ENOLCK +77 繝ュ繝繧ッ縺悟茜逕ィ縺ァ縺阪∪縺帙s +$ ENOSYS +78 髢「謨ー縺悟ョ溯」縺輔l縺ヲ縺縺セ縺帙s +$ EFTYPE +79 繝輔ぃ繧、繝ォ縺ョ蝙九∪縺溘ッ蠖「蠑上′荳埼←蛻縺ァ縺 +$ EAUTH +80 隱崎ィシ繧ィ繝ゥ繝シ縺ァ縺 +$ ENEEDAUTH +81 隱崎ィシ迚ゥ縺悟ソ隕√〒縺 +$ EIDRM +82 隴伜挨蟄舌ッ蜑企勁縺輔l縺セ縺励◆ +$ ENOMSG +83 隕∵アゅ&繧後◆蝙九ョ繝。繝繧サ繝シ繧ク縺後≠繧翫∪縺帙s +$ EOVERFLOW +84 繝繝シ繧ソ蝙九↓譬シ邏阪☆繧九↓縺ッ螟ァ縺阪☆縺弱k蛟、縺ァ縺 +$ ECANCELED +85 蜃ヲ逅縺後く繝」繝ウ繧サ繝ォ縺輔l縺セ縺励◆ +$ EILSEQ +86 荳肴ュ」縺ェ繝舌う繝亥励〒縺 +$ ENOATTR +87 縺昴ョ繧医≧縺ェ螻樊ァ縺ッ縺ゅj縺セ縺帙s +$ EDOOFUS +88 繝励Ο繧ー繝ゥ繝溘Φ繧ー繧ィ繝ゥ繝シ縺ァ縺 +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 繝上Φ繧ー繧「繝繝 +$ SIGINT +2 蜑イ繧願セシ縺ソ +$ SIGQUIT +3 荳ュ譁ュ +$ SIGILL +4 荳肴ュ」蜻ス莉、 +$ SIGTRAP +5 繝医Ξ繝シ繧ケ/BPT 繝医Λ繝繝 +$ SIGABRT +6 繧「繝懊シ繝医ヨ繝ゥ繝繝 +$ SIGEMT +7 EMT 繝医Λ繝繝 +$ SIGFPE +8 豬ョ蜍募ー乗焚轤ケ萓句、 +$ SIGKILL +9 Kill 縺輔l縺 +$ SIGBUS +10 繝舌せ繧ィ繝ゥ繝シ +$ SIGSEGV +11 繧サ繧ー繝。繝ウ繝繝シ繧キ繝ァ繝ウ驕募渚 +$ SIGSYS +12 蟄伜惠縺励↑縺繧キ繧ケ繝繝繧ウ繝シ繝ォ +$ SIGPIPE +13 繝代う繝礼エ螢 +$ SIGALRM +14 繧「繝ゥ繝シ繝繧ッ繝ュ繝繧ッ +$ SIGTERM +15 邨ゆコ +$ SIGURG +16 邱頑・蜈・蜃コ蜉帷憾豕 +$ SIGSTOP +17 荳譎ょ●豁「 (繧キ繧ー繝翫Ν) +$ SIGTSTP +18 荳譎ょ●豁「 +$ SIGCONT +19 邯咏カ +$ SIGCHLD +20 蟄舌励Ο繧サ繧ケ縺ョ邨ゆコ +$ SIGTTIN +21 荳譎ょ●豁「 (tty 蜈・蜉) +$ SIGTTOU +22 荳譎ょ●豁「 (tty 蜃コ蜉) +$ SIGIO +23 蜈・蜃コ蜉帛庄閭ス +$ SIGXCPU +24 CPU 譎る俣縺ョ蛻カ髯占カ驕 +$ SIGXFSZ +25 繝輔ぃ繧、繝ォ繧オ繧、繧コ縺ョ蛻カ髯占カ驕 +$ SIGVTALRM +26 莉ョ諠ウ繧ソ繧、繝槭ョ譛滄剞雜驕 +$ SIGPROF +27 繝励Ο繝輔ぃ繧、繝ォ繧ソ繧、繝槭ョ譛滄剞雜驕 +$ SIGWINCH +28 繧ヲ繧」繝ウ繝峨え繧オ繧、繧コ縺ョ螟牙喧 +$ SIGINFO +29 諠蝣ア隕∵ア +$ SIGUSR1 +30 繝ヲ繝シ繧カ螳夂セゥ繧キ繧ー繝翫Ν 1 +$ SIGUSR2 +31 繝ヲ繝シ繧カ螳夂セゥ繧キ繧ー繝翫Ν 2 From be77e7423ca90301fc7a4dc6c13c1fd7113f2706 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 9 Nov 2009 12:33:47 +0000 Subject: [PATCH 587/646] Add ja_JP.eucJP catalog. Reviewed by: hrs, nork, takawata MFC after: 1 week --- lib/libc/nls/Makefile.inc | 1 + lib/libc/nls/ja_JP.eucJP.msg | 249 +++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 lib/libc/nls/ja_JP.eucJP.msg diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc index 9b7148f4a36..f5c6885ae04 100644 --- a/lib/libc/nls/Makefile.inc +++ b/lib/libc/nls/Makefile.inc @@ -24,6 +24,7 @@ NLS+= gl_ES.ISO8859-1 NLS+= hu_HU.ISO8859-2 NLS+= it_IT.ISO8859-15 NLS+= ja_JP.UTF-8 +NLS+= ja_JP.eucJP NLS+= ko_KR.UTF-8 NLS+= ko_KR.eucKR NLS+= mn_MN.UTF-8 diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg new file mode 100644 index 00000000000..194016d0e3a --- /dev/null +++ b/lib/libc/nls/ja_JP.eucJP.msg @@ -0,0 +1,249 @@ +$ $FreeBSD$ +$ +$ Message catalog for C locale (template) +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 オイト、オ、、ニ、、、ハ、、チ犲、ヌ、ケ +$ ENOENT +2 、ス、ホ、隍ヲ、ハ・ユ・。・、・、゙、ソ、マ・ヌ・」・・ッ・ネ・熙マ、「、熙゙、サ、 +$ ESRCH +3 、ス、ホ、隍ヲ、ハ・ラ・・サ・ケ、マ、「、熙゙、サ、 +$ EINTR +4 ・キ・ケ・ニ・爭ウ。シ・、ャテ貪ヌ、オ、、゙、キ、ソ +$ EIO +5 ニスミホマ・ィ・鬘シ、ヌ、ケ +$ ENXIO +6 ・ヌ・ミ・、・ケ、ャス猜、オ、、ニ、、、゙、サ、 +$ E2BIG +7 ーソ、ホ・・ケ・ネ、ャトケ、ケ、ョ、゙、ケ +$ ENOEXEC +8 フオク、ハシツケヤキチシー、ヌ、ケ +$ EBADF +9 フオク、ハ・ユ・。・、・オュスメサメ、ヌ、ケ +$ ECHILD +10 サメ・ラ・・サ・ケ、ャ、「、熙゙、サ、 +$ EDEADLK +11 ・・ス。シ・ケ・ヌ・テ・ノ・・テ・ッ、イネ、キ、゙、キ、ソ +$ ENOMEM +12 ・皈筵熙ホウ荀ナ、ニ、ャ、ヌ、ュ、゙、サ、 +$ EACCES +13 ・ム。シ・゚・テ・キ・逾、ャオタ荀オ、、゙、キ、ソ +$ EFAULT +14 フオク、ハ・「・ノ・・ケ、ヌ、ケ +$ ENOTBLK +15 ・ヨ・・テ・ッ・ヌ・ミ・、・ケ、ャヘラオ皃オ、、ニ、、、゙、ケ +$ EBUSY +16 ・ヌ・ミ・、・ケ、ャ・モ・ク。シセツヨ、ヌ、ケ +$ EEXIST +17 ・ユ・。・、・、ャツクコ゚、キ、゙、ケ +$ EXDEV +18 ・ヌ・ミ・、・ケ、、゙、ソ、ー・・・ッ、ヌ、ケ +$ ENODEV +19 ・ヌ・ミ・、・ケ、ャツミア、キ、ニ、ハ、、チ犲、ヌ、ケ +$ ENOTDIR +20 ・ヌ・」・・ッ・ネ・熙ヌ、マ、「、熙゙、サ、 +$ EISDIR +21 ・ヌ・」・・ッ・ネ・熙ヌ、ケ +$ EINVAL +22 フオク、ハーソ、ヌ、ケ +$ ENFILE +23 ・キ・ケ・ニ・猗筅ヌ・ェ。シ・ラ・、オ、、ニ、、、・ユ・。・、・、ャツソ、ケ、ョ、゙、ケ +$ EMFILE +24 ・ェ。シ・ラ・、キ、ニ、、、・ユ・。・、・、ャツソ、ケ、ョ、゙、ケ +$ ENOTTY +25 ・ヌ・ミ・、・ケ、ャツミア、キ、ニ、、、ハ、、 ioctl 、ヌ、ケ +$ ETXTBSY +26 ・ニ・ュ・ケ・ネ・ユ・。・、・、ャ・モ・ク。シセツヨ、ヌ、ケ +$ EFBIG +27 ・ユ・。・、・、ャツ遉ュ、ケ、ョ、゙、ケ +$ ENOSPC +28 ・ヌ・ミ・、・ケ、ホカ、ュホホー靄ヤツュ、ヌ、ケ +$ ESPIPE +29 フオク、ハ・キ。シ・ッ、ヌ、ケ +$ EROFS +30 ニノ、゚ケ、゚タヘム・ユ・。・、・・キ・ケ・ニ・爨ヌ、ケ +$ EMLINK +31 ・・・ッソ、ャツソ、ケ、ョ、゙、ケ +$ EPIPE +32 ・ム・、・ラ、ャヌヒイ、オ、、ニ、゙、キ、ソ +$ EDOM +33 ソテヘーソ、ャネマーマウー、ヌ、ケ +$ ERANGE +34 キイフ、ャツ遉ュイ皃ョ、゙、ケ +$ EAGAIN, EWOULDBLOCK +35 ・・ス。シ・ケ、ャーサナェ、ヒヘヘム、ヌ、ュ、゙、サ、 +$ EINPROGRESS +36 チ犲、ャクスコ゚ソハケヤテ讀ヌ、ケ +$ EALREADY +37 チ犲、マエ、ヒソハケヤテ讀ヌ、ケ +$ ENOTSOCK +38 ・ス・ア・テ・ネ、ヌ、ハ、、、筅ホ、ヒ、ト、、、ニ・ス・ア・テ・ネチ犲、ケヤ、、、゙、キ、ソ +$ EDESTADDRREQ +39 ークタ隘「・ノ・・ケ、ャヘラオ皃オ、、ニ、、、゙、ケ +$ EMSGSIZE +40 ・皈テ・サ。シ・ク、ャトケ、ケ、ョ、゙、ケ +$ EPROTOTYPE +41 ・ス・ア・テ・ネ、ャツミア、キ、ニ、、、ハ、、・ラ・・ネ・ウ・・ソ・、・ラ、ヌ、ケ +$ ENOPROTOOPT +42 ヘヘム、ヌ、ュ、ハ、、・ラ・・ネ・ウ・、ヌ、ケ +$ EPROTONOSUPPORT +43 ツミア、キ、ニ、、、ハ、、・ラ・・ネ・ウ・、ヌ、ケ +$ ESOCKTNOSUPPORT +44 ツミア、キ、ニ、、、ハ、、・ス・ア・テ・ネ・ソ・、・ラ、ヌ、ケ +$ EOPNOTSUPP +45 ツミア、キ、ニ、、、ハ、、チ犲、ヌ、ケ +$ EPFNOSUPPORT +46 ツミア、キ、ニ、、、ハ、、・ラ・・ネ・ウ・・ユ・。・゚・熙ヌ、ケ +$ EAFNOSUPPORT +47 ・ラ・・ネ・ウ・・ユ・。・゚・熙ャツミア、キ、ニ、、、ハ、、・「・ノ・・ケ・ユ・。・゚・熙ャサリト熙オ、、゙、キ、ソ +$ EADDRINUSE +48 ・「・ノ・・ケ、ャエ、ヒサネヘムテ讀ヌ、ケ +$ EADDRNOTAVAIL +49 ヘラオ皃オ、、ソ・「・ノ・・ケ、ウ荀ナ、ニ、ヌ、ュ、゙、サ、 +$ ENETDOWN +50 ・ヘ・テ・ネ・。シ・ッ、ャ・タ・ヲ・、キ、ニ、、、゙、ケ +$ ENETUNREACH +51 ・ヘ・テ・ネ・。シ・ッ、ヒナテ」、ヌ、ュ、゙、サ、 +$ ENETRESET +52 ・・サ・テ・ネ、ヒ、隍・ヘ・テ・ネ・。シ・ッ、ホタワツウ、ャシコ、、、゙、キ、ソ +$ ECONNABORTED +53 ・ス・ユ・ネ・ヲ・ァ・「、ヒ、隍テ、ニタワツウ、ャタレテヌ、オ、、゙、キ、ソ +$ ECONNRESET +54 タワツウ、ャトフソョチシ熙ヒ、隍テ、ニ・・サ・テ・ネ、オ、、゙、キ、ソ +$ ENOBUFS +55 ・ミ・テ・ユ・。、ホヘニホフノヤツュ、ヌ、ケ +$ EISCONN +56 ・ス・ア・テ・ネ、マエ、ヒタワツウ、オ、、ニ、、、゙、ケ +$ ENOTCONN +57 ・ス・ア・テ・ネ、マタワツウ、オ、、ニ、、、゙、サ、 +$ ESHUTDOWN +58 ・ス・ア・テ・ネ、ホ・キ・罕テ・ネ・タ・ヲ・、ホク螟ヌチソョ、ャ、ヌ、ュ、゙、サ、 +$ ETOOMANYREFS +59 ス靉クツウヲ、トカ、ィ、ツソスナサイセネ、ヌ、ケ +$ ETIMEDOUT +60 チ犲、ャ・ソ・、・爭「・ヲ・ネ、キ、゙、キ、ソ +$ ECONNREFUSED +61 タワツウ、ャオタ荀オ、、゙、キ、ソ +$ ELOOP +62 ス靉クツウヲ、トカ、ィ、・キ・・ワ・・テ・ッ・・・ッ・・ル・、ヌ、ケ +$ ENAMETOOLONG +63 ・ユ・。・、・フセ、ャトケ、ケ、ョ、゙、ケ +$ EHOSTDOWN +64 ・ロ・ケ・ネ、ャ・タ・ヲ・、キ、ニ、、、゙、ケ +$ EHOSTUNREACH +65 ・ロ・ケ・ネ、リ、ホキミマゥ、ャ、「、熙゙、サ、 +$ ENOTEMPTY +66 ・ヌ・」・・ッ・ネ・熙ャカ、ヌ、マ、「、熙゙、サ、 +$ EPROCLIM +67 ・ラ・・サ・ケ、ャツソ、ケ、ョ、゙、ケ +$ EUSERS +68 ・譯シ・カ、ャツソ、ケ、ョ、゙、ケ +$ EDQUOT +69 ・ヌ・」・ケ・ッ・ッ・ゥ。シ・ソ、ャトカイ皃キ、゙、キ、ソ +$ ESTALE +70 シコク、キ、ソ NFS ・ユ・。・、・・マ・・ノ・、ヌ、ケ +$ EREMOTE +71 ・ム・ケテ讀ホ・・筍シ・ネ、ホ・・ル・、ャツソ、ケ、ョ、゙、ケ +$ EBADRPC +72 フオク、ハ RPC ケスツ、ツホ、ヌ、ケ +$ ERPCMISMATCH +73 RPC ・ミ。シ・ク・逾、ャエヨー网テ、ニ、、、゙、ケ +$ EPROGUNAVAIL +74 RPC ・ラ・・ー・鬣爨ャヘヘム、ヌ、ュ、゙、サ、 +$ EPROGMISMATCH +75 ・ラ・・ー・鬣爨ホ・ミ。シ・ク・逾、ャケ遉テ、ニ、、、゙、サ、 +$ EPROCUNAVAIL +76 ・ラ・・ー・鬣爨ヌ、マヘヘム、ヌ、ュ、ハ、、 procedure 、ヌ、ケ +$ ENOLCK +77 ・・テ・ッ、ャヘヘム、ヌ、ュ、゙、サ、 +$ ENOSYS +78 エリソ、ャシツチ、オ、、ニ、、、゙、サ、 +$ EFTYPE +79 ・ユ・。・、・、ホキソ、゙、ソ、マキチシー、ャノヤナャタレ、ヌ、ケ +$ EAUTH +80 ヌァセレ・ィ・鬘シ、ヌ、ケ +$ ENEEDAUTH +81 ヌァセレハェ、ャノャヘラ、ヌ、ケ +$ EIDRM +82 シアハフサメ、マコス、オ、、゙、キ、ソ +$ ENOMSG +83 ヘラオ皃オ、、ソキソ、ホ・皈テ・サ。シ・ク、ャ、「、熙゙、サ、 +$ EOVERFLOW +84 ・ヌ。シ・ソキソ、ヒウハヌシ、ケ、、ヒ、マツ遉ュ、ケ、ョ、テヘ、ヌ、ケ +$ ECANCELED +85 ス靉、ャ・ュ・罕・サ・、オ、、゙、キ、ソ +$ EILSEQ +86 ノヤタオ、ハ・ミ・、・ネホ、ヌ、ケ +$ ENOATTR +87 、ス、ホ、隍ヲ、ハツータュ、マ、「、熙゙、サ、 +$ EDOOFUS +88 ・ラ・・ー・鬣゚・・ー・ィ・鬘シ、ヌ、ケ +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 ・マ・・ー・「・テ・ラ +$ SIGINT +2 ウ荀ケ、゚ +$ SIGQUIT +3 テ貪ヌ +$ SIGILL +4 ノヤタオフソホ +$ SIGTRAP +5 ・ネ・。シ・ケ/BPT ・ネ・鬣テ・ラ +$ SIGABRT +6 ・「・ワ。シ・ネ・ネ・鬣テ・ラ +$ SIGEMT +7 EMT ・ネ・鬣テ・ラ +$ SIGFPE +8 ノ簇ーセョソナタホ羌ー +$ SIGKILL +9 Kill 、オ、、ソ +$ SIGBUS +10 ・ミ・ケ・ィ・鬘シ +$ SIGSEGV +11 ・サ・ー・皈・ニ。シ・キ・逾ー翳ソ +$ SIGSYS +12 ツクコ゚、キ、ハ、、・キ・ケ・ニ・爭ウ。シ・ +$ SIGPIPE +13 ・ム・、・ラヌヒイ +$ SIGALRM +14 ・「・鬘シ・爭ッ・・テ・ッ +$ SIGTERM +15 スェホサ +$ SIGURG +16 カロオ゙ニスミホマセカキ +$ SIGSTOP +17 ーサト莉゚ (・キ・ー・ハ・) +$ SIGTSTP +18 ーサト莉゚ +$ SIGCONT +19 キムツウ +$ SIGCHLD +20 サメ・ラ・・サ・ケ、ホスェホサ +$ SIGTTIN +21 ーサト莉゚ (tty ニホマ) +$ SIGTTOU +22 ーサト莉゚ (tty スミホマ) +$ SIGIO +23 ニスミホマイトヌス +$ SIGXCPU +24 CPU サエヨ、ホタゥクツトカイ +$ SIGXFSZ +25 ・ユ・。・、・・オ・、・コ、ホタゥクツトカイ +$ SIGVTALRM +26 イセチロ・ソ・、・゙、ホエクツトカイ +$ SIGPROF +27 ・ラ・・ユ・。・、・・ソ・、・゙、ホエクツトカイ +$ SIGWINCH +28 ・ヲ・」・・ノ・ヲ・オ・、・コ、ホハムイス +$ SIGINFO +29 セハヘラオ +$ SIGUSR1 +30 ・譯シ・カトオチ・キ・ー・ハ・ 1 +$ SIGUSR2 +31 ・譯シ・カトオチ・キ・ー・ハ・ 2 From 42f4692f5236fc29529d63552596f6c62c61ea9d Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 9 Nov 2009 12:38:13 +0000 Subject: [PATCH 588/646] Fix comment. Pointed out by: nyan MFC after: 1 week --- lib/libc/nls/ja_JP.UTF-8.msg | 2 +- lib/libc/nls/ja_JP.eucJP.msg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/nls/ja_JP.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg index 940f7b9923c..9ee98d17ae3 100644 --- a/lib/libc/nls/ja_JP.UTF-8.msg +++ b/lib/libc/nls/ja_JP.UTF-8.msg @@ -1,6 +1,6 @@ $ $FreeBSD$ $ -$ Message catalog for C locale (template) +$ Message catalog for ja_JP.UTF-8 locale $ $ strerror() support catalog $ diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg index 194016d0e3a..cba0157cb1f 100644 --- a/lib/libc/nls/ja_JP.eucJP.msg +++ b/lib/libc/nls/ja_JP.eucJP.msg @@ -1,6 +1,6 @@ $ $FreeBSD$ $ -$ Message catalog for C locale (template) +$ Message catalog for ja_JP.eucJP locale $ $ strerror() support catalog $ From 0d384326cdaa2c8deb57437b11e72ea44db25582 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 9 Nov 2009 12:46:59 +0000 Subject: [PATCH 589/646] Add NLS catalogs support to gai_strerror(3). Controlled by NLS define. --- lib/libc/net/gai_strerror.c | 58 +++++++++++++++++++++++++++++++++++++ lib/libc/nls/C.msg | 36 +++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/lib/libc/net/gai_strerror.c b/lib/libc/net/gai_strerror.c index 5611559cfe0..4f60f2db391 100644 --- a/lib/libc/net/gai_strerror.c +++ b/lib/libc/net/gai_strerror.c @@ -30,7 +30,17 @@ #include __FBSDID("$FreeBSD$"); +#include "namespace.h" #include +#if defined(NLS) +#include +#include +#include +#include +#include +#include "reentrant.h" +#endif +#include "un-namespace.h" /* Entries EAI_ADDRFAMILY (1) and EAI_NODATA (7) are obsoleted, but left */ /* for backward compatibility with userland code prior to 2553bis-02 */ @@ -52,9 +62,57 @@ static const char *ai_errlist[] = { "Argument buffer overflow" /* EAI_OVERFLOW */ }; +#if defined(NLS) +static char gai_buf[NL_TEXTMAX]; +static once_t gai_init_once = ONCE_INITIALIZER; +static thread_key_t gai_key; +static int gai_keycreated = 0; + +static void +gai_keycreate(void) +{ + gai_keycreated = (thr_keycreate(&gai_key, free) == 0); +} +#endif + const char * gai_strerror(int ecode) { +#if defined(NLS) + nl_catd catd; + char *buf; + + if (thr_main() != 0) + buf = gai_buf; + else { + if (thr_once(&gai_init_once, gai_keycreate) != 0 || + !gai_keycreated) + goto thr_err; + if ((buf = thr_getspecific(gai_key)) == NULL) { + if ((buf = malloc(sizeof(gai_buf))) == NULL) + goto thr_err; + if (thr_setspecific(gai_key, buf) != 0) { + free(buf); + goto thr_err; + } + } + } + + catd = catopen("libc", NL_CAT_LOCALE); + if (ecode > 0 && ecode < EAI_MAX) + strlcpy(buf, catgets(catd, 3, ecode, ai_errlist[ecode]), + sizeof(gai_buf)); + else if (ecode == 0) + strlcpy(buf, catgets(catd, 3, NL_MSGMAX - 1, "Success"), + sizeof(gai_buf)); + else + strlcpy(buf, catgets(catd, 3, NL_MSGMAX, "Unknown error"), + sizeof(gai_buf)); + catclose(catd); + return buf; + +thr_err: +#endif if (ecode >= 0 && ecode < EAI_MAX) return ai_errlist[ecode]; return "Unknown error"; diff --git a/lib/libc/nls/C.msg b/lib/libc/nls/C.msg index b25e83f330a..2210df6cc46 100644 --- a/lib/libc/nls/C.msg +++ b/lib/libc/nls/C.msg @@ -257,3 +257,39 @@ $ SIGUSR1 30 User defined signal 1 $ SIGUSR2 31 User defined signal 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 Address family for hostname not supported +$ EAI_AGAIN +2 Temporary failure in name resolution +$ EAI_BADFLAGS +3 Invalid value for ai_flags +$ EAI_FAIL +4 Non-recoverable failure in name resolution +$ EAI_FAMILY +5 ai_family not supported +$ EAI_MEMORY +6 Memory allocation failure +$ 7 (obsolete) +7 No address associated with hostname +$ EAI_NONAME +8 hostname nor servname provided, or not known +$ EAI_SERVICE +9 servname not supported for ai_socktype +$ EAI_SOCKTYPE +10 ai_socktype not supported +$ EAI_SYSTEM +11 System error returned in errno +$ EAI_BADHINTS +12 Invalid value for hints +$ EAI_PROTOCOL +13 Resolved protocol is unknown +$ EAI_OVERFLOW +14 Argument buffer overflow +$ 0 +32766 Success +$ NL_MSGMAX +32767 Unknown error From f90550c2d27c96bad81ae6afde592b4074060ed1 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Mon, 9 Nov 2009 14:26:23 +0000 Subject: [PATCH 590/646] Increase the size of the OFW translations buffer to handle G5 systems that use many translation regions in firmware, and add bounds checking to prevent buffer overflows in case even the new value is exceeded. Reported by: Jacob Lambert MFC after: 3 days --- sys/powerpc/aim/mmu_oea64.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 680a3915e1f..e9b9a1f73d2 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -264,7 +264,7 @@ static struct mem_region *pregions; extern u_int phys_avail_count; extern int regions_sz, pregions_sz; extern int ofw_real_mode; -static struct ofw_map translations[64]; +static struct ofw_map translations[96]; extern struct pmap ofw_pmap; @@ -897,6 +897,9 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele panic("moea64_bootstrap: can't get mmu package"); if ((sz = OF_getproplen(mmu, "translations")) == -1) panic("moea64_bootstrap: can't get ofw translation count"); + if (size > sizeof(translations)) + panic("moea64_bootstrap: too many ofw translations (%d)", + sz/sizeof(*translations)); bzero(translations, sz); if (OF_getprop(mmu, "translations", translations, sz) == -1) From 4d16b4ec425f9a3ffb19cea592b1199ce3885ad9 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 9 Nov 2009 15:59:09 +0000 Subject: [PATCH 591/646] Driver for the Apple Touchpad present on MacBook (non-Pro & Pro). Submitted by: Rohit Grover MFC after: 2 months --- sys/conf/files | 1 + sys/dev/usb/input/atp.c | 2047 ++++++++++++++++++++++++++++++++++ sys/modules/usb/Makefile | 2 +- sys/modules/usb/atp/Makefile | 11 + 4 files changed, 2060 insertions(+), 1 deletion(-) create mode 100644 sys/dev/usb/input/atp.c create mode 100644 sys/modules/usb/atp/Makefile diff --git a/sys/conf/files b/sys/conf/files index b8dee582038..a536b6d6731 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1698,6 +1698,7 @@ dev/usb/misc/udbp.c optional udbp # # USB input drivers # +dev/usb/input/atp.c optional atp dev/usb/input/uhid.c optional uhid dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c new file mode 100644 index 00000000000..18068029e6c --- /dev/null +++ b/sys/dev/usb/input/atp.c @@ -0,0 +1,2047 @@ +/*- + * Copyright (c) 2009 Rohit Grover + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "usbdevs.h" + +#define USB_DEBUG_VAR atp_debug +#include + +#include + +#define ATP_DRIVER_NAME "atp" + +/* + * Driver specific options: the following options may be set by + * `options' statements in the kernel configuration file. + */ + +/* The multiplier used to translate sensor reported positions to mickeys. */ +#ifndef ATP_SCALE_FACTOR +#define ATP_SCALE_FACTOR 48 +#endif + +/* + * This is the age (in microseconds) beyond which a touch is + * considered to be a slide; and therefore a tap event isn't registered. + */ +#ifndef ATP_TOUCH_TIMEOUT +#define ATP_TOUCH_TIMEOUT 125000 +#endif + +/* + * A double-tap followed by a single-finger slide is treated as a + * special gesture. The driver responds to this gesture by assuming a + * virtual button-press for the lifetime of the slide. The following + * threshold is the maximum time gap (in microseconds) between the two + * tap events preceding the slide for such a gesture. + */ +#ifndef ATP_DOUBLE_TAP_N_DRAG_THRESHOLD +#define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 200000 +#endif + +/* + * The device provides us only with pressure readings from an array of + * X and Y sensors; for our algorithms, we need to interpret groups + * (typically pairs) of X and Y readings as being related to a single + * finger stroke. We can relate X and Y readings based on their times + * of incidence. The coincidence window should be at least 10000us + * since it is used against values from getmicrotime(), which has a + * precision of around 10ms. + */ +#ifndef ATP_COINCIDENCE_THRESHOLD +#define ATP_COINCIDENCE_THRESHOLD 40000 /* unit: microseconds */ +#if ATP_COINCIDENCE_THRESHOLD > 100000 +#error "ATP_COINCIDENCE_THRESHOLD too large" +#endif +#endif /* #ifndef ATP_COINCIDENCE_THRESHOLD */ + +/* + * The wait duration (in microseconds) after losing a touch contact + * before zombied strokes are reaped and turned into button events. + */ +#define ATP_ZOMBIE_STROKE_REAP_WINDOW 50000 +#if ATP_ZOMBIE_STROKE_REAP_WINDOW > 100000 +#error "ATP_ZOMBIE_STROKE_REAP_WINDOW too large" +#endif + +/* end of driver specific options */ + + +/* Tunables */ +SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB atp"); + +#if USB_DEBUG +enum atp_log_level { + ATP_LLEVEL_DISABLED = 0, + ATP_LLEVEL_ERROR, + ATP_LLEVEL_DEBUG, /* for troubleshooting */ + ATP_LLEVEL_INFO, /* for diagnostics */ +}; +static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */ +SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RW, + &atp_debug, ATP_LLEVEL_ERROR, "ATP debug level"); +#endif /* #if USB_DEBUG */ + +static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT; +SYSCTL_INT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RW, &atp_touch_timeout, + 125000, "age threshold (in micros) for a touch"); + +static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD; +SYSCTL_INT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RW, + &atp_double_tap_threshold, ATP_DOUBLE_TAP_N_DRAG_THRESHOLD, + "maximum time (in micros) between a double-tap"); + +static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR; +static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale_factor, CTLTYPE_UINT | CTLFLAG_RW, + &atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor), + atp_sysctl_scale_factor_handler, "IU", "movement scale factor"); + +static u_int atp_small_movement_threshold = ATP_SCALE_FACTOR >> 3; +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RW, + &atp_small_movement_threshold, ATP_SCALE_FACTOR >> 3, + "the small movement black-hole for filtering noise"); +/* + * The movement threshold for a stroke; this is the maximum difference + * in position which will be resolved as a continuation of a stroke + * component. + */ +static u_int atp_max_delta_mickeys = ((3 * ATP_SCALE_FACTOR) >> 1); +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, max_delta_mickeys, CTLFLAG_RW, + &atp_max_delta_mickeys, ((3 * ATP_SCALE_FACTOR) >> 1), + "max. mickeys-delta which will match against an existing stroke"); +/* + * Strokes which accumulate at least this amount of absolute movement + * from the aggregate of their components are considered as + * slides. Unit: mickeys. + */ +static u_int atp_slide_min_movement = (ATP_SCALE_FACTOR >> 3); +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RW, + &atp_slide_min_movement, (ATP_SCALE_FACTOR >> 3), + "strokes with at least this amt. of movement are considered slides"); + +/* + * The minimum age of a stroke for it to be considered mature; this + * helps filter movements (noise) from immature strokes. Units: interrupts. + */ +static u_int atp_stroke_maturity_threshold = 2; +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RW, + &atp_stroke_maturity_threshold, 2, + "the minimum age of a stroke for it to be considered mature"); + +/* Accept pressure readings from sensors only if above this value. */ +static u_int atp_sensor_noise_threshold = 2; +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, sensor_noise_threshold, CTLFLAG_RW, + &atp_sensor_noise_threshold, 2, + "accept pressure readings from sensors only if above this value"); + +/* Ignore pressure spans with cumulative press. below this value. */ +static u_int atp_pspan_min_cum_pressure = 10; +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_min_cum_pressure, CTLFLAG_RW, + &atp_pspan_min_cum_pressure, 10, + "ignore pressure spans with cumulative press. below this value"); + +/* Maximum allowed width for pressure-spans.*/ +static u_int atp_pspan_max_width = 4; +SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_max_width, CTLFLAG_RW, + &atp_pspan_max_width, 4, + "maximum allowed width (in sensors) for pressure-spans"); + + +/* Define the various flavours of devices supported by this driver. */ +enum { + ATP_DEV_PARAMS_0, + ATP_N_DEV_PARAMS +}; +struct atp_dev_params { + u_int data_len; /* for sensor data */ + u_int n_xsensors; + u_int n_ysensors; +} atp_dev_params[ATP_N_DEV_PARAMS] = { + [ATP_DEV_PARAMS_0] = { + .data_len = 64, + .n_xsensors = 20, + .n_ysensors = 10 + }, +}; + +static const struct usb_device_id atp_devs[] = { + /* Core Duo MacBook & MacBook Pro */ + { USB_VPI(USB_VENDOR_APPLE, 0x0217, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x0218, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x0219, ATP_DEV_PARAMS_0) }, + + /* Core2 Duo MacBook & MacBook Pro */ + { USB_VPI(USB_VENDOR_APPLE, 0x021a, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x021b, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x021c, ATP_DEV_PARAMS_0) }, + + /* Core2 Duo MacBook3,1 */ + { USB_VPI(USB_VENDOR_APPLE, 0x0229, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x022a, ATP_DEV_PARAMS_0) }, + { USB_VPI(USB_VENDOR_APPLE, 0x022b, ATP_DEV_PARAMS_0) }, +}; + +/* + * The following structure captures the state of a pressure span along + * an axis. Each contact with the touchpad results in separate + * pressure spans along the two axes. + */ +typedef struct atp_pspan { + u_int width; /* in units of sensors */ + u_int cum; /* cumulative compression (from all sensors) */ + u_int cog; /* center of gravity */ + u_int loc; /* location (scaled using the mickeys factor) */ + boolean_t matched; /* to track pspans as they match against strokes. */ +} atp_pspan; + +typedef enum atp_stroke_type { + ATP_STROKE_TOUCH, + ATP_STROKE_SLIDE, +} atp_stroke_type; + +#define ATP_MAX_PSPANS_PER_AXIS 3 + +typedef struct atp_stroke_component { + /* Fields encapsulating the pressure-span. */ + u_int loc; /* location (scaled) */ + u_int cum_pressure; /* cumulative compression */ + u_int max_cum_pressure; /* max cumulative compression */ + boolean_t matched; /*to track components as they match against pspans.*/ + + /* Fields containing information about movement. */ + int delta_mickeys; /* change in location (un-smoothened movement)*/ + int pending; /* cum. of pending short movements */ + int movement; /* current smoothened movement */ +} atp_stroke_component; + +typedef enum atp_axis { + X = 0, + Y = 1 +} atp_axis; + +#define ATP_MAX_STROKES (2 * ATP_MAX_PSPANS_PER_AXIS) + +/* + * The following structure captures a finger contact with the + * touchpad. A stroke comprises two p-span components and some state. + */ +typedef struct atp_stroke { + atp_stroke_type type; + struct timeval ctime; /* create time; for coincident siblings. */ + u_int age; /* + * Unit: interrupts; we maintain + * this value in addition to + * 'ctime' in order to avoid the + * expensive call to microtime() + * at every interrupt. + */ + + atp_stroke_component components[2]; + u_int velocity_squared; /* + * Average magnitude (squared) + * of recent velocity. + */ + u_int cum_movement; /* cum. absolute movement so far */ + + uint32_t flags; /* the state of this stroke */ +#define ATSF_ZOMBIE 0x1 +} atp_stroke; + +#define ATP_FIFO_BUF_SIZE 8 /* bytes */ +#define ATP_FIFO_QUEUE_MAXLEN 50 /* units */ + +enum { + ATP_INTR_DT, + ATP_N_TRANSFER, +}; + +struct atp_softc { + device_t sc_dev; + struct usb_device *sc_usb_device; +#define MODE_LENGTH 8 + char sc_mode_bytes[MODE_LENGTH]; /* device mode */ + struct mtx sc_mutex; /* for synchronization */ + struct usb_xfer *sc_xfer[ATP_N_TRANSFER]; + struct usb_fifo_sc sc_fifo; + + struct atp_dev_params *sc_params; + + mousehw_t sc_hw; + mousemode_t sc_mode; + u_int sc_pollrate; + mousestatus_t sc_status; + u_int sc_state; +#define ATP_ENABLED 0x01 +#define ATP_ZOMBIES_EXIST 0x02 +#define ATP_DOUBLE_TAP_DRAG 0x04 + + u_int sc_left_margin; + u_int sc_right_margin; + + atp_stroke sc_strokes[ATP_MAX_STROKES]; + u_int sc_n_strokes; + + int8_t *sensor_data; /* from interrupt packet */ + int *base_x; /* base sensor readings */ + int *base_y; + int *cur_x; /* current sensor readings */ + int *cur_y; + int *pressure_x; /* computed pressures */ + int *pressure_y; + + u_int sc_idlecount; /* preceding idle interrupts */ +#define ATP_IDLENESS_THRESHOLD 10 + + struct timeval sc_reap_time; + struct timeval sc_reap_ctime; /*ctime of siblings to be reaped*/ +}; + +/* + * The last byte of the sensor data contains status bits; the + * following values define the meanings of these bits. + */ +enum atp_status_bits { + ATP_STATUS_BUTTON = (uint8_t)0x01, /* The button was pressed */ + ATP_STATUS_BASE_UPDATE = (uint8_t)0x04, /* Data from an untouched pad.*/ +}; + +typedef enum interface_mode { + RAW_SENSOR_MODE = (uint8_t)0x04, + HID_MODE = (uint8_t)0x08 +} interface_mode; + +/* + * function prototypes + */ +static usb_fifo_cmd_t atp_start_read; +static usb_fifo_cmd_t atp_stop_read; +static usb_fifo_open_t atp_open; +static usb_fifo_close_t atp_close; +static usb_fifo_ioctl_t atp_ioctl; + +static struct usb_fifo_methods atp_fifo_methods = { + .f_open = &atp_open, + .f_close = &atp_close, + .f_ioctl = &atp_ioctl, + .f_start_read = &atp_start_read, + .f_stop_read = &atp_stop_read, + .basename[0] = ATP_DRIVER_NAME, +}; + +/* device initialization and shutdown */ +static usb_error_t atp_req_get_report(struct usb_device *udev, void *data); +static int atp_set_device_mode(device_t dev, interface_mode mode); +static int atp_enable(struct atp_softc *sc); +static void atp_disable(struct atp_softc *sc); +static int atp_softc_populate(struct atp_softc *); +static void atp_softc_unpopulate(struct atp_softc *); + +/* sensor interpretation */ +static __inline void atp_interpret_sensor_data(const int8_t *, u_int, u_int, + int *); +static __inline void atp_get_pressures(int *, const int *, const int *, int); +static void atp_detect_pspans(int *, u_int, u_int, atp_pspan *, + u_int *); + +/* movement detection */ +static boolean_t atp_match_stroke_component(atp_stroke_component *, + const atp_pspan *); +static void atp_match_strokes_against_pspans(struct atp_softc *, + atp_axis, atp_pspan *, u_int, u_int); +static boolean_t atp_update_strokes(struct atp_softc *, + atp_pspan *, u_int, atp_pspan *, u_int); +static __inline void atp_add_stroke(struct atp_softc *, const atp_pspan *, + const atp_pspan *); +static void atp_add_new_strokes(struct atp_softc *, atp_pspan *, + u_int, atp_pspan *, u_int); +static void atp_advance_stroke_state(struct atp_softc *, + atp_stroke *, boolean_t *); +static void atp_terminate_stroke(struct atp_softc *, u_int); +static __inline boolean_t atp_stroke_has_small_movement(const atp_stroke *); +static __inline void atp_update_pending_mickeys(atp_stroke_component *); +static void atp_compute_smoothening_scale_ratio(atp_stroke *, int *, + int *); +static boolean_t atp_compute_stroke_movement(atp_stroke *); + +/* tap detection */ +static __inline void atp_setup_reap_time(struct atp_softc *, struct timeval *); +static void atp_reap_zombies(struct atp_softc *, u_int *, u_int *); + +/* updating fifo */ +static void atp_reset_buf(struct atp_softc *sc); +static void atp_add_to_queue(struct atp_softc *, int, int, uint32_t); + + +usb_error_t +atp_req_get_report(struct usb_device *udev, void *data) +{ + struct usb_device_request req; + + req.bmRequestType = UT_READ_CLASS_INTERFACE; + req.bRequest = UR_GET_REPORT; + USETW2(req.wValue, (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */); + USETW(req.wIndex, 0); + USETW(req.wLength, MODE_LENGTH); + + return (usbd_do_request(udev, NULL /* mutex */, &req, data)); +} + +static int +atp_set_device_mode(device_t dev, interface_mode mode) +{ + struct atp_softc *sc; + usb_device_request_t req; + usb_error_t err; + + if ((mode != RAW_SENSOR_MODE) && (mode != HID_MODE)) + return (ENXIO); + + sc = device_get_softc(dev); + + sc->sc_mode_bytes[0] = mode; + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_SET_REPORT; + USETW2(req.wValue, (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */); + USETW(req.wIndex, 0); + USETW(req.wLength, MODE_LENGTH); + err = usbd_do_request(sc->sc_usb_device, NULL, &req, sc->sc_mode_bytes); + if (err != USB_ERR_NORMAL_COMPLETION) + return (ENXIO); + + return (0); +} + +static int +atp_enable(struct atp_softc *sc) +{ + /* Allocate the dynamic buffers */ + if (atp_softc_populate(sc) != 0) { + atp_softc_unpopulate(sc); + return (ENOMEM); + } + + /* reset status */ + memset(sc->sc_strokes, 0, sizeof(sc->sc_strokes)); + sc->sc_n_strokes = 0; + memset(&sc->sc_status, 0, sizeof(sc->sc_status)); + sc->sc_idlecount = 0; + sc->sc_state |= ATP_ENABLED; + + DPRINTFN(ATP_LLEVEL_INFO, "enabled atp\n"); + return (0); +} + +static void +atp_disable(struct atp_softc *sc) +{ + atp_softc_unpopulate(sc); + + sc->sc_state &= ~ATP_ENABLED; + DPRINTFN(ATP_LLEVEL_INFO, "disabled atp\n"); +} + +/* Allocate dynamic memory for some fields in softc. */ +static int +atp_softc_populate(struct atp_softc *sc) +{ + const struct atp_dev_params *params = sc->sc_params; + + if (params == NULL) { + DPRINTF("params uninitialized!\n"); + return (ENXIO); + } + if (params->data_len) { + sc->sensor_data = malloc(params->data_len * sizeof(int8_t), + M_USB, M_WAITOK); + if (sc->sensor_data == NULL) { + DPRINTF("mem for sensor_data\n"); + return (ENXIO); + } + } + + if (params->n_xsensors != 0) { + sc->base_x = malloc(params->n_xsensors * sizeof(*(sc->base_x)), + M_USB, M_WAITOK); + if (sc->base_x == NULL) { + DPRINTF("mem for sc->base_x\n"); + return (ENXIO); + } + + sc->cur_x = malloc(params->n_xsensors * sizeof(*(sc->cur_x)), + M_USB, M_WAITOK); + if (sc->cur_x == NULL) { + DPRINTF("mem for sc->cur_x\n"); + return (ENXIO); + } + + sc->pressure_x = + malloc(params->n_xsensors * sizeof(*(sc->pressure_x)), + M_USB, M_WAITOK); + if (sc->pressure_x == NULL) { + DPRINTF("mem. for pressure_x\n"); + return (ENXIO); + } + } + + if (params->n_ysensors != 0) { + sc->base_y = malloc(params->n_ysensors * sizeof(*(sc->base_y)), + M_USB, M_WAITOK); + if (sc->base_y == NULL) { + DPRINTF("mem for base_y\n"); + return (ENXIO); + } + + sc->cur_y = malloc(params->n_ysensors * sizeof(*(sc->cur_y)), + M_USB, M_WAITOK); + if (sc->cur_y == NULL) { + DPRINTF("mem for cur_y\n"); + return (ENXIO); + } + + sc->pressure_y = + malloc(params->n_ysensors * sizeof(*(sc->pressure_y)), + M_USB, M_WAITOK); + if (sc->pressure_y == NULL) { + DPRINTF("mem. for pressure_y\n"); + return (ENXIO); + } + } + + return (0); +} + +/* Free dynamic memory allocated for some fields in softc. */ +static void +atp_softc_unpopulate(struct atp_softc *sc) +{ + const struct atp_dev_params *params = sc->sc_params; + + if (params == NULL) { + return; + } + if (params->n_xsensors != 0) { + if (sc->base_x != NULL) { + free(sc->base_x, M_USB); + sc->base_x = NULL; + } + + if (sc->cur_x != NULL) { + free(sc->cur_x, M_USB); + sc->cur_x = NULL; + } + + if (sc->pressure_x != NULL) { + free(sc->pressure_x, M_USB); + sc->pressure_x = NULL; + } + } + if (params->n_ysensors != 0) { + if (sc->base_y != NULL) { + free(sc->base_y, M_USB); + sc->base_y = NULL; + } + + if (sc->cur_y != NULL) { + free(sc->cur_y, M_USB); + sc->cur_y = NULL; + } + + if (sc->pressure_y != NULL) { + free(sc->pressure_y, M_USB); + sc->pressure_y = NULL; + } + } + if (sc->sensor_data != NULL) { + free(sc->sensor_data, M_USB); + sc->sensor_data = NULL; + } +} + +/* + * Interpret the data from the X and Y pressure sensors. This function + * is called separately for the X and Y sensor arrays. The data in the + * USB packet is laid out in the following manner: + * + * sensor_data: + * --,--,Y1,Y2,--,Y3,Y4,--,Y5,...,Y10, ... X1,X2,--,X3,X4 + * indices: 0 1 2 3 4 5 6 7 8 ... 15 ... 20 21 22 23 24 + * + * '--' (in the above) indicates that the value is unimportant. + * + * Information about the above layout was obtained from the + * implementation of the AppleTouch driver in Linux. + * + * parameters: + * sensor_data + * raw sensor data from the USB packet. + * num + * The number of elements in the array 'arr'. + * di_start + * The index of the first data element to be interpreted for + * this sensor array--i.e. when called to interpret the Y + * sensors, di_start passed in as 2, which is the index of Y1 in + * the raw data. + * arr + * The array to be initialized with the readings. + */ +static __inline void +atp_interpret_sensor_data(const int8_t *sensor_data, u_int num, u_int di_start, + int *arr) +{ + u_int i; + u_int di; /* index into sensor data */ + + for (i = 0, di = di_start; i < num; /* empty */ ) { + arr[i++] = sensor_data[di++]; + arr[i++] = sensor_data[di++]; + di++; + } +} + +static __inline void +atp_get_pressures(int *p, const int *cur, const int *base, int n) +{ + int i; + + for (i = 0; i < n; i++) { + p[i] = cur[i] - base[i]; + if (p[i] > 127) + p[i] -= 256; + if (p[i] < -127) + p[i] += 256; + if (p[i] < 0) + p[i] = 0; + + /* + * Shave off pressures below the noise-pressure + * threshold; this will reduce the contribution from + * lower pressure readings. + */ + if (p[i] <= atp_sensor_noise_threshold) + p[i] = 0; /* filter away noise */ + else + p[i] -= atp_sensor_noise_threshold; + } +} + +static void +atp_detect_pspans(int *p, u_int num_sensors, + u_int max_spans, /* max # of pspans permitted */ + atp_pspan *spans, /* finger spans */ + u_int *nspans_p) /* num spans detected */ +{ + u_int i; + int maxp; /* max pressure seen within a span */ + u_int num_spans = 0; + + enum atp_pspan_state { + ATP_PSPAN_INACTIVE, + ATP_PSPAN_INCREASING, + ATP_PSPAN_DECREASING, + } state; /* state of the pressure span */ + + /* + * The following is a simple state machine to track + * the phase of the pressure span. + */ + memset(spans, 0, max_spans * sizeof(atp_pspan)); + maxp = 0; + state = ATP_PSPAN_INACTIVE; + for (i = 0; i < num_sensors; i++) { + if (num_spans >= max_spans) + break; + + if (p[i] == 0) { + if (state == ATP_PSPAN_INACTIVE) { + /* + * There is no pressure information for this + * sensor, and we aren't tracking a finger. + */ + continue; + } else { + state = ATP_PSPAN_INACTIVE; + maxp = 0; + num_spans++; + } + } else { + switch (state) { + case ATP_PSPAN_INACTIVE: + state = ATP_PSPAN_INCREASING; + maxp = p[i]; + break; + + case ATP_PSPAN_INCREASING: + if (p[i] > maxp) + maxp = p[i]; + else if (p[i] <= (maxp >> 1)) + state = ATP_PSPAN_DECREASING; + break; + + case ATP_PSPAN_DECREASING: + if (p[i] > p[i - 1]) { + /* + * This is the beginning of + * another span; change state + * to give the appearance that + * we're starting from an + * inactive span, and then + * re-process this reading in + * the next iteration. + */ + num_spans++; + state = ATP_PSPAN_INACTIVE; + maxp = 0; + i--; + continue; + } + break; + } + + /* Update the finger span with this reading. */ + spans[num_spans].width++; + spans[num_spans].cum += p[i]; + spans[num_spans].cog += p[i] * (i + 1); + } + } + if (state != ATP_PSPAN_INACTIVE) + num_spans++; /* close the last finger span */ + + /* post-process the spans */ + for (i = 0; i < num_spans; i++) { + /* filter away unwanted pressure spans */ + if ((spans[i].cum < atp_pspan_min_cum_pressure) || + (spans[i].width > atp_pspan_max_width)) { + if ((i + 1) < num_spans) { + memcpy(&spans[i], &spans[i + 1], + (num_spans - i - 1) * sizeof(atp_pspan)); + i--; + } + num_spans--; + continue; + } + + /* compute this span's representative location */ + spans[i].loc = spans[i].cog * atp_mickeys_scale_factor / + spans[i].cum; + + spans[i].matched = FALSE; /* not yet matched against a stroke */ + } + + *nspans_p = num_spans; +} + +/* + * Match a pressure-span against a stroke-component. If there is a + * match, update the component's state and return TRUE. + */ +static boolean_t +atp_match_stroke_component(atp_stroke_component *component, + const atp_pspan *pspan) +{ + int delta_mickeys = pspan->loc - component->loc; + + if (abs(delta_mickeys) > atp_max_delta_mickeys) + return (FALSE); /* the finger span is too far out; no match */ + + component->loc = pspan->loc; + component->cum_pressure = pspan->cum; + if (pspan->cum > component->max_cum_pressure) + component->max_cum_pressure = pspan->cum; + + /* + * If the cumulative pressure drops below a quarter of the max, + * then disregard the component's movement. + */ + if (component->cum_pressure < (component->max_cum_pressure >> 2)) + delta_mickeys = 0; + + component->delta_mickeys = delta_mickeys; + return (TRUE); +} + +static void +atp_match_strokes_against_pspans(struct atp_softc *sc, atp_axis axis, + atp_pspan *pspans, u_int n_pspans, u_int repeat_count) +{ + u_int i, j; + u_int repeat_index = 0; + + /* Determine the index of the multi-span. */ + if (repeat_count) { + u_int cum = 0; + for (i = 0; i < n_pspans; i++) { + if (pspans[i].cum > cum) { + repeat_index = i; + cum = pspans[i].cum; + } + } + } + + for (i = 0; i < sc->sc_n_strokes; i++) { + atp_stroke *stroke = &sc->sc_strokes[i]; + if (stroke->components[axis].matched) + continue; /* skip matched components */ + + for (j = 0; j < n_pspans; j++) { + if (pspans[j].matched) + continue; /* skip matched pspans */ + + if (atp_match_stroke_component( + &stroke->components[axis], &pspans[j])) { + /* There is a match. */ + stroke->components[axis].matched = TRUE; + + /* Take care to repeat at the multi-span. */ + if ((repeat_count > 0) && (j == repeat_index)) + repeat_count--; + else + pspans[j].matched = TRUE; + + break; /* skip to the next stroke */ + } + } /* loop over pspans */ + } /* loop over strokes */ +} + +/* + * Update strokes by matching against current pressure-spans. + * Return TRUE if any movement is detected. + */ +static boolean_t +atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x, + u_int n_xpspans, atp_pspan *pspans_y, u_int n_ypspans) +{ + u_int i, j; + atp_stroke *stroke; + boolean_t movement = FALSE; + u_int repeat_count = 0; + + /* Reset X and Y components of all strokes as unmatched. */ + for (i = 0; i < sc->sc_n_strokes; i++) { + stroke = &sc->sc_strokes[i]; + stroke->components[X].matched = FALSE; + stroke->components[Y].matched = FALSE; + } + + /* + * Usually, the X and Y pspans come in pairs (the common case + * being a single pair). It is possible, however, that + * multiple contacts resolve to a single pspan along an + * axis, as illustrated in the following: + * + * F = finger-contact + * + * pspan pspan + * +-----------------------+ + * | . . | + * | . . | + * | . . | + * | . . | + * pspan |.........F......F | + * | | + * | | + * | | + * +-----------------------+ + * + * + * The above case can be detected by a difference in the + * number of X and Y pspans. When this happens, X and Y pspans + * aren't easy to pair or match against strokes. + * + * When X and Y pspans differ in number, the axis with the + * smaller number of pspans is regarded as having a repeating + * pspan (or a multi-pspan)--in the above illustration, the + * Y-axis has a repeating pspan. Our approach is to try to + * match the multi-pspan repeatedly against strokes. The + * difference between the number of X and Y pspans gives us a + * crude repeat_count for matching multi-pspans--i.e. the + * multi-pspan along the Y axis (above) has a repeat_count of 1. + */ + repeat_count = abs(n_xpspans - n_ypspans); + + atp_match_strokes_against_pspans(sc, X, pspans_x, n_xpspans, + (((repeat_count != 0) && ((n_xpspans < n_ypspans))) ? + repeat_count : 0)); + atp_match_strokes_against_pspans(sc, Y, pspans_y, n_ypspans, + (((repeat_count != 0) && (n_ypspans < n_xpspans)) ? + repeat_count : 0)); + + /* Update the state of strokes based on the above pspan matches. */ + for (i = 0; i < sc->sc_n_strokes; i++) { + stroke = &sc->sc_strokes[i]; + if (stroke->components[X].matched && + stroke->components[Y].matched) { + atp_advance_stroke_state(sc, stroke, &movement); + } else { + /* + * At least one component of this stroke + * didn't match against current pspans; + * terminate it. + */ + atp_terminate_stroke(sc, i); + } + } + + /* Add new strokes for pairs of unmatched pspans */ + for (i = 0; i < n_xpspans; i++) { + if (pspans_x[i].matched == FALSE) break; + } + for (j = 0; j < n_ypspans; j++) { + if (pspans_y[j].matched == FALSE) break; + } + if ((i < n_xpspans) && (j < n_ypspans)) { +#if USB_DEBUG + if (atp_debug >= ATP_LLEVEL_INFO) { + printf("unmatched pspans:"); + for (; i < n_xpspans; i++) { + if (pspans_x[i].matched) + continue; + printf(" X:[loc:%u,cum:%u]", + pspans_x[i].loc, pspans_x[i].cum); + } + for (; j < n_ypspans; j++) { + if (pspans_y[j].matched) + continue; + printf(" Y:[loc:%u,cum:%u]", + pspans_y[j].loc, pspans_y[j].cum); + } + printf("\n"); + } +#endif /* #if USB_DEBUG */ + if ((n_xpspans == 1) && (n_ypspans == 1)) + /* The common case of a single pair of new pspans. */ + atp_add_stroke(sc, &pspans_x[0], &pspans_y[0]); + else + atp_add_new_strokes(sc, + pspans_x, n_xpspans, + pspans_y, n_ypspans); + } + +#if USB_DEBUG + if (atp_debug >= ATP_LLEVEL_INFO) { + for (i = 0; i < sc->sc_n_strokes; i++) { + atp_stroke *stroke = &sc->sc_strokes[i]; + + printf(" %s%clc:%u,dm:%d,pnd:%d,mv:%d%c" + ",%clc:%u,dm:%d,pnd:%d,mv:%d%c", + (stroke->flags & ATSF_ZOMBIE) ? "zomb:" : "", + (stroke->type == ATP_STROKE_TOUCH) ? '[' : '<', + stroke->components[X].loc, + stroke->components[X].delta_mickeys, + stroke->components[X].pending, + stroke->components[X].movement, + (stroke->type == ATP_STROKE_TOUCH) ? ']' : '>', + (stroke->type == ATP_STROKE_TOUCH) ? '[' : '<', + stroke->components[Y].loc, + stroke->components[Y].delta_mickeys, + stroke->components[Y].pending, + stroke->components[Y].movement, + (stroke->type == ATP_STROKE_TOUCH) ? ']' : '>'); + } + if (sc->sc_n_strokes) + printf("\n"); + } +#endif /* #if USB_DEBUG */ + + return (movement); +} + +/* Initialize a stroke using a pressure-span. */ +static __inline void +atp_add_stroke(struct atp_softc *sc, const atp_pspan *pspan_x, + const atp_pspan *pspan_y) +{ + atp_stroke *stroke; + + if (sc->sc_n_strokes >= ATP_MAX_STROKES) + return; + stroke = &sc->sc_strokes[sc->sc_n_strokes]; + + memset(stroke, 0, sizeof(atp_stroke)); + + /* + * Strokes begin as potential touches. If a stroke survives + * longer than a threshold, or if it records significant + * cumulative movement, then it is considered a 'slide'. + */ + stroke->type = ATP_STROKE_TOUCH; + microtime(&stroke->ctime); + stroke->age = 1; /* Unit: interrupts */ + + stroke->components[X].loc = pspan_x->loc; + stroke->components[X].cum_pressure = pspan_x->cum; + stroke->components[X].max_cum_pressure = pspan_x->cum; + stroke->components[X].matched = TRUE; + + stroke->components[Y].loc = pspan_y->loc; + stroke->components[Y].cum_pressure = pspan_y->cum; + stroke->components[Y].max_cum_pressure = pspan_y->cum; + stroke->components[Y].matched = TRUE; + + sc->sc_n_strokes++; + if (sc->sc_n_strokes > 1) { + /* Reset double-tap-n-drag if we have more than one strokes. */ + sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; + } + + DPRINTFN(ATP_LLEVEL_INFO, "[%u,%u], time: %u,%ld\n", + stroke->components[X].loc, + stroke->components[Y].loc, + (unsigned int)stroke->ctime.tv_sec, + (unsigned long int)stroke->ctime.tv_usec); +} + +static void +atp_add_new_strokes(struct atp_softc *sc, atp_pspan *pspans_x, + u_int n_xpspans, atp_pspan *pspans_y, u_int n_ypspans) +{ + int i, j; + atp_pspan spans[2][ATP_MAX_PSPANS_PER_AXIS]; + u_int nspans[2]; + + /* Copy unmatched pspans into the local arrays. */ + for (i = 0, nspans[X] = 0; i < n_xpspans; i++) { + if (pspans_x[i].matched == FALSE) { + spans[X][nspans[X]] = pspans_x[i]; + nspans[X]++; + } + } + for (j = 0, nspans[Y] = 0; j < n_ypspans; j++) { + if (pspans_y[j].matched == FALSE) { + spans[Y][nspans[Y]] = pspans_y[j]; + nspans[Y]++; + } + } + + if (nspans[X] == nspans[Y]) { + /* Create new strokes from pairs of unmatched pspans */ + for (i = 0, j = 0; (i < nspans[X]) && (j < nspans[Y]); i++, j++) + atp_add_stroke(sc, &spans[X][i], &spans[Y][j]); + } else { + u_int cum = 0; + atp_axis repeat_axis; /* axis with multi-pspans */ + u_int repeat_count; /* repeat count for the multi-pspan*/ + u_int repeat_index = 0; /* index of the multi-span */ + + repeat_axis = (nspans[X] > nspans[Y]) ? Y : X; + repeat_count = abs(nspans[X] - nspans[Y]); + for (i = 0; i < nspans[repeat_axis]; i++) { + if (spans[repeat_axis][i].cum > cum) { + repeat_index = i; + cum = spans[repeat_axis][i].cum; + } + } + + /* Create new strokes from pairs of unmatched pspans */ + i = 0, j = 0; + for (; (i < nspans[X]) && (j < nspans[Y]); i++, j++) { + atp_add_stroke(sc, &spans[X][i], &spans[Y][j]); + + /* Take care to repeat at the multi-pspan. */ + if (repeat_count > 0) { + if ((repeat_axis == X) && + (repeat_index == i)) { + i--; /* counter loop increment */ + repeat_count--; + } else if ((repeat_axis == Y) && + (repeat_index == j)) { + j--; /* counter loop increment */ + repeat_count--; + } + } + } + } +} + +/* + * Advance the state of this stroke--and update the out-parameter + * 'movement' as a side-effect. + */ +void +atp_advance_stroke_state(struct atp_softc *sc, atp_stroke *stroke, + boolean_t *movement) +{ + stroke->age++; + if (stroke->age <= atp_stroke_maturity_threshold) { + /* Avoid noise from immature strokes. */ + stroke->components[X].delta_mickeys = 0; + stroke->components[Y].delta_mickeys = 0; + } + + /* Revitalize stroke if it had previously been marked as a zombie. */ + if (stroke->flags & ATSF_ZOMBIE) + stroke->flags &= ~ATSF_ZOMBIE; + + if (atp_compute_stroke_movement(stroke)) + *movement = TRUE; + + /* Convert touch strokes to slides upon detecting movement or age. */ + if (stroke->type == ATP_STROKE_TOUCH) { + struct timeval tdiff; + + /* Compute the stroke's age. */ + getmicrotime(&tdiff); + if (timevalcmp(&tdiff, &stroke->ctime, >)) + timevalsub(&tdiff, &stroke->ctime); + else { + /* + * If we are here, it is because getmicrotime + * reported the current time as being behind + * the stroke's start time; getmicrotime can + * be imprecise. + */ + tdiff.tv_sec = 0; + tdiff.tv_usec = 0; + } + + if ((tdiff.tv_sec > (atp_touch_timeout / 1000000)) || + ((tdiff.tv_sec == (atp_touch_timeout / 1000000)) && + (tdiff.tv_usec > atp_touch_timeout)) || + (stroke->cum_movement >= atp_slide_min_movement)) { + /* Switch this stroke to being a slide. */ + stroke->type = ATP_STROKE_SLIDE; + + /* Are we at the beginning of a double-click-n-drag? */ + if ((sc->sc_n_strokes == 1) && + ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) && + timevalcmp(&stroke->ctime, &sc->sc_reap_time, >)) { + struct timeval delta; + struct timeval window = { + atp_double_tap_threshold / 1000000, + atp_double_tap_threshold % 1000000 + }; + + delta = stroke->ctime; + timevalsub(&delta, &sc->sc_reap_time); + if (timevalcmp(&delta, &window, <=)) + sc->sc_state |= ATP_DOUBLE_TAP_DRAG; + } + } + } +} + +/* + * Terminate a stroke. While SLIDE strokes are dropped, TOUCH strokes + * are retained as zombies so as to reap all their siblings together; + * this helps establish the number of fingers involved in the tap. + */ +static void +atp_terminate_stroke(struct atp_softc *sc, + u_int index) /* index of the stroke to be terminated */ +{ + atp_stroke *s = &sc->sc_strokes[index]; + + if (s->flags & ATSF_ZOMBIE) { + return; + } + + if ((s->type == ATP_STROKE_TOUCH) && + (s->age > atp_stroke_maturity_threshold)) { + s->flags |= ATSF_ZOMBIE; + + /* If no zombies exist, then prepare to reap zombies later. */ + if ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) { + atp_setup_reap_time(sc, &s->ctime); + sc->sc_state |= ATP_ZOMBIES_EXIST; + } + } else { + /* Drop this stroke. */ + memcpy(&sc->sc_strokes[index], &sc->sc_strokes[index + 1], + (sc->sc_n_strokes - index - 1) * sizeof(atp_stroke)); + sc->sc_n_strokes--; + + /* + * Reset the double-click-n-drag at the termination of + * any slide stroke. + */ + sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; + } +} + +static __inline boolean_t +atp_stroke_has_small_movement(const atp_stroke *stroke) +{ + return ((abs(stroke->components[X].delta_mickeys) <= + atp_small_movement_threshold) && + (abs(stroke->components[Y].delta_mickeys) <= + atp_small_movement_threshold)); +} + +/* + * Accumulate delta_mickeys into the component's 'pending' bucket; if + * the aggregate exceeds the small_movement_threshold, then retain + * delta_mickeys for later. + */ +static __inline void +atp_update_pending_mickeys(atp_stroke_component *component) +{ + component->pending += component->delta_mickeys; + if (abs(component->pending) <= atp_small_movement_threshold) + component->delta_mickeys = 0; + else { + /* + * Penalise pending mickeys for having accumulated + * over short deltas. This operation has the effect of + * scaling down the cumulative contribution of short + * movements. + */ + component->pending -= (component->delta_mickeys << 1); + } +} + + +static void +atp_compute_smoothening_scale_ratio(atp_stroke *stroke, int *numerator, + int *denominator) +{ + int dxdt; + int dydt; + u_int vel_squared; /* Square of the velocity vector's magnitude. */ + u_int vel_squared_smooth; + + /* Table holding (10 * sqrt(x)) for x between 1 and 256. */ + static uint8_t sqrt_table[256] = { + 10, 14, 17, 20, 22, 24, 26, 28, + 30, 31, 33, 34, 36, 37, 38, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 50, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 60, 61, 62, 63, + 64, 64, 65, 66, 67, 67, 68, 69, + 70, 70, 71, 72, 72, 73, 74, 74, + 75, 76, 76, 77, 78, 78, 79, 80, + 80, 81, 81, 82, 83, 83, 84, 84, + 85, 86, 86, 87, 87, 88, 88, 89, + 90, 90, 91, 91, 92, 92, 93, 93, + 94, 94, 95, 95, 96, 96, 97, 97, + 98, 98, 99, 100, 100, 100, 101, 101, + 102, 102, 103, 103, 104, 104, 105, 105, + 106, 106, 107, 107, 108, 108, 109, 109, + 110, 110, 110, 111, 111, 112, 112, 113, + 113, 114, 114, 114, 115, 115, 116, 116, + 117, 117, 117, 118, 118, 119, 119, 120, + 120, 120, 121, 121, 122, 122, 122, 123, + 123, 124, 124, 124, 125, 125, 126, 126, + 126, 127, 127, 128, 128, 128, 129, 129, + 130, 130, 130, 131, 131, 131, 132, 132, + 133, 133, 133, 134, 134, 134, 135, 135, + 136, 136, 136, 137, 137, 137, 138, 138, + 138, 139, 139, 140, 140, 140, 141, 141, + 141, 142, 142, 142, 143, 143, 143, 144, + 144, 144, 145, 145, 145, 146, 146, 146, + 147, 147, 147, 148, 148, 148, 149, 149, + 150, 150, 150, 150, 151, 151, 151, 152, + 152, 152, 153, 153, 153, 154, 154, 154, + 155, 155, 155, 156, 156, 156, 157, 157, + 157, 158, 158, 158, 159, 159, 159, 160 + }; + const u_int N = sizeof(sqrt_table) / sizeof(sqrt_table[0]); + + dxdt = stroke->components[X].delta_mickeys; + dydt = stroke->components[Y].delta_mickeys; + + *numerator = 0, *denominator = 0; /* default values. */ + + /* Compute a smoothened magnitude_squared of the stroke's velocity. */ + vel_squared = dxdt * dxdt + dydt * dydt; + vel_squared_smooth = (3 * stroke->velocity_squared + vel_squared) >> 2; + stroke->velocity_squared = vel_squared_smooth; /* retained as history */ + if ((vel_squared == 0) || (vel_squared_smooth == 0)) + return; /* returning (numerator == 0) will imply zero movement*/ + + /* + * In order to determine the overall movement scale factor, + * we're actually interested in the effect of smoothening upon + * the *magnitude* of velocity; i.e. we need to compute the + * square-root of (vel_squared_smooth / vel_squared) in the + * form of a numerator and denominator. + */ + + /* Keep within the bounds of the square-root table. */ + while ((vel_squared > N) || (vel_squared_smooth > N)) { + /* Dividing uniformly by 2 won't disturb the final ratio. */ + vel_squared >>= 1; + vel_squared_smooth >>= 1; + } + + *numerator = sqrt_table[vel_squared_smooth - 1]; + *denominator = sqrt_table[vel_squared - 1]; +} + +/* + * Compute a smoothened value for the stroke's movement from + * delta_mickeys in the X and Y components. + */ +static boolean_t +atp_compute_stroke_movement(atp_stroke *stroke) +{ + int num; /* numerator of scale ratio */ + int denom; /* denominator of scale ratio */ + + /* + * Short movements are added first to the 'pending' bucket, + * and then acted upon only when their aggregate exceeds a + * threshold. This has the effect of filtering away movement + * noise. + */ + if (atp_stroke_has_small_movement(stroke)) { + atp_update_pending_mickeys(&stroke->components[X]); + atp_update_pending_mickeys(&stroke->components[Y]); + } else { /* large movement */ + /* clear away any pending mickeys if there are large movements*/ + stroke->components[X].pending = 0; + stroke->components[Y].pending = 0; + } + + /* Get the scale ratio and smoothen movement. */ + atp_compute_smoothening_scale_ratio(stroke, &num, &denom); + if ((num == 0) || (denom == 0)) { + stroke->components[X].movement = 0; + stroke->components[Y].movement = 0; + stroke->velocity_squared >>= 1; /* Erode velocity_squared. */ + } else { + stroke->components[X].movement = + (stroke->components[X].delta_mickeys * num) / denom; + stroke->components[Y].movement = + (stroke->components[Y].delta_mickeys * num) / denom; + + stroke->cum_movement += + abs(stroke->components[X].movement) + + abs(stroke->components[Y].movement); + } + + return ((stroke->components[X].movement != 0) || + (stroke->components[Y].movement != 0)); +} + +static __inline void +atp_setup_reap_time(struct atp_softc *sc, struct timeval *tvp) +{ + struct timeval reap_window = { + ATP_ZOMBIE_STROKE_REAP_WINDOW / 1000000, + ATP_ZOMBIE_STROKE_REAP_WINDOW % 1000000 + }; + + microtime(&sc->sc_reap_time); + timevaladd(&sc->sc_reap_time, &reap_window); + + sc->sc_reap_ctime = *tvp; /* ctime to reap */ +} + +static void +atp_reap_zombies(struct atp_softc *sc, u_int *n_reaped, u_int *reaped_xlocs) +{ + u_int i; + atp_stroke *stroke; + + *n_reaped = 0; + for (i = 0; i < sc->sc_n_strokes; i++) { + struct timeval tdiff; + + stroke = &sc->sc_strokes[i]; + + if ((stroke->flags & ATSF_ZOMBIE) == 0) + continue; + + /* Compare this stroke's ctime with the ctime being reaped. */ + if (timevalcmp(&stroke->ctime, &sc->sc_reap_ctime, >=)) { + tdiff = stroke->ctime; + timevalsub(&tdiff, &sc->sc_reap_ctime); + } else { + tdiff = sc->sc_reap_ctime; + timevalsub(&tdiff, &stroke->ctime); + } + + if ((tdiff.tv_sec > (ATP_COINCIDENCE_THRESHOLD / 1000000)) || + ((tdiff.tv_sec == (ATP_COINCIDENCE_THRESHOLD / 1000000)) && + (tdiff.tv_usec > (ATP_COINCIDENCE_THRESHOLD % 1000000)))) { + continue; /* Skip non-siblings. */ + } + + /* + * Reap this sibling zombie stroke. + */ + + if (reaped_xlocs != NULL) + reaped_xlocs[*n_reaped] = stroke->components[X].loc; + + /* Erase the stroke from the sc. */ + memcpy(&stroke[i], &stroke[i + 1], + (sc->sc_n_strokes - i - 1) * sizeof(atp_stroke)); + sc->sc_n_strokes--; + + *n_reaped += 1; + --i; /* Decr. i to keep it unchanged for the next iteration */ + } + + DPRINTFN(ATP_LLEVEL_INFO, "reaped %u zombies\n", *n_reaped); + + /* There could still be zombies remaining in the system. */ + for (i = 0; i < sc->sc_n_strokes; i++) { + stroke = &sc->sc_strokes[i]; + if (stroke->flags & ATSF_ZOMBIE) { + DPRINTFN(ATP_LLEVEL_INFO, "zombies remain!\n"); + atp_setup_reap_time(sc, &stroke->ctime); + return; + } + } + + /* If we reach here, then no more zombies remain. */ + sc->sc_state &= ~ATP_ZOMBIES_EXIST; +} + + +/* Device methods. */ +static device_probe_t atp_probe; +static device_attach_t atp_attach; +static device_detach_t atp_detach; +static usb_callback_t atp_intr; + +static const struct usb_config atp_config[ATP_N_TRANSFER] = { + [ATP_INTR_DT] = { + .type = UE_INTERRUPT, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .flags = { + .pipe_bof = 1, + .short_xfer_ok = 1, + }, + .bufsize = 0, /* use wMaxPacketSize */ + .callback = &atp_intr, + }, +}; + +static int +atp_probe(device_t self) +{ + struct usb_attach_arg *uaa = device_get_ivars(self); + + if (uaa->usb_mode != USB_MODE_HOST) + return (ENXIO); + + if ((uaa->info.bInterfaceClass != UICLASS_HID) || + (uaa->info.bInterfaceProtocol != UIPROTO_MOUSE)) + return (ENXIO); + + if (usbd_lookup_id_by_uaa(atp_devs, sizeof(atp_devs), uaa) == 0) + return BUS_PROBE_SPECIFIC; + else + return ENXIO; +} + +static int +atp_attach(device_t dev) +{ + struct atp_softc *sc = device_get_softc(dev); + struct usb_attach_arg *uaa = device_get_ivars(dev); + usb_error_t err; + + /* ensure that the probe was successful */ + if (uaa->driver_info >= ATP_N_DEV_PARAMS) { + DPRINTF("device probe returned bad id: %lu\n", + uaa->driver_info); + return (ENXIO); + } + DPRINTFN(ATP_LLEVEL_INFO, "sc=%p\n", sc); + + sc->sc_dev = dev; + sc->sc_usb_device = uaa->device; + + /* + * By default the touchpad behaves like an HID device, sending + * packets with reportID = 2. Such reports contain only + * limited information--they encode movement deltas and button + * events,--but do not include data from the pressure + * sensors. The device input mode can be switched from HID + * reports to raw sensor data using vendor-specific USB + * control commands; but first the mode must be read. + */ + err = atp_req_get_report(sc->sc_usb_device, sc->sc_mode_bytes); + if (err != USB_ERR_NORMAL_COMPLETION) { + DPRINTF("failed to read device mode (%d)\n", err); + return (ENXIO); + } + + if (atp_set_device_mode(dev, RAW_SENSOR_MODE) != 0) { + DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err); + return (ENXIO); + } + + mtx_init(&sc->sc_mutex, "atpmtx", NULL, MTX_DEF | MTX_RECURSE); + + err = usbd_transfer_setup(uaa->device, + &uaa->info.bIfaceIndex, sc->sc_xfer, atp_config, + ATP_N_TRANSFER, sc, &sc->sc_mutex); + + if (err) { + DPRINTF("error=%s\n", usbd_errstr(err)); + goto detach; + } + + if (usb_fifo_attach(sc->sc_usb_device, sc, &sc->sc_mutex, + &atp_fifo_methods, &sc->sc_fifo, + device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex, + UID_ROOT, GID_OPERATOR, 0644)) { + goto detach; + } + + device_set_usb_desc(dev); + + sc->sc_params = &atp_dev_params[uaa->driver_info]; + + sc->sc_hw.buttons = 3; + sc->sc_hw.iftype = MOUSE_IF_USB; + sc->sc_hw.type = MOUSE_PAD; + sc->sc_hw.model = MOUSE_MODEL_GENERIC; + sc->sc_hw.hwid = 0; + sc->sc_mode.protocol = MOUSE_PROTO_MSC; + sc->sc_mode.rate = -1; + sc->sc_mode.resolution = MOUSE_RES_UNKNOWN; + sc->sc_mode.accelfactor = 0; + sc->sc_mode.level = 0; + sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; + sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; + sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; + + sc->sc_state = 0; + + sc->sc_left_margin = atp_mickeys_scale_factor; + sc->sc_right_margin = (sc->sc_params->n_xsensors - 1) * + atp_mickeys_scale_factor; + + return (0); + +detach: + atp_detach(dev); + return (ENOMEM); +} + +static int +atp_detach(device_t dev) +{ + struct atp_softc *sc; + int err; + + sc = device_get_softc(dev); + if (sc->sc_state & ATP_ENABLED) { + mtx_lock(&sc->sc_mutex); + atp_disable(sc); + mtx_unlock(&sc->sc_mutex); + } + + usb_fifo_detach(&sc->sc_fifo); + + usbd_transfer_unsetup(sc->sc_xfer, ATP_N_TRANSFER); + + mtx_destroy(&sc->sc_mutex); + + err = atp_set_device_mode(dev, HID_MODE); + if (err != 0) { + DPRINTF("failed to reset mode to 'HID' (%d)\n", err); + return (err); + } + + return (0); +} + +static void +atp_intr(struct usb_xfer *xfer, usb_error_t error) +{ + struct atp_softc *sc = usbd_xfer_softc(xfer); + int len; + struct usb_page_cache *pc; + uint8_t status_bits; + atp_pspan pspans_x[ATP_MAX_PSPANS_PER_AXIS]; + atp_pspan pspans_y[ATP_MAX_PSPANS_PER_AXIS]; + u_int n_xpspans = 0, n_ypspans = 0; + u_int reaped_xlocs[ATP_MAX_STROKES]; + u_int tap_fingers = 0; + + usbd_xfer_status(xfer, &len, NULL, NULL, NULL); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + if (len > sc->sc_params->data_len) { + DPRINTFN(ATP_LLEVEL_ERROR, + "truncating large packet from %u to %u bytes\n", + len, sc->sc_params->data_len); + len = sc->sc_params->data_len; + } + if (len == 0) + goto tr_setup; + + pc = usbd_xfer_get_frame(xfer, 0); + usbd_copy_out(pc, 0, sc->sensor_data, sc->sc_params->data_len); + + /* Interpret sensor data */ + atp_interpret_sensor_data(sc->sensor_data, + sc->sc_params->n_xsensors, 20, sc->cur_x); + atp_interpret_sensor_data(sc->sensor_data, + sc->sc_params->n_ysensors, 2, sc->cur_y); + + /* + * If this is the initial update (from an untouched + * pad), we should set the base values for the sensor + * data; deltas with respect to these base values can + * be used as pressure readings subsequently. + */ + status_bits = sc->sensor_data[sc->sc_params->data_len - 1]; + if (status_bits & ATP_STATUS_BASE_UPDATE) { + memcpy(sc->base_x, sc->cur_x, + sc->sc_params->n_xsensors * sizeof(*(sc->base_x))); + memcpy(sc->base_y, sc->cur_y, + sc->sc_params->n_ysensors * sizeof(*(sc->base_y))); + goto tr_setup; + } + + /* Get pressure readings and detect p-spans for both axes. */ + atp_get_pressures(sc->pressure_x, sc->cur_x, sc->base_x, + sc->sc_params->n_xsensors); + atp_detect_pspans(sc->pressure_x, sc->sc_params->n_xsensors, + ATP_MAX_PSPANS_PER_AXIS, + pspans_x, &n_xpspans); + atp_get_pressures(sc->pressure_y, sc->cur_y, sc->base_y, + sc->sc_params->n_ysensors); + atp_detect_pspans(sc->pressure_y, sc->sc_params->n_ysensors, + ATP_MAX_PSPANS_PER_AXIS, + pspans_y, &n_ypspans); + + /* Update strokes with new pspans to detect movements. */ + sc->sc_status.flags &= ~MOUSE_POSCHANGED; + if (atp_update_strokes(sc, + pspans_x, n_xpspans, + pspans_y, n_ypspans)) + sc->sc_status.flags |= MOUSE_POSCHANGED; + + /* Reap zombies if it is time. */ + if (sc->sc_state & ATP_ZOMBIES_EXIST) { + struct timeval now; + + getmicrotime(&now); + if (timevalcmp(&now, &sc->sc_reap_time, >=)) + atp_reap_zombies(sc, &tap_fingers, + reaped_xlocs); + } + + sc->sc_status.flags &= ~MOUSE_STDBUTTONSCHANGED; + sc->sc_status.obutton = sc->sc_status.button; + + /* Get the state of the physical buttton. */ + sc->sc_status.button = (status_bits & ATP_STATUS_BUTTON) ? + MOUSE_BUTTON1DOWN : 0; + if (sc->sc_status.button != 0) { + /* Reset DOUBLE_TAP_N_DRAG if the button is pressed. */ + sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; + } else if (sc->sc_state & ATP_DOUBLE_TAP_DRAG) { + /* Assume a button-press with DOUBLE_TAP_N_DRAG. */ + sc->sc_status.button = MOUSE_BUTTON1DOWN; + } + + sc->sc_status.flags |= + sc->sc_status.button ^ sc->sc_status.obutton; + if (sc->sc_status.flags & MOUSE_STDBUTTONSCHANGED) { + DPRINTFN(ATP_LLEVEL_INFO, "button %s\n", + ((sc->sc_status.button & MOUSE_BUTTON1DOWN) ? + "pressed" : "released")); + } else if ((sc->sc_status.obutton == 0) && + (sc->sc_status.button == 0) && + (tap_fingers != 0)) { + /* Ignore single-finger taps at the edges. */ + if ((tap_fingers == 1) && + ((reaped_xlocs[0] <= sc->sc_left_margin) || + (reaped_xlocs[0] > sc->sc_right_margin))) { + tap_fingers = 0; + } + DPRINTFN(ATP_LLEVEL_INFO, + "tap_fingers: %u\n", tap_fingers); + } + + if (sc->sc_status.flags & + (MOUSE_POSCHANGED | MOUSE_STDBUTTONSCHANGED)) { + int dx, dy; + u_int n_movements; + + dx = 0, dy = 0, n_movements = 0; + for (u_int i = 0; i < sc->sc_n_strokes; i++) { + atp_stroke *stroke = &sc->sc_strokes[i]; + + if ((stroke->components[X].movement) || + (stroke->components[Y].movement)) { + dx += stroke->components[X].movement; + dy += stroke->components[Y].movement; + n_movements++; + } + } + /* + * Disregard movement if multiple + * strokes record motion. + */ + if (n_movements != 1) + dx = 0, dy = 0; + + sc->sc_status.dx += dx; + sc->sc_status.dy += dy; + atp_add_to_queue(sc, dx, -dy, sc->sc_status.button); + } + + if (tap_fingers != 0) { + /* Add a pair of events (button-down and button-up). */ + switch (tap_fingers) { + case 1: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON1DOWN); + break; + case 2: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON2DOWN); + break; + case 3: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON3DOWN); + break; + default: break;/* handle taps of only up to 3 fingers */ + } + atp_add_to_queue(sc, 0, 0, 0); /* button release */ + } + + /* + * The device continues to trigger interrupts at a + * fast rate even after touchpad activity has + * stopped. Upon detecting that the device has + * remained idle beyond a threshold, we reinitialize + * it to silence the interrupts. + */ + if ((sc->sc_status.flags == 0) && + (sc->sc_n_strokes == 0) && + (sc->sc_status.button == 0)) { + sc->sc_idlecount++; + if (sc->sc_idlecount >= ATP_IDLENESS_THRESHOLD) { + DPRINTFN(ATP_LLEVEL_INFO, "idle\n"); + atp_set_device_mode(sc->sc_dev,RAW_SENSOR_MODE); + sc->sc_idlecount = 0; + } + } else { + sc->sc_idlecount = 0; + } + + case USB_ST_SETUP: + tr_setup: + /* check if we can put more data into the FIFO */ + if (usb_fifo_put_bytes_max( + sc->sc_fifo.fp[USB_FIFO_RX]) != 0) { + usbd_xfer_set_frame_len(xfer, 0, + usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); + } + break; + + default: /* Error */ + if (error != USB_ERR_CANCELLED) { + /* try clear stall first */ + usbd_xfer_set_stall(xfer); + goto tr_setup; + } + break; + } + + return; +} + +static void +atp_add_to_queue(struct atp_softc *sc, int dx, int dy, uint32_t buttons_in) +{ + uint32_t buttons_out; + uint8_t buf[8]; + + dx = imin(dx, 254); dx = imax(dx, -256); + dy = imin(dy, 254); dy = imax(dy, -256); + + buttons_out = MOUSE_MSC_BUTTONS; + if (buttons_in & MOUSE_BUTTON1DOWN) + buttons_out &= ~MOUSE_MSC_BUTTON1UP; + else if (buttons_in & MOUSE_BUTTON2DOWN) + buttons_out &= ~MOUSE_MSC_BUTTON2UP; + else if (buttons_in & MOUSE_BUTTON3DOWN) + buttons_out &= ~MOUSE_MSC_BUTTON3UP; + + DPRINTFN(ATP_LLEVEL_INFO, "dx=%d, dy=%d, buttons=%x\n", + dx, dy, buttons_out); + + /* Encode the mouse data in standard format; refer to mouse(4) */ + buf[0] = sc->sc_mode.syncmask[1]; + buf[0] |= buttons_out; + buf[1] = dx >> 1; + buf[2] = dy >> 1; + buf[3] = dx - (dx >> 1); + buf[4] = dy - (dy >> 1); + /* Encode extra bytes for level 1 */ + if (sc->sc_mode.level == 1) { + buf[5] = 0; /* dz */ + buf[6] = 0; /* dz - (dz / 2) */ + buf[7] = MOUSE_SYS_EXTBUTTONS; /* Extra buttons all up. */ + } + + usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf, + sc->sc_mode.packetsize, 1); +} + +static void +atp_reset_buf(struct atp_softc *sc) +{ + /* reset read queue */ + usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]); +} + +static void +atp_start_read(struct usb_fifo *fifo) +{ + struct atp_softc *sc = usb_fifo_softc(fifo); + int rate; + + /* Check if we should override the default polling interval */ + rate = sc->sc_pollrate; + /* Range check rate */ + if (rate > 1000) + rate = 1000; + /* Check for set rate */ + if ((rate > 0) && (sc->sc_xfer[ATP_INTR_DT] != NULL)) { + /* Stop current transfer, if any */ + usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); + /* Set new interval */ + usbd_xfer_set_interval(sc->sc_xfer[ATP_INTR_DT], 1000 / rate); + /* Only set pollrate once */ + sc->sc_pollrate = 0; + } + + usbd_transfer_start(sc->sc_xfer[ATP_INTR_DT]); +} + +static void +atp_stop_read(struct usb_fifo *fifo) +{ + struct atp_softc *sc = usb_fifo_softc(fifo); + + usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); +} + + +static int +atp_open(struct usb_fifo *fifo, int fflags) +{ + DPRINTFN(ATP_LLEVEL_INFO, "\n"); + + if (fflags & FREAD) { + struct atp_softc *sc = usb_fifo_softc(fifo); + int rc; + + if (sc->sc_state & ATP_ENABLED) + return (EBUSY); + + if (usb_fifo_alloc_buffer(fifo, + ATP_FIFO_BUF_SIZE, ATP_FIFO_QUEUE_MAXLEN)) { + return (ENOMEM); + } + + rc = atp_enable(sc); + if (rc != 0) { + usb_fifo_free_buffer(fifo); + return (rc); + } + } + + return (0); +} + +static void +atp_close(struct usb_fifo *fifo, int fflags) +{ + if (fflags & FREAD) { + struct atp_softc *sc = usb_fifo_softc(fifo); + + atp_disable(sc); + usb_fifo_free_buffer(fifo); + } +} + +int +atp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags) +{ + struct atp_softc *sc = usb_fifo_softc(fifo); + mousemode_t mode; + int error = 0; + + mtx_lock(&sc->sc_mutex); + + switch(cmd) { + case MOUSE_GETHWINFO: + *(mousehw_t *)addr = sc->sc_hw; + break; + case MOUSE_GETMODE: + *(mousemode_t *)addr = sc->sc_mode; + break; + case MOUSE_SETMODE: + mode = *(mousemode_t *)addr; + + if (mode.level == -1) + /* Don't change the current setting */ + ; + else if ((mode.level < 0) || (mode.level > 1)) { + error = EINVAL; + goto done; + } + sc->sc_mode.level = mode.level; + sc->sc_pollrate = mode.rate; + sc->sc_hw.buttons = 3; + + if (sc->sc_mode.level == 0) { + sc->sc_mode.protocol = MOUSE_PROTO_MSC; + sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; + sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; + sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; + } else if (sc->sc_mode.level == 1) { + sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; + sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; + sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; + sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; + } + atp_reset_buf(sc); + break; + case MOUSE_GETLEVEL: + *(int *)addr = sc->sc_mode.level; + break; + case MOUSE_SETLEVEL: + if (*(int *)addr < 0 || *(int *)addr > 1) { + error = EINVAL; + goto done; + } + sc->sc_mode.level = *(int *)addr; + sc->sc_hw.buttons = 3; + + if (sc->sc_mode.level == 0) { + sc->sc_mode.protocol = MOUSE_PROTO_MSC; + sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; + sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; + sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; + } else if (sc->sc_mode.level == 1) { + sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; + sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; + sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; + sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; + } + atp_reset_buf(sc); + break; + case MOUSE_GETSTATUS: { + mousestatus_t *status = (mousestatus_t *)addr; + + *status = sc->sc_status; + sc->sc_status.obutton = sc->sc_status.button; + sc->sc_status.button = 0; + sc->sc_status.dx = 0; + sc->sc_status.dy = 0; + sc->sc_status.dz = 0; + + if (status->dx || status->dy || status->dz) + status->flags |= MOUSE_POSCHANGED; + if (status->button != status->obutton) + status->flags |= MOUSE_BUTTONSCHANGED; + break; + } + default: + error = ENOTTY; + } + +done: + mtx_unlock(&sc->sc_mutex); + return (error); +} + +static int +atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS) +{ + int error; + u_int tmp; + u_int prev_mickeys_scale_factor; + + prev_mickeys_scale_factor = atp_mickeys_scale_factor; + + tmp = atp_mickeys_scale_factor; + error = sysctl_handle_int(oidp, &tmp, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (tmp == prev_mickeys_scale_factor) + return (0); /* no change */ + + atp_mickeys_scale_factor = tmp; + DPRINTFN(ATP_LLEVEL_INFO, "%s: resetting mickeys_scale_factor to %u\n", + ATP_DRIVER_NAME, tmp); + + /* Update dependent thresholds. */ + if (atp_small_movement_threshold == (prev_mickeys_scale_factor >> 3)) + atp_small_movement_threshold = atp_mickeys_scale_factor >> 3; + if (atp_max_delta_mickeys == ((3 * prev_mickeys_scale_factor) >> 1)) + atp_max_delta_mickeys = ((3 * atp_mickeys_scale_factor) >>1); + if (atp_slide_min_movement == (prev_mickeys_scale_factor >> 3)) + atp_slide_min_movement = atp_mickeys_scale_factor >> 3; + + return (0); +} + +static device_method_t atp_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, atp_probe), + DEVMETHOD(device_attach, atp_attach), + DEVMETHOD(device_detach, atp_detach), + { 0, 0 } +}; + +static driver_t atp_driver = { + ATP_DRIVER_NAME, + atp_methods, + sizeof(struct atp_softc) +}; + +static devclass_t atp_devclass; + +DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0); +MODULE_DEPEND(atp, usb, 1, 1, 1); diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile index 2555b83c65b..8c771d7c382 100644 --- a/sys/modules/usb/Makefile +++ b/sys/modules/usb/Makefile @@ -28,7 +28,7 @@ SUBDIR = usb SUBDIR += ehci musb ohci uhci uss820dci ${_at91dci} ${_atmegadci} SUBDIR += rum uath upgt ural zyd ${_urtw} -SUBDIR += uhid ukbd ums udbp ufm +SUBDIR += atp uhid ukbd ums udbp ufm SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \ umct umodem umoscom uplcom uslcom uvisor uvscom SUBDIR += uether aue axe cdce cue kue rue udav diff --git a/sys/modules/usb/atp/Makefile b/sys/modules/usb/atp/Makefile new file mode 100644 index 00000000000..8e68d1c4871 --- /dev/null +++ b/sys/modules/usb/atp/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +S= ${.CURDIR}/../../.. + +.PATH: $S/dev/usb/input + +KMOD= atp +SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h usbdevs.h \ + atp.c + +.include From 07ddebb5fb94daf3ca5e5b98eae80d125a476868 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 9 Nov 2009 16:05:32 +0000 Subject: [PATCH 592/646] Mention the layout change of ieee80211req_scan_result. --- UPDATING | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UPDATING b/UPDATING index 5e49f4dd966..170248c809e 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW: machines to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20091109: + The layout of the structure ieee80211req_scan_result has changed. + Applications that require wireless scan results (e.g. ifconfig(8)) + from net80211 need to be recompiled. + 20091025: The iwn(4) driver has been updated to support the 5000 and 5150 series. There's one kernel module for each firmware. Adding "device iwnfw" From 9020e36353b93caca0df5b5756acd2b63ac69c04 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Mon, 9 Nov 2009 17:26:16 +0000 Subject: [PATCH 593/646] Add gai_strerror() catalog for ja_JP.UTF-8 and ja_JP.eucJP. --- lib/libc/nls/ja_JP.UTF-8.msg | 36 ++++++++++++++++++++++++++++++++++++ lib/libc/nls/ja_JP.eucJP.msg | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/lib/libc/nls/ja_JP.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg index 9ee98d17ae3..b4d2144cffe 100644 --- a/lib/libc/nls/ja_JP.UTF-8.msg +++ b/lib/libc/nls/ja_JP.UTF-8.msg @@ -247,3 +247,39 @@ $ SIGUSR1 30 繝ヲ繝シ繧カ螳夂セゥ繧キ繧ー繝翫Ν 1 $ SIGUSR2 31 繝ヲ繝シ繧カ螳夂セゥ繧キ繧ー繝翫Ν 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 繝帙せ繝亥錐縺ョ繧「繝峨Ξ繧ケ繝輔ぃ繝溘Μ繝シ縺ッ繧オ繝昴シ繝医&繧後∪縺帙s +$ EAI_AGAIN +2 蜷榊燕隗」豎コ縺ァ縺ョ荳譎ら噪縺ェ螟ア謨 +$ EAI_BADFLAGS +3 ai_flags 縺ョ蛟、縺檎┌蜉ケ +$ EAI_FAIL +4 蜷榊燕隗」豎コ縺ァ縺ョ蝗槫セゥ荳崎ス縺ェ螟ア謨 +$ EAI_FAMILY +5 ai_family 縺ッ繧オ繝昴シ繝医&繧後∪縺帙s +$ EAI_MEMORY +6 繝。繝「繝ェ蜑イ繧雁ス薙※螟ア謨 +$ 7 (obsolete) +7 繝帙せ繝亥錐縺ォ蟇セ蠢懊☆繧九い繝峨Ξ繧ケ縺ッ縺ゅj縺セ縺帙s +$ EAI_NONAME +8 繝帙せ繝亥錐縺九し繝シ繝薙せ蜷阪′謖螳壹&繧後↑縺縲√∪縺溘ッ荳肴 +$ EAI_SERVICE +9 繧オ繝シ繝薙せ蜷阪ッ ai_socktype 縺ォ蟇セ縺励※繧オ繝昴シ繝医&繧後∪縺帙s +$ EAI_SOCKTYPE +10 ai_socktype 縺ッ繧オ繝昴シ繝医&繧後∪縺帙s +$ EAI_SYSTEM +11 繧キ繧ケ繝繝繧ィ繝ゥ繝シ縲‘rrno 蜿らァ +$ EAI_BADHINTS +12 hints 縺ョ蛟、縺檎┌蜉ケ +$ EAI_PROTOCOL +13 隗」豎コ縺輔l縺溘励Ο繝医さ繝ォ縺ッ荳肴弱〒縺 +$ EAI_OVERFLOW +14 蠑墓焚繝舌ャ繝輔ぃ繧ェ繝シ繝舌ヵ繝ュ繝シ +$ 0 +32766 謌仙粥 +$ NL_MSGMAX +32767 荳肴弱↑繧ィ繝ゥ繝シ diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg index cba0157cb1f..461a39b01e1 100644 --- a/lib/libc/nls/ja_JP.eucJP.msg +++ b/lib/libc/nls/ja_JP.eucJP.msg @@ -247,3 +247,39 @@ $ SIGUSR1 30 ・譯シ・カトオチ・キ・ー・ハ・ 1 $ SIGUSR2 31 ・譯シ・カトオチ・キ・ー・ハ・ 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 ・ロ・ケ・ネフセ、ホ・「・ノ・・ケ・ユ・。・゚・遙シ、マ・オ・ン。シ・ネ、オ、、゙、サ、 +$ EAI_AGAIN +2 フセチーイキ隍ヌ、ホーサナェ、ハシコヌヤ +$ EAI_BADFLAGS +3 ai_flags 、ホテヘ、ャフオク +$ EAI_FAIL +4 フセチーイキ隍ヌ、ホイノノヤヌス、ハシコヌヤ +$ EAI_FAMILY +5 ai_family 、マ・オ・ン。シ・ネ、オ、、゙、サ、 +$ EAI_MEMORY +6 ・皈筵ウ荀ナ、ニシコヌヤ +$ 7 (obsolete) +7 ・ロ・ケ・ネフセ、ヒツミア、ケ、・「・ノ・・ケ、マ、「、熙゙、サ、 +$ EAI_NONAME +8 ・ロ・ケ・ネフセ、ォ・オ。シ・モ・ケフセ、ャサリト熙オ、、ハ、、。「、゙、ソ、マノヤフタ +$ EAI_SERVICE +9 ・オ。シ・モ・ケフセ、マ ai_socktype 、ヒツミ、キ、ニ・オ・ン。シ・ネ、オ、、゙、サ、 +$ EAI_SOCKTYPE +10 ai_socktype 、マ・オ・ン。シ・ネ、オ、、゙、サ、 +$ EAI_SYSTEM +11 ・キ・ケ・ニ・爭ィ・鬘シ。「errno サイセネ +$ EAI_BADHINTS +12 hints 、ホテヘ、ャフオク +$ EAI_PROTOCOL +13 イキ隍オ、、ソ・ラ・・ネ・ウ・、マノヤフタ、ヌ、ケ +$ EAI_OVERFLOW +14 ーソ・ミ・テ・ユ・。・ェ。シ・ミ・ユ・。シ +$ 0 +32766 タョク +$ NL_MSGMAX +32767 ノヤフタ、ハ・ィ・鬘シ From 88cbe43d651fdb5768d5e844c6166816f9bcca28 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 9 Nov 2009 19:47:46 +0000 Subject: [PATCH 595/646] Fix variable type. --- sbin/camcontrol/camcontrol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 1638a5dbaf5..7d88998a237 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -4143,7 +4143,7 @@ atapm(struct cam_device *device, int argc, char **argv, union ccb *ccb; int retval = 0; int t = -1; - char c; + int c; u_char cmd, sc; ccb = cam_getccb(device); From 4f7418a09f3018ef909c7bf5cf11984e53f85407 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 9 Nov 2009 19:53:34 +0000 Subject: [PATCH 596/646] Remove ifdefed out part of code, which seems to have originated a decade ago in OpenBSD. As it is now, there is no way for this to be useful, since IPsec is free to forward packets via whatever interface it wants, so checking capabilities of the interface passed from ip_output (fetched from the routing table) serves no purpose. Discussed with: sam@ --- sys/netinet/ip_ipsec.c | 17 +---------------- sys/netinet/ip_ipsec.h | 3 +-- sys/netinet/ip_output.c | 2 +- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 0eb4673a038..b49b620f397 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -260,8 +260,7 @@ ip_ipsec_mtu(struct mbuf *m, int mtu) * -1 = packet was reinjected and stop processing packet */ int -ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, - struct ifnet **ifp) +ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error) { #ifdef IPSEC struct secpolicy *sp = NULL; @@ -390,20 +389,6 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, } else { /* No IPsec processing for this packet. */ } -#ifdef notyet - /* - * If deferred crypto processing is needed, check that - * the interface supports it. - */ - mtag = m_tag_find(*m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL); - if (mtag != NULL && ifp != NULL && - ((*ifp)->if_capenable & IFCAP_IPSEC) == 0) { - /* notify IPsec to do its own crypto */ - ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); - *error = EHOSTUNREACH; - goto bad; - } -#endif } done: if (sp != NULL) diff --git a/sys/netinet/ip_ipsec.h b/sys/netinet/ip_ipsec.h index 31bc86a1749..2870c1146ea 100644 --- a/sys/netinet/ip_ipsec.h +++ b/sys/netinet/ip_ipsec.h @@ -36,6 +36,5 @@ int ip_ipsec_filtertunnel(struct mbuf *); int ip_ipsec_fwd(struct mbuf *); int ip_ipsec_input(struct mbuf *); int ip_ipsec_mtu(struct mbuf *, int); -int ip_ipsec_output(struct mbuf **, struct inpcb *, int *, int *, - struct ifnet **); +int ip_ipsec_output(struct mbuf **, struct inpcb *, int *, int *); #endif diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b5be6fd1e1f..8a53043b3d0 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -466,7 +466,7 @@ again: sendit: #ifdef IPSEC - switch(ip_ipsec_output(&m, inp, &flags, &error, &ifp)) { + switch(ip_ipsec_output(&m, inp, &flags, &error)) { case 1: goto bad; case -1: From 68c4dfdf0ca8fd0e6125e6c389b6cc21e225ac7c Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Mon, 9 Nov 2009 20:29:10 +0000 Subject: [PATCH 597/646] Make isa_dma functions MPSAFE by introducing its own private lock. These functions are selfcontained (ie. they touch only isa_dma.c static variables and hardware) so a private lock is sufficient to prevent races. This changes only i386/amd64 while there are also isa_dma functions for ia64/sparc64. Sparc64 are ones empty stubs and ia64 ones are unused as ia64 does not have isa (says marcel). This patch removes explicit locking of Giant from a few drivers (there are some that requires this but lack ones - this patch fixes this) and also removes the need for implicit locking of Giant from attach routines where it's provided by newbus. Approved by: ed (mentor, implicit) Reviewed by: jhb, attilio (glanced by) Tested by: Giovanni Trematerra IA64 clue: marcel --- sys/amd64/isa/isa_dma.c | 116 +++++++++++++++++++++++++++++----------- sys/dev/fdc/fdc.c | 6 --- sys/dev/ieee488/ibfoo.c | 8 --- sys/i386/isa/isa_dma.c | 116 +++++++++++++++++++++++++++++----------- 4 files changed, 172 insertions(+), 74 deletions(-) diff --git a/sys/amd64/isa/isa_dma.c b/sys/amd64/isa/isa_dma.c index ffd3baaddba..0e997783c83 100644 --- a/sys/amd64/isa/isa_dma.c +++ b/sys/amd64/isa/isa_dma.c @@ -71,6 +71,8 @@ static u_int8_t dma_bounced = 0; static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */ static u_int8_t dma_inuse = 0; /* User for acquire/release */ static u_int8_t dma_auto_mode = 0; +static struct mtx isa_dma_lock; +MTX_SYSINIT(isa_dma_lock, &isa_dma_lock, "isa DMA lock", MTX_DEF); #define VALID_DMA_MASK (7) @@ -84,7 +86,34 @@ int isa_dma_init(int chan, u_int bouncebufsize, int flag) { void *buf; + int contig; +#ifdef DIAGNOSTIC + if (chan & ~VALID_DMA_MASK) + panic("isa_dma_init: channel out of range"); +#endif + + + /* Try malloc() first. It works better if it works. */ + buf = malloc(bouncebufsize, M_DEVBUF, flag); + if (buf != NULL) { + if (isa_dmarangecheck(buf, bouncebufsize, chan) != 0) { + free(buf, M_DEVBUF); + buf = NULL; + } + contig = 0; + } + + if (buf == NULL) { + buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful, + 1ul, chan & 4 ? 0x20000ul : 0x10000ul); + contig = 1; + } + + if (buf == NULL) + return (ENOMEM); + + mtx_lock(&isa_dma_lock); /* * If a DMA channel is shared, both drivers have to call isa_dma_init * since they don't know that the other driver will do it. @@ -93,30 +122,20 @@ isa_dma_init(int chan, u_int bouncebufsize, int flag) * XXX: is typically the case since they are multiple instances of * XXX: the same driver. */ - if (dma_bouncebuf[chan] != NULL) + if (dma_bouncebuf[chan] != NULL) { + if (contig) + contigfree(buf, bouncebufsize, M_DEVBUF); + else + free(buf, M_DEVBUF); + mtx_unlock(&isa_dma_lock); return (0); - -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dma_init: channel out of range"); -#endif + } dma_bouncebufsize[chan] = bouncebufsize; - - /* Try malloc() first. It works better if it works. */ - buf = malloc(bouncebufsize, M_DEVBUF, flag); - if (buf != NULL) { - if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) { - dma_bouncebuf[chan] = buf; - return (0); - } - free(buf, M_DEVBUF); - } - buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful, - 1ul, chan & 4 ? 0x20000ul : 0x10000ul); - if (buf == NULL) - return (ENOMEM); dma_bouncebuf[chan] = buf; + + mtx_unlock(&isa_dma_lock); + return (0); } @@ -133,12 +152,15 @@ isa_dma_acquire(chan) panic("isa_dma_acquire: channel out of range"); #endif + mtx_lock(&isa_dma_lock); if (dma_inuse & (1 << chan)) { printf("isa_dma_acquire: channel %d already in use\n", chan); + mtx_unlock(&isa_dma_lock); return (EBUSY); } dma_inuse |= (1 << chan); dma_auto_mode &= ~(1 << chan); + mtx_unlock(&isa_dma_lock); return (0); } @@ -155,8 +177,11 @@ isa_dma_release(chan) if (chan & ~VALID_DMA_MASK) panic("isa_dma_release: channel out of range"); + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dma_release: channel %d not in use\n", chan); +#else + mtx_lock(&isa_dma_lock); #endif if (dma_busy & (1 << chan)) { @@ -171,6 +196,8 @@ isa_dma_release(chan) dma_inuse &= ~(1 << chan); dma_auto_mode &= ~(1 << chan); + + mtx_unlock(&isa_dma_lock); } /* @@ -186,6 +213,7 @@ isa_dmacascade(chan) panic("isa_dmacascade: channel out of range"); #endif + mtx_lock(&isa_dma_lock); /* set dma channel mode, and set dma channel mode */ if ((chan & 4) == 0) { outb(DMA1_MODE, DMA37MD_CASCADE | chan); @@ -194,6 +222,7 @@ isa_dmacascade(chan) outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3)); outb(DMA2_SMSK, chan & 3); } + mtx_unlock(&isa_dma_lock); } /* @@ -206,8 +235,11 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) vm_paddr_t phys; int waport; caddr_t newaddr; + int dma_range_checked; - GIANT_REQUIRED; + /* translate to physical */ + phys = pmap_extract(kernel_pmap, (vm_offset_t)addr); + dma_range_checked = isa_dmarangecheck(addr, nbytes, chan); #ifdef DIAGNOSTIC if (chan & ~VALID_DMA_MASK) @@ -217,8 +249,11 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) || (chan >= 4 && (nbytes > (1<<17) || (uintptr_t)addr & 1))) panic("isa_dmastart: impossible request"); + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dmastart: channel %d not acquired\n", chan); +#else + mtx_lock(&isa_dma_lock); #endif #if 0 @@ -233,7 +268,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) dma_busy |= (1 << chan); - if (isa_dmarangecheck(addr, nbytes, chan)) { + if (dma_range_checked) { if (dma_bouncebuf[chan] == NULL || dma_bouncebufsize[chan] < nbytes) panic("isa_dmastart: bad bounce buffer"); @@ -246,9 +281,6 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) addr = newaddr; } - /* translate to physical */ - phys = pmap_extract(kernel_pmap, (vm_offset_t)addr); - if (flags & ISADMA_RAW) { dma_auto_mode |= (1 << chan); } else { @@ -323,6 +355,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) /* unmask channel */ outb(DMA2_SMSK, chan & 3); } + mtx_unlock(&isa_dma_lock); } void @@ -336,6 +369,7 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) printf("isa_dmadone: channel %d not acquired\n", chan); #endif + mtx_lock(&isa_dma_lock); if (((dma_busy & (1 << chan)) == 0) && (dma_auto_mode & (1 << chan)) == 0 ) printf("isa_dmadone: channel %d not busy\n", chan); @@ -351,6 +385,7 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) dma_bounced &= ~(1 << chan); } dma_busy &= ~(1 << chan); + mtx_unlock(&isa_dma_lock); } /* @@ -367,8 +402,6 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) vm_offset_t endva; u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); - GIANT_REQUIRED; - endva = (vm_offset_t)round_page((vm_offset_t)va + length); for (; va < (caddr_t) endva ; va += PAGE_SIZE) { phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va)); @@ -420,13 +453,15 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) * or -1 if the channel requested is not active. * */ -int -isa_dmastatus(int chan) +static int +isa_dmastatus_locked(int chan) { u_long cnt = 0; int ffport, waport; u_long low1, high1, low2, high2; + mtx_assert(&isa_dma_lock, MA_OWNED); + /* channel active? */ if ((dma_inuse & (1 << chan)) == 0) { printf("isa_dmastatus: channel %d not active\n", chan); @@ -472,6 +507,18 @@ isa_dmastatus(int chan) return(cnt); } +int +isa_dmastatus(int chan) +{ + int status; + + mtx_lock(&isa_dma_lock); + status = isa_dmastatus_locked(chan); + mtx_unlock(&isa_dma_lock); + + return (status); +} + /* * Reached terminal count yet ? */ @@ -491,12 +538,16 @@ isa_dmatc(int chan) int isa_dmastop(int chan) { + int status; + + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dmastop: channel %d not acquired\n", chan); if (((dma_busy & (1 << chan)) == 0) && ((dma_auto_mode & (1 << chan)) == 0)) { printf("chan %d not busy\n", chan); + mtx_unlock(&isa_dma_lock); return -2 ; } @@ -505,7 +556,12 @@ isa_dmastop(int chan) } else { outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */); } - return(isa_dmastatus(chan)); + + status = isa_dmastatus_locked(chan); + + mtx_unlock(&isa_dma_lock); + + return (status); } /* diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 458c839bff2..ed621b22f5f 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -781,11 +781,9 @@ fdc_worker(struct fdc_data *fdc) /* Disable ISADMA if we bailed while it was active */ if (fd != NULL && (fd->flags & FD_ISADMA)) { - mtx_lock(&Giant); isa_dmadone( bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE, fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_unlock(&Giant); mtx_lock(&fdc->fdc_mtx); fd->flags &= ~FD_ISADMA; mtx_unlock(&fdc->fdc_mtx); @@ -958,11 +956,9 @@ fdc_worker(struct fdc_data *fdc) /* Setup ISADMA if we need it and have it */ if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_FMT)) && !(fdc->flags & FDC_NODMA)) { - mtx_lock(&Giant); isa_dmastart( bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE, fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_unlock(&Giant); mtx_lock(&fdc->fdc_mtx); fd->flags |= FD_ISADMA; mtx_unlock(&fdc->fdc_mtx); @@ -1040,11 +1036,9 @@ fdc_worker(struct fdc_data *fdc) /* Finish DMA */ if (fd->flags & FD_ISADMA) { - mtx_lock(&Giant); isa_dmadone( bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE, fd->fd_ioptr, fd->fd_iosize, fdc->dmachan); - mtx_unlock(&Giant); mtx_lock(&fdc->fdc_mtx); fd->flags &= ~FD_ISADMA; mtx_unlock(&fdc->fdc_mtx); diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c index f199920f5f3..7458d8b5812 100644 --- a/sys/dev/ieee488/ibfoo.c +++ b/sys/dev/ieee488/ibfoo.c @@ -397,18 +397,14 @@ dma_idata(struct upd7210 *u, u_char *data, int len) KASSERT(u->dmachan >= 0, ("Bogus dmachan %d", u->dmachan)); ib = u->ibfoo; ib->mode = DMA_IDATA; - mtx_lock(&Giant); isa_dmastart(ISADMA_READ, data, len, u->dmachan); - mtx_unlock(&Giant); mtx_lock(&u->mutex); upd7210_wr(u, IMR1, IXR1_ENDRX); upd7210_wr(u, IMR2, IMR2_DMAI); gpib_ib_wait_xfer(u, ib); mtx_unlock(&u->mutex); - mtx_lock(&Giant); j = isa_dmastatus(u->dmachan); isa_dmadone(ISADMA_READ, data, len, u->dmachan); - mtx_unlock(&Giant); return (len - j); } @@ -790,14 +786,12 @@ gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) mtx_unlock(&u->mutex); if (u->dmachan >= 0) { - mtx_lock(&Giant); error = isa_dma_acquire(u->dmachan); if (!error) { error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK); if (error) isa_dma_release(u->dmachan); } - mtx_unlock(&Giant); } if (error) { @@ -855,9 +849,7 @@ gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td) free(ib, M_IBFOO); if (u->dmachan >= 0) { - mtx_lock(&Giant); isa_dma_release(u->dmachan); - mtx_unlock(&Giant); } mtx_lock(&u->mutex); u->busy = 0; diff --git a/sys/i386/isa/isa_dma.c b/sys/i386/isa/isa_dma.c index ccfb9c54c77..69d61c39314 100644 --- a/sys/i386/isa/isa_dma.c +++ b/sys/i386/isa/isa_dma.c @@ -69,6 +69,8 @@ static u_int8_t dma_bounced = 0; static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */ static u_int8_t dma_inuse = 0; /* User for acquire/release */ static u_int8_t dma_auto_mode = 0; +static struct mtx isa_dma_lock; +MTX_SYSINIT(isa_dma_lock, &isa_dma_lock, "isa DMA lock", MTX_DEF); #define VALID_DMA_MASK (7) @@ -82,7 +84,34 @@ int isa_dma_init(int chan, u_int bouncebufsize, int flag) { void *buf; + int contig; +#ifdef DIAGNOSTIC + if (chan & ~VALID_DMA_MASK) + panic("isa_dma_init: channel out of range"); +#endif + + + /* Try malloc() first. It works better if it works. */ + buf = malloc(bouncebufsize, M_DEVBUF, flag); + if (buf != NULL) { + if (isa_dmarangecheck(buf, bouncebufsize, chan) != 0) { + free(buf, M_DEVBUF); + buf = NULL; + } + contig = 0; + } + + if (buf == NULL) { + buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful, + 1ul, chan & 4 ? 0x20000ul : 0x10000ul); + contig = 1; + } + + if (buf == NULL) + return (ENOMEM); + + mtx_lock(&isa_dma_lock); /* * If a DMA channel is shared, both drivers have to call isa_dma_init * since they don't know that the other driver will do it. @@ -91,30 +120,20 @@ isa_dma_init(int chan, u_int bouncebufsize, int flag) * XXX: is typically the case since they are multiple instances of * XXX: the same driver. */ - if (dma_bouncebuf[chan] != NULL) + if (dma_bouncebuf[chan] != NULL) { + if (contig) + contigfree(buf, bouncebufsize, M_DEVBUF); + else + free(buf, M_DEVBUF); + mtx_unlock(&isa_dma_lock); return (0); - -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dma_init: channel out of range"); -#endif + } dma_bouncebufsize[chan] = bouncebufsize; - - /* Try malloc() first. It works better if it works. */ - buf = malloc(bouncebufsize, M_DEVBUF, flag); - if (buf != NULL) { - if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) { - dma_bouncebuf[chan] = buf; - return (0); - } - free(buf, M_DEVBUF); - } - buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful, - 1ul, chan & 4 ? 0x20000ul : 0x10000ul); - if (buf == NULL) - return (ENOMEM); dma_bouncebuf[chan] = buf; + + mtx_unlock(&isa_dma_lock); + return (0); } @@ -131,12 +150,15 @@ isa_dma_acquire(chan) panic("isa_dma_acquire: channel out of range"); #endif + mtx_lock(&isa_dma_lock); if (dma_inuse & (1 << chan)) { printf("isa_dma_acquire: channel %d already in use\n", chan); + mtx_unlock(&isa_dma_lock); return (EBUSY); } dma_inuse |= (1 << chan); dma_auto_mode &= ~(1 << chan); + mtx_unlock(&isa_dma_lock); return (0); } @@ -153,8 +175,11 @@ isa_dma_release(chan) if (chan & ~VALID_DMA_MASK) panic("isa_dma_release: channel out of range"); + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dma_release: channel %d not in use\n", chan); +#else + mtx_lock(&isa_dma_lock); #endif if (dma_busy & (1 << chan)) { @@ -169,6 +194,8 @@ isa_dma_release(chan) dma_inuse &= ~(1 << chan); dma_auto_mode &= ~(1 << chan); + + mtx_unlock(&isa_dma_lock); } /* @@ -184,6 +211,7 @@ isa_dmacascade(chan) panic("isa_dmacascade: channel out of range"); #endif + mtx_lock(&isa_dma_lock); /* set dma channel mode, and set dma channel mode */ if ((chan & 4) == 0) { outb(DMA1_MODE, DMA37MD_CASCADE | chan); @@ -192,6 +220,7 @@ isa_dmacascade(chan) outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3)); outb(DMA2_SMSK, chan & 3); } + mtx_unlock(&isa_dma_lock); } /* @@ -204,8 +233,11 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) vm_paddr_t phys; int waport; caddr_t newaddr; + int dma_range_checked; - GIANT_REQUIRED; + /* translate to physical */ + phys = pmap_extract(kernel_pmap, (vm_offset_t)addr); + dma_range_checked = isa_dmarangecheck(addr, nbytes, chan); #ifdef DIAGNOSTIC if (chan & ~VALID_DMA_MASK) @@ -215,8 +247,11 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) || (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1))) panic("isa_dmastart: impossible request"); + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dmastart: channel %d not acquired\n", chan); +#else + mtx_lock(&isa_dma_lock); #endif #if 0 @@ -231,7 +266,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) dma_busy |= (1 << chan); - if (isa_dmarangecheck(addr, nbytes, chan)) { + if (dma_range_checked) { if (dma_bouncebuf[chan] == NULL || dma_bouncebufsize[chan] < nbytes) panic("isa_dmastart: bad bounce buffer"); @@ -244,9 +279,6 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) addr = newaddr; } - /* translate to physical */ - phys = pmap_extract(kernel_pmap, (vm_offset_t)addr); - if (flags & ISADMA_RAW) { dma_auto_mode |= (1 << chan); } else { @@ -321,6 +353,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) /* unmask channel */ outb(DMA2_SMSK, chan & 3); } + mtx_unlock(&isa_dma_lock); } void @@ -334,6 +367,7 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) printf("isa_dmadone: channel %d not acquired\n", chan); #endif + mtx_lock(&isa_dma_lock); if (((dma_busy & (1 << chan)) == 0) && (dma_auto_mode & (1 << chan)) == 0 ) printf("isa_dmadone: channel %d not busy\n", chan); @@ -349,6 +383,7 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) dma_bounced &= ~(1 << chan); } dma_busy &= ~(1 << chan); + mtx_unlock(&isa_dma_lock); } /* @@ -365,8 +400,6 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) vm_offset_t endva; u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); - GIANT_REQUIRED; - endva = (vm_offset_t)round_page((vm_offset_t)va + length); for (; va < (caddr_t) endva ; va += PAGE_SIZE) { phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va)); @@ -419,13 +452,15 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) * or -1 if the channel requested is not active. * */ -int -isa_dmastatus(int chan) +static int +isa_dmastatus_locked(int chan) { u_long cnt = 0; int ffport, waport; u_long low1, high1, low2, high2; + mtx_assert(&isa_dma_lock, MA_OWNED); + /* channel active? */ if ((dma_inuse & (1 << chan)) == 0) { printf("isa_dmastatus: channel %d not active\n", chan); @@ -471,6 +506,18 @@ isa_dmastatus(int chan) return(cnt); } +int +isa_dmastatus(int chan) +{ + int status; + + mtx_lock(&isa_dma_lock); + status = isa_dmastatus_locked(chan); + mtx_unlock(&isa_dma_lock); + + return (status); +} + /* * Reached terminal count yet ? */ @@ -490,12 +537,16 @@ isa_dmatc(int chan) int isa_dmastop(int chan) { + int status; + + mtx_lock(&isa_dma_lock); if ((dma_inuse & (1 << chan)) == 0) printf("isa_dmastop: channel %d not acquired\n", chan); if (((dma_busy & (1 << chan)) == 0) && ((dma_auto_mode & (1 << chan)) == 0)) { printf("chan %d not busy\n", chan); + mtx_unlock(&isa_dma_lock); return -2 ; } @@ -504,7 +555,12 @@ isa_dmastop(int chan) } else { outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */); } - return(isa_dmastatus(chan)); + + status = isa_dmastatus_locked(chan); + + mtx_unlock(&isa_dma_lock); + + return (status); } /* From ed0358683824e21d6c4211ecc338f4693319ce15 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 9 Nov 2009 20:44:37 +0000 Subject: [PATCH 598/646] Vendor import of tzdata2009r: - Three Australian stations in Antarctica have changed their time zone: Casey moved from UTC+8 to UTC+11 Davis moved from UTC+7 to UTC+5 Mawson moved from UTC+6 to UTC+5 The changes occurred on 2009-10-18 at 02:00 (local times). Obtained from: ftp://elsie.nci.nih.gov/pub/ --- antarctica | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/antarctica b/antarctica index 8511ab207e5..52d604b4aed 100644 --- a/antarctica +++ b/antarctica @@ -1,5 +1,5 @@ #
    -# @(#)antarctica	8.5
    +# @(#)antarctica	8.6
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -80,15 +80,38 @@ Rule	ChileAQ	2000	max	-	Mar	Sun>=9	3:00u	0	-
     # Davis, Vestfold Hills, -6835+07759, since 1957-01-13
     #	(except 1964-11 - 1969-02)
     # Mawson, Holme Bay, -6736+06253, since 1954-02-13
    +
    +# From Steffen Thorsen (2009-03-11):
    +# Three Australian stations in Antarctica have changed their time zone:
    +# Casey moved from UTC+8 to UTC+11
    +# Davis moved from UTC+7 to UTC+5
    +# Mawson moved from UTC+6 to UTC+5
    +# The changes occurred on 2009-10-18 at 02:00 (local times).
    +#
    +# Government source: (Australian Antarctic Division)
    +# 
    +# http://www.aad.gov.au/default.asp?casid=37079
    +# 
    +#
    +# We have more background information here:
    +# 
    +# http://www.timeanddate.com/news/time/antarctica-new-times.html
    +# 
    +
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone Antarctica/Casey	0	-	zzz	1969
    -			8:00	-	WST	# Western (Aus) Standard Time
    +			8:00	-	WST	2009 Oct 18 2:00
    +						# Western (Aus) Standard Time
    +			11:00	-	CAST	# Casey Time
     Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
     			7:00	-	DAVT	1964 Nov # Davis Time
     			0	-	zzz	1969 Feb
    -			7:00	-	DAVT
    +			7:00	-	DAVT	2009 Oct 18 2:0
    +			5:00	-	DAVT
     Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
    -			6:00	-	MAWT	# Mawson Time
    +			6:00	-	MAWT	2009 Oct 18 2:00
    +						# Mawson Time
    +			5:00	-	MAWT
     # References:
     # 
     # Casey Weather (1998-02-26)
    
    From c10d3c2cd8aaba6724aa95d44d33885373058c07 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Mon, 9 Nov 2009 21:12:28 +0000
    Subject: [PATCH 599/646] Spell sz correctly.
    
    Pointed out by:	jmallett
    ---
     sys/powerpc/aim/mmu_oea64.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index e9b9a1f73d2..0fde1c981df 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -897,7 +897,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     		panic("moea64_bootstrap: can't get mmu package");
     	    if ((sz = OF_getproplen(mmu, "translations")) == -1)
     		panic("moea64_bootstrap: can't get ofw translation count");
    -	    if (size > sizeof(translations))
    +	    if (sz > sizeof(translations))
     		panic("moea64_bootstrap: too many ofw translations (%d)",
     		      sz/sizeof(*translations));
     
    
    From 950e46c329994dbc0aa73b0261f5cf27ec7e8e5f Mon Sep 17 00:00:00 2001
    From: Oleksandr Tymoshenko 
    Date: Mon, 9 Nov 2009 22:01:58 +0000
    Subject: [PATCH 600/646] Unbreak booting of FreeBSD/mips by merging r195429
     from projects/mips: - Move dpcpu initialization to mips_proc0_init. It's    
     more appropriate place for it. Besides dpcpu_init     requires pmap module to
     be initialized and calling it     int pmap.c hangs the system
    
    ---
     sys/mips/mips/machdep.c | 3 +++
     sys/mips/mips/pmap.c    | 3 ---
     2 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c
    index 6bd518018e7..9898ab76384 100644
    --- a/sys/mips/mips/machdep.c
    +++ b/sys/mips/mips/machdep.c
    @@ -274,6 +274,9 @@ mips_proc0_init(void)
     	    (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1;
     	thread0.td_frame = &thread0.td_pcb->pcb_regs;
     
    +	/* Steal memory for the dynamic per-cpu area. */
    +	dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0);
    +
     	/*
     	 * There is no need to initialize md_upte array for thread0 as it's
     	 * located in .bss section and should be explicitly zeroed during 
    diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
    index 25b0b3a7bbd..de144391a66 100644
    --- a/sys/mips/mips/pmap.c
    +++ b/sys/mips/mips/pmap.c
    @@ -331,9 +331,6 @@ again:
     	msgbufp = (struct msgbuf *)pmap_steal_memory(MSGBUF_SIZE);
     	msgbufinit(msgbufp, MSGBUF_SIZE);
     
    -	/* Steal memory for the dynamic per-cpu area. */
    -	dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0);
    -
     	/*
     	 * Steal thread0 kstack.
     	 */
    
    From aa94f33338c6b7d1bad1c3631b060a41fbc37663 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 9 Nov 2009 22:58:30 +0000
    Subject: [PATCH 601/646] Add missing bus_dmamap_sync(9) before issuing kick
     command.
    
    ---
     sys/dev/bge/if_bge.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 9a27d31e55b..8687d166bb2 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -3826,6 +3826,9 @@ bge_start_locked(struct ifnet *ifp)
     		/* No packets were dequeued. */
     		return;
     
    +	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
    +	    sc->bge_cdata.bge_tx_ring_map,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
     	/* Transmit. */
     	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
     	/* 5700 b2 errata */
    
    From e6bf277effaa89ed0726c948327607543d7b6040 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 9 Nov 2009 23:09:18 +0000
    Subject: [PATCH 602/646] Zero out Tx/Rx descriptors before using them. Also
     add missing bus_dmamap_sync(9) after Tx descriptor initialization.
    
    ---
     sys/dev/bge/if_bge.c | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 8687d166bb2..3ecbcbe43b7 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -1046,6 +1046,7 @@ bge_init_rx_ring_std(struct bge_softc *sc)
     {
     	int error, i;
     
    +	bzero(sc->bge_ldata.bge_rx_std_ring, BGE_STD_RX_RING_SZ);
     	sc->bge_std = 0;
     	for (i = 0; i < BGE_SSLOTS; i++) {
     		if ((error = bge_newbuf_std(sc, i)) != 0)
    @@ -1089,6 +1090,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc)
     	struct bge_rcb *rcb;
     	int error, i;
     
    +	bzero(sc->bge_ldata.bge_rx_jumbo_ring, BGE_JUMBO_RX_RING_SZ);
     	sc->bge_jumbo = 0;
     	for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
     		if ((error = bge_newbuf_jumbo(sc, i)) != 0)
    @@ -1161,6 +1163,11 @@ bge_init_tx_ring(struct bge_softc *sc)
     	sc->bge_txcnt = 0;
     	sc->bge_tx_saved_considx = 0;
     
    +	bzero(sc->bge_ldata.bge_tx_ring, BGE_TX_RING_SZ);
    +	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
    +	    sc->bge_cdata.bge_tx_ring_map,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +
     	/* Initialize transmit producer index for host-memory send ring. */
     	sc->bge_tx_prodidx = 0;
     	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
    
    From 4ed03b8dd481c1768c6986a41d97d9de7379b629 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 10 Nov 2009 00:48:24 +0000
    Subject: [PATCH 603/646] Add a minimal change to prevent NULL deference in
     ee(1).
    
    To repeat the problem, one can press "Ctrl+C" and then enter "0".
    
    Submitted by:	Alexander Best 
    ---
     contrib/ee/ee.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/contrib/ee/ee.c b/contrib/ee/ee.c
    index a603756fb51..ae37f65e717 100755
    --- a/contrib/ee/ee.c
    +++ b/contrib/ee/ee.c
    @@ -1989,7 +1989,7 @@ char *cmd_str;
     	int number;
     	int i;
     	char *ptr;
    -	char *direction = NULL;
    +	char *direction = "d";
     	struct text *t_line;
     
     	ptr = cmd_str;
    
    From b31787ae6c71d3db1991049aea24cb18aa2a6368 Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Tue, 10 Nov 2009 03:18:49 +0000
    Subject: [PATCH 604/646] Add a note about no hostname leading to "Amnesiac" on
     the console
    
    The text is inspired by the PR, but more in line with the existing text
    
    PR:		docs/140434
    Submitted by:	Jason Helfman 
    ---
     share/man/man5/rc.conf.5 | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
    index e9ed4dcf5d2..a0b3f0b5372 100644
    --- a/share/man/man5/rc.conf.5
    +++ b/share/man/man5/rc.conf.5
    @@ -351,6 +351,9 @@ If
     .Xr dhclient 8
     is used to set the hostname via DHCP,
     this variable should be set to an empty string.
    +If this value remains unset when the system is done booting
    +your console login will display a default hostname of
    +.Dq Amnesiac.
     .It Va nisdomainname
     .Pq Vt str
     The NIS domain name of this host, or
    
    From 17898870002feee5629966bc225f4bb1baeed20a Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Tue, 10 Nov 2009 03:56:51 +0000
    Subject: [PATCH 605/646] Add Japanese catalogue entries for newer errnos:
     EBADMSG, EMULTIHOP, ENOLINK, EPROTO, ENOTCAPABLE.
    
    ---
     lib/libc/nls/ja_JP.UTF-8.msg | 10 ++++++++++
     lib/libc/nls/ja_JP.eucJP.msg | 10 ++++++++++
     2 files changed, 20 insertions(+)
    
    diff --git a/lib/libc/nls/ja_JP.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg
    index b4d2144cffe..6be65fbb5c0 100644
    --- a/lib/libc/nls/ja_JP.UTF-8.msg
    +++ b/lib/libc/nls/ja_JP.UTF-8.msg
    @@ -181,6 +181,16 @@ $ ENOATTR
     87 縺昴ョ繧医≧縺ェ螻樊ァ縺ッ縺ゅj縺セ縺帙s
     $ EDOOFUS
     88 繝励Ο繧ー繝ゥ繝溘Φ繧ー繧ィ繝ゥ繝シ縺ァ縺
    +$ EBADMSG
    +89 辟。蜉ケ縺ェ繝。繝繧サ繝シ繧ク縺ァ縺
    +$ EMULTIHOP
    +90 繝槭Ν繝√帙ャ繝励′隧ヲ縺ソ繧峨l縺セ縺励◆
    +$ ENOLINK
    +91 繝ェ繝ウ繧ッ縺悟譁ュ縺輔l縺ヲ縺縺セ縺
    +$ EPROTO
    +92 繝励Ο繝医さ繝ォ繧ィ繝ゥ繝シ縺ァ縺
    +$ ENOTCAPABLE
    +93 繧ア繝シ繝代ン繝ェ繝繧」縺御ク崎カウ縺ァ縺
     $
     $ strsignal() support catalog
     $
    diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg
    index 461a39b01e1..e3fac48c6a1 100644
    --- a/lib/libc/nls/ja_JP.eucJP.msg
    +++ b/lib/libc/nls/ja_JP.eucJP.msg
    @@ -181,6 +181,16 @@ $ ENOATTR
     87 、ス、ホ、隍ヲ、ハツータュ、マ、「、熙゙、サ、
     $ EDOOFUS
     88 ・ラ・・ー・鬣゚・・ー・ィ・鬘シ、ヌ、ケ
    +$ EBADMSG
    +89 フオク、ハ・皈テ・サ。シ・ク、ヌ、ケ
    +$ EMULTIHOP
    +90 ・゙・・チ・ロ・テ・ラ、ャサ、゚、鬢、゙、キ、ソ
    +$ ENOLINK
    +91 ・・・ッ、ャタレテヌ、オ、、ニ、、、゙、ケ
    +$ EPROTO
    +92 ・ラ・・ネ・ウ・・ィ・鬘シ、ヌ、ケ
    +$ ENOTCAPABLE
    +93 ・ア。シ・ム・モ・・ニ・」、ャノヤツュ、ヌ、ケ
     $
     $ strsignal() support catalog
     $
    
    From c574558f28d6aa70148e943b9a83dd7d206f7d78 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
    Date: Tue, 10 Nov 2009 09:44:55 +0000
    Subject: [PATCH 606/646] More rational usage()
    
    ---
     sbin/reboot/reboot.c | 8 +++++---
     1 file changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
    index 3a4d20cb458..cae709f3b06 100644
    --- a/sbin/reboot/reboot.c
    +++ b/sbin/reboot/reboot.c
    @@ -216,10 +216,12 @@ restart:
     }
     
     static void
    -usage()
    +usage(void)
     {
    -	(void)fprintf(stderr, "usage: %s [-%slnpq] [-k kernel]\n",
    -	    getprogname(), dohalt ? "" : "d");
    +
    +	(void)fprintf(stderr, dohalt ?
    +	    "usage: halt [-lnpq] [-k kernel]\n" :
    +	    "usage: reboot [-dlnpq] [-k kernel]\n");
     	exit(1);
     }
     
    
    From 0c56c384d684cc8aa3e2ef3962e5a7f50a052d96 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
    Date: Tue, 10 Nov 2009 09:45:43 +0000
    Subject: [PATCH 607/646] Fix globbing
    
    Noticed by:	delphij, David Cornejo 
    Forgotten by:	des
    ---
     crypto/openssh/ssh_namespace.h | 2 ++
     secure/lib/libssh/Makefile     | 2 +-
     2 files changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h
    index 5a61eff81f7..89978fc938c 100644
    --- a/crypto/openssh/ssh_namespace.h
    +++ b/crypto/openssh/ssh_namespace.h
    @@ -223,6 +223,8 @@
     #define get_u32					ssh_get_u32
     #define get_u64					ssh_get_u64
     #define getrrsetbyname				ssh_getrrsetbyname
    +#define glob					ssh_glob
    +#define globfree				ssh_globfree
     #define host_hash				ssh_host_hash
     #define hostfile_read_key			ssh_hostfile_read_key
     #define hpdelim					ssh_hpdelim
    diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile
    index ecc1a928165..32b5069b751 100644
    --- a/secure/lib/libssh/Makefile
    +++ b/secure/lib/libssh/Makefile
    @@ -19,7 +19,7 @@ SRCS=	acss.c authfd.c authfile.c bufaux.c bufbn.c buffer.c \
     # compiled directly into sshd instead.
     
     # Portability layer
    -SRCS+=	bsd-misc.c fmt_scaled.c getrrsetbyname.c \
    +SRCS+=	bsd-misc.c fmt_scaled.c getrrsetbyname.c glob.c \
     	openssl-compat.c port-tun.c strtonum.c vis.c xcrypt.c xmmap.c
     # FreeBSD additions
     SRCS+=	version.c
    
    From 03a6387ec3facae01368fe475bbeaf51489d60a0 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Tue, 10 Nov 2009 09:46:52 +0000
    Subject: [PATCH 608/646] MFp4: Organize device IDs and add some more of them.
    
    ---
     sys/dev/siis/siis.c | 46 ++++++++++++++++++++++++++++++---------------
     sys/dev/siis/siis.h |  6 ------
     2 files changed, 31 insertions(+), 21 deletions(-)
    
    diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
    index adc68e43301..41a5cc7e5b4 100644
    --- a/sys/dev/siis/siis.c
    +++ b/sys/dev/siis/siis.c
    @@ -89,24 +89,37 @@ static void siispoll(struct cam_sim *sim);
     
     MALLOC_DEFINE(M_SIIS, "SIIS driver", "SIIS driver data buffers");
     
    +static struct {
    +	uint32_t	id;
    +	const char	*name;
    +	int		ports;
    +} siis_ids[] = {
    +	{0x31241095,	"SiI3124",	4},
    +	{0x31248086,	"SiI3124",	4},
    +	{0x31321095,	"SiI3132",	2},
    +	{0x02421095,	"SiI3132",	2},
    +	{0x02441095,	"SiI3132",	2},
    +	{0x31311095,	"SiI3131",	1},
    +	{0x35311095,	"SiI3531",	1},
    +	{0,		NULL,		0}
    +};
    +
     static int
     siis_probe(device_t dev)
     {
    +	char buf[64];
    +	int i;
     	uint32_t devid = pci_get_devid(dev);
     
    -	if (devid == SIIS_SII3124) {
    -		device_set_desc_copy(dev, "SiI3124 SATA2 controller");
    -	} else if (devid == SIIS_SII3132 ||
    -		   devid == SIIS_SII3132_1 ||
    -		   devid == SIIS_SII3132_2) {
    -		device_set_desc_copy(dev, "SiI3132 SATA2 controller");
    -	} else if (devid == SIIS_SII3531) {
    -		device_set_desc_copy(dev, "SiI3531 SATA2 controller");
    -	} else {
    -		return (ENXIO);
    +	for (i = 0; siis_ids[i].id != 0; i++) {
    +		if (siis_ids[i].id == devid) {
    +			snprintf(buf, sizeof(buf), "%s SATA2 controller",
    +			    siis_ids[i].name);
    +			device_set_desc_copy(dev, buf);
    +			return (BUS_PROBE_VENDOR);
    +		}
     	}
    -
    -	return (BUS_PROBE_VENDOR);
    +	return (ENXIO);
     }
     
     static int
    @@ -115,8 +128,12 @@ siis_attach(device_t dev)
     	struct siis_controller *ctlr = device_get_softc(dev);
     	uint32_t devid = pci_get_devid(dev);
     	device_t child;
    -	int	error, unit;
    +	int	error, i, unit;
     
    +	for (i = 0; siis_ids[i].id != 0; i++) {
    +		if (siis_ids[i].id == devid)
    +			break;
    +	}
     	ctlr->dev = dev;
     	/* Global memory */
     	ctlr->r_grid = PCIR_BAR(0);
    @@ -146,8 +163,7 @@ siis_attach(device_t dev)
     	/* Reset controller */
     	siis_resume(dev);
     	/* Number of HW channels */
    -	ctlr->channels = (devid == SIIS_SII3124) ? 4 :
    -	    (devid == SIIS_SII3531 ? 1 : 2);
    +	ctlr->channels = siis_ids[i].ports;
     	/* Setup interrupts. */
     	if (siis_setup_interrupt(dev)) {
     		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
    diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h
    index ab18e6ed524..20de88fd94d 100644
    --- a/sys/dev/siis/siis.h
    +++ b/sys/dev/siis/siis.h
    @@ -137,12 +137,6 @@
     
     #define ATA_SACTIVE                     16
     
    -#define SIIS_SII3124		0x31241095
    -#define SIIS_SII3132		0x31321095
    -#define SIIS_SII3132_1		0x02421095
    -#define SIIS_SII3132_2		0x02441095
    -#define SIIS_SII3531		0x35311095
    -
     /*
      * Global registers
      */
    
    From 151a18cd10c75e0066a42ae5151452eed8147039 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
    Date: Tue, 10 Nov 2009 10:34:44 +0000
    Subject: [PATCH 609/646] Remove a bunch of code used to detect SMP on ((i386
     && !pc98) || amd64) and offer to install an SMP kernel.  The way this worked
     was: on supported platforms, code to read ACPI tables and BIOS MP tables was
     compiled into sysinstall, and if an SMP kernel config was present in the
     source tree when sysinstall was built, code that called it was also compiled.
      Since we haven't had SMP kernel configs in years, the latter was never
     compiled and the former never ran.
    
    This only removes dead and unreachable code; it does *not* remove the NCpus
    variable, nor the code that sets it to 1, nor the code that asks the user to
    select a kernel from a list.
    
    Discussed with:	re@, randi@ and others
    ---
     usr.sbin/sysinstall/Makefile      |  31 ---
     usr.sbin/sysinstall/acpi.c        | 356 ------------------------------
     usr.sbin/sysinstall/acpidump.h    | 177 ---------------
     usr.sbin/sysinstall/biosmptable.c | 275 -----------------------
     usr.sbin/sysinstall/dist.c        |   8 -
     usr.sbin/sysinstall/install.c     |  15 +-
     usr.sbin/sysinstall/menus.c       |   4 -
     usr.sbin/sysinstall/sysinstall.8  |   2 -
     8 files changed, 1 insertion(+), 867 deletions(-)
     delete mode 100644 usr.sbin/sysinstall/acpi.c
     delete mode 100644 usr.sbin/sysinstall/acpidump.h
     delete mode 100644 usr.sbin/sysinstall/biosmptable.c
    
    diff --git a/usr.sbin/sysinstall/Makefile b/usr.sbin/sysinstall/Makefile
    index 3f2b7584837..db61cae2d06 100644
    --- a/usr.sbin/sysinstall/Makefile
    +++ b/usr.sbin/sysinstall/Makefile
    @@ -23,37 +23,6 @@ CFLAGS+= -I${.CURDIR}/../../gnu/lib/libdialog -I.
     DPADD=	${LIBDIALOG} ${LIBNCURSES} ${LIBUTIL} ${LIBDISK} ${LIBFTPIO}
     LDADD=	-ldialog -lncurses -lutil -ldisk -lftpio
     
    -#
    -# When distributions have both UP and SMP kernels sysinstall
    -# will probe for the number of cpus on the target machine and
    -# automatically select which is appropriate.  This can be overridden
    -# through the menus or both kernels can be installed (with the
    -# most "appropriate" one setup as /boot/kernel).  For now this
    -# is done for i386 and amd64; for other systems support must be
    -# added to identify the cpu count if acpi and MPTable probing
    -# is insufficient.
    -#
    -# The unmber of cpus probed is passed through the environment in
    -# VAR_NCPUS ("ncpus") to scripts.
    -#
    -# Note that WITH_SMP is a compile time option that enables the
    -# builtin menus for the SMP kernel configuration.  If this kernel
    -# is not built (see release/Makefile) then this should not be
    -# enabled as sysinstall may try to select an SMP kernel config
    -# where none is available.  This option should not be needed--we
    -# should probe for an SMP kernel in the distribution but doing
    -# that is painful because of media changes and the structure of
    -# sysinstall so for now it's a priori.
    -#
    -.if ${MACHINE} == "i386" || ${MACHINE_ARCH} == "amd64"
    -SRCS+=	acpi.c biosmptable.c
    -.if exists(${.CURDIR}/../../sys/${MACHINE}/conf/SMP)
    -CFLAGS+=-DWITH_SMP	
    -.endif
    -DPADD+=	${LIBDEVINFO}
    -LDADD+=	-ldevinfo
    -.endif
    -
     CLEANFILES=	makedevs.c rtermcap
     CLEANFILES+=	keymap.tmp keymap.h countries.tmp countries.h
     
    diff --git a/usr.sbin/sysinstall/acpi.c b/usr.sbin/sysinstall/acpi.c
    deleted file mode 100644
    index 4a375a1c0b8..00000000000
    --- a/usr.sbin/sysinstall/acpi.c
    +++ /dev/null
    @@ -1,356 +0,0 @@
    -/*-
    - * Copyright (c) 1998 Doug Rabson
    - * Copyright (c) 2000 Mitsuru IWASAKI 
    - * 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.
    - */
    -
    -#include 
    -__FBSDID("$FreeBSD$");
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#include "acpidump.h"
    -#include "sysinstall.h"
    -
    -static void	acpi_handle_apic(struct ACPIsdt *sdp);
    -static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
    -static void	acpi_handle_rsdt(struct ACPIsdt *rsdp);
    -static struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t, size_t);
    -static void *	acpi_map_physical(vm_offset_t, size_t);
    -
    -/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
    -static int addr_size;
    -
    -static int ncpu;
    -
    -static void
    -acpi_handle_apic(struct ACPIsdt *sdp)
    -{
    -	struct MADTbody *madtp;
    -	struct MADT_APIC *mp;
    -	struct MADT_local_apic *apic;
    -	struct MADT_local_sapic *sapic;
    -
    -	madtp = (struct MADTbody *) sdp->body;
    -	mp = (struct MADT_APIC *)madtp->body;
    -	while (((uintptr_t)mp) - ((uintptr_t)sdp) < sdp->len) {
    -		switch (mp->type) {
    -		case ACPI_MADT_APIC_TYPE_LOCAL_APIC:
    -			apic = &mp->body.local_apic;
    -			msgDebug("MADT: Found CPU APIC ID %d %s\n",
    -			    apic->cpu_id,
    -			    apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
    -				"enabled" : "disabled");
    -			if (apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
    -				ncpu++;
    -			break;
    -		case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC:
    -			sapic = &mp->body.local_sapic;
    -			msgDebug("MADT: Found CPU SAPIC ID %d %s\n",
    -			    sapic->cpu_id,
    -			    sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
    -				"enabled" : "disabled");
    -			/* XXX is enable flag the same? */
    -			if (sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
    -				ncpu++;
    -			break;
    -		default:
    -			break;
    -		}
    -		mp = (struct MADT_APIC *) ((char *)mp + mp->len);
    -	}
    -}
    -
    -static int
    -acpi_checksum(void *p, size_t length)
    -{
    -	u_int8_t *bp;
    -	u_int8_t sum;
    -
    -	bp = p;
    -	sum = 0;
    -	while (length--)
    -		sum += *bp++;
    -
    -	return (sum);
    -}
    -
    -static struct ACPIsdt *
    -acpi_map_sdt(vm_offset_t pa)
    -{
    -	struct	ACPIsdt *sp;
    -
    -	sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
    -	if (sp != NULL)
    -		sp = acpi_map_physical(pa, sp->len);
    -	return (sp);
    -}
    -
    -static void
    -acpi_handle_rsdt(struct ACPIsdt *rsdp)
    -{
    -	struct ACPIsdt *sdp;
    -	vm_offset_t addr;
    -	int entries, i;
    -
    -	entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
    -	for (i = 0; i < entries; i++) {
    -		switch (addr_size) {
    -		case 4:
    -			addr = le32dec((char*)rsdp->body + i * addr_size);
    -			break;
    -		case 8:
    -			addr = le64dec((char*)rsdp->body + i * addr_size);
    -			break;
    -		default:
    -			assert((addr = 0));
    -		}
    -
    -		sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
    -		if (sdp == NULL) {
    -			msgDebug("%s: unable to map sdt\n", __func__);
    -			continue;
    -		}
    -		if (acpi_checksum(sdp, sdp->len)) {
    -#if 0
    -			msgDebug("RSDT entry %d (sig %.4s) has bad checksum\n",
    -			    i, sdp->signature);
    -#endif
    -			continue;
    -		}
    -		if (!memcmp(sdp->signature, "APIC", 4))
    -			acpi_handle_apic(sdp);
    -	}
    -}
    -
    -static char	machdep_acpi_root[] = "machdep.acpi_root";
    -static int      acpi_mem_fd = -1;
    -
    -struct acpi_user_mapping {
    -	LIST_ENTRY(acpi_user_mapping) link;
    -	vm_offset_t     pa;
    -	caddr_t         va;
    -	size_t          size;
    -};
    -
    -LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
    -
    -static int
    -acpi_user_init(void)
    -{
    -
    -	if (acpi_mem_fd == -1) {
    -		acpi_mem_fd = open(_PATH_MEM, O_RDONLY);
    -		if (acpi_mem_fd == -1) {
    -			msgDebug("%s: error opening %s: %s\n", __func__,
    -			    _PATH_MEM, strerror(errno));
    -			return 0;
    -		}
    -		LIST_INIT(&maplist);
    -	}
    -	return 1;
    -}
    -
    -static struct acpi_user_mapping *
    -acpi_user_find_mapping(vm_offset_t pa, size_t size)
    -{
    -	struct	acpi_user_mapping *map;
    -
    -	/* First search for an existing mapping */
    -	for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) {
    -		if (map->pa <= pa && map->size >= pa + size - map->pa)
    -			return (map);
    -	}
    -
    -	/* Then create a new one */
    -	size = round_page(pa + size) - trunc_page(pa);
    -	pa = trunc_page(pa);
    -	map = malloc(sizeof(struct acpi_user_mapping));
    -	if (!map) {
    -		msgDebug("%s: out of memory: %s\n", __func__, strerror(errno));
    -		return (map);
    -	}
    -	map->pa = pa;
    -	map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
    -	map->size = size;
    -	if ((intptr_t) map->va == -1) {
    -		msgDebug("%s: can't mmap address %lu size %lu: %s\n", __func__,
    -		    (unsigned long) pa, (unsigned long) size, strerror(errno));
    -		free(map);
    -		return (NULL);
    -	}
    -	LIST_INSERT_HEAD(&maplist, map, link);
    -
    -	return (map);
    -}
    -
    -static void *
    -acpi_map_physical(vm_offset_t pa, size_t size)
    -{
    -	struct	acpi_user_mapping *map;
    -
    -	map = acpi_user_find_mapping(pa, size);
    -	return (map == NULL ? NULL : map->va + (pa - map->pa));
    -}
    -
    -static struct ACPIrsdp *
    -acpi_get_rsdp(u_long addr)
    -{
    -	struct ACPIrsdp rsdp;
    -	size_t len;
    -
    -	/* Read in the table signature and check it. */
    -	pread(acpi_mem_fd, &rsdp, 8, addr);
    -	if (memcmp(rsdp.signature, "RSD PTR ", 8))
    -		return (NULL);
    -
    -	/* Read the entire table. */
    -	pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
    -
    -	/* Run the checksum only over the version 1 header. */
    -	if (acpi_checksum(&rsdp, 20))
    -		return (NULL);
    -
    -	/* If the revision is 0, assume a version 1 length. */
    -	if (rsdp.revision == 0)
    -		len = 20;
    -	else
    -		len = rsdp.length;
    -
    -	/* XXX Should handle ACPI 2.0 RSDP extended checksum here. */
    -
    -	return (acpi_map_physical(addr, len));
    -}
    -
    -static const char *
    -devstate(devinfo_state_t state)
    -{
    -	switch (state) {
    -	case DIS_NOTPRESENT:
    -		return "not-present";
    -	case DIS_ALIVE:
    -		return "alive";
    -	case DIS_ATTACHED:
    -		return "attached";
    -	case DIS_BUSY:
    -		return "busy";
    -	default:
    -		return "unknown-state";
    -	}
    -}
    -
    -static int
    -acpi0_check(struct devinfo_dev *dd, void *arg)
    -{
    -	printf("%s: %s %s\n", __func__, dd->dd_name, devstate(dd->dd_state));
    -	/* NB: device must be present AND attached */
    -	if (strcmp(dd->dd_name, "acpi0") == 0)
    -		return (dd->dd_state == DIS_ATTACHED ||
    -			dd->dd_state == DIS_BUSY);
    -	return devinfo_foreach_device_child(dd, acpi0_check, arg);
    -}
    -
    -static int
    -acpi0_present(void)
    -{
    -	struct devinfo_dev *root;
    -	int found;
    -
    -	found = 0;
    -	devinfo_init();
    -	root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE);
    -	if (root != NULL)
    -		found = devinfo_foreach_device_child(root, acpi0_check, NULL);
    -	devinfo_free();
    -	return found;
    -}
    -
    -int
    -acpi_detect(void)
    -{
    -	struct ACPIrsdp *rp;
    -	struct ACPIsdt *rsdp;
    -	u_long addr;
    -	size_t len;
    -
    -	if (!acpi0_present()) {
    -		msgDebug("%s: no acpi0 device located\n", __func__);
    -		return -1;
    -	}
    -
    -	if (!acpi_user_init())
    -		return -1;
    -
    -	/* Attempt to use sysctl to find RSD PTR record. */
    -	len = sizeof(addr);
    -	if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) {
    -		msgDebug("%s: cannot find ACPI information\n", __func__);
    -		return -1;
    -	}
    -	rp = acpi_get_rsdp(addr);
    -	if (rp == NULL) {
    -		msgDebug("%s: cannot find ACPI information: "
    -		    "sysctl %s does not point to RSDP\n", __func__,
    -		    machdep_acpi_root);
    -		return -1;
    -	}
    -	if (rp->revision < 2) {
    -		rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
    -		if (rsdp == NULL)
    -			return -1;
    -		if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
    -		    acpi_checksum(rsdp, rsdp->len) != 0) {
    -			msgDebug("%s: RSDT is corrupted\n", __func__);
    -			return -1;
    -		}
    -		addr_size = sizeof(uint32_t);
    -	} else {
    -		rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
    -		if (rsdp == NULL)
    -			return -1;
    -		if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
    -		    acpi_checksum(rsdp, rsdp->len) != 0) {
    -			msgDebug("%s: XSDT is corrupted\n", __func__);
    -			return -1;
    -		}
    -		addr_size = sizeof(uint64_t);
    -	}
    -	ncpu = 0;
    -	acpi_handle_rsdt(rsdp);
    -	return (ncpu == 0 ? 1 : ncpu);
    -}
    diff --git a/usr.sbin/sysinstall/acpidump.h b/usr.sbin/sysinstall/acpidump.h
    deleted file mode 100644
    index 9c2b5b6e502..00000000000
    --- a/usr.sbin/sysinstall/acpidump.h
    +++ /dev/null
    @@ -1,177 +0,0 @@
    -/*-
    - * Copyright (c) 1999 Doug Rabson
    - * Copyright (c) 2000 Mitsuru IWASAKI 
    - * 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$
    - */
    -
    -#ifndef _ACPIDUMP_H_
    -#define _ACPIDUMP_H_
    -
    -/* Root System Description Pointer */
    -struct ACPIrsdp {
    -	u_char		signature[8];
    -	u_char		sum;
    -	u_char		oem[6];
    -	u_char		revision;
    -	u_int32_t	rsdt_addr;
    -	u_int32_t	length;
    -	u_int64_t	xsdt_addr;
    -	u_char		xsum;
    -	u_char		_reserved_[3];
    -} __packed;
    -
    -/* System Description Table */
    -struct ACPIsdt {
    -	u_char		signature[4];
    -	u_int32_t	len;
    -	u_char		rev;
    -	u_char		check;
    -	u_char		oemid[6];
    -	u_char		oemtblid[8];
    -	u_int32_t	oemrev;
    -	u_char		creator[4];
    -	u_int32_t	crerev;
    -#define SIZEOF_SDT_HDR 36	/* struct size except body */
    -	u_int32_t	body[1];/* This member should be casted */
    -} __packed;
    -
    -struct MADT_local_apic {
    -	u_char		cpu_id;
    -	u_char		apic_id;
    -	u_int32_t	flags;
    -#define	ACPI_MADT_APIC_LOCAL_FLAG_ENABLED	1
    -} __packed;
    -
    -struct MADT_io_apic {
    -	u_char		apic_id;
    -	u_char		reserved;
    -	u_int32_t	apic_addr;
    -	u_int32_t	int_base;
    -} __packed;
    -
    -struct MADT_int_override {
    -	u_char		bus;
    -	u_char		source;
    -	u_int32_t	intr;
    -	u_int16_t	mps_flags;
    -#define	MPS_INT_FLAG_POLARITY_MASK	0x3
    -#define	MPS_INT_FLAG_POLARITY_CONFORM	0x0
    -#define	MPS_INT_FLAG_POLARITY_HIGH	0x1
    -#define	MPS_INT_FLAG_POLARITY_LOW	0x3
    -#define	MPS_INT_FLAG_TRIGGER_MASK	0xc
    -#define	MPS_INT_FLAG_TRIGGER_CONFORM	0x0
    -#define	MPS_INT_FLAG_TRIGGER_EDGE	0x4
    -#define	MPS_INT_FLAG_TRIGGER_LEVEL	0xc
    -} __packed;
    -
    -struct MADT_nmi {
    -	u_int16_t	mps_flags;
    -	u_int32_t	intr;
    -} __packed;
    -
    -struct MADT_local_nmi {
    -	u_char		cpu_id;
    -	u_int16_t	mps_flags;
    -	u_char		lintpin;
    -} __packed;
    -
    -struct MADT_local_apic_override {
    -	u_char		reserved[2];
    -	u_int64_t	apic_addr;
    -} __packed;
    -
    -struct MADT_io_sapic {
    -	u_char		apic_id;
    -	u_char		reserved;
    -	u_int32_t	int_base;
    -	u_int64_t	apic_addr;
    -} __packed;
    -
    -struct MADT_local_sapic {
    -	u_char		cpu_id;
    -	u_char		apic_id;
    -	u_char		apic_eid;
    -	u_char		reserved[3];
    -	u_int32_t	flags;
    -} __packed;
    -
    -struct MADT_int_src {
    -	u_int16_t	mps_flags;
    -	u_char		type;
    -#define	ACPI_MADT_APIC_INT_SOURCE_PMI	1
    -#define	ACPI_MADT_APIC_INT_SOURCE_INIT	2
    -#define	ACPI_MADT_APIC_INT_SOURCE_CPEI	3	/* Corrected Platform Error */
    -	u_char		cpu_id;
    -	u_char		cpu_eid;
    -	u_char		sapic_vector;
    -	u_int32_t	intr;
    -	u_char		reserved[4];
    -} __packed;
    -
    -struct MADT_APIC {
    -	u_char		type;
    -#define	ACPI_MADT_APIC_TYPE_LOCAL_APIC	0
    -#define	ACPI_MADT_APIC_TYPE_IO_APIC	1
    -#define	ACPI_MADT_APIC_TYPE_INT_OVERRIDE 2
    -#define	ACPI_MADT_APIC_TYPE_NMI		3
    -#define	ACPI_MADT_APIC_TYPE_LOCAL_NMI	4
    -#define	ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE 5
    -#define	ACPI_MADT_APIC_TYPE_IO_SAPIC	6
    -#define	ACPI_MADT_APIC_TYPE_LOCAL_SAPIC	7
    -#define	ACPI_MADT_APIC_TYPE_INT_SRC	8
    -	u_char		len;
    -	union {
    -		struct MADT_local_apic local_apic;
    -		struct MADT_io_apic io_apic;
    -		struct MADT_int_override int_override;
    -		struct MADT_nmi nmi;
    -		struct MADT_local_nmi local_nmi;
    -		struct MADT_local_apic_override local_apic_override;
    -		struct MADT_io_sapic io_sapic;
    -		struct MADT_local_sapic local_sapic;
    -		struct MADT_int_src int_src;
    -	} body;
    -} __packed;
    -
    -struct MADTbody {
    -	u_int32_t	lapic_addr;
    -	u_int32_t	flags;
    -#define	ACPI_APIC_FLAG_PCAT_COMPAT 1	/* System has dual-8259 setup. */
    -	u_char		body[1];
    -} __packed;
    -
    -/*
    - * Addresses to scan on ia32 for the RSD PTR.  According to section 5.2.2
    - * of the ACPI spec, we only consider two regions for the base address:
    - * 1. EBDA (1 KB area addressed to by 16 bit pointer at 0x40E)
    - * 2. High memory (0xE0000 - 0xFFFFF)
    - */
    -#define RSDP_EBDA_PTR	0x40E
    -#define RSDP_EBDA_SIZE	0x400
    -#define RSDP_HI_START	0xE0000
    -#define RSDP_HI_SIZE	0x20000
    -
    -#endif	/* !_ACPIDUMP_H_ */
    diff --git a/usr.sbin/sysinstall/biosmptable.c b/usr.sbin/sysinstall/biosmptable.c
    deleted file mode 100644
    index 5a507bd6bfd..00000000000
    --- a/usr.sbin/sysinstall/biosmptable.c
    +++ /dev/null
    @@ -1,275 +0,0 @@
    -/*-
    - * Copyright (c) 2005 Sandvine Incorporated.  All righs 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.
    - *
    - * Author: Ed Maste 
    - */
    -
    -/*
    - * This module detects Intel Multiprocessor spec info (mptable) and returns
    - * the number of cpu's identified.
    - */
    -
    -#include 
    -__FBSDID("$FreeBSD$");
    -
    -#include 
    -#include 
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#include "sysinstall.h"
    -
    -#define MPFPS_SIG "_MP_"
    -#define MPCTH_SIG "PCMP"
    -
    -#define	PTOV(pa)	((off_t)(pa))
    -
    -static mpfps_t biosmptable_find_mpfps(void);
    -static mpfps_t biosmptable_search_mpfps(off_t base, int length);
    -static mpcth_t biosmptable_check_mpcth(off_t addr);
    -
    -static int memopen(void);
    -static void memclose(void);
    -
    -int
    -biosmptable_detect(void)
    -{
    -    mpfps_t mpfps;
    -    mpcth_t mpcth;
    -    char *entry_type_p;
    -    proc_entry_ptr proc;
    -    int ncpu, i;
    -
    -    if (!memopen())
    -	return -1;		/* XXX 0? */
    -    /* locate and validate the mpfps */
    -    mpfps = biosmptable_find_mpfps();
    -    mpcth = NULL;
    -    if (mpfps == NULL) {
    -	ncpu = 0;
    -    } else if (mpfps->config_type != 0) {
    -	/* 
    -	 * If thie config_type is nonzero then this is a default configuration
    -	 * from Chapter 5 in the MP spec.  Report 2 cpus and 1 I/O APIC.
    -	 */
    -    	ncpu = 2;
    -    } else {
    -	ncpu = 0;
    -	mpcth = biosmptable_check_mpcth(PTOV(mpfps->pap));
    -	if (mpcth != NULL) {
    -	    entry_type_p = (char *)(mpcth + 1);
    -	    for (i = 0; i < mpcth->entry_count; i++) {
    -		switch (*entry_type_p) {
    -		case 0:
    -		    entry_type_p += sizeof(struct PROCENTRY);
    -		    proc = (proc_entry_ptr) entry_type_p;
    -		    msgDebug("MPTable: Found CPU APIC ID %d %s\n",
    -			proc->apic_id,
    -			proc->cpu_flags & PROCENTRY_FLAG_EN ?
    -				"enabled" : "disabled");
    -		    if (proc->cpu_flags & PROCENTRY_FLAG_EN)
    -			ncpu++;
    -		    break;
    -		case 1:
    -		    entry_type_p += sizeof(struct BUSENTRY);
    -		    break;
    -		case 2:
    -		    entry_type_p += sizeof(struct IOAPICENTRY);
    -		    break;
    -		case 3:
    -		case 4:
    -		    entry_type_p += sizeof(struct INTENTRY);
    -		    break;
    -		default:
    -		    msgDebug("%s: unknown mptable entry type (%d)\n",
    -			__func__, *entry_type_p);
    -		    goto done;		/* XXX error return? */
    -		}
    -	    }
    -	done:
    -	    ;
    -	}
    -    }
    -    memclose();
    -    if (mpcth != NULL)
    -	free(mpcth);
    -    if (mpfps != NULL)
    -	free(mpfps);
    -
    -    return ncpu;
    -}
    -
    -static int pfd = -1;
    -
    -static int
    -memopen(void)
    -{
    -    if (pfd < 0) {
    -	pfd = open(_PATH_MEM, O_RDONLY);
    -	if (pfd < 0)
    -		warn("%s: cannot open", _PATH_MEM);
    -    }
    -    return pfd >= 0;
    -}
    -
    -static void
    -memclose(void)
    -{
    -    if (pfd >= 0) {
    -	close(pfd);
    -	pfd = -1;
    -    }
    -}
    -
    -static int
    -memread(off_t addr, void* entry, size_t size)
    -{
    -    if ((size_t)pread(pfd, entry, size, addr) != size) {
    -	warn("pread (%zu @ 0x%llx)", size, addr);
    -	return 0;
    -    }
    -    return 1;
    -}
    -
    -
    -/*
    - * Find the MP Floating Pointer Structure.  See the MP spec section 4.1.
    - */
    -static mpfps_t
    -biosmptable_find_mpfps(void)
    -{
    -    mpfps_t mpfps;
    -    uint16_t addr;
    -
    -    /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
    -    if (!memread(PTOV(0x40E), &addr, sizeof(addr)))
    -	return (NULL);
    -    mpfps = biosmptable_search_mpfps(PTOV(addr << 4), 0x400);
    -    if (mpfps != NULL)
    -	return (mpfps);
    -
    -    /* Check the BIOS. */
    -    mpfps = biosmptable_search_mpfps(PTOV(0xf0000), 0x10000);
    -    if (mpfps != NULL)
    -	return (mpfps);
    -
    -    return (NULL);
    -}
    -
    -static mpfps_t
    -biosmptable_search_mpfps(off_t base, int length)
    -{
    -    mpfps_t mpfps;
    -    u_int8_t *cp, sum;
    -    int ofs, idx;
    -
    -    mpfps = malloc(sizeof(*mpfps));
    -    if (mpfps == NULL) {
    -	msgDebug("%s: unable to malloc space for "
    -	    "MP Floating Pointer Structure\n", __func__);
    -	return (NULL);
    -    }
    -    /* search on 16-byte boundaries */
    -    for (ofs = 0; ofs < length; ofs += 16) {
    -	if (!memread(base + ofs, mpfps, sizeof(*mpfps)))
    -	    break;
    -
    -	/* compare signature, validate checksum */
    -	if (!strncmp(mpfps->signature, MPFPS_SIG, strlen(MPFPS_SIG))) {
    -	    cp = (u_int8_t *)mpfps;
    -	    sum = 0;
    -	    /* mpfps is 16 bytes, or one "paragraph" */
    -	    if (mpfps->length != 1) {
    -	    	msgDebug("%s: bad mpfps length (%d)\n",
    -		    __func__, mpfps->length);
    -		continue;
    -	    }
    -	    for (idx = 0; idx < mpfps->length * 16; idx++)
    -		sum += *(cp + idx);
    -	    if (sum != 0) {
    -		msgDebug("%s: bad mpfps checksum (%d)\n", __func__, sum);
    -		continue;
    -	    }
    -	    return (mpfps);
    -	}
    -    }
    -    free(mpfps);
    -    return (NULL);
    -}
    -
    -static mpcth_t
    -biosmptable_check_mpcth(off_t addr)
    -{
    -    mpcth_t mpcth;
    -    u_int8_t *cp, sum;
    -    int idx, table_length;
    -
    -    /* mpcth must be in the first 1MB */
    -    if ((u_int32_t)addr >= 1024 * 1024) {
    -	msgDebug("%s: bad mpcth address (0x%llx)\n", __func__, addr);
    -	return (NULL);
    -    }
    -
    -    mpcth = malloc(sizeof(*mpcth));
    -    if (mpcth == NULL) {
    -	msgDebug("%s: unable to malloc space for "
    -	    "MP Configuration Table Header\n", __func__);
    -	return (NULL);
    -    }
    -    if (!memread(addr, mpcth, sizeof(*mpcth)))
    -	goto bad;
    -    /* Compare signature and validate checksum. */
    -    if (strncmp(mpcth->signature, MPCTH_SIG, strlen(MPCTH_SIG)) != 0) {
    -        msgDebug("%s: bad mpcth signature\n", __func__);
    -	goto bad;
    -    }
    -    table_length = mpcth->base_table_length;
    -    mpcth = realloc(mpcth, table_length);
    -    if (mpcth == NULL) {
    -	msgDebug("%s: unable to realloc space for mpcth (len %u)\n",
    -	    __func__, table_length);
    -	return  (NULL);
    -    }
    -    if (!memread(addr, mpcth, table_length))
    -	goto bad;
    -    cp = (u_int8_t *)mpcth;
    -    sum = 0;
    -    for (idx = 0; idx < mpcth->base_table_length; idx++)
    -	sum += *(cp + idx);
    -    if (sum != 0) {
    -	msgDebug("%s: bad mpcth checksum (%d)\n", __func__, sum);
    -	goto bad;
    -    }
    -
    -    return mpcth;
    -bad:
    -    free(mpcth);
    -    return (NULL);
    -}
    diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c
    index 3c84a1d2ed6..5c9fe1cb316 100644
    --- a/usr.sbin/sysinstall/dist.c
    +++ b/usr.sbin/sysinstall/dist.c
    @@ -99,9 +99,6 @@ static Distribution DistTable[] = {
     /* The kernel distributions */
     static Distribution KernelDistTable[] = {
         DTE_TARBALL("GENERIC",  &KernelDists, KERNEL_GENERIC, "/boot"),
    -#ifdef WITH_SMP
    -    DTE_TARBALL("SMP", 	    &KernelDists, KERNEL_SMP,	  "/boot"),
    -#endif
         DTE_END,
     };
     
    @@ -207,12 +204,7 @@ distConfig(dialogMenuItem *self)
     int
     selectKernel(void)
     {
    -#ifdef WITH_SMP
    -    /* select default kernel based on deduced cpu count */
    -    return NCpus > 1 ? DIST_KERNEL_SMP : DIST_KERNEL_GENERIC;
    -#else
         return DIST_KERNEL_GENERIC;
    -#endif
     }
     
     int
    diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
    index a2979c900b0..ac2280311f7 100644
    --- a/usr.sbin/sysinstall/install.c
    +++ b/usr.sbin/sysinstall/install.c
    @@ -938,20 +938,12 @@ installFixupKernel(dialogMenuItem *self, int dists)
         /* All of this is done only as init, just to be safe */
         if (RunningAsInit) {
     	/*
    -	 * Install something as /boot/kernel.  Prefer SMP
    -	 * over GENERIC--this should handle the case where
    -	 * both SMP and GENERIC are installed (otherwise we
    -	 * select the one kernel that was installed).
    +	 * Install something as /boot/kernel.
     	 *
     	 * NB: we assume any existing kernel has been saved
     	 *     already and the /boot/kernel we remove is empty.
     	 */
     	vsystem("rm -rf /boot/kernel");
    -#if WITH_SMP
    -	if (dists & DIST_KERNEL_SMP)
    -		vsystem("mv /boot/SMP /boot/kernel");
    -	else
    -#endif
     		vsystem("mv /boot/GENERIC /boot/kernel");
         }
         return DITEM_SUCCESS | DITEM_RESTORE;
    @@ -1255,11 +1247,6 @@ installVarDefaults(dialogMenuItem *self)
     	variable_set2(SYSTEM_STATE,		"init", 0);
         variable_set2(VAR_NEWFS_ARGS,		"-b 16384 -f 2048", 0);
         variable_set2(VAR_CONSTERM,                 "NO", 0);
    -#if (defined(__i386__) && !defined(PC98)) || defined(__amd64__)
    -    NCpus = acpi_detect();
    -    if (NCpus == -1)
    -	NCpus = biosmptable_detect();
    -#endif
         if (NCpus <= 0)
     	NCpus = 1;
         snprintf(ncpus, sizeof(ncpus), "%u", NCpus);
    diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
    index 8ea7f9876e3..decb4fd0b87 100644
    --- a/usr.sbin/sysinstall/menus.c
    +++ b/usr.sbin/sysinstall/menus.c
    @@ -1031,10 +1031,6 @@ DMenu MenuKernelDistributions = {
     	NULL,		clearKernel, NULL, NULL, ' ', ' ', ' ' },
           { " GENERIC",	"GENERIC kernel configuration",
     	dmenuFlagCheck,	dmenuSetFlag, NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_GENERIC },
    -#ifdef WITH_SMP
    -      { " SMP",		"GENERIC symmetric multiprocessor kernel configuration",
    -	dmenuFlagCheck,	dmenuSetFlag,	NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_SMP },
    -#endif
           { NULL } },
     };
     
    diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8
    index 46a14fc8d9c..cdaec6dcc21 100644
    --- a/usr.sbin/sysinstall/sysinstall.8
    +++ b/usr.sbin/sysinstall/sysinstall.8
    @@ -413,8 +413,6 @@ Possible distribution values are:
     The base binary distribution.
     .It Li GENERIC
     The GENERIC kernel.
    -.It Li SMP
    -A kernel suitable for multiple processor systems.
     .It Li doc
     Miscellaneous documentation
     .It Li games
    
    From 1a29dc59c5c30d714948258a150c11d0ea5e4744 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
    Date: Tue, 10 Nov 2009 10:42:48 +0000
    Subject: [PATCH 610/646] Check fork() return value
    
    ---
     tools/regression/lib/libutil/test-flopen.c | 7 +++++--
     1 file changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/tools/regression/lib/libutil/test-flopen.c b/tools/regression/lib/libutil/test-flopen.c
    index d6ecac3a315..a3ae35c7ea5 100644
    --- a/tools/regression/lib/libutil/test-flopen.c
    +++ b/tools/regression/lib/libutil/test-flopen.c
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2007-2009 Dag-Erling Codan Smrgrav
    + * Copyright (c) 2007-2009 Dag-Erling Coテッdan Smテクrgrav
      * All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
    @@ -161,7 +161,10 @@ test_flopen_lock_child(void)
     	if (fd1 < 0) {
     		result = strerror(errno);
     	} else {
    -		if ((pid = fork()) == 0) {
    +		pid = fork();
    +		if (pid == -1) {
    +			result = strerror(errno);
    +		} else if (pid == 0) {
     			select(0, 0, 0, 0, 0);
     			_exit(0);
     		}
    
    From a7b890448ca154fad9a3205e6294c362ea92f533 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 10 Nov 2009 11:43:07 +0000
    Subject: [PATCH 611/646] Extract the code that records syscall results in the
     frame into MD function cpu_set_syscall_retval().
    
    Suggested by:	marcel
    Reviewed by:	marcel, davidxu
    PowerPC, ARM, ia64 changes:	marcel
    Sparc64 tested and reviewed by:	marius, also sunv reviewed
    MIPS tested by:	gonzo
    MFC after:	1 month
    ---
     sys/amd64/amd64/trap.c           | 34 +------------------
     sys/amd64/amd64/vm_machdep.c     | 39 ++++++++++++++++++++++
     sys/arm/arm/trap.c               | 37 +--------------------
     sys/arm/arm/vm_machdep.c         | 53 +++++++++++++++++++++++++++++
     sys/i386/i386/trap.c             | 30 +----------------
     sys/i386/i386/vm_machdep.c       | 36 ++++++++++++++++++++
     sys/ia64/ia64/trap.c             | 21 +-----------
     sys/ia64/ia64/vm_machdep.c       | 31 +++++++++++++++++
     sys/mips/include/pcb.h           |  1 +
     sys/mips/mips/trap.c             | 42 ++---------------------
     sys/mips/mips/vm_machdep.c       | 57 ++++++++++++++++++++++++++++++++
     sys/powerpc/aim/trap.c           | 39 ++--------------------
     sys/powerpc/aim/vm_machdep.c     | 55 ++++++++++++++++++++++++++++++
     sys/powerpc/booke/trap.c         | 37 +--------------------
     sys/powerpc/booke/vm_machdep.c   | 55 ++++++++++++++++++++++++++++++
     sys/sparc64/include/pcb.h        |  3 +-
     sys/sparc64/sparc64/trap.c       | 37 ++-------------------
     sys/sparc64/sparc64/vm_machdep.c | 37 +++++++++++++++++++++
     sys/sun4v/sun4v/trap.c           | 38 ++-------------------
     sys/sun4v/sun4v/vm_machdep.c     | 37 +++++++++++++++++++++
     sys/sys/proc.h                   |  2 +-
     21 files changed, 418 insertions(+), 303 deletions(-)
    
    diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
    index c97985d4494..3f7ea818b80 100644
    --- a/sys/amd64/amd64/trap.c
    +++ b/sys/amd64/amd64/trap.c
    @@ -1007,39 +1007,7 @@ syscall(struct trapframe *frame)
     #endif
     	}
     
    -	switch (error) {
    -	case 0:
    -		frame->tf_rax = td->td_retval[0];
    -		frame->tf_rdx = td->td_retval[1];
    -		frame->tf_rflags &= ~PSL_C;
    -		break;
    -
    -	case ERESTART:
    -		/*
    -		 * Reconstruct pc, we know that 'syscall' is 2 bytes.
    -		 * We have to do a full context restore so that %r10
    -		 * (which was holding the value of %rcx) is restored for
    -		 * the next iteration.
    -		 */
    -		frame->tf_rip -= frame->tf_err;
    -		frame->tf_r10 = frame->tf_rcx;
    -		td->td_pcb->pcb_flags |= PCB_FULLCTX;
    -		break;
    -
    -	case EJUSTRETURN:
    -		break;
    -
    -	default:
    - 		if (p->p_sysent->sv_errsize) {
    - 			if (error >= p->p_sysent->sv_errsize)
    -  				error = -1;	/* XXX */
    -   			else
    -  				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		frame->tf_rax = error;
    -		frame->tf_rflags |= PSL_C;
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Traced syscall.
    diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
    index 51d1d6218b1..6e567400355 100644
    --- a/sys/amd64/amd64/vm_machdep.c
    +++ b/sys/amd64/amd64/vm_machdep.c
    @@ -317,6 +317,45 @@ cpu_thread_free(struct thread *td)
     	cpu_thread_clean(td);
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +
    +	switch (error) {
    +	case 0:
    +		td->td_frame->tf_rax = td->td_retval[0];
    +		td->td_frame->tf_rdx = td->td_retval[1];
    +		td->td_frame->tf_rflags &= ~PSL_C;
    +		break;
    +
    +	case ERESTART:
    +		/*
    +		 * Reconstruct pc, we know that 'syscall' is 2 bytes.
    +		 * We have to do a full context restore so that %r10
    +		 * (which was holding the value of %rcx) is restored
    +		 * for the next iteration.
    +		 */
    +		td->td_frame->tf_rip -= td->td_frame->tf_err;
    +		td->td_frame->tf_r10 = td->td_frame->tf_rcx;
    +		td->td_pcb->pcb_flags |= PCB_FULLCTX;
    +		break;
    +
    +	case EJUSTRETURN:
    +		break;
    +
    +	default:
    +		if (td->td_proc->p_sysent->sv_errsize) {
    +			if (error >= td->td_proc->p_sysent->sv_errsize)
    +				error = -1;	/* XXX */
    +			else
    +				error = td->td_proc->p_sysent->sv_errtbl[error];
    +		}
    +		td->td_frame->tf_rax = error;
    +		td->td_frame->tf_rflags |= PSL_C;
    +		break;
    +	}
    +}
    +
     /*
      * Initialize machine state (pcb and trap frame) for a new thread about to
      * upcall. Put enough state in the new thread's PCB to get it to go back 
    diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
    index e6150c03961..348ec5a3bdd 100644
    --- a/sys/arm/arm/trap.c
    +++ b/sys/arm/arm/trap.c
    @@ -932,43 +932,8 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
     		KASSERT(td->td_ar == NULL, 
     		    ("returning from syscall with td_ar set!"));
     	}
    -	switch (error) {
    -	case 0: 
    -#ifdef __ARMEB__
    -		if ((insn & 0x000fffff) == SYS___syscall &&
    -		    code != SYS_freebsd6_lseek && code != SYS_lseek) {
    -			/*
    -			 * 64-bit return, 32-bit syscall. Fixup byte order
    -			 */ 
    -			frame->tf_r0 = 0;
    -			frame->tf_r1 = td->td_retval[0];
    -		} else {
    -			frame->tf_r0 = td->td_retval[0];
    -			frame->tf_r1 = td->td_retval[1];
    -		}
    -#else
    -		frame->tf_r0 = td->td_retval[0];
    -	  	frame->tf_r1 = td->td_retval[1];
    -#endif
    -					      
    -		frame->tf_spsr &= ~PSR_C_bit;   /* carry bit */
    -		break;
    -		
    -	case ERESTART:
    -		/*
    -		 * Reconstruct the pc to point at the swi.
    -		 */
    -		frame->tf_pc -= INSN_SIZE;
    -		break;
    -	case EJUSTRETURN:                                       
    -		/* nothing to do */  
    -		break;
    -	default:
     bad:
    -		frame->tf_r0 = error;
    -		frame->tf_spsr |= PSR_C_bit;    /* carry bit */
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
     	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
    diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
    index 6bd57999d3a..95b9ca8fc9a 100644
    --- a/sys/arm/arm/vm_machdep.c
    +++ b/sys/arm/arm/vm_machdep.c
    @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
    +#include 
     #include 
     #include 
     #include 
    @@ -261,6 +263,57 @@ done:
     #endif
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +	trapframe_t *frame;
    +	int fixup;
    +#ifdef __ARMEB__
    +	uint32_t insn;
    +#endif
    +
    +	frame = td->td_frame;
    +	fixup = 0;
    +
    +#ifdef __ARMEB__
    +	insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
    +	if ((insn & 0x000fffff) == SYS___syscall) {
    +		register_t *ap = &frame->tf_r0;
    +		register_t code = ap[_QUAD_LOWWORD];
    +		if (td->td_proc->p_sysent->sv_mask)
    +			code &= td->td_proc->p_sysent->sv_mask;
    +		fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek)
    +		    ? 1 : 0;
    +	}
    +#endif
    +
    +	switch (error) {
    +	case 0:
    +		if (fixup) {
    +			frame->tf_r0 = 0;
    +			frame->tf_r1 = td->td_retval[0];
    +		} else {
    +			frame->tf_r0 = td->td_retval[0];
    +			frame->tf_r1 = td->td_retval[1];
    +		}
    +		frame->tf_spsr &= ~PSR_C_bit;   /* carry bit */
    +		break;
    +	case ERESTART:
    +		/*
    +		 * Reconstruct the pc to point at the swi.
    +		 */
    +		frame->tf_pc -= INSN_SIZE;
    +		break;
    +	case EJUSTRETURN:
    +		/* nothing to do */
    +		break;
    +	default:
    +		frame->tf_r0 = error;
    +		frame->tf_spsr |= PSR_C_bit;    /* carry bit */
    +		break;
    +	}
    +}
    +
     /*
      * Initialize machine state (pcb and trap frame) for a new thread about to
      * upcall. Put enough state in the new thread's PCB to get it to go back 
    diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
    index f4df6687021..f8d0ea02634 100644
    --- a/sys/i386/i386/trap.c
    +++ b/sys/i386/i386/trap.c
    @@ -1093,35 +1093,7 @@ syscall(struct trapframe *frame)
     #endif
     	}
     
    -	switch (error) {
    -	case 0:
    -		frame->tf_eax = td->td_retval[0];
    -		frame->tf_edx = td->td_retval[1];
    -		frame->tf_eflags &= ~PSL_C;
    -		break;
    -
    -	case ERESTART:
    -		/*
    -		 * Reconstruct pc, assuming lcall $X,y is 7 bytes,
    -		 * int 0x80 is 2 bytes. We saved this in tf_err.
    -		 */
    -		frame->tf_eip -= frame->tf_err;
    -		break;
    -
    -	case EJUSTRETURN:
    -		break;
    -
    -	default:
    - 		if (p->p_sysent->sv_errsize) {
    - 			if (error >= p->p_sysent->sv_errsize)
    -  				error = -1;	/* XXX */
    -   			else
    -  				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		frame->tf_eax = error;
    -		frame->tf_eflags |= PSL_C;
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Traced syscall.
    diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
    index e7f55a1aac4..2948eb7e000 100644
    --- a/sys/i386/i386/vm_machdep.c
    +++ b/sys/i386/i386/vm_machdep.c
    @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -380,6 +381,41 @@ cpu_thread_free(struct thread *td)
     	cpu_thread_clean(td);
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +
    +	switch (error) {
    +	case 0:
    +		td->td_frame->tf_eax = td->td_retval[0];
    +		td->td_frame->tf_edx = td->td_retval[1];
    +		td->td_frame->tf_eflags &= ~PSL_C;
    +		break;
    +
    +	case ERESTART:
    +		/*
    +		 * Reconstruct pc, assuming lcall $X,y is 7 bytes, int
    +		 * 0x80 is 2 bytes. We saved this in tf_err.
    +		 */
    +		td->td_frame->tf_eip -= td->td_frame->tf_err;
    +		break;
    +
    +	case EJUSTRETURN:
    +		break;
    +
    +	default:
    +		if (td->td_proc->p_sysent->sv_errsize) {
    +			if (error >= td->td_proc->p_sysent->sv_errsize)
    +				error = -1;	/* XXX */
    +			else
    +				error = td->td_proc->p_sysent->sv_errtbl[error];
    +		}
    +		td->td_frame->tf_eax = error;
    +		td->td_frame->tf_eflags |= PSL_C;
    +		break;
    +	}
    +}
    +
     /*
      * Initialize machine state (pcb and trap frame) for a new thread about to
      * upcall. Put enough state in the new thread's PCB to get it to go back 
    diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
    index 2633ad208e4..2a4dca83a9f 100644
    --- a/sys/ia64/ia64/trap.c
    +++ b/sys/ia64/ia64/trap.c
    @@ -976,26 +976,7 @@ syscall(struct trapframe *tf)
     	error = (*callp->sy_call)(td, args);
     	AUDIT_SYSCALL_EXIT(error, td);
     
    -	if (error != EJUSTRETURN) {
    -		/*
    -		 * Save the "raw" error code in r10. We use this to handle
    -		 * syscall restarts (see do_ast()).
    -		 */
    -		tf->tf_scratch.gr10 = error;
    -		if (error == 0) {
    -			tf->tf_scratch.gr8 = td->td_retval[0];
    -			tf->tf_scratch.gr9 = td->td_retval[1];
    -		} else if (error != ERESTART) {
    -			if (error < p->p_sysent->sv_errsize)
    -				error = p->p_sysent->sv_errtbl[error];
    -			/*
    -			 * Translated error codes are returned in r8. User
    -			 * processes use the translated error code.
    -			 */
    -			tf->tf_scratch.gr8 = error;
    -		}
    -	}
    -
    +	cpu_set_syscall_retval(td, error);
     	td->td_syscalls++;
     
     	/*
    diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c
    index e5088a5a9c2..37af94b081c 100644
    --- a/sys/ia64/ia64/vm_machdep.c
    +++ b/sys/ia64/ia64/vm_machdep.c
    @@ -73,6 +73,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -139,6 +140,36 @@ cpu_thread_swapout(struct thread *td)
     	ia64_highfp_save(td);
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +	struct proc *p;
    +	struct trapframe *tf;
    +
    +	if (error == EJUSTRETURN)
    +		return;
    +
    +	tf = td->td_frame;
    +
    +	/*
    +	 * Save the "raw" error code in r10. We use this to handle
    +	 * syscall restarts (see do_ast()).
    +	 */
    +	tf->tf_scratch.gr10 = error;
    +	if (error == 0) {
    +		tf->tf_scratch.gr8 = td->td_retval[0];
    +		tf->tf_scratch.gr9 = td->td_retval[1];
    +	} else if (error != ERESTART) {
    +		p = td->td_proc;
    +		if (error < p->p_sysent->sv_errsize)
    +			error = p->p_sysent->sv_errtbl[error];
    +		/*
    +		 * Translated error codes are returned in r8. User
    +		 */
    +		tf->tf_scratch.gr8 = error;
    +	}
    +}
    +
     void
     cpu_set_upcall(struct thread *td, struct thread *td0)
     {
    diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h
    index 16d274dbf41..f54f2d736c2 100644
    --- a/sys/mips/include/pcb.h
    +++ b/sys/mips/include/pcb.h
    @@ -52,6 +52,7 @@ struct pcb
     	struct trapframe pcb_regs;	/* saved CPU and registers */
     	label_t pcb_context;		/* kernel context for resume */
     	int	pcb_onfault;		/* for copyin/copyout faults */
    +	register_t pcb_tpc;
     };
     
     /* these match the regnum's in regnum.h
    diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
    index 6d047ccdda2..1124b1c97fd 100644
    --- a/sys/mips/mips/trap.c
    +++ b/sys/mips/mips/trap.c
    @@ -644,7 +644,6 @@ dofault:
     			struct trapframe *locr0 = td->td_frame;
     			struct sysent *callp;
     			unsigned int code;
    -			unsigned int tpc;
     			int nargs, nsaved;
     			register_t args[8];
     
    @@ -660,7 +659,7 @@ dofault:
     				thread_user_enter(td);
     #endif
     			/* compute next PC after syscall instruction */
    -			tpc = trapframe->pc;	/* Remember if restart */
    +			td->td_pcb->pcb_tpc = trapframe->pc;	/* Remember if restart */
     			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
     				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
     				    0);
    @@ -761,44 +760,7 @@ dofault:
     			locr0 = td->td_frame;
     #endif
     			trapdebug_enter(locr0, -code);
    -			switch (i) {
    -			case 0:
    -				if (quad_syscall && code != SYS_lseek) {
    -					/*
    -					 * System call invoked through the
    -					 * SYS___syscall interface but the
    -					 * return value is really just 32
    -					 * bits.
    -					 */
    -					locr0->v0 = td->td_retval[0];
    -					if (_QUAD_LOWWORD)
    -						locr0->v1 = td->td_retval[0];
    -					locr0->a3 = 0;
    -				} else {
    -					locr0->v0 = td->td_retval[0];
    -					locr0->v1 = td->td_retval[1];
    -					locr0->a3 = 0;
    -				}
    -				break;
    -
    -			case ERESTART:
    -				locr0->pc = tpc;
    -				break;
    -
    -			case EJUSTRETURN:
    -				break;	/* nothing to do */
    -
    -			default:
    -				if (quad_syscall && code != SYS_lseek) {
    -					locr0->v0 = i;
    -					if (_QUAD_LOWWORD)
    -						locr0->v1 = i;
    -					locr0->a3 = 1;
    -				} else {
    -					locr0->v0 = i;
    -					locr0->a3 = 1;
    -				}
    -			}
    +			cpu_set_syscall_retval(td, i);
     
     			/*
     			 * The sync'ing of I & D caches for SYS_ptrace() is
    diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c
    index 26b64778b8c..918c5f04a9c 100644
    --- a/sys/mips/mips/vm_machdep.c
    +++ b/sys/mips/mips/vm_machdep.c
    @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -256,6 +257,62 @@ cpu_thread_alloc(struct thread *td)
     	}
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +	struct trapframe *locr0 = td->td_frame;
    +	unsigned int code;
    +	int quad_syscall;
    +
    +	code = locr0->v0;
    +	quad_syscall = 0;
    +	if (code == SYS_syscall)
    +		code = locr0->a0;
    +	else if (code == SYS___syscall) {
    +		code = _QUAD_LOWWORD ? locr0->a1 : locr0->a0;
    +		quad_syscall = 1;
    +	}
    +
    +	switch (error) {
    +	case 0:
    +		if (quad_syscall && code != SYS_lseek) {
    +			/*
    +			 * System call invoked through the
    +			 * SYS___syscall interface but the
    +			 * return value is really just 32
    +			 * bits.
    +			 */
    +			locr0->v0 = td->td_retval[0];
    +			if (_QUAD_LOWWORD)
    +				locr0->v1 = td->td_retval[0];
    +			locr0->a3 = 0;
    +		} else {
    +			locr0->v0 = td->td_retval[0];
    +			locr0->v1 = td->td_retval[1];
    +			locr0->a3 = 0;
    +		}
    +		break;
    +
    +	case ERESTART:
    +		locr0->pc = td->td_pcb->pcb_tpc;
    +		break;
    +
    +	case EJUSTRETURN:
    +		break;	/* nothing to do */
    +
    +	default:
    +		if (quad_syscall && code != SYS_lseek) {
    +			locr0->v0 = error;
    +			if (_QUAD_LOWWORD)
    +				locr0->v1 = error;
    +			locr0->a3 = 1;
    +		} else {
    +			locr0->v0 = error;
    +			locr0->a3 = 1;
    +		}
    +	}
    +}
    +
     /*
      * Initialize machine state (pcb and trap frame) for a new thread about to
      * upcall. Put enough state in the new thread's PCB to get it to go back
    diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
    index ee9c7d30ef0..60c6bb07977 100644
    --- a/sys/powerpc/aim/trap.c
    +++ b/sys/powerpc/aim/trap.c
    @@ -415,43 +415,8 @@ syscall(struct trapframe *frame)
     		CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", td->td_name,
     		     syscallnames[code], td->td_retval[0]);
     	}
    -	switch (error) {
    -	case 0:
    -		if (frame->fixreg[0] == SYS___syscall &&
    -		    code != SYS_freebsd6_lseek && code != SYS_lseek) {
    -			/*
    -			 * 64-bit return, 32-bit syscall. Fixup byte order
    -			 */
    -			frame->fixreg[FIRSTARG] = 0;
    -			frame->fixreg[FIRSTARG + 1] = td->td_retval[0];
    -		} else {
    -			frame->fixreg[FIRSTARG] = td->td_retval[0];
    -			frame->fixreg[FIRSTARG + 1] = td->td_retval[1];
    -		}
    -		/* XXX: Magic number */
    -		frame->cr &= ~0x10000000;
    -		break;
    -	case ERESTART:
    -		/*
    -		 * Set user's pc back to redo the system call.
    -		 */
    -		frame->srr0 -= 4;
    -		break;
    -	case EJUSTRETURN:
    -		/* nothing to do */
    -		break;
    -	default:
    -		if (p->p_sysent->sv_errsize) {
    -			if (error >= p->p_sysent->sv_errsize)
    -				error = -1;	/* XXX */
    -			else
    -				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		frame->fixreg[FIRSTARG] = error;
    -		/* XXX: Magic number: Carry Flag Equivalent? */
    -		frame->cr |= 0x10000000;
    -		break;
    -	}
    +
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Check for misbehavior.
    diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c
    index af83854e3b5..3967176e2b0 100644
    --- a/sys/powerpc/aim/vm_machdep.c
    +++ b/sys/powerpc/aim/vm_machdep.c
    @@ -81,7 +81,9 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
    +#include 
     #include 
     
     #include 
    @@ -421,6 +423,59 @@ cpu_thread_swapout(struct thread *td)
     {
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +	struct proc *p;
    +	struct trapframe *tf;
    +	int fixup;
    +
    +	if (error == EJUSTRETURN)
    +		return;
    +
    +	p = td->td_proc;
    +	tf = td->td_frame;
    +
    +	if (tf->fixreg[0] == SYS___syscall) {
    +		int code = tf->fixreg[FIRSTARG + 1];
    +		if (p->p_sysent->sv_mask)
    +			code &= p->p_sysent->sv_mask;
    +		fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ?
    +		    1 : 0;
    +	} else
    +		fixup = 0;
    +
    +	switch (error) {
    +	case 0:
    +		if (fixup) {
    +			/*
    +			 * 64-bit return, 32-bit syscall. Fixup byte order
    +			 */
    +			tf->fixreg[FIRSTARG] = 0;
    +			tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
    +		} else {
    +			tf->fixreg[FIRSTARG] = td->td_retval[0];
    +			tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
    +		}
    +		tf->cr &= ~0x10000000;		/* XXX: Magic number */
    +		break;
    +	case ERESTART:
    +		/*
    +		 * Set user's pc back to redo the system call.
    +		 */
    +		tf->srr0 -= 4;
    +		break;
    +	default:
    +		if (p->p_sysent->sv_errsize) {
    +			error = (error < p->p_sysent->sv_errsize) ?
    +			    p->p_sysent->sv_errtbl[error] : -1;
    +		}
    +		tf->fixreg[FIRSTARG] = error;
    +		tf->cr |= 0x10000000;		/* XXX: Magic number */
    +		break;
    +	}
    +}
    +
     void
     cpu_set_upcall(struct thread *td, struct thread *td0)
     {
    diff --git a/sys/powerpc/booke/trap.c b/sys/powerpc/booke/trap.c
    index 0e746f4f0c7..d98efb99292 100644
    --- a/sys/powerpc/booke/trap.c
    +++ b/sys/powerpc/booke/trap.c
    @@ -417,42 +417,7 @@ syscall(struct trapframe *frame)
     		     syscallnames[code], td->td_retval[0]);
     	}
     
    -	switch (error) {
    -	case 0:
    -		if (frame->fixreg[0] == SYS___syscall && SYS_lseek) {
    -			/*
    -			 * 64-bit return, 32-bit syscall. Fixup byte order
    -			 */
    -			frame->fixreg[FIRSTARG] = 0;
    -			frame->fixreg[FIRSTARG + 1] = td->td_retval[0];
    -		} else {
    -			frame->fixreg[FIRSTARG] = td->td_retval[0];
    -			frame->fixreg[FIRSTARG + 1] = td->td_retval[1];
    -		}
    -		/* XXX: Magic number */
    -		frame->cr &= ~0x10000000;
    -		break;
    -	case ERESTART:
    -		/*
    -		 * Set user's pc back to redo the system call.
    -		 */
    -		frame->srr0 -= 4;
    -		break;
    -	case EJUSTRETURN:
    -		/* nothing to do */
    -		break;
    -	default:
    -		if (p->p_sysent->sv_errsize) {
    -			if (error >= p->p_sysent->sv_errsize)
    -				error = -1;	/* XXX */
    -			else
    -				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		frame->fixreg[FIRSTARG] = error;
    -		/* XXX: Magic number: Carry Flag Equivalent? */
    -		frame->cr |= 0x10000000;
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Check for misbehavior.
    diff --git a/sys/powerpc/booke/vm_machdep.c b/sys/powerpc/booke/vm_machdep.c
    index 178b863de54..7d2b88b4bce 100644
    --- a/sys/powerpc/booke/vm_machdep.c
    +++ b/sys/powerpc/booke/vm_machdep.c
    @@ -113,7 +113,9 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
    +#include 
     #include 
     
     #include 
    @@ -422,6 +424,59 @@ cpu_thread_swapout(struct thread *td)
     
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +	struct proc *p;
    +	struct trapframe *tf;
    +	int fixup;
    +
    +	p = td->td_proc;
    +	tf = td->td_frame;
    +
    +	if (tf->fixreg[0] == SYS___syscall) {
    +		int code = tf->fixreg[FIRSTARG + 1];
    +		if (p->p_sysent->sv_mask)
    +			code &= p->p_sysent->sv_mask;
    +		fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ?
    +		    1 : 0;
    +	} else
    +		fixup = 0;
    +
    +	switch (error) {
    +	case 0:
    +		if (fixup) {
    +			/*
    +			 * 64-bit return, 32-bit syscall. Fixup byte order
    +			 */
    +			tf->fixreg[FIRSTARG] = 0;
    +			tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
    +		} else {
    +			tf->fixreg[FIRSTARG] = td->td_retval[0];
    +			tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
    +		}
    +		tf->cr &= ~0x10000000;		/* XXX: Magic number */
    +		break;
    +	case ERESTART:
    +		/*
    +		 * Set user's pc back to redo the system call.
    +		 */
    +		tf->srr0 -= 4;
    +		break;
    +	case EJUSTRETURN:
    +		/* nothing to do */
    +		break;
    +	default:
    +		if (p->p_sysent->sv_errsize) {
    +			error = (error < p->p_sysent->sv_errsize) ?
    +			    p->p_sysent->sv_errtbl[error] : -1;
    +		}
    +		tf->fixreg[FIRSTARG] = error;
    +		tf->cr |= 0x10000000;		/* XXX: Magic number */
    +		break;
    +	}
    +}
    +
     void
     cpu_set_upcall(struct thread *td, struct thread *td0)
     {
    diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h
    index 7e8294ad9b6..f23c1f291c2 100644
    --- a/sys/sparc64/include/pcb.h
    +++ b/sys/sparc64/include/pcb.h
    @@ -49,7 +49,8 @@ struct pcb {
     	uint64_t pcb_nsaved;
     	uint64_t pcb_pc;
     	uint64_t pcb_sp;
    -	uint64_t pcb_pad[4];
    +	uint64_t pcb_tpc;
    +	uint64_t pcb_pad[3];
     } __aligned(64);
     
     #ifdef _KERNEL
    diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
    index 702e4f19866..0c07eafd4f7 100644
    --- a/sys/sparc64/sparc64/trap.c
    +++ b/sys/sparc64/sparc64/trap.c
    @@ -538,7 +538,6 @@ syscall(struct trapframe *tf)
     	register_t *argp;
     	struct proc *p;
     	u_long code;
    -	u_long tpc;
     	int reg;
     	int regcnt;
     	int narg;
    @@ -562,7 +561,7 @@ syscall(struct trapframe *tf)
     	 * For syscalls, we don't want to retry the faulting instruction
     	 * (usually), instead we need to advance one instruction.
     	 */
    -	tpc = tf->tf_tpc;
    +	td->td_pcb->pcb_tpc = tf->tf_tpc;
     	TF_DONE(tf);
     
     	reg = 0;
    @@ -626,39 +625,7 @@ syscall(struct trapframe *tf)
     		    td->td_retval[1]);
     	}
     
    -	/*
    -	 * MP SAFE (we may or may not have the MP lock at this point)
    -	 */
    -	switch (error) {
    -	case 0:
    -		tf->tf_out[0] = td->td_retval[0];
    -		tf->tf_out[1] = td->td_retval[1];
    -		tf->tf_tstate &= ~TSTATE_XCC_C;
    -		break;
    -
    -	case ERESTART:
    -		/*
    -		 * Undo the tpc advancement we have done above, we want to
    -		 * reexecute the system call.
    -		 */
    -		tf->tf_tpc = tpc;
    -		tf->tf_tnpc -= 4;
    -		break;
    -
    -	case EJUSTRETURN:
    -		break;
    -
    -	default:
    -		if (p->p_sysent->sv_errsize) {
    -			if (error >= p->p_sysent->sv_errsize)
    -				error = -1;	/* XXX */
    -			else
    -				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		tf->tf_out[0] = error;
    -		tf->tf_tstate |= TSTATE_XCC_C;
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Check for misbehavior.
    diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
    index 76521a6bca3..009f45d650a 100644
    --- a/sys/sparc64/sparc64/vm_machdep.c
    +++ b/sys/sparc64/sparc64/vm_machdep.c
    @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -165,6 +166,42 @@ cpu_thread_swapout(struct thread *td)
     
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +
    +	switch (error) {
    +	case 0:
    +		td->td_frame->tf_out[0] = td->td_retval[0];
    +		td->td_frame->tf_out[1] = td->td_retval[1];
    +		td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
    +		break;
    +
    +	case ERESTART:
    +		/*
    +		 * Undo the tpc advancement we have done on syscall
    +		 * enter, we want to reexecute the system call.
    +		 */
    +		td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
    +		td->td_frame->tf_tnpc -= 4;
    +		break;
    +
    +	case EJUSTRETURN:
    +		break;
    +
    +	default:
    +		if (td->td_proc->p_sysent->sv_errsize) {
    +			if (error >= td->td_proc->p_sysent->sv_errsize)
    +				error = -1;	/* XXX */
    +			else
    +				error = td->td_proc->p_sysent->sv_errtbl[error];
    +		}
    +		td->td_frame->tf_out[0] = error;
    +		td->td_frame->tf_tstate |= TSTATE_XCC_C;
    +		break;
    +	}
    +}
    +
     void
     cpu_set_upcall(struct thread *td, struct thread *td0)
     {
    diff --git a/sys/sun4v/sun4v/trap.c b/sys/sun4v/sun4v/trap.c
    index ffa0e8ca633..353462da7c3 100644
    --- a/sys/sun4v/sun4v/trap.c
    +++ b/sys/sun4v/sun4v/trap.c
    @@ -81,6 +81,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -582,7 +583,6 @@ syscall(struct trapframe *tf)
     	register_t *argp;
     	struct proc *p;
     	u_long code;
    -	u_long tpc;
     	int reg;
     	int regcnt;
     	int narg;
    @@ -606,7 +606,7 @@ syscall(struct trapframe *tf)
     	 * For syscalls, we don't want to retry the faulting instruction
     	 * (usually), instead we need to advance one instruction.
     	 */
    -	tpc = tf->tf_tpc;
    +	td->td_pcb->pcb_tpc = tf->tf_tpc;
     	TF_DONE(tf);
     
     	reg = 0;
    @@ -673,40 +673,8 @@ syscall(struct trapframe *tf)
     		    error, syscallnames[code], td->td_retval[0],
     		    td->td_retval[1]);
     	}
    -	
    -	/*
    -	 * MP SAFE (we may or may not have the MP lock at this point)
    -	 */
    -	switch (error) {
    -	case 0:
    -		tf->tf_out[0] = td->td_retval[0];
    -		tf->tf_out[1] = td->td_retval[1];
    -		tf->tf_tstate &= ~TSTATE_XCC_C;
    -		break;
     
    -	case ERESTART:
    -		/*
    -		 * Undo the tpc advancement we have done above, we want to
    -		 * reexecute the system call.
    -		 */
    -		tf->tf_tpc = tpc;
    -		tf->tf_tnpc -= 4;
    -		break;
    -
    -	case EJUSTRETURN:
    -		break;
    -
    -	default:
    - 		if (p->p_sysent->sv_errsize) {
    - 			if (error >= p->p_sysent->sv_errsize)
    -  				error = -1;	/* XXX */
    -   			else
    -  				error = p->p_sysent->sv_errtbl[error];
    -		}
    -		tf->tf_out[0] = error;
    -		tf->tf_tstate |= TSTATE_XCC_C;
    -		break;
    -	}
    +	cpu_set_syscall_retval(td, error);
     
     	/*
     	 * Handle reschedule and other end-of-syscall issues
    diff --git a/sys/sun4v/sun4v/vm_machdep.c b/sys/sun4v/sun4v/vm_machdep.c
    index 63a002f5e50..5e02aec29d2 100644
    --- a/sys/sun4v/sun4v/vm_machdep.c
    +++ b/sys/sun4v/sun4v/vm_machdep.c
    @@ -57,6 +57,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     
    @@ -141,6 +142,42 @@ cpu_thread_swapout(struct thread *td)
     {
     }
     
    +void
    +cpu_set_syscall_retval(struct thread *td, int error)
    +{
    +
    +	switch (error) {
    +	case 0:
    +		td->td_frame->tf_out[0] = td->td_retval[0];
    +		td->td_frame->tf_out[1] = td->td_retval[1];
    +		td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
    +		break;
    +
    +	case ERESTART:
    +		/*
    +		 * Undo the tpc advancement we have done on syscall
    +		 * enter, we want to reexecute the system call.
    +		 */
    +		td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
    +		td->td_frame->tf_tnpc -= 4;
    +		break;
    +
    +	case EJUSTRETURN:
    +		break;
    +
    +	default:
    +		if (td->td_proc->p_sysent->sv_errsize) {
    +			if (error >= td->td_proc->p_sysent->sv_errsize)
    +				error = -1;	/* XXX */
    +			else
    +				error = td->td_proc->p_sysent->sv_errtbl[error];
    +		}
    +		td->td_frame->tf_out[0] = error;
    +		td->td_frame->tf_tstate |= TSTATE_XCC_C;
    +		break;
    +	}
    +}
    +
     void
     cpu_set_upcall(struct thread *td, struct thread *td0)
     {
    diff --git a/sys/sys/proc.h b/sys/sys/proc.h
    index 384f2805ca0..3eb6ea6a4d3 100644
    --- a/sys/sys/proc.h
    +++ b/sys/sys/proc.h
    @@ -836,7 +836,7 @@ void	cpu_exit(struct thread *);
     void	exit1(struct thread *, int) __dead2;
     void	cpu_fork(struct thread *, struct proc *, struct thread *, int);
     void	cpu_set_fork_handler(struct thread *, void (*)(void *), void *);
    -
    +void	cpu_set_syscall_retval(struct thread *, int);
     void	cpu_set_upcall(struct thread *td, struct thread *td0);
     void	cpu_set_upcall_kse(struct thread *, void (*)(void *), void *,
     	    stack_t *);
    
    From 75c586a4c8feeed9bc50a07d32247000ca91e114 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 10 Nov 2009 11:46:53 +0000
    Subject: [PATCH 612/646] In r198506, kern_sigsuspend() started doing
     cursig/postsig loop to make sure that a signal was delivered to the thread
     before returning from syscall. Signal delivery puts new return frame on the
     user stack, and modifies trap frame to enter signal handler. As a
     consequence, syscall return code sets EINTR as error return for signal frame,
     instead of the syscall return.
    
    Also, for ia64, due to different registers layout for those two kind of
    frames, usermode sigsegfaulted when returned from signal handler.
    
    Use newly-introduced cpu_set_syscall_retval(9) to set syscall result,
    and return EJUSTRETURN from kern_sigsuspend() to prevent syscall return
    code from modifying this frame [1].
    
    Another issue is that pending SIGCONT might be cancelled by SIGSTOP,
    causing postsig() not to deliver any catched signal [2]. Modify
    postsig() to return 1 if signal was posted, and 0 otherwise, and use
    this in the kern_sigsuspend loop.
    
    Proposed by:	marcel [1]
    Noted by:	davidxu [2]
    Reviewed by:	marcel, davidxu
    MFC after:	1 month
    ---
     sys/kern/kern_sig.c | 15 +++++++--------
     sys/sys/signalvar.h |  2 +-
     2 files changed, 8 insertions(+), 9 deletions(-)
    
    diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
    index e174df1e42d..412e00db618 100644
    --- a/sys/kern/kern_sig.c
    +++ b/sys/kern/kern_sig.c
    @@ -1471,21 +1471,19 @@ kern_sigsuspend(struct thread *td, sigset_t mask)
     	 * thread. But sigsuspend should return only on signal
     	 * delivery.
     	 */
    +	cpu_set_syscall_retval(td, EINTR);
     	for (has_sig = 0; !has_sig;) {
     		while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause",
     			0) == 0)
     			/* void */;
     		thread_suspend_check(0);
     		mtx_lock(&p->p_sigacts->ps_mtx);
    -		while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0) {
    -			postsig(sig);
    -			has_sig = 1;
    -		}
    +		while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0)
    +			has_sig += postsig(sig);
     		mtx_unlock(&p->p_sigacts->ps_mtx);
     	}
     	PROC_UNLOCK(p);
    -	/* always return EINTR rather than ERESTART... */
    -	return (EINTR);
    +	return (EJUSTRETURN);
     }
     
     #ifdef COMPAT_43	/* XXX - COMPAT_FBSD3 */
    @@ -2670,7 +2668,7 @@ thread_stopped(struct proc *p)
      * Take the action for the specified signal
      * from the current set of pending signals.
      */
    -void
    +int
     postsig(sig)
     	register int sig;
     {
    @@ -2689,7 +2687,7 @@ postsig(sig)
     	ksiginfo_init(&ksi);
     	if (sigqueue_get(&td->td_sigqueue, sig, &ksi) == 0 &&
     	    sigqueue_get(&p->p_sigqueue, sig, &ksi) == 0)
    -		return;
    +		return (0);
     	ksi.ksi_signo = sig;
     	if (ksi.ksi_code == SI_TIMER)
     		itimer_accept(p, ksi.ksi_timerid, &ksi);
    @@ -2757,6 +2755,7 @@ postsig(sig)
     		}
     		(*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
     	}
    +	return (1);
     }
     
     /*
    diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
    index c27a1280801..65d9cf53ef3 100644
    --- a/sys/sys/signalvar.h
    +++ b/sys/sys/signalvar.h
    @@ -330,7 +330,7 @@ void	gsignal(int pgid, int sig);
     void	killproc(struct proc *p, char *why);
     void	pgsigio(struct sigio **, int signum, int checkctty);
     void	pgsignal(struct pgrp *pgrp, int sig, int checkctty);
    -void	postsig(int sig);
    +int	postsig(int sig);
     void	psignal(struct proc *p, int sig);
     int	psignal_event(struct proc *p, struct sigevent *, ksiginfo_t *);
     struct sigacts *sigacts_alloc(void);
    
    From 88e6f61a194cfb882704d52b4ba2bfd85f88e248 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 10 Nov 2009 11:50:37 +0000
    Subject: [PATCH 613/646] When rename("a", "b/.") is performed, target namei()
     call returns dvp == vp. Rename syscall does not check for the case, and at
     least ufs_rename() cannot deal with it. POSIX explicitely requires that both
     rename(2) and rmdir(2) return EINVAL when any of the pathes end in "/.".
    
    Detect the slashdot lookup for RENAME or REMOVE in lookup(), and return
    EINVAL.
    
    Reported by:	Jim Meyering 
    Tested by:	simon, pho
    MFC after:	1 week
    ---
     sys/kern/vfs_lookup.c | 6 ++++++
     1 file changed, 6 insertions(+)
    
    diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
    index e553ae4dc06..51985622079 100644
    --- a/sys/kern/vfs_lookup.c
    +++ b/sys/kern/vfs_lookup.c
    @@ -552,6 +552,12 @@ dirloop:
     	else
     		cnp->cn_flags &= ~ISLASTCN;
     
    +	if ((cnp->cn_flags & ISLASTCN) != 0 &&
    +	    cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.' &&
    +	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
    +		error = EINVAL;
    +		goto bad;
    +	}
     
     	/*
     	 * Check for degenerate name (e.g. / or "")
    
    From d7f36840905d682ce24c886b0b79d9a2debd1476 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Tue, 10 Nov 2009 19:14:06 +0000
    Subject: [PATCH 615/646] Add support for the touchpads found in later models
     of iBook and Powerbook.
    
    Reviewed by:	Rohit Grover 
    ---
     sys/dev/usb/input/atp.c | 110 ++++++++++++++++++++++++++++++++--------
     1 file changed, 89 insertions(+), 21 deletions(-)
    
    diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c
    index 18068029e6c..dcd95949b44 100644
    --- a/sys/dev/usb/input/atp.c
    +++ b/sys/dev/usb/input/atp.c
    @@ -193,21 +193,50 @@ SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_max_width, CTLFLAG_RW,
         &atp_pspan_max_width, 4,
         "maximum allowed width (in sensors) for pressure-spans");
     
    +/* We support three payload protocols */
    +typedef enum {
    +	ATP_PROT_GEYSER1,
    +	ATP_PROT_GEYSER2,
    +	ATP_PROT_GEYSER3,
    +} atp_protocol;
     
     /* Define the various flavours of devices supported by this driver. */
     enum {
     	ATP_DEV_PARAMS_0,
    +	ATP_DEV_PARAMS_PBOOK,
    +	ATP_DEV_PARAMS_PBOOK_15A,
    +	ATP_DEV_PARAMS_PBOOK_17,
     	ATP_N_DEV_PARAMS
     };
     struct atp_dev_params {
     	u_int            data_len;   /* for sensor data */
     	u_int            n_xsensors;
     	u_int            n_ysensors;
    +	atp_protocol     prot;
     } atp_dev_params[ATP_N_DEV_PARAMS] = {
     	[ATP_DEV_PARAMS_0] = {
     		.data_len   = 64,
     		.n_xsensors = 20,
    -		.n_ysensors = 10
    +		.n_ysensors = 10,
    +		.prot       = ATP_PROT_GEYSER3
    +	},
    +	[ATP_DEV_PARAMS_PBOOK] = {
    +		.data_len   = 81,
    +		.n_xsensors = 16,
    +		.n_ysensors = 16,
    +		.prot       = ATP_PROT_GEYSER1
    +	},
    +	[ATP_DEV_PARAMS_PBOOK_15A] = {
    +		.data_len   = 64,
    +		.n_xsensors = 15,
    +		.n_ysensors = 9,
    +		.prot       = ATP_PROT_GEYSER2
    +	},
    +	[ATP_DEV_PARAMS_PBOOK_17] = {
    +		.data_len   = 81,
    +		.n_xsensors = 26,
    +		.n_ysensors = 16,
    +		.prot       = ATP_PROT_GEYSER1
     	},
     };
     
    @@ -226,6 +255,19 @@ static const struct usb_device_id atp_devs[] = {
     	{ USB_VPI(USB_VENDOR_APPLE, 0x0229, ATP_DEV_PARAMS_0) },
     	{ USB_VPI(USB_VENDOR_APPLE, 0x022a, ATP_DEV_PARAMS_0) },
     	{ USB_VPI(USB_VENDOR_APPLE, 0x022b, ATP_DEV_PARAMS_0) },
    +
    +	/* 12 inch PowerBook and iBook */
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x030a, ATP_DEV_PARAMS_PBOOK) },
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x030b, ATP_DEV_PARAMS_PBOOK) },
    +
    +	/* 15 inch PowerBook */
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x020e, ATP_DEV_PARAMS_PBOOK) },
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x020f, ATP_DEV_PARAMS_PBOOK) },
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x0215, ATP_DEV_PARAMS_PBOOK_15A) },
    +
    +	/* 17 inch PowerBook */
    +	{ USB_VPI(USB_VENDOR_APPLE, 0x020d, ATP_DEV_PARAMS_PBOOK_17) },
    +
     };
     
     /*
    @@ -321,6 +363,7 @@ struct atp_softc {
     #define ATP_ENABLED            0x01
     #define ATP_ZOMBIES_EXIST      0x02
     #define ATP_DOUBLE_TAP_DRAG    0x04
    +#define ATP_VALID              0x08
     
     	u_int                  sc_left_margin;
     	u_int                  sc_right_margin;
    @@ -384,8 +427,8 @@ static int           atp_softc_populate(struct atp_softc *);
     static void          atp_softc_unpopulate(struct atp_softc *);
     
     /* sensor interpretation */
    -static __inline void atp_interpret_sensor_data(const int8_t *, u_int, u_int,
    -			 int *);
    +static __inline void atp_interpret_sensor_data(const int8_t *, u_int, atp_axis,
    +			 int *, atp_protocol);
     static __inline void atp_get_pressures(int *, const int *, const int *, int);
     static void          atp_detect_pspans(int *, u_int, u_int, atp_pspan *,
     			 u_int *);
    @@ -483,7 +526,7 @@ atp_disable(struct atp_softc *sc)
     {
     	atp_softc_unpopulate(sc);
     
    -	sc->sc_state &= ~ATP_ENABLED;
    +	sc->sc_state &= ~(ATP_ENABLED | ATP_VALID);
     	DPRINTFN(ATP_LLEVEL_INFO, "disabled atp\n");
     }
     
    @@ -623,25 +666,42 @@ atp_softc_unpopulate(struct atp_softc *sc)
      *       raw sensor data from the USB packet.
      *   num
      *       The number of elements in the array 'arr'.
    - *   di_start
    - *       The index of the first data element to be interpreted for
    - *       this sensor array--i.e. when called to interpret the Y
    - *       sensors, di_start passed in as 2, which is the index of Y1 in
    - *       the raw data.
    + *   axis
    + *       Axis of data to fetch
      *   arr
      *       The array to be initialized with the readings.
    + *   prot
    + *       The protocol to use to interpret the data
      */
     static __inline void
    -atp_interpret_sensor_data(const int8_t *sensor_data, u_int num, u_int di_start,
    -    int	*arr)
    +atp_interpret_sensor_data(const int8_t *sensor_data, u_int num, atp_axis axis,
    +    int	*arr, atp_protocol prot)
     {
     	u_int i;
     	u_int di;   /* index into sensor data */
     
    -	for (i = 0, di = di_start; i < num; /* empty */ ) {
    -		arr[i++] = sensor_data[di++];
    -		arr[i++] = sensor_data[di++];
    -		di++;
    +	switch (prot) {
    +	case ATP_PROT_GEYSER1:
    +		/*
    +		 * For Geyser 1, the sensors are laid out in pairs
    +		 * every 5 bytes.
    +		 */
    +		for (i = 0, di = (axis == Y) ? 1 : 2; i < 8; di += 5, i++) {
    +			arr[i] = sensor_data[di];
    +			arr[i+8] = sensor_data[di+2];
    +			if (axis == X && num > 16) 
    +				arr[i+16] = sensor_data[di+40];
    +		}
    +
    +		break;
    +	case ATP_PROT_GEYSER2:
    +	case ATP_PROT_GEYSER3:
    +		for (i = 0, di = (axis == Y) ? 2 : 20; i < num; /* empty */ ) {
    +			arr[i++] = sensor_data[di++];
    +			arr[i++] = sensor_data[di++];
    +			di++;
    +		}
    +		break;
     	}
     }
     
    @@ -1613,7 +1673,7 @@ atp_intr(struct usb_xfer *xfer, usb_error_t error)
     			    len, sc->sc_params->data_len);
     			len = sc->sc_params->data_len;
     		}
    -		if (len == 0)
    +		if (len < sc->sc_params->data_len)
     			goto tr_setup;
     
     		pc = usbd_xfer_get_frame(xfer, 0);
    @@ -1621,9 +1681,11 @@ atp_intr(struct usb_xfer *xfer, usb_error_t error)
     
     		/* Interpret sensor data */
     		atp_interpret_sensor_data(sc->sensor_data,
    -		    sc->sc_params->n_xsensors, 20, sc->cur_x);
    +		    sc->sc_params->n_xsensors, X, sc->cur_x,
    +		    sc->sc_params->prot);
     		atp_interpret_sensor_data(sc->sensor_data,
    -		    sc->sc_params->n_ysensors, 2,  sc->cur_y);
    +		    sc->sc_params->n_ysensors, Y,  sc->cur_y,
    +		    sc->sc_params->prot);
     
     		/*
     		 * If this is the initial update (from an untouched
    @@ -1632,11 +1694,14 @@ atp_intr(struct usb_xfer *xfer, usb_error_t error)
     		 * be used as pressure readings subsequently.
     		 */
     		status_bits = sc->sensor_data[sc->sc_params->data_len - 1];
    -		if (status_bits & ATP_STATUS_BASE_UPDATE) {
    +		if ((sc->sc_params->prot == ATP_PROT_GEYSER3 &&
    +		    (status_bits & ATP_STATUS_BASE_UPDATE)) || 
    +		    !(sc->sc_state & ATP_VALID)) {
     			memcpy(sc->base_x, sc->cur_x,
     			    sc->sc_params->n_xsensors * sizeof(*(sc->base_x)));
     			memcpy(sc->base_y, sc->cur_y,
     			    sc->sc_params->n_ysensors * sizeof(*(sc->base_y)));
    +			sc->sc_state |= ATP_VALID;
     			goto tr_setup;
     		}
     
    @@ -1757,8 +1822,11 @@ atp_intr(struct usb_xfer *xfer, usb_error_t error)
     			sc->sc_idlecount++;
     			if (sc->sc_idlecount >= ATP_IDLENESS_THRESHOLD) {
     				DPRINTFN(ATP_LLEVEL_INFO, "idle\n");
    -				atp_set_device_mode(sc->sc_dev,RAW_SENSOR_MODE);
     				sc->sc_idlecount = 0;
    +
    +				mtx_unlock(&sc->sc_mutex);
    +				atp_set_device_mode(sc->sc_dev,RAW_SENSOR_MODE);
    +				mtx_lock(&sc->sc_mutex);
     			}
     		} else {
     			sc->sc_idlecount = 0;
    @@ -1770,7 +1838,7 @@ atp_intr(struct usb_xfer *xfer, usb_error_t error)
     		if (usb_fifo_put_bytes_max(
     			    sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
     			usbd_xfer_set_frame_len(xfer, 0,
    -			    usbd_xfer_max_len(xfer));
    +			    sc->sc_params->data_len);
     			usbd_transfer_submit(xfer);
     		}
     		break;
    
    From 127de7748c7da0b3fcc487e9d65c6e649786c979 Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Tue, 10 Nov 2009 19:50:28 +0000
    Subject: [PATCH 616/646] s/a default/the default/
    
    Submitted by:	remko
    ---
     share/man/man5/rc.conf.5 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
    index a0b3f0b5372..7f90f4cac9c 100644
    --- a/share/man/man5/rc.conf.5
    +++ b/share/man/man5/rc.conf.5
    @@ -352,7 +352,7 @@ If
     is used to set the hostname via DHCP,
     this variable should be set to an empty string.
     If this value remains unset when the system is done booting
    -your console login will display a default hostname of
    +your console login will display the default hostname of
     .Dq Amnesiac.
     .It Va nisdomainname
     .Pq Vt str
    
    From 5c1da2fac0d9f5f8dc51ef542ff4c31b574c77fd Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 10 Nov 2009 20:29:20 +0000
    Subject: [PATCH 617/646] Controller does not update Tx descriptors(send BDs)
     after sending frames so remove unnecessary BUS_DMASYNC_PREREAD and
     BUS_DMASYNC_POSTREAD of bus_dmamap_sync(9).
    
    ---
     sys/dev/bge/if_bge.c | 9 +++------
     1 file changed, 3 insertions(+), 6 deletions(-)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 3ecbcbe43b7..0a1db828ded 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -1165,8 +1165,7 @@ bge_init_tx_ring(struct bge_softc *sc)
     
     	bzero(sc->bge_ldata.bge_tx_ring, BGE_TX_RING_SZ);
     	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
    -	    sc->bge_cdata.bge_tx_ring_map,
    -	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +	    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
     
     	/* Initialize transmit producer index for host-memory send ring. */
     	sc->bge_tx_prodidx = 0;
    @@ -3323,8 +3322,7 @@ bge_txeof(struct bge_softc *sc)
     	ifp = sc->bge_ifp;
     
     	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
    -	    sc->bge_cdata.bge_tx_ring_map,
    -	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    +	    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_POSTWRITE);
     	/*
     	 * Go through our tx ring and free mbufs for those
     	 * frames that have been sent.
    @@ -3834,8 +3832,7 @@ bge_start_locked(struct ifnet *ifp)
     		return;
     
     	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
    -	    sc->bge_cdata.bge_tx_ring_map,
    -	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +	    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
     	/* Transmit. */
     	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
     	/* 5700 b2 errata */
    
    From 3be4af9213ff46d46dfa78b255e51016ecf922a2 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Tue, 10 Nov 2009 22:04:19 +0000
    Subject: [PATCH 618/646] - Locking fixes to not do silly things like drop the
     lock only to call a   function that immediately reacquires the lock.  Also
     removes recursive   locking. - Use the statistics timer to drive the transmit
     watchdog instead of using   if_watchdog and if_timer.
    
    Tested by:	gavin
    ---
     sys/dev/an/if_an.c    | 142 ++++++++++++++++++++----------------------
     sys/dev/an/if_anreg.h |   1 +
     2 files changed, 67 insertions(+), 76 deletions(-)
    
    diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
    index 0cbda3d51b3..fd9f04415df 100644
    --- a/sys/dev/an/if_an.c
    +++ b/sys/dev/an/if_an.c
    @@ -140,9 +140,11 @@ static void an_reset(struct an_softc *);
     static int an_init_mpi350_desc(struct an_softc *);
     static int an_ioctl(struct ifnet *, u_long, caddr_t);
     static void an_init(void *);
    +static void an_init_locked(struct an_softc *);
     static int an_init_tx_ring(struct an_softc *);
     static void an_start(struct ifnet *);
    -static void an_watchdog(struct ifnet *);
    +static void an_start_locked(struct ifnet *);
    +static void an_watchdog(struct an_softc *);
     static void an_rxeof(struct an_softc *);
     static void an_txeof(struct an_softc *, int);
     
    @@ -314,7 +316,7 @@ an_pci_probe(device_t dev)
     	struct an_softc *sc = device_get_softc(dev);
     
     	mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
    -	    MTX_DEF | MTX_RECURSE);
    +	    MTX_DEF);
     
     	return(0);
     }
    @@ -359,7 +361,7 @@ an_probe(device_t dev)
     	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
     
     	mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
    -	    MTX_DEF | MTX_RECURSE);
    +	    MTX_DEF);
     	AN_LOCK(sc);
     	an_reset(sc);
     
    @@ -766,7 +768,6 @@ an_attach(struct an_softc *sc, int flags)
     	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     	ifp->if_ioctl = an_ioctl;
     	ifp->if_start = an_start;
    -	ifp->if_watchdog = an_watchdog;
     	ifp->if_init = an_init;
     	ifp->if_baudrate = 10000000;
     	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    @@ -1130,7 +1131,7 @@ an_txeof(struct an_softc *sc, int status)
     	AN_LOCK_ASSERT(sc);
     	ifp = sc->an_ifp;
     
    -	ifp->if_timer = 0;
    +	sc->an_timer = 0;
     	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     
     	if (!sc->mpi350) {
    @@ -1183,6 +1184,8 @@ an_stats_update(void *xsc)
     	sc = xsc;
     	AN_LOCK_ASSERT(sc);
     	ifp = sc->an_ifp;
    +	if (sc->an_timer > 0 && --sc->an_timer == 0)
    +		an_watchdog(sc);
     
     	sc->an_status.an_type = AN_RID_STATUS;
     	sc->an_status.an_len = sizeof(struct an_ltv_status);
    @@ -1274,7 +1277,7 @@ an_intr(void *xsc)
     	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
     
     	if ((ifp->if_flags & IFF_UP) && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    -		an_start(ifp);
    +		an_start_locked(ifp);
     
     	AN_UNLOCK(sc);
     
    @@ -1825,9 +1828,7 @@ an_setdef(struct an_softc *sc, struct an_req *areq)
     	case AN_RID_WEP_PERM:
     	case AN_RID_LEAPUSERNAME:
     	case AN_RID_LEAPPASSWORD:
    -		AN_UNLOCK(sc);
    -		an_init(sc);
    -		AN_LOCK(sc);
    +		an_init_locked(sc);
     
     		/* Disable the MAC. */
     		an_cmd(sc, AN_CMD_DISABLE, 0);
    @@ -1868,11 +1869,8 @@ an_setdef(struct an_softc *sc, struct an_req *areq)
     
     
     	/* Reinitialize the card. */
    -	if (ifp->if_flags) {
    -		AN_UNLOCK(sc);
    -		an_init(sc);
    -		AN_LOCK(sc);
    -	}
    +	if (ifp->if_flags)
    +		an_init_locked(sc);
     
     	return;
     }
    @@ -1890,11 +1888,8 @@ an_promisc(struct an_softc *sc, int promisc)
     		if (sc->mpi350)
     			an_init_mpi350_desc(sc);
     	}
    -	if (sc->an_monitor || sc->an_was_monitor) {
    -		AN_UNLOCK(sc);
    -		an_init(sc);
    -		AN_LOCK(sc);
    -	}
    +	if (sc->an_monitor || sc->an_was_monitor)
    +		an_init_locked(sc);
     
     	sc->an_was_monitor = sc->an_monitor;
     	an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
    @@ -1948,20 +1943,14 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			    !(ifp->if_flags & IFF_PROMISC) &&
     			    sc->an_if_flags & IFF_PROMISC) {
     				an_promisc(sc, 0);
    -			} else {
    -				AN_UNLOCK(sc);
    -				an_init(sc);
    -				AN_LOCK(sc);
    -			}
    +			} else
    +				an_init_locked(sc);
     		} else {
    -			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    -				AN_UNLOCK(sc);
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
     				an_stop(sc);
    -				AN_LOCK(sc);
    -			}
     		}
    -		AN_UNLOCK(sc);
     		sc->an_if_flags = ifp->if_flags;
    +		AN_UNLOCK(sc);
     		error = 0;
     		break;
     	case SIOCSIFMEDIA:
    @@ -2485,7 +2474,6 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     				AN_UNLOCK(sc);
     				break;
     			}
    -			AN_UNLOCK(sc);
     			if (ireq->i_val ==  4) {
     				config->an_home_product |= AN_HOME_NETWORK;
     				ireq->i_val = 0;
    @@ -2497,10 +2485,9 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     				= config->an_home_product;
     
     			/* update configuration */
    -			an_init(sc);
    +			an_init_locked(sc);
     
     			bzero(&sc->areq, sizeof(struct an_ltv_key));
    -			AN_LOCK(sc);
     			sc->areq.an_len = sizeof(struct an_ltv_key);
     			sc->areq.an_type = AN_RID_WEP_PERM;
     			key->kindex = 0xffff;
    @@ -2583,6 +2570,9 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			an_setdef(sc, &sc->areq);
     			AN_UNLOCK(sc);
     			break;
    +		default:
    +			AN_UNLOCK(sc);
    +			break;
     		}
     
     		/*
    @@ -2632,14 +2622,21 @@ static void
     an_init(void *xsc)
     {
     	struct an_softc		*sc = xsc;
    -	struct ifnet		*ifp = sc->an_ifp;
     
     	AN_LOCK(sc);
    +	an_init_locked(sc);
    +	AN_UNLOCK(sc);
    +}
     
    -	if (sc->an_gone) {
    -		AN_UNLOCK(sc);
    +static void
    +an_init_locked(struct an_softc *sc)
    +{
    +	struct ifnet *ifp;
    +
    +	AN_LOCK_ASSERT(sc);
    +	ifp = sc->an_ifp;
    +	if (sc->an_gone)
     		return;
    -	}
     
     	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
     		an_stop(sc);
    @@ -2653,7 +2650,6 @@ an_init(void *xsc)
     			an_init_mpi350_desc(sc);
     		if (an_init_tx_ring(sc)) {
     			if_printf(ifp, "tx buffer allocation failed\n");
    -			AN_UNLOCK(sc);
     			return;
     		}
     	}
    @@ -2694,7 +2690,6 @@ an_init(void *xsc)
     	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
     	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
     		if_printf(ifp, "failed to set ssid list\n");
    -		AN_UNLOCK(sc);
     		return;
     	}
     
    @@ -2703,7 +2698,6 @@ an_init(void *xsc)
     	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
     	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
     		if_printf(ifp, "failed to set AP list\n");
    -		AN_UNLOCK(sc);
     		return;
     	}
     
    @@ -2712,14 +2706,12 @@ an_init(void *xsc)
     	sc->an_config.an_type = AN_RID_GENCONFIG;
     	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
     		if_printf(ifp, "failed to set configuration\n");
    -		AN_UNLOCK(sc);
     		return;
     	}
     
     	/* Enable the MAC */
     	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
     		if_printf(ifp, "failed to enable MAC\n");
    -		AN_UNLOCK(sc);
     		return;
     	}
     
    @@ -2733,13 +2725,23 @@ an_init(void *xsc)
     	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     
     	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
    -	AN_UNLOCK(sc);
     
     	return;
     }
     
     static void
     an_start(struct ifnet *ifp)
    +{
    +	struct an_softc		*sc;
    +
    +	sc = ifp->if_softc;
    +	AN_LOCK(sc);
    +	an_start_locked(ifp);
    +	AN_UNLOCK(sc);
    +}
    +
    +static void
    +an_start_locked(struct ifnet *ifp)
     {
     	struct an_softc		*sc;
     	struct mbuf		*m0 = NULL;
    @@ -2752,6 +2754,7 @@ an_start(struct ifnet *ifp)
     
     	sc = ifp->if_softc;
     
    +	AN_LOCK_ASSERT(sc);
     	if (sc->an_gone)
     		return;
     
    @@ -2774,7 +2777,6 @@ an_start(struct ifnet *ifp)
     
     	idx = sc->an_rdata.an_tx_prod;
     
    -	AN_LOCK(sc);
     	if (!sc->mpi350) {
     		bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
     
    @@ -2832,7 +2834,7 @@ an_start(struct ifnet *ifp)
     			/*
     			 * Set a timeout in case the chip goes out to lunch.
     			 */
    -			ifp->if_timer = 5;
    +			sc->an_timer = 5;
     		}
     	} else { /* MPI-350 */
     		/* Disable interrupts. */
    @@ -2909,13 +2911,12 @@ an_start(struct ifnet *ifp)
     			/*
     			 * Set a timeout in case the chip goes out to lunch.
     			 */
    -			ifp->if_timer = 5;
    +			sc->an_timer = 5;
     		}
     
     		/* Re-enable interrupts. */
     		CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
     	}
    -	AN_UNLOCK(sc);
     
     	if (m0 != NULL)
     		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    @@ -2931,12 +2932,10 @@ an_stop(struct an_softc *sc)
     	struct ifnet		*ifp;
     	int			i;
     
    -	AN_LOCK(sc);
    +	AN_LOCK_ASSERT(sc);
     
    -	if (sc->an_gone) {
    -		AN_UNLOCK(sc);
    +	if (sc->an_gone)
     		return;
    -	}
     
     	ifp = sc->an_ifp;
     
    @@ -2955,36 +2954,27 @@ an_stop(struct an_softc *sc)
     		free(sc->an_flash_buffer, M_DEVBUF);
     		sc->an_flash_buffer = NULL;
     	}
    -
    -	AN_UNLOCK(sc);
    -
    -	return;
     }
     
     static void
    -an_watchdog(struct ifnet *ifp)
    +an_watchdog(struct an_softc *sc)
     {
    -	struct an_softc		*sc;
    +	struct ifnet *ifp;
     
    -	sc = ifp->if_softc;
    -	AN_LOCK(sc);
    +	AN_LOCK_ASSERT(sc);
     
    -	if (sc->an_gone) {
    -		AN_UNLOCK(sc);
    +	if (sc->an_gone)
     		return;
    -	}
     
    +	ifp = sc->an_ifp;
     	if_printf(ifp, "device timeout\n");
     
     	an_reset(sc);
     	if (sc->mpi350)
     		an_init_mpi350_desc(sc);
    -	AN_UNLOCK(sc);
    -	an_init(sc);
    +	an_init_locked(sc);
     
     	ifp->if_oerrors++;
    -
    -	return;
     }
     
     int
    @@ -2993,10 +2983,12 @@ an_shutdown(device_t dev)
     	struct an_softc		*sc;
     
     	sc = device_get_softc(dev);
    +	AN_LOCK(sc);
     	an_stop(sc);
     	sc->an_gone = 1;
    +	AN_UNLOCK(sc);
     
    -	return 0;
    +	return (0);
     }
     
     void
    @@ -3014,7 +3006,7 @@ an_resume(device_t dev)
     	an_reset(sc);
     	if (sc->mpi350)
     		an_init_mpi350_desc(sc);
    -	an_init(sc);
    +	an_init_locked(sc);
     
     	/* Recovery temporary keys */
     	for (i = 0; i < 4; i++) {
    @@ -3026,7 +3018,7 @@ an_resume(device_t dev)
     	}
     
     	if (ifp->if_flags & IFF_UP)
    -		an_start(ifp);
    +		an_start_locked(ifp);
     	AN_UNLOCK(sc);
     
     	return;
    @@ -3251,12 +3243,12 @@ an_media_change(struct ifnet *ifp)
     	int otype = sc->an_config.an_opmode;
     	int orate = sc->an_tx_rate;
     
    +	AN_LOCK(sc);
     	sc->an_tx_rate = ieee80211_media2rate(
     		IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media));
     	if (sc->an_tx_rate < 0)
     		sc->an_tx_rate = 0;
     
    -	AN_LOCK(sc);
     	if (orate != sc->an_tx_rate) {
     		/* Read the current configuration */
     		sc->an_config.an_type = AN_RID_GENCONFIG;
    @@ -3277,11 +3269,11 @@ an_media_change(struct ifnet *ifp)
     		sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION;
     	else
     		sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION;
    -	AN_UNLOCK(sc);
     
     	if (otype != sc->an_config.an_opmode ||
     	    orate != sc->an_tx_rate)
    -		an_init(sc);
    +		an_init_locked(sc);
    +	AN_UNLOCK(sc);
     
     	return(0);
     }
    @@ -3302,7 +3294,6 @@ an_media_status(struct ifnet *ifp, struct ifmediareq *imr)
     		imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
     		imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
     	}
    -	AN_UNLOCK(sc);
     
     	if (sc->an_tx_rate == 0) {
     		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
    @@ -3315,6 +3306,7 @@ an_media_status(struct ifnet *ifp, struct ifmediareq *imr)
     	imr->ifm_status = IFM_AVALID;
     	if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
     		imr->ifm_status |= IFM_ACTIVE;
    +	AN_UNLOCK(sc);
     }
     
     /********************** Cisco utility support routines *************/
    @@ -3559,9 +3551,9 @@ cmdreset(struct ifnet *ifp)
     	int		status;
     	struct an_softc	*sc = ifp->if_softc;
     
    +	AN_LOCK(sc);
     	an_stop(sc);
     
    -	AN_LOCK(sc);
     	an_cmd(sc, AN_CMD_DISABLE, 0);
     
     	if (!(status = WaitBusy(ifp, AN_TIMEOUT))) {
    @@ -3749,9 +3741,7 @@ flashrestart(struct ifnet *ifp)
     
     	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
     
    -	AN_UNLOCK(sc);
    -	an_init(sc);
    -	AN_LOCK(sc);
    +	an_init_locked(sc);
     
     	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
     	return status;
    diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h
    index 7b1484c4f60..051a93bbf57 100644
    --- a/sys/dev/an/if_anreg.h
    +++ b/sys/dev/an/if_anreg.h
    @@ -489,6 +489,7 @@ struct an_softc	{
     	struct ifmedia		an_ifmedia;
     	int		        an_monitor;
     	int		        an_was_monitor;
    +	int			an_timer;
     	u_char			buf_802_11[MCLBYTES];
     	struct an_req		areq;
     	unsigned short*		an_flash_buffer;
    
    From fa14cadab990b2ef03bb5e6128b614fd7c1df1bf Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Tue, 10 Nov 2009 22:07:37 +0000
    Subject: [PATCH 619/646] Add ixgb(4) to NOTES.
    
    Approved by:	jfv
    ---
     sys/conf/NOTES | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/conf/NOTES b/sys/conf/NOTES
    index 7c4208d7cfc..6eb35d03a6c 100644
    --- a/sys/conf/NOTES
    +++ b/sys/conf/NOTES
    @@ -2003,6 +2003,7 @@ device		bwi		# Broadcom BCM430* BCM431*
     device		de		# DEC/Intel DC21x4x (``Tulip'')
     device		em		# Intel Pro/1000 Gigabit Ethernet
     device		igb		# Intel Pro/1000 PCIE Gigabit Ethernet
    +device		ixgb		# Intel Pro/10Gbe PCI-X Ethernet
     device		ixgbe		# Intel Pro/10Gbe PCIE Ethernet
     device		le		# AMD Am7900 LANCE and Am79C9xx PCnet
     device		mxge		# Myricom Myri-10G 10GbE NIC
    
    From 56697614cc8766467c70fde99b309102cb04f5ff Mon Sep 17 00:00:00 2001
    From: Pawel Jakub Dawidek 
    Date: Tue, 10 Nov 2009 22:25:46 +0000
    Subject: [PATCH 620/646] Avoid passing invalid mountpoint to getnewvnode().
    
    Reported by:	rwatson
    Tested by:	rwatson
    MFC after:	3 days
    ---
     .../opensolaris/uts/common/fs/zfs/zfs_znode.c | 39 +++++++++----------
     1 file changed, 18 insertions(+), 21 deletions(-)
    
    diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
    index c43a8500818..7157930f729 100644
    --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
    +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
    @@ -143,16 +143,19 @@ zfs_znode_cache_constructor(void *buf, void *arg, int kmflags)
     
     	POINTER_INVALIDATE(&zp->z_zfsvfs);
     	ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs));
    -	ASSERT(vfsp != NULL);
     
    -	error = getnewvnode("zfs", vfsp, &zfs_vnodeops, &vp);
    -	if (error != 0 && (kmflags & KM_NOSLEEP))
    -		return (-1);
    -	ASSERT(error == 0);
    -	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    -	zp->z_vnode = vp;
    -	vp->v_data = (caddr_t)zp;
    -	VN_LOCK_AREC(vp);
    +	if (vfsp != NULL) {
    +		error = getnewvnode("zfs", vfsp, &zfs_vnodeops, &vp);
    +		if (error != 0 && (kmflags & KM_NOSLEEP))
    +			return (-1);
    +		ASSERT(error == 0);
    +		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    +		zp->z_vnode = vp;
    +		vp->v_data = (caddr_t)zp;
    +		VN_LOCK_AREC(vp);
    +	} else {
    +		zp->z_vnode = NULL;
    +	}
     
     	list_link_init(&zp->z_link_node);
     
    @@ -1435,7 +1438,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     	nvpair_t	*elem;
     	int		error;
     	znode_t		*rootzp = NULL;
    -	vnode_t		*vp;
    +	vnode_t		vnode;
     	vattr_t		vattr;
     	znode_t		*zp;
     
    @@ -1504,13 +1507,13 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     	vattr.va_gid = crgetgid(cr);
     
     	rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
    -	zfs_znode_cache_constructor(rootzp, &zfsvfs, 0);
    +	zfs_znode_cache_constructor(rootzp, NULL, 0);
     	rootzp->z_unlinked = 0;
     	rootzp->z_atime_dirty = 0;
     
    -	vp = ZTOV(rootzp);
    -	vp->v_type = VDIR;
    -	VN_LOCK_ASHARE(vp);
    +	vnode.v_type = VDIR;
    +	vnode.v_data = rootzp;
    +	rootzp->z_vnode = &vnode;
     
     	bzero(&zfsvfs, sizeof (zfsvfs_t));
     
    @@ -1539,16 +1542,10 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     	ASSERT(error == 0);
     	POINTER_INVALIDATE(&rootzp->z_zfsvfs);
     
    -	VI_LOCK(vp);
    -	ZTOV(rootzp)->v_data = NULL;
    -	ZTOV(rootzp)->v_count = 0;
    -	ZTOV(rootzp)->v_holdcnt = 0;
    -	rootzp->z_vnode = NULL;
    -	VOP_UNLOCK(vp, 0);
    -	vdestroy(vp);
     	dmu_buf_rele(rootzp->z_dbuf, NULL);
     	rootzp->z_dbuf = NULL;
     	mutex_destroy(&zfsvfs.z_znodes_lock);
    +	rootzp->z_vnode = NULL;
     	kmem_cache_free(znode_cache, rootzp);
     }
     
    
    From fd9ee28bfc52ff3fb0c97a2a4c88419a9acb34ed Mon Sep 17 00:00:00 2001
    From: Pawel Jakub Dawidek 
    Date: Tue, 10 Nov 2009 22:27:33 +0000
    Subject: [PATCH 621/646] Be careful which vattr fields are set during setattr
     replay. Without this fix strange things can appear after unclean shutdown
     like files with mode set to 07777.
    
    Reported by:	des
    MFC after:	3 days
    ---
     .../opensolaris/uts/common/fs/zfs/zfs_replay.c       | 12 ++++++++----
     1 file changed, 8 insertions(+), 4 deletions(-)
    
    diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c
    index 573a82c98e1..658e53998c9 100644
    --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c
    +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c
    @@ -60,10 +60,14 @@ zfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode,
     {
     	VATTR_NULL(vap);
     	vap->va_mask = (uint_t)mask;
    -	vap->va_type = IFTOVT(mode);
    -	vap->va_mode = mode & MODEMASK;
    -	vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid;
    -	vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid;
    +	if (mask & AT_TYPE)
    +		vap->va_type = IFTOVT(mode);
    +	if (mask & AT_MODE)
    +		vap->va_mode = mode & MODEMASK;
    +	if (mask & AT_UID)
    +		vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid;
    +	if (mask & AT_GID)
    +		vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid;
     	vap->va_rdev = zfs_cmpldev(rdev);
     	vap->va_nodeid = nodeid;
     }
    
    From b201cde68de6594252589ffdc19565c9629dd242 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Wed, 11 Nov 2009 03:17:51 +0000
    Subject: [PATCH 622/646] Reduce probe priority of USB input devices to
     BUS_PROBE_GENERIC from BUS_PROBE_SPECIFIC. This allows device-specific
     drivers like atp to attach reliably.
    
    Reviewed by:	hps
    ---
     sys/dev/usb/input/uhid.c | 2 +-
     sys/dev/usb/input/ukbd.c | 4 ++--
     sys/dev/usb/input/ums.c  | 4 ++--
     3 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
    index 411aeb6170d..63972e43665 100644
    --- a/sys/dev/usb/input/uhid.c
    +++ b/sys/dev/usb/input/uhid.c
    @@ -633,7 +633,7 @@ uhid_probe(device_t dev)
     	if (usb_test_quirk(uaa, UQ_HID_IGNORE)) {
     		return (ENXIO);
     	}
    -	return (0);
    +	return (BUS_PROBE_GENERIC);
     }
     
     static int
    diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
    index 8378cafc73d..26ed8bce19c 100644
    --- a/sys/dev/usb/input/ukbd.c
    +++ b/sys/dev/usb/input/ukbd.c
    @@ -749,7 +749,7 @@ ukbd_probe(device_t dev)
     		if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
     			return (ENXIO);
     		else
    -			return (0);
    +			return (BUS_PROBE_GENERIC);
     	}
     
     	error = usbd_req_get_hid_desc(uaa->device, NULL,
    @@ -771,7 +771,7 @@ ukbd_probe(device_t dev)
     		if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
     			error = ENXIO;
     		else
    -			error = 0;
    +			error = BUS_PROBE_GENERIC;
     	} else
     		error = ENXIO;
     
    diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
    index 52c02dc358c..e29f4ebbb28 100644
    --- a/sys/dev/usb/input/ums.c
    +++ b/sys/dev/usb/input/ums.c
    @@ -375,7 +375,7 @@ ums_probe(device_t dev)
     
     	if ((uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) &&
     	    (uaa->info.bInterfaceProtocol == UIPROTO_MOUSE))
    -		return (0);
    +		return (BUS_PROBE_GENERIC);
     
     	error = usbd_req_get_hid_desc(uaa->device, NULL,
     	    &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
    @@ -385,7 +385,7 @@ ums_probe(device_t dev)
     
     	if (hid_is_collection(d_ptr, d_len,
     	    HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
    -		error = 0;
    +		error = BUS_PROBE_GENERIC;
     	else
     		error = ENXIO;
     
    
    From 0475bba7f5d9ff73cc59c9a734e88f31eb0ec11a Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 11 Nov 2009 08:11:21 +0000
    Subject: [PATCH 623/646] Always home the cursor when changing the scrolling
     region.
    
    I thought this only had to be done when in origin mode, to ensure that
    the cursor is not placed outside the origin, but it seems this is also
    done when not in origin mode.
    
    This fixes some artifacts when pressing ^L while running irssi in tmux.
    (Almost) nobody noticed this, because cons25 doesn't have scrolling
    regions.
    ---
     sys/teken/teken_subr.h | 15 ++++++++-------
     1 file changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
    index ad10abbb6fd..4caa5007358 100644
    --- a/sys/teken/teken_subr.h
    +++ b/sys/teken/teken_subr.h
    @@ -1237,16 +1237,17 @@ teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top,
     		bottom = t->t_winsize.tp_row;
     	}
     
    +	/* Apply scrolling region. */
     	t->t_scrollreg.ts_begin = top;
     	t->t_scrollreg.ts_end = bottom;
    -	if (t->t_stateflags & TS_ORIGIN) {
    -		/* XXX: home cursor? */
    +	if (t->t_stateflags & TS_ORIGIN)
     		t->t_originreg = t->t_scrollreg;
    -		t->t_cursor.tp_row = t->t_originreg.ts_begin;
    -		t->t_cursor.tp_col = 0;
    -		t->t_stateflags &= ~TS_WRAPPED;
    -		teken_funcs_cursor(t);
    -	}
    +
    +	/* Home cursor to the top left of the scrolling region. */
    +	t->t_cursor.tp_row = t->t_originreg.ts_begin;
    +	t->t_cursor.tp_col = 0;
    +	t->t_stateflags &= ~TS_WRAPPED;
    +	teken_funcs_cursor(t);
     }
     
     static void
    
    From 3a8a07eaddc5c0e54a22f0e7bba7d6d412fd7e80 Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 11 Nov 2009 08:20:19 +0000
    Subject: [PATCH 624/646] Allow Syscons terminal emulators to provide function
     key strings.
    
    xterm and cons25 have some incompatibilities when it comes to escape
    sequences for special keys, such as F1 to F12, home, end, etc. Add a new
    te_fkeystr() that can be used to override the strings.
    
    scterm-sck won't do anything with this, but scterm-teken will use
    teken_get_sequences() to obtain the proper sequence.
    ---
     sys/dev/syscons/scterm-teken.c | 69 ++++++++++++++++++++++++++----
     sys/dev/syscons/syscons.c      | 20 ++++++---
     sys/dev/syscons/syscons.h      |  2 +
     sys/pc98/cbus/scterm-sck.c     | 25 +++++++----
     sys/teken/teken.c              | 77 ++++++++++++++++++++++++++++++----
     sys/teken/teken.h              | 40 ++++++++++++++----
     sys/teken/teken_subr.h         |  4 +-
     7 files changed, 199 insertions(+), 38 deletions(-)
    
    diff --git a/sys/dev/syscons/scterm-teken.c b/sys/dev/syscons/scterm-teken.c
    index 5fafccd45d3..12b040e201f 100644
    --- a/sys/dev/syscons/scterm-teken.c
    +++ b/sys/dev/syscons/scterm-teken.c
    @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     
     #if defined(__sparc64__) || defined(__powerpc__)
     #include 
    @@ -52,14 +53,15 @@ __FBSDID("$FreeBSD$");
     static void scteken_revattr(unsigned char, teken_attr_t *);
     static unsigned int scteken_attr(const teken_attr_t *);
     
    -static sc_term_init_t	scteken_init;
    -static sc_term_term_t	scteken_term;
    -static sc_term_puts_t	scteken_puts;
    -static sc_term_ioctl_t	scteken_ioctl;
    -static sc_term_default_attr_t scteken_default_attr;
    -static sc_term_clear_t	scteken_clear;
    -static sc_term_input_t	scteken_input;
    -static void		scteken_nop(void);
    +static sc_term_init_t		scteken_init;
    +static sc_term_term_t		scteken_term;
    +static sc_term_puts_t		scteken_puts;
    +static sc_term_ioctl_t		scteken_ioctl;
    +static sc_term_default_attr_t	scteken_default_attr;
    +static sc_term_clear_t		scteken_clear;
    +static sc_term_input_t		scteken_input;
    +static sc_term_fkeystr_t	scteken_fkeystr;
    +static void			scteken_nop(void);
     
     typedef struct {
     	teken_t		ts_teken;
    @@ -84,6 +86,7 @@ static sc_term_sw_t sc_term_scteken = {
     	scteken_clear,
     	(sc_term_notify_t *)scteken_nop,
     	scteken_input,
    +	scteken_fkeystr,
     };
     
     SCTERM_MODULE(scteken, sc_term_scteken);
    @@ -241,6 +244,56 @@ scteken_input(scr_stat *scp, int c, struct tty *tp)
     	return FALSE;
     }
     
    +static const char *
    +scteken_fkeystr(scr_stat *scp, int c)
    +{
    +	teken_stat *ts = scp->ts;
    +	unsigned int k;
    +
    +	switch (c) {
    +	case FKEY | F(1):  case FKEY | F(2):  case FKEY | F(3):
    +	case FKEY | F(4):  case FKEY | F(5):  case FKEY | F(6):
    +	case FKEY | F(7):  case FKEY | F(8):  case FKEY | F(9):
    +	case FKEY | F(10): case FKEY | F(11): case FKEY | F(12):
    +		k = TKEY_F1 + c - (FKEY | F(1));
    +		break;
    +	case FKEY | F(49):
    +		k = TKEY_HOME;
    +		break;
    +	case FKEY | F(50):
    +		k = TKEY_UP;
    +		break;
    +	case FKEY | F(51):
    +		k = TKEY_PAGE_UP;
    +		break;
    +	case FKEY | F(53):
    +		k = TKEY_LEFT;
    +		break;
    +	case FKEY | F(55):
    +		k = TKEY_RIGHT;
    +		break;
    +	case FKEY | F(57):
    +		k = TKEY_END;
    +		break;
    +	case FKEY | F(58):
    +		k = TKEY_DOWN;
    +		break;
    +	case FKEY | F(59):
    +		k = TKEY_PAGE_DOWN;
    +		break;
    +	case FKEY | F(60):
    +		k = TKEY_INSERT;
    +		break;
    +	case FKEY | F(61):
    +		k = TKEY_DELETE;
    +		break;
    +	default:
    +		return (NULL);
    +	}
    +
    +	return (teken_get_sequence(&ts->ts_teken, k));
    +}
    +
     static void
     scteken_nop(void)
     {
    diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
    index 836db55eb5c..99d4246eb61 100644
    --- a/sys/dev/syscons/syscons.c
    +++ b/sys/dev/syscons/syscons.c
    @@ -625,7 +625,7 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
         struct tty *cur_tty;
         int c, error = 0; 
         size_t len;
    -    u_char *cp;
    +    const u_char *cp;
     
         sc = (sc_softc_t *)arg;
         /* assert(thiskbd == sc->kbd) */
    @@ -664,6 +664,11 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
     	    ttydisc_rint(cur_tty, KEYCHAR(c), 0);
     	    break;
     	case FKEY:  /* function key, return string */
    +	    cp = (*sc->cur_scp->tsw->te_fkeystr)(sc->cur_scp, c);
    +	    if (cp != NULL) {
    +	    	ttydisc_rint_simple(cur_tty, cp, strlen(cp));
    +		break;
    +	    }
     	    cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
     	    if (cp != NULL)
     	    	ttydisc_rint_simple(cur_tty, cp, len);
    @@ -673,9 +678,7 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
     	    ttydisc_rint(cur_tty, KEYCHAR(c), 0);
     	    break;
     	case BKEY:  /* backtab fixed sequence (esc [ Z) */
    -	    ttydisc_rint(cur_tty, 0x1b, 0);
    -	    ttydisc_rint(cur_tty, '[', 0);
    -	    ttydisc_rint(cur_tty, 'Z', 0);
    +	    ttydisc_rint_simple(cur_tty, "\x1B[Z", 3);
     	    break;
     	}
     
    @@ -1572,7 +1575,7 @@ sc_cngetc(struct consdev *cd)
         static struct fkeytab fkey;
         static int fkeycp;
         scr_stat *scp;
    -    u_char *p;
    +    const u_char *p;
         int cur_mode;
         int s = spltty();	/* block sckbdevent and scrn_timer while we poll */
         int c;
    @@ -1621,6 +1624,13 @@ sc_cngetc(struct consdev *cd)
         case 0:	/* normal char */
     	return KEYCHAR(c);
         case FKEY:	/* function key */
    +	p = (*scp->tsw->te_fkeystr)(scp, c);
    +	if (p != NULL) {
    +	    fkey.len = strlen(p);
    +	    bcopy(p, fkey.str, fkey.len);
    +	    fkeycp = 1;
    +	    return fkey.str[0];
    +	}
     	p = kbdd_get_fkeystr(scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp);
     	fkey.len = fkeycp;
     	if ((p != NULL) && (fkey.len > 0)) {
    diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
    index abac2ac6f49..2f05755c734 100644
    --- a/sys/dev/syscons/syscons.h
    +++ b/sys/dev/syscons/syscons.h
    @@ -381,6 +381,7 @@ typedef void	sc_term_notify_t(scr_stat *scp, int event);
     #define SC_TE_NOTIFY_VTSWITCH_IN	0
     #define SC_TE_NOTIFY_VTSWITCH_OUT	1
     typedef int	sc_term_input_t(scr_stat *scp, int c, struct tty *tp);
    +typedef const char *sc_term_fkeystr_t(scr_stat *scp, int c);
     
     typedef struct sc_term_sw {
     	LIST_ENTRY(sc_term_sw)	link;
    @@ -398,6 +399,7 @@ typedef struct sc_term_sw {
     	sc_term_clear_t		*te_clear;
     	sc_term_notify_t	*te_notify;
     	sc_term_input_t		*te_input;
    +	sc_term_fkeystr_t	*te_fkeystr;
     } sc_term_sw_t;
     
     #define SCTERM_MODULE(name, sw)					\
    diff --git a/sys/pc98/cbus/scterm-sck.c b/sys/pc98/cbus/scterm-sck.c
    index ce2324ff157..b4bf70ffa4f 100644
    --- a/sys/pc98/cbus/scterm-sck.c
    +++ b/sys/pc98/cbus/scterm-sck.c
    @@ -94,15 +94,16 @@ typedef struct {
     	color_t		dflt_rev_color;		/* default reverse color */
     } term_stat;
     
    -static sc_term_init_t	scterm_init;
    -static sc_term_term_t	scterm_term;
    -static sc_term_puts_t	scterm_puts;
    -static sc_term_ioctl_t	scterm_ioctl;
    -static sc_term_reset_t	scterm_reset;
    +static sc_term_init_t		scterm_init;
    +static sc_term_term_t		scterm_term;
    +static sc_term_puts_t		scterm_puts;
    +static sc_term_ioctl_t		scterm_ioctl;
    +static sc_term_reset_t		scterm_reset;
     static sc_term_default_attr_t	scterm_default_attr;
    -static sc_term_clear_t	scterm_clear;
    -static sc_term_notify_t	scterm_notify;
    -static sc_term_input_t	scterm_input;
    +static sc_term_clear_t		scterm_clear;
    +static sc_term_notify_t		scterm_notify;
    +static sc_term_input_t		scterm_input;
    +static sc_term_fkeystr_t	scterm_fkeystr;
     
     static sc_term_sw_t sc_term_sc = {
     	{ NULL, NULL },
    @@ -120,6 +121,7 @@ static sc_term_sw_t sc_term_sc = {
     	scterm_clear,
     	scterm_notify,
     	scterm_input,
    +	scterm_fkeystr,
     };
     
     SCTERM_MODULE(sc, sc_term_sc);
    @@ -1191,6 +1193,13 @@ scterm_input(scr_stat *scp, int c, struct tty *tp)
     	return FALSE;
     }
     
    +static const char *
    +scterm_fkeystr(scr_stat *scp, int c)
    +{
    +
    +	return (NULL);
    +}
    +
     /*
      * Calculate hardware attributes word using logical attributes mask and
      * hardware colors
    diff --git a/sys/teken/teken.c b/sys/teken/teken.c
    index 81b8ac08f81..d50edc844e5 100644
    --- a/sys/teken/teken.c
    +++ b/sys/teken/teken.c
    @@ -49,14 +49,15 @@ static FILE *df;
     #endif /* __FreeBSD__ && _KERNEL */
     
     /* Private flags for t_stateflags. */
    -#define	TS_FIRSTDIGIT	0x01	/* First numeric digit in escape sequence. */
    -#define	TS_INSERT	0x02	/* Insert mode. */
    -#define	TS_AUTOWRAP	0x04	/* Autowrap. */
    -#define	TS_ORIGIN	0x08	/* Origin mode. */
    -#define	TS_WRAPPED	0x10	/* Next character should be printed on col 0. */
    -#define	TS_8BIT		0x20	/* UTF-8 disabled. */
    -#define	TS_CONS25	0x40	/* cons25 emulation. */
    -#define	TS_INSTRING	0x80	/* Inside string. */
    +#define	TS_FIRSTDIGIT	0x0001	/* First numeric digit in escape sequence. */
    +#define	TS_INSERT	0x0002	/* Insert mode. */
    +#define	TS_AUTOWRAP	0x0004	/* Autowrap. */
    +#define	TS_ORIGIN	0x0008	/* Origin mode. */
    +#define	TS_WRAPPED	0x0010	/* Next character should be printed on col 0. */
    +#define	TS_8BIT		0x0020	/* UTF-8 disabled. */
    +#define	TS_CONS25	0x0040	/* cons25 emulation. */
    +#define	TS_INSTRING	0x0080	/* Inside string. */
    +#define	TS_CURSORKEYS	0x0100	/* Cursor keys mode. */
     
     /* Character that blanks a cell. */
     #define	BLANK	' '
    @@ -479,4 +480,64 @@ teken_256to8(teken_color_t c)
     	}
     }
     
    +static const char * const special_strings_cons25[] = {
    +	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
    +	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
    +
    +	[TKEY_INSERT] = "\x1B[L",	[TKEY_DELETE] = "\x7F",
    +	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
    +	[TKEY_PAGE_UP] = "\x1B[I",	[TKEY_PAGE_DOWN] = "\x1B[G",
    +
    +	[TKEY_F1] = "\x1B[M",		[TKEY_F2] = "\x1B[N",
    +	[TKEY_F3] = "\x1B[O",		[TKEY_F4] = "\x1B[P",
    +	[TKEY_F5] = "\x1B[Q",		[TKEY_F6] = "\x1B[R",
    +	[TKEY_F7] = "\x1B[S",		[TKEY_F8] = "\x1B[T",
    +	[TKEY_F9] = "\x1B[U",		[TKEY_F10] = "\x1B[V",
    +	[TKEY_F11] = "\x1B[W",		[TKEY_F12] = "\x1B[X",
    +};
    +
    +static const char * const special_strings_ckeys[] = {
    +	[TKEY_UP] = "\x1BOA",		[TKEY_DOWN] = "\x1BOB",
    +	[TKEY_LEFT] = "\x1BOD",		[TKEY_RIGHT] = "\x1BOC",
    +
    +	[TKEY_HOME] = "\x1BOH",		[TKEY_END] = "\x1BOF",
    +};
    +
    +static const char * const special_strings_normal[] = {
    +	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
    +	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
    +
    +	[TKEY_INSERT] = "\x1B[2~",	[TKEY_DELETE] = "\x1B[3~",
    +	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
    +	[TKEY_PAGE_UP] = "\x1B[5~",	[TKEY_PAGE_DOWN] = "\x1B[6~",
    +
    +	[TKEY_F1] = "\x1BOP",		[TKEY_F2] = "\x1BOQ",
    +	[TKEY_F3] = "\x1BOR",		[TKEY_F4] = "\x1BOS",
    +	[TKEY_F5] = "\x1B[15~",		[TKEY_F6] = "\x1B[17~",
    +	[TKEY_F7] = "\x1B[18~",		[TKEY_F8] = "\x1B[19~",
    +	[TKEY_F9] = "\x1B[20~",		[TKEY_F10] = "\x1B[21~",
    +	[TKEY_F11] = "\x1B[23~",	[TKEY_F12] = "\x1B[24~",
    +};
    +
    +const char *
    +teken_get_sequence(teken_t *t, unsigned int k)
    +{
    +
    +	/* Cons25 mode. */
    +	if (t->t_stateflags & TS_CONS25 &&
    +	    k < sizeof special_strings_cons25 / sizeof(char *))
    +		return (special_strings_cons25[k]);
    +
    +	/* Cursor keys mode. */
    +	if (t->t_stateflags & TS_CURSORKEYS &&
    +	    k < sizeof special_strings_ckeys / sizeof(char *))
    +		return (special_strings_ckeys[k]);
    +
    +	/* Default xterm sequences. */
    +	if (k < sizeof special_strings_normal / sizeof(char *))
    +		return (special_strings_normal[k]);
    +	
    +	return (NULL);
    +}
    +
     #include "teken_state.h"
    diff --git a/sys/teken/teken.h b/sys/teken/teken.h
    index 22b57452c06..e129d471d4c 100644
    --- a/sys/teken/teken.h
    +++ b/sys/teken/teken.h
    @@ -89,15 +89,14 @@ typedef void tf_fill_t(void *, const teken_rect_t *, teken_char_t,
     typedef void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *);
     typedef void tf_param_t(void *, int, unsigned int);
     #define	TP_SHOWCURSOR	0
    -#define	TP_CURSORKEYS	1
    -#define	TP_KEYPADAPP	2
    -#define	TP_AUTOREPEAT	3
    -#define	TP_SWITCHVT	4
    -#define	TP_132COLS	5
    -#define	TP_SETBELLPD	6
    +#define	TP_KEYPADAPP	1
    +#define	TP_AUTOREPEAT	2
    +#define	TP_SWITCHVT	3
    +#define	TP_132COLS	4
    +#define	TP_SETBELLPD	5
     #define	TP_SETBELLPD_PITCH(pd)		((pd) >> 16)
     #define	TP_SETBELLPD_DURATION(pd)	((pd) & 0xffff)
    -#define	TP_MOUSE	7
    +#define	TP_MOUSE	6
     typedef void tf_respond_t(void *, const void *, size_t);
     
     typedef struct {
    @@ -168,6 +167,33 @@ void	teken_set_curattr(teken_t *, const teken_attr_t *);
     void	teken_set_defattr(teken_t *, const teken_attr_t *);
     void	teken_set_winsize(teken_t *, const teken_pos_t *);
     
    +/* Key input escape sequences. */
    +#define	TKEY_UP		0x00
    +#define	TKEY_DOWN	0x01
    +#define	TKEY_LEFT	0x02
    +#define	TKEY_RIGHT	0x03
    +
    +#define	TKEY_INSERT	0x04
    +#define	TKEY_DELETE	0x05
    +#define	TKEY_HOME	0x06
    +#define	TKEY_END	0x07
    +#define	TKEY_PAGE_UP	0x08
    +#define	TKEY_PAGE_DOWN	0x09
    +
    +#define	TKEY_F1		0x0a
    +#define	TKEY_F2		0x0b
    +#define	TKEY_F3		0x0c
    +#define	TKEY_F4		0x0d
    +#define	TKEY_F5		0x0e
    +#define	TKEY_F6		0x0f
    +#define	TKEY_F7		0x10
    +#define	TKEY_F8		0x11
    +#define	TKEY_F9		0x12
    +#define	TKEY_F10	0x13
    +#define	TKEY_F11	0x14
    +#define	TKEY_F12	0x15
    +const char *teken_get_sequence(teken_t *, unsigned int);
    +
     /* Legacy features. */
     void	teken_set_8bit(teken_t *);
     void	teken_set_cons25(teken_t *);
    diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
    index 4caa5007358..6bad71e3656 100644
    --- a/sys/teken/teken_subr.h
    +++ b/sys/teken/teken_subr.h
    @@ -903,7 +903,7 @@ teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
     
     	switch (cmd) {
     	case 1: /* Cursor keys mode. */
    -		teken_funcs_param(t, TP_CURSORKEYS, 0);
    +		t->t_stateflags &= ~TS_CURSORKEYS;
     		break;
     	case 2: /* DECANM: ANSI/VT52 mode. */
     		teken_printf("DECRST VT52\n");
    @@ -1052,7 +1052,7 @@ teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
     
     	switch (cmd) {
     	case 1: /* Cursor keys mode. */
    -		teken_funcs_param(t, TP_CURSORKEYS, 1);
    +		t->t_stateflags |= TS_CURSORKEYS;
     		break;
     	case 2: /* DECANM: ANSI/VT52 mode. */
     		teken_printf("DECSET VT52\n");
    
    From f0c0b1430c438783879bf09885788ff375b9da24 Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Wed, 11 Nov 2009 08:28:18 +0000
    Subject: [PATCH 625/646] CURVNET_RESTORE() was not called in certain cases.
    
    MFC after:	3 days
    ---
     sys/netinet6/nd6.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
    index 77dcf9cee04..3225b82f30d 100644
    --- a/sys/netinet6/nd6.c
    +++ b/sys/netinet6/nd6.c
    @@ -582,10 +582,10 @@ nd6_llinfo_timer(void *arg)
     		}
     		break;
     	}
    -	CURVNET_RESTORE();
     done:
     	if (ln != NULL)
     		LLE_FREE(ln);
    +	CURVNET_RESTORE();
     }
     
     
    
    From c8f1c8170247cad4b9d1da3bb626ea06d413fb73 Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 11 Nov 2009 08:39:57 +0000
    Subject: [PATCH 626/646] Add a new flag to vidcontrol, -T, that allows
     terminal mode switching.
    
    This will make it more easy for people to experiment with TERM=xterm.
    Instead of echoing these strange escape sequences, I can just instruct
    them to run `vidcontrol -T xterm'.
    ---
     usr.sbin/vidcontrol/vidcontrol.1 |  3 +++
     usr.sbin/vidcontrol/vidcontrol.c | 22 +++++++++++++++++++---
     2 files changed, 22 insertions(+), 3 deletions(-)
    
    diff --git a/usr.sbin/vidcontrol/vidcontrol.1 b/usr.sbin/vidcontrol/vidcontrol.1
    index 2abaa1e1997..cb545eeda92 100644
    --- a/usr.sbin/vidcontrol/vidcontrol.1
    +++ b/usr.sbin/vidcontrol/vidcontrol.1
    @@ -38,6 +38,7 @@
     .Op Fl r Ar foreground Ar background
     .Op Fl S Cm on | off
     .Op Fl s Ar number
    +.Op Fl T Cm xterm | cons25
     .Op Fl t Ar N | Cm off
     .Op Ar mode
     .Op Ar foreground Op Ar background
    @@ -243,6 +244,8 @@ is supposed to be physically secure.
     .It Fl s Ar number
     Set the current vty to
     .Ar number .
    +.It Fl T Cm xterm | cons25
    +Switch between xterm and cons25 style terminal emulation.
     .It Fl t Ar N | Cm off
     Set the screensaver timeout to
     .Ar N
    diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c
    index 847ff3e6e23..06afe53e019 100644
    --- a/usr.sbin/vidcontrol/vidcontrol.c
    +++ b/usr.sbin/vidcontrol/vidcontrol.c
    @@ -185,8 +185,8 @@ usage(void)
     "usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]",
     "                  [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]",
     "                  [-M char] [-m on | off] [-r foreground background]",
    -"                  [-S on | off] [-s number] [-t N | off] [mode]",
    -"                  [foreground [background]] [show]");
    +"                  [-S on | off] [-s number] [-T xterm | cons25] [-t N | off]",
    +"                  [mode] [foreground [background]] [show]");
     	exit(1);
     }
     
    @@ -1159,6 +1159,18 @@ clear_history(void)
     	}
     }
     
    +static void
    +set_terminal_mode(char *arg)
    +{
    +
    +	if (strcmp(arg, "xterm") == 0)
    +		fprintf(stderr, "\033[=T");
    +	else if (strcmp(arg, "cons25") == 0)
    +		fprintf(stderr, "\033[=1T");
    +	else
    +		usage();
    +}
    +
     
     int
     main(int argc, char **argv)
    @@ -1175,7 +1187,8 @@ main(int argc, char **argv)
     		err(1, "must be on a virtual console");
     	dumpmod = 0;
     	dumpopt = DUMP_FBF;
    -	while((opt = getopt(argc, argv, "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:t:x")) != -1)
    +	while ((opt = getopt(argc, argv,
    +	    "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:T:t:x")) != -1)
     		switch(opt) {
     		case 'b':
     			set_border_color(optarg);
    @@ -1244,6 +1257,9 @@ main(int argc, char **argv)
     		case 's':
     			set_console(optarg);
     			break;
    +		case 'T':
    +			set_terminal_mode(optarg);
    +			break;
     		case 't':
     			set_screensaver_timeout(optarg);
     			break;
    
    From d80a1e6c1b3a6e0e070cd22344d2defbee84daeb Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 11 Nov 2009 09:43:26 +0000
    Subject: [PATCH 627/646] Place home and end before insert and delete.
    
    These keys have different sequences when using cursorkeys, while insert
    and delete stay the same. If they are placed like this, libteken will
    return NULL instead of a proper sequence for these characters.
    ---
     sys/teken/teken.c | 4 ++--
     sys/teken/teken.h | 8 ++++----
     2 files changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/sys/teken/teken.c b/sys/teken/teken.c
    index d50edc844e5..1435d2fa9b1 100644
    --- a/sys/teken/teken.c
    +++ b/sys/teken/teken.c
    @@ -484,8 +484,8 @@ static const char * const special_strings_cons25[] = {
     	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
     	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
     
    -	[TKEY_INSERT] = "\x1B[L",	[TKEY_DELETE] = "\x7F",
     	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
    +	[TKEY_INSERT] = "\x1B[L",	[TKEY_DELETE] = "\x7F",
     	[TKEY_PAGE_UP] = "\x1B[I",	[TKEY_PAGE_DOWN] = "\x1B[G",
     
     	[TKEY_F1] = "\x1B[M",		[TKEY_F2] = "\x1B[N",
    @@ -507,8 +507,8 @@ static const char * const special_strings_normal[] = {
     	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
     	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
     
    -	[TKEY_INSERT] = "\x1B[2~",	[TKEY_DELETE] = "\x1B[3~",
     	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
    +	[TKEY_INSERT] = "\x1B[2~",	[TKEY_DELETE] = "\x1B[3~",
     	[TKEY_PAGE_UP] = "\x1B[5~",	[TKEY_PAGE_DOWN] = "\x1B[6~",
     
     	[TKEY_F1] = "\x1BOP",		[TKEY_F2] = "\x1BOQ",
    diff --git a/sys/teken/teken.h b/sys/teken/teken.h
    index e129d471d4c..36cb71aa1d0 100644
    --- a/sys/teken/teken.h
    +++ b/sys/teken/teken.h
    @@ -173,10 +173,10 @@ void	teken_set_winsize(teken_t *, const teken_pos_t *);
     #define	TKEY_LEFT	0x02
     #define	TKEY_RIGHT	0x03
     
    -#define	TKEY_INSERT	0x04
    -#define	TKEY_DELETE	0x05
    -#define	TKEY_HOME	0x06
    -#define	TKEY_END	0x07
    +#define	TKEY_HOME	0x04
    +#define	TKEY_END	0x05
    +#define	TKEY_INSERT	0x06
    +#define	TKEY_DELETE	0x07
     #define	TKEY_PAGE_UP	0x08
     #define	TKEY_PAGE_DOWN	0x09
     
    
    From 8e57bf8357f64ab4b0e9899943cc5677e4c6460c Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Wed, 11 Nov 2009 10:44:09 +0000
    Subject: [PATCH 628/646] MFp4: Add set of chip IDs, known to support AHCI.
    
    ---
     sys/dev/ahci/ahci.c | 153 ++++++++++++++++++++++++++++++++++++++++----
     1 file changed, 142 insertions(+), 11 deletions(-)
    
    diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
    index 3e58cb5d49d..92a65199c65 100644
    --- a/sys/dev/ahci/ahci.c
    +++ b/sys/dev/ahci/ahci.c
    @@ -96,23 +96,154 @@ static void ahcipoll(struct cam_sim *sim);
     
     MALLOC_DEFINE(M_AHCI, "AHCI driver", "AHCI driver data buffers");
     
    -/*
    - * AHCI v1.x compliant SATA chipset support functions
    - */
    +static struct {
    +	uint32_t	id;
    +	const char	*name;
    +	int		flags;
    +} ahci_ids[] = {
    +	{0x43801002, "ATI IXP600",	0},
    +	{0x43901002, "ATI IXP700",	0},
    +	{0x43911002, "ATI IXP700",	0},
    +	{0x43921002, "ATI IXP700",	0},
    +	{0x43931002, "ATI IXP700",	0},
    +	{0x43941002, "ATI IXP800",	0},
    +	{0x43951002, "ATI IXP800",	0},
    +	{0x26528086, "Intel ICH6",	0},
    +	{0x26538086, "Intel ICH6M",	0},
    +	{0x26818086, "Intel ESB2",	0},
    +	{0x26828086, "Intel ESB2",	0},
    +	{0x26838086, "Intel ESB2",	0},
    +	{0x27c18086, "Intel ICH7",	0},
    +	{0x27c38086, "Intel ICH7",	0},
    +	{0x27c58086, "Intel ICH7M",	0},
    +	{0x27c68086, "Intel ICH7M",	0},
    +	{0x28218086, "Intel ICH8",	0},
    +	{0x28228086, "Intel ICH8",	0},
    +	{0x28248086, "Intel ICH8",	0},
    +	{0x28298086, "Intel ICH8M",	0},
    +	{0x282a8086, "Intel ICH8M",	0},
    +	{0x29228086, "Intel ICH9",	0},
    +	{0x29238086, "Intel ICH9",	0},
    +	{0x29248086, "Intel ICH9",	0},
    +	{0x29258086, "Intel ICH9",	0},
    +	{0x29278086, "Intel ICH9",	0},
    +	{0x29298086, "Intel ICH9M",	0},
    +	{0x292a8086, "Intel ICH9M",	0},
    +	{0x292b8086, "Intel ICH9M",	0},
    +	{0x292c8086, "Intel ICH9M",	0},
    +	{0x292f8086, "Intel ICH9M",	0},
    +	{0x294d8086, "Intel ICH9",	0},
    +	{0x294e8086, "Intel ICH9M",	0},
    +	{0x3a058086, "Intel ICH10",	0},
    +	{0x3a228086, "Intel ICH10",	0},
    +	{0x3a258086, "Intel ICH10",	0},
    +	{0x3b228086, "Intel PCH",	0},
    +	{0x3b238086, "Intel PCH",	0},
    +	{0x3b248086, "Intel PCH",	0},
    +	{0x3b258086, "Intel PCH",	0},
    +	{0x3b298086, "Intel PCH",	0},
    +	{0x3b2b8086, "Intel PCH",	0},
    +	{0x3b2c8086, "Intel PCH",	0},
    +	{0x3b2f8086, "Intel PCH",	0},
    +	{0x044c10de, "NVIDIA MCP65",	0},
    +	{0x044d10de, "NVIDIA MCP65",	0},
    +	{0x044e10de, "NVIDIA MCP65",	0},
    +	{0x044f10de, "NVIDIA MCP65",	0},
    +	{0x045c10de, "NVIDIA MCP65",	0},
    +	{0x045d10de, "NVIDIA MCP65",	0},
    +	{0x045e10de, "NVIDIA MCP65",	0},
    +	{0x045f10de, "NVIDIA MCP65",	0},
    +	{0x055010de, "NVIDIA MCP67",	0},
    +	{0x055110de, "NVIDIA MCP67",	0},
    +	{0x055210de, "NVIDIA MCP67",	0},
    +	{0x055310de, "NVIDIA MCP67",	0},
    +	{0x055410de, "NVIDIA MCP67",	0},
    +	{0x055510de, "NVIDIA MCP67",	0},
    +	{0x055610de, "NVIDIA MCP67",	0},
    +	{0x055710de, "NVIDIA MCP67",	0},
    +	{0x055810de, "NVIDIA MCP67",	0},
    +	{0x055910de, "NVIDIA MCP67",	0},
    +	{0x055A10de, "NVIDIA MCP67",	0},
    +	{0x055B10de, "NVIDIA MCP67",	0},
    +	{0x058410de, "NVIDIA MCP67",	0},
    +	{0x07f010de, "NVIDIA MCP73",	0},
    +	{0x07f110de, "NVIDIA MCP73",	0},
    +	{0x07f210de, "NVIDIA MCP73",	0},
    +	{0x07f310de, "NVIDIA MCP73",	0},
    +	{0x07f410de, "NVIDIA MCP73",	0},
    +	{0x07f510de, "NVIDIA MCP73",	0},
    +	{0x07f610de, "NVIDIA MCP73",	0},
    +	{0x07f710de, "NVIDIA MCP73",	0},
    +	{0x07f810de, "NVIDIA MCP73",	0},
    +	{0x07f910de, "NVIDIA MCP73",	0},
    +	{0x07fa10de, "NVIDIA MCP73",	0},
    +	{0x07fb10de, "NVIDIA MCP73",	0},
    +	{0x0ad010de, "NVIDIA MCP77",	0},
    +	{0x0ad110de, "NVIDIA MCP77",	0},
    +	{0x0ad210de, "NVIDIA MCP77",	0},
    +	{0x0ad310de, "NVIDIA MCP77",	0},
    +	{0x0ad410de, "NVIDIA MCP77",	0},
    +	{0x0ad510de, "NVIDIA MCP77",	0},
    +	{0x0ad610de, "NVIDIA MCP77",	0},
    +	{0x0ad710de, "NVIDIA MCP77",	0},
    +	{0x0ad810de, "NVIDIA MCP77",	0},
    +	{0x0ad910de, "NVIDIA MCP77",	0},
    +	{0x0ada10de, "NVIDIA MCP77",	0},
    +	{0x0adb10de, "NVIDIA MCP77",	0},
    +	{0x0ab410de, "NVIDIA MCP79",	0},
    +	{0x0ab510de, "NVIDIA MCP79",	0},
    +	{0x0ab610de, "NVIDIA MCP79",	0},
    +	{0x0ab710de, "NVIDIA MCP79",	0},
    +	{0x0ab810de, "NVIDIA MCP79",	0},
    +	{0x0ab910de, "NVIDIA MCP79",	0},
    +	{0x0aba10de, "NVIDIA MCP79",	0},
    +	{0x0abb10de, "NVIDIA MCP79",	0},
    +	{0x0abc10de, "NVIDIA MCP79",	0},
    +	{0x0abd10de, "NVIDIA MCP79",	0},
    +	{0x0abe10de, "NVIDIA MCP79",	0},
    +	{0x0abf10de, "NVIDIA MCP79",	0},
    +	{0x0d8410de, "NVIDIA MCP89",	0},
    +	{0x0d8510de, "NVIDIA MCP89",	0},
    +	{0x0d8610de, "NVIDIA MCP89",	0},
    +	{0x0d8710de, "NVIDIA MCP89",	0},
    +	{0x0d8810de, "NVIDIA MCP89",	0},
    +	{0x0d8910de, "NVIDIA MCP89",	0},
    +	{0x0d8a10de, "NVIDIA MCP89",	0},
    +	{0x0d8b10de, "NVIDIA MCP89",	0},
    +	{0x0d8c10de, "NVIDIA MCP89",	0},
    +	{0x0d8d10de, "NVIDIA MCP89",	0},
    +	{0x0d8e10de, "NVIDIA MCP89",	0},
    +	{0x0d8f10de, "NVIDIA MCP89",	0},
    +	{0x33491106, "VIA VT8251",	0},
    +	{0x62871106, "VIA VT8251",	0},
    +	{0x11841039, "SiS 966",		0},
    +	{0x11851039, "SiS 968",		0},
    +	{0x01861039, "SiS 968",		0},
    +	{0,	     NULL,		0}
    +};
    +
     static int
     ahci_probe(device_t dev)
     {
    +	char buf[64];
    +	int i;
    +	uint32_t devid = pci_get_devid(dev);
     
    -	/* is this a possible AHCI candidate ? */
    +	/* Is this a known AHCI chip? */
    +	for (i = 0; ahci_ids[i].id != 0; i++) {
    +		if (ahci_ids[i].id == devid) {
    +			snprintf(buf, sizeof(buf), "%s AHCI SATA controller",
    +			    ahci_ids[i].name);
    +			device_set_desc_copy(dev, buf);
    +			return (BUS_PROBE_VENDOR);
    +		}
    +	}
    +	/* Is this a possible AHCI candidate? */
     	if (pci_get_class(dev) != PCIC_STORAGE ||
    -	    pci_get_subclass(dev) != PCIS_STORAGE_SATA)
    +	    pci_get_subclass(dev) != PCIS_STORAGE_SATA ||
    +	    pci_get_progif(dev) != PCIP_STORAGE_SATA_AHCI_1_0)
     		return (ENXIO);
    -
    -	/* is this PCI device flagged as an AHCI compliant chip ? */
    -	if (pci_get_progif(dev) != PCIP_STORAGE_SATA_AHCI_1_0)
    -		return (ENXIO);
    -
    -	device_set_desc_copy(dev, "AHCI controller");
    +	device_set_desc_copy(dev, "AHCI SATA controller");
     	return (BUS_PROBE_VENDOR);
     }
     
    
    From b4263060748915db48ac68cf21810786d70fcf38 Mon Sep 17 00:00:00 2001
    From: Ruslan Ermilov 
    Date: Wed, 11 Nov 2009 11:07:30 +0000
    Subject: [PATCH 629/646] Added option NETGRAPH_VLAN.
    
    Submitted by:	pluknet
    ---
     sys/conf/NOTES   | 1 +
     sys/conf/files   | 1 +
     sys/conf/options | 1 +
     3 files changed, 3 insertions(+)
    
    diff --git a/sys/conf/NOTES b/sys/conf/NOTES
    index 6eb35d03a6c..a5b5f5d88b1 100644
    --- a/sys/conf/NOTES
    +++ b/sys/conf/NOTES
    @@ -706,6 +706,7 @@ options 	NETGRAPH_TCPMSS
     options 	NETGRAPH_TEE
     options 	NETGRAPH_UI
     options 	NETGRAPH_VJC
    +options 	NETGRAPH_VLAN
     
     # NgATM - Netgraph ATM
     options 	NGATM_ATM
    diff --git a/sys/conf/files b/sys/conf/files
    index a536b6d6731..b7d99508de6 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -2399,6 +2399,7 @@ netgraph/ng_tcpmss.c		optional netgraph_tcpmss
     netgraph/ng_tee.c		optional netgraph_tee
     netgraph/ng_tty.c		optional netgraph_tty
     netgraph/ng_vjc.c		optional netgraph_vjc
    +netgraph/ng_vlan.c		optional netgraph_vlan
     netinet/accf_data.c		optional accept_filter_data inet
     netinet/accf_dns.c		optional accept_filter_dns inet
     netinet/accf_http.c		optional accept_filter_http inet
    diff --git a/sys/conf/options b/sys/conf/options
    index 5c146c8765f..dc35aa09eda 100644
    --- a/sys/conf/options
    +++ b/sys/conf/options
    @@ -497,6 +497,7 @@ NETGRAPH_TEE		opt_netgraph.h
     NETGRAPH_TTY		opt_netgraph.h
     NETGRAPH_UI		opt_netgraph.h
     NETGRAPH_VJC		opt_netgraph.h
    +NETGRAPH_VLAN		opt_netgraph.h
     
     # NgATM options
     NGATM_ATM		opt_netgraph.h
    
    From 30a4094f86e4b05c28c4d89342f047142f349ab4 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Wed, 11 Nov 2009 11:10:36 +0000
    Subject: [PATCH 630/646] MFp4: - Move tagged queueing control from ADA to ATA
     XPT. It allows to control   device command queue length correctly. First step
     to support < 32 tags. - Limit queue for non-tagged devices by 2 slots for
     ahci(4) and siis(4). - Implement quirk matching for ATA devices. - Move
     xpt_schedule_dev_sendq() from header to source file. - Move delayed queue
     shrinking to the more expected place - element freeing. - Remove some SCSIsms
     in ATA.
    
    ---
     sys/cam/ata/ata_all.c      |  35 ++++++++++
     sys/cam/ata/ata_all.h      |   3 +
     sys/cam/ata/ata_da.c       |  31 ++++-----
     sys/cam/ata/ata_xpt.c      | 128 +++++++++++--------------------------
     sys/cam/cam.c              |   6 +-
     sys/cam/cam_ccb.h          |   2 +-
     sys/cam/cam_xpt.c          |  60 ++++++++++++++---
     sys/cam/cam_xpt_internal.h |  25 +-------
     sys/cam/scsi/scsi_xpt.c    |  19 +-----
     sys/dev/ahci/ahci.c        |   3 +-
     sys/dev/siis/siis.c        |   2 +-
     11 files changed, 154 insertions(+), 160 deletions(-)
    
    diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
    index 266dc32ceab..5863ea84180 100644
    --- a/sys/cam/ata/ata_all.c
    +++ b/sys/cam/ata/ata_all.c
    @@ -509,3 +509,38 @@ ata_max_mode(struct ata_params *ap, int mode, int maxmode)
         return (mode);
     }
     
    +int
    +ata_identify_match(caddr_t identbuffer, caddr_t table_entry)
    +{
    +	struct scsi_inquiry_pattern *entry;
    +	struct ata_params *ident;
    + 
    +	entry = (struct scsi_inquiry_pattern *)table_entry;
    +	ident = (struct ata_params *)identbuffer;
    +
    +	if ((cam_strmatch(ident->model, entry->product,
    +			  sizeof(ident->model)) == 0)
    +	 && (cam_strmatch(ident->revision, entry->revision,
    +			  sizeof(ident->revision)) == 0)) {
    +		return (0);
    +	}
    +        return (-1);
    +}
    +
    +int
    +ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry)
    +{
    +	struct scsi_static_inquiry_pattern *entry;
    +	struct ata_params *ident;
    + 
    +	entry = (struct scsi_static_inquiry_pattern *)table_entry;
    +	ident = (struct ata_params *)identbuffer;
    +
    +	if ((cam_strmatch(ident->model, entry->product,
    +			  sizeof(ident->model)) == 0)
    +	 && (cam_strmatch(ident->revision, entry->revision,
    +			  sizeof(ident->revision)) == 0)) {
    +		return (0);
    +	}
    +        return (-1);
    +}
    diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h
    index b711df7a8f0..13de02de8b5 100644
    --- a/sys/cam/ata/ata_all.h
    +++ b/sys/cam/ata/ata_all.h
    @@ -114,4 +114,7 @@ int	ata_max_wmode(struct ata_params *ap);
     int	ata_max_umode(struct ata_params *ap);
     int	ata_max_mode(struct ata_params *ap, int mode, int maxmode);
     
    +int	ata_identify_match(caddr_t identbuffer, caddr_t table_entry);
    +int	ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
    +
     #endif
    diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
    index 12719edc4dc..4a9a9c3d715 100644
    --- a/sys/cam/ata/ata_da.c
    +++ b/sys/cam/ata/ata_da.c
    @@ -122,9 +122,17 @@ struct ada_quirk_entry {
     	ada_quirks quirks;
     };
     
    -//static struct ada_quirk_entry ada_quirk_table[] =
    -//{
    -//};
    +static struct ada_quirk_entry ada_quirk_table[] =
    +{
    +	{
    +		/* Default */
    +		{
    +		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
    +		  /*vendor*/"*", /*product*/"*", /*revision*/"*"
    +		},
    +		/*quirks*/0
    +	},
    +};
     
     static	disk_strategy_t	adastrategy;
     static	dumper_t	adadump;
    @@ -618,7 +626,7 @@ adaregister(struct cam_periph *periph, void *arg)
     	if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
     		softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
     	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
    -	    cgd->ident_data.queue >= 31)
    +	    cgd->inq_flags & SID_CmdQue)
     		softc->flags |= ADA_FLAG_CAN_NCQ;
     	softc->state = ADA_STATE_NORMAL;
     
    @@ -627,12 +635,10 @@ adaregister(struct cam_periph *periph, void *arg)
     	/*
     	 * See if this device has any quirks.
     	 */
    -//	match = cam_quirkmatch((caddr_t)&cgd->inq_data,
    -//			       (caddr_t)ada_quirk_table,
    -//			       sizeof(ada_quirk_table)/sizeof(*ada_quirk_table),
    -//			       sizeof(*ada_quirk_table), scsi_inquiry_match);
    -	match = NULL;
    -
    +	match = cam_quirkmatch((caddr_t)&cgd->ident_data,
    +			       (caddr_t)ada_quirk_table,
    +			       sizeof(ada_quirk_table)/sizeof(*ada_quirk_table),
    +			       sizeof(*ada_quirk_table), ata_identify_match);
     	if (match != NULL)
     		softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
     	else
    @@ -700,11 +706,6 @@ adaregister(struct cam_periph *periph, void *arg)
     		dp->secsize, dp->heads,
     		dp->secs_per_track, dp->cylinders);
     	xpt_announce_periph(periph, announce_buf);
    -	if (softc->flags & ADA_FLAG_CAN_NCQ) {
    -		printf("%s%d: Native Command Queueing enabled\n",
    -		       periph->periph_name, periph->unit_number);
    -	}
    -
     	/*
     	 * Add async callbacks for bus reset and
     	 * bus device reset calls.  I don't bother
    diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
    index 56371ee52bd..6485d265921 100644
    --- a/sys/cam/ata/ata_xpt.c
    +++ b/sys/cam/ata/ata_xpt.c
    @@ -66,17 +66,12 @@ __FBSDID("$FreeBSD$");
     #include 	/* for xpt_print below */
     #include "opt_cam.h"
     
    -struct scsi_quirk_entry {
    +struct ata_quirk_entry {
     	struct scsi_inquiry_pattern inq_pat;
     	u_int8_t quirks;
    -#define	CAM_QUIRK_NOLUNS	0x01
    -#define	CAM_QUIRK_NOSERIAL	0x02
    -#define	CAM_QUIRK_HILUNS	0x04
    -#define	CAM_QUIRK_NOHILUNS	0x08
    -	u_int mintags;
    +#define	CAM_QUIRK_MAXTAGS	0x01
     	u_int maxtags;
     };
    -#define SCSI_QUIRK(dev)	((struct scsi_quirk_entry *)((dev)->quirk))
     
     static periph_init_t probe_periph_init;
     
    @@ -138,7 +133,7 @@ typedef struct {
     	struct cam_periph *periph;
     } probe_softc;
     
    -static struct scsi_quirk_entry scsi_quirk_table[] =
    +static struct ata_quirk_entry ata_quirk_table[] =
     {
     	{
     		/* Default tagged queuing parameters for all devices */
    @@ -146,12 +141,12 @@ static struct scsi_quirk_entry scsi_quirk_table[] =
     		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
     		  /*vendor*/"*", /*product*/"*", /*revision*/"*"
     		},
    -		/*quirks*/0, /*mintags*/2, /*maxtags*/32
    +		/*quirks*/0, /*maxtags*/0
     	},
     };
     
    -static const int scsi_quirk_table_size =
    -	sizeof(scsi_quirk_table) / sizeof(*scsi_quirk_table);
    +static const int ata_quirk_table_size =
    +	sizeof(ata_quirk_table) / sizeof(*ata_quirk_table);
     
     static cam_status	proberegister(struct cam_periph *periph,
     				      void *arg);
    @@ -162,7 +157,7 @@ static void	 probestart(struct cam_periph *periph, union ccb *start_ccb);
     //				     struct cam_ed *device);
     static void	 probedone(struct cam_periph *periph, union ccb *done_ccb);
     static void	 probecleanup(struct cam_periph *periph);
    -static void	 scsi_find_quirk(struct cam_ed *device);
    +static void	 ata_find_quirk(struct cam_ed *device);
     static void	 ata_scan_bus(struct cam_periph *periph, union ccb *ccb);
     static void	 ata_scan_lun(struct cam_periph *periph,
     			       struct cam_path *path, cam_flags flags,
    @@ -172,10 +167,9 @@ static struct cam_ed *
     		 ata_alloc_device(struct cam_eb *bus, struct cam_et *target,
     				   lun_id_t lun_id);
     static void	 ata_device_transport(struct cam_path *path);
    -static void	 scsi_set_transfer_settings(struct ccb_trans_settings *cts,
    +static void	 ata_set_transfer_settings(struct ccb_trans_settings *cts,
     					    struct cam_ed *device,
     					    int async_update);
    -static void	 scsi_toggle_tags(struct cam_path *path);
     static void	 ata_dev_async(u_int32_t async_code,
     				struct cam_eb *bus,
     				struct cam_et *target,
    @@ -717,6 +711,17 @@ noerror:
     
     			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
     		}
    +		if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) {
    +			path->device->mintags = path->device->maxtags =
    +			    ATA_QUEUE_LEN(ident_buf->queue) + 1;
    +		}
    +		ata_find_quirk(path->device);
    +		/* XXX: If not all tags allowed, we must to tell SIM which are. */
    +		if (path->device->mintags < path->bus->sim->max_tagged_dev_openings)
    +			path->device->mintags = path->device->maxtags = 0;
    +		if (path->device->mintags != 0) {
    +			xpt_start_tags(path);
    +		}
     		ata_device_transport(path);
     		PROBE_SET_ACTION(softc, PROBE_SETMODE);
     		xpt_release_ccb(done_ccb);
    @@ -776,7 +781,6 @@ noerror:
     			return;
     		}
     
    -		scsi_find_quirk(path->device);
     		ata_device_transport(path);
     		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
     			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
    @@ -853,24 +857,23 @@ probecleanup(struct cam_periph *periph)
     }
     
     static void
    -scsi_find_quirk(struct cam_ed *device)
    +ata_find_quirk(struct cam_ed *device)
     {
    -	struct scsi_quirk_entry *quirk;
    +	struct ata_quirk_entry *quirk;
     	caddr_t	match;
     
    -	match = cam_quirkmatch((caddr_t)&device->inq_data,
    -			       (caddr_t)scsi_quirk_table,
    -			       sizeof(scsi_quirk_table) /
    -			       sizeof(*scsi_quirk_table),
    -			       sizeof(*scsi_quirk_table), scsi_inquiry_match);
    +	match = cam_quirkmatch((caddr_t)&device->ident_data,
    +			       (caddr_t)ata_quirk_table,
    +			       ata_quirk_table_size,
    +			       sizeof(*ata_quirk_table), ata_identify_match);
     
     	if (match == NULL)
     		panic("xpt_find_quirk: device didn't match wildcard entry!!");
     
    -	quirk = (struct scsi_quirk_entry *)match;
    +	quirk = (struct ata_quirk_entry *)match;
     	device->quirk = quirk;
    -	device->mintags = quirk->mintags;
    -	device->maxtags = quirk->maxtags;
    +	if (quirk->quirks & CAM_QUIRK_MAXTAGS)
    +		device->mintags = device->maxtags = quirk->maxtags;
     }
     
     typedef struct {
    @@ -1101,7 +1104,7 @@ static struct cam_ed *
     ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
     {
     	struct cam_path path;
    -	struct scsi_quirk_entry *quirk;
    +	struct ata_quirk_entry *quirk;
     	struct cam_ed *device;
     	struct cam_ed *cur_device;
     
    @@ -1113,10 +1116,10 @@ ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
     	 * Take the default quirk entry until we have inquiry
     	 * data and can determine a better quirk to use.
     	 */
    -	quirk = &scsi_quirk_table[scsi_quirk_table_size - 1];
    +	quirk = &ata_quirk_table[ata_quirk_table_size - 1];
     	device->quirk = (void *)quirk;
    -	device->mintags = quirk->mintags;
    -	device->maxtags = quirk->maxtags;
    +	device->mintags = 0;
    +	device->maxtags = 0;
     	bzero(&device->inq_data, sizeof(device->inq_data));
     	device->inq_flags = 0;
     	device->queue_flags = 0;
    @@ -1199,7 +1202,7 @@ ata_action(union ccb *start_ccb)
     	switch (start_ccb->ccb_h.func_code) {
     	case XPT_SET_TRAN_SETTINGS:
     	{
    -		scsi_set_transfer_settings(&start_ccb->cts,
    +		ata_set_transfer_settings(&start_ccb->cts,
     					   start_ccb->ccb_h.path->device,
     					   /*async_update*/FALSE);
     		break;
    @@ -1227,7 +1230,7 @@ ata_action(union ccb *start_ccb)
     }
     
     static void
    -scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
    +ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
     			   int async_update)
     {
     	struct	ccb_pathinq cpi;
    @@ -1379,24 +1382,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
     				device->tag_delay_count = CAM_TAG_DELAY_COUNT;
     				device->flags |= CAM_DEV_TAG_AFTER_COUNT;
     			} else {
    -				struct ccb_relsim crs;
    -
    -				xpt_freeze_devq(cts->ccb_h.path, /*count*/1);
    -		  		device->inq_flags &= ~SID_CmdQue;
    -				xpt_dev_ccbq_resize(cts->ccb_h.path,
    -						    sim->max_dev_openings);
    -				device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
    -				device->tag_delay_count = 0;
    -
    -				xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
    -				    CAM_PRIORITY_NORMAL);
    -				crs.ccb_h.func_code = XPT_REL_SIMQ;
    -				crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
    -				crs.openings
    -				    = crs.release_timeout
    -				    = crs.qfrozen_cnt
    -				    = 0;
    -				xpt_action((union ccb *)&crs);
    +				xpt_stop_tags(cts->ccb_h.path);
     			}
     		}
     	}
    @@ -1404,39 +1390,6 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
     		(*(sim->sim_action))(sim, (union ccb *)cts);
     }
     
    -static void
    -scsi_toggle_tags(struct cam_path *path)
    -{
    -	struct cam_ed *dev;
    -
    -	/*
    -	 * Give controllers a chance to renegotiate
    -	 * before starting tag operations.  We
    -	 * "toggle" tagged queuing off then on
    -	 * which causes the tag enable command delay
    -	 * counter to come into effect.
    -	 */
    -	dev = path->device;
    -	if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
    -	 || ((dev->inq_flags & SID_CmdQue) != 0
    - 	  && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
    -		struct ccb_trans_settings cts;
    -
    -		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
    -		cts.protocol = PROTO_SCSI;
    -		cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
    -		cts.transport = XPORT_UNSPECIFIED;
    -		cts.transport_version = XPORT_VERSION_UNSPECIFIED;
    -		cts.proto_specific.scsi.flags = 0;
    -		cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ;
    -		scsi_set_transfer_settings(&cts, path->device,
    -					  /*async_update*/TRUE);
    -		cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB;
    -		scsi_set_transfer_settings(&cts, path->device,
    -					  /*async_update*/TRUE);
    -	}
    -}
    -
     /*
      * Handle any per-device event notifications that require action by the XPT.
      */
    @@ -1469,15 +1422,6 @@ ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
     		status = CAM_REQ_CMP_ERR;
     
     	if (status == CAM_REQ_CMP) {
    -
    -		/*
    -		 * Allow transfer negotiation to occur in a
    -		 * tag free environment.
    -		 */
    -		if (async_code == AC_SENT_BDR
    -		 || async_code == AC_BUS_RESET)
    -			scsi_toggle_tags(&newpath);
    -
     		if (async_code == AC_INQ_CHANGED) {
     			/*
     			 * We've sent a start unit command, or
    @@ -1498,7 +1442,7 @@ ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
     		struct ccb_trans_settings *settings;
     
     		settings = (struct ccb_trans_settings *)async_arg;
    -		scsi_set_transfer_settings(settings, device,
    +		ata_set_transfer_settings(settings, device,
     					  /*async_update*/TRUE);
     	}
     }
    diff --git a/sys/cam/cam.c b/sys/cam/cam.c
    index eff83a1ad13..85b02fb9cfa 100644
    --- a/sys/cam/cam.c
    +++ b/sys/cam/cam.c
    @@ -165,8 +165,12 @@ cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len)
     		str++;
     		str_len--;
     	}
    -	while (str_len > 0 && *str++ == ' ')
    +	while (str_len > 0 && *str == ' ') {
    +		str++;
     		str_len--;
    +	}
    +	if (str_len > 0 && *str == 0)
    +		str_len = 0;
     
     	return (str_len);
     }
    diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
    index 483f22b5de1..815da9d8815 100644
    --- a/sys/cam/cam_ccb.h
    +++ b/sys/cam/cam_ccb.h
    @@ -307,7 +307,7 @@ struct ccb_getdev {
     	struct scsi_inquiry_data inq_data;
     	struct ata_params ident_data;
     	u_int8_t  serial_num[252];
    -	u_int8_t  reserved;
    +	u_int8_t  inq_flags;
     	u_int8_t  serial_num_len;
     };
     
    diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
    index e09308457a9..e9133f6a5eb 100644
    --- a/sys/cam/cam_xpt.c
    +++ b/sys/cam/cam_xpt.c
    @@ -285,7 +285,6 @@ static xpt_devicefunc_t	xptsetasyncfunc;
     static xpt_busfunc_t	xptsetasyncbusfunc;
     static cam_status	xptregister(struct cam_periph *periph,
     				    void *arg);
    -static void	 xpt_start_tags(struct cam_path *path);
     static __inline int xpt_schedule_dev_allocq(struct cam_eb *bus,
     					    struct cam_ed *dev);
     static __inline int periph_is_queued(struct cam_periph *periph);
    @@ -299,12 +298,6 @@ xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
     	int retval;
     
     	if (dev->ccbq.devq_openings > 0) {
    -		if ((dev->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) != 0) {
    -			cam_ccbq_resize(&dev->ccbq,
    -					dev->ccbq.dev_openings
    -					+ dev->ccbq.dev_active);
    -			dev->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
    -		}
     		/*
     		 * The priority of a device waiting for CCB resources
     		 * is that of the the highest priority peripheral driver
    @@ -320,6 +313,27 @@ xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
     	return (retval);
     }
     
    +static __inline int
    +xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
    +{
    +	int	retval;
    +
    +	if (dev->ccbq.dev_openings > 0) {
    +		/*
    +		 * The priority of a device waiting for controller
    +		 * resources is that of the the highest priority CCB
    +		 * enqueued.
    +		 */
    +		retval =
    +		    xpt_schedule_dev(&bus->sim->devq->send_queue,
    +				     &dev->send_ccb_entry.pinfo,
    +				     CAMQ_GET_HEAD(&dev->ccbq.queue)->priority);
    +	} else {
    +		retval = 0;
    +	}
    +	return (retval);
    +}
    +
     static __inline int
     periph_is_queued(struct cam_periph *periph)
     {
    @@ -2657,6 +2671,7 @@ xpt_action_default(union ccb *start_ccb)
     			cgd->protocol = dev->protocol;
     			cgd->inq_data = dev->inq_data;
     			cgd->ident_data = dev->ident_data;
    +			cgd->inq_flags = dev->inq_flags;
     			cgd->ccb_h.status = CAM_REQ_CMP;
     			cgd->serial_num_len = dev->serial_num_len;
     			if ((dev->serial_num_len > 0)
    @@ -3747,6 +3762,11 @@ xpt_release_ccb(union ccb *free_ccb)
     	mtx_assert(sim->mtx, MA_OWNED);
     
     	cam_ccbq_release_opening(&device->ccbq);
    +	if (device->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) {
    +		device->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
    +		cam_ccbq_resize(&device->ccbq,
    +		    device->ccbq.dev_openings + device->ccbq.dev_active);
    +	}
     	if (sim->ccb_count > sim->max_ccbs) {
     		xpt_free_ccb(free_ccb);
     		sim->ccb_count--;
    @@ -4573,7 +4593,7 @@ xpt_find_device(struct cam_et *target, lun_id_t lun_id)
     	return (device);
     }
     
    -static void
    +void
     xpt_start_tags(struct cam_path *path)
     {
     	struct ccb_relsim crs;
    @@ -4602,6 +4622,30 @@ xpt_start_tags(struct cam_path *path)
     	xpt_action((union ccb *)&crs);
     }
     
    +void
    +xpt_stop_tags(struct cam_path *path)
    +{
    +	struct ccb_relsim crs;
    +	struct cam_ed *device;
    +	struct cam_sim *sim;
    +
    +	device = path->device;
    +	sim = path->bus->sim;
    +	device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
    +	device->tag_delay_count = 0;
    +	xpt_freeze_devq(path, /*count*/1);
    +	device->inq_flags &= ~SID_CmdQue;
    +	xpt_dev_ccbq_resize(path, sim->max_dev_openings);
    +	xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
    +	crs.ccb_h.func_code = XPT_REL_SIMQ;
    +	crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
    +	crs.openings
    +	    = crs.release_timeout
    +	    = crs.qfrozen_cnt
    +	    = 0;
    +	xpt_action((union ccb *)&crs);
    +}
    +
     static int busses_to_config;
     static int busses_to_reset;
     
    diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
    index 643ddf16f5b..146764ef763 100644
    --- a/sys/cam/cam_xpt_internal.h
    +++ b/sys/cam/cam_xpt_internal.h
    @@ -176,29 +176,8 @@ void			xpt_run_dev_sendq(struct cam_eb *bus);
     int			xpt_schedule_dev(struct camq *queue, cam_pinfo *dev_pinfo,
     					 u_int32_t new_priority);
     u_int32_t		xpt_dev_ccbq_resize(struct cam_path *path, int newopenings);
    -
    -
    -
    -static __inline int
    -xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
    -{
    -	int	retval;
    -
    -	if (dev->ccbq.dev_openings > 0) {
    -		/*
    -		 * The priority of a device waiting for controller
    -		 * resources is that of the the highest priority CCB
    -		 * enqueued.
    -		 */
    -		retval =
    -		    xpt_schedule_dev(&bus->sim->devq->send_queue,
    -				     &dev->send_ccb_entry.pinfo,
    -				     CAMQ_GET_HEAD(&dev->ccbq.queue)->priority);
    -	} else {
    -		retval = 0;
    -	}
    -	return (retval);
    -}
    +void			xpt_start_tags(struct cam_path *path);
    +void			xpt_stop_tags(struct cam_path *path);
     
     MALLOC_DECLARE(M_CAMXPT);
     
    diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
    index d780f9a9019..cae7be61ac9 100644
    --- a/sys/cam/scsi/scsi_xpt.c
    +++ b/sys/cam/scsi/scsi_xpt.c
    @@ -2274,24 +2274,7 @@ scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device
     				device->tag_delay_count = CAM_TAG_DELAY_COUNT;
     				device->flags |= CAM_DEV_TAG_AFTER_COUNT;
     			} else {
    -				struct ccb_relsim crs;
    -
    -				xpt_freeze_devq(cts->ccb_h.path, /*count*/1);
    -		  		device->inq_flags &= ~SID_CmdQue;
    -				xpt_dev_ccbq_resize(cts->ccb_h.path,
    -						    sim->max_dev_openings);
    -				device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
    -				device->tag_delay_count = 0;
    -
    -				xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
    -				    CAM_PRIORITY_NORMAL);
    -				crs.ccb_h.func_code = XPT_REL_SIMQ;
    -				crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
    -				crs.openings
    -				    = crs.release_timeout
    -				    = crs.qfrozen_cnt
    -				    = 0;
    -				xpt_action((union ccb *)&crs);
    +				xpt_stop_tags(cts->ccb_h.path);
     			}
     		}
     	}
    diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
    index 92a65199c65..c46d0ce495d 100644
    --- a/sys/dev/ahci/ahci.c
    +++ b/sys/dev/ahci/ahci.c
    @@ -733,7 +733,8 @@ ahci_ch_attach(device_t dev)
     	}
     	/* Construct SIM entry */
     	ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch,
    -	    device_get_unit(dev), &ch->mtx, ch->numslots, 0, devq);
    +	    device_get_unit(dev), &ch->mtx,
    +	    min(2, ch->numslots), ch->numslots, devq);
     	if (ch->sim == NULL) {
     		device_printf(dev, "unable to allocate sim\n");
     		error = ENOMEM;
    diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
    index 41a5cc7e5b4..73786f3a613 100644
    --- a/sys/dev/siis/siis.c
    +++ b/sys/dev/siis/siis.c
    @@ -454,7 +454,7 @@ siis_ch_attach(device_t dev)
     	}
     	/* Construct SIM entry */
     	ch->sim = cam_sim_alloc(siisaction, siispoll, "siisch", ch,
    -	    device_get_unit(dev), &ch->mtx, SIIS_MAX_SLOTS, 0, devq);
    +	    device_get_unit(dev), &ch->mtx, 2, SIIS_MAX_SLOTS, devq);
     	if (ch->sim == NULL) {
     		device_printf(dev, "unable to allocate sim\n");
     		error = ENOMEM;
    
    From 2711d444492be05c1abfc407bb93fef0fb9b814b Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Wed, 11 Nov 2009 11:24:02 +0000
    Subject: [PATCH 631/646] Add unit to the short month names for Japanese
     locales. Without unit, the output of the application like ls(1) is
     complicated.
    
    Reviewed by:	nork
    MFC after:	1 week
    ---
     share/timedef/ja_JP.SJIS.src  | 24 ++++++++++++------------
     share/timedef/ja_JP.UTF-8.src | 24 ++++++++++++------------
     share/timedef/ja_JP.eucJP.src | 24 ++++++++++++------------
     3 files changed, 36 insertions(+), 36 deletions(-)
    
    diff --git a/share/timedef/ja_JP.SJIS.src b/share/timedef/ja_JP.SJIS.src
    index 8a1de08bb95..57fd95ca32e 100644
    --- a/share/timedef/ja_JP.SJIS.src
    +++ b/share/timedef/ja_JP.SJIS.src
    @@ -5,18 +5,18 @@
     #
     # Short month names
     #
    - 1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    + 1月
    + 2月
    + 3月
    + 4月
    + 5月
    + 6月
    + 7月
    + 8月
    + 9月
    +10月
    +11月
    +12月
     #
     # Long month names (as in a date)
     #
    diff --git a/share/timedef/ja_JP.UTF-8.src b/share/timedef/ja_JP.UTF-8.src
    index 9ee39a5286f..1ee99ca8af5 100644
    --- a/share/timedef/ja_JP.UTF-8.src
    +++ b/share/timedef/ja_JP.UTF-8.src
    @@ -4,18 +4,18 @@
     # WARNING: empty lines are essential too
     #
     # Short month names
    - 1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    + 1譛
    + 2譛
    + 3譛
    + 4譛
    + 5譛
    + 6譛
    + 7譛
    + 8譛
    + 9譛
    +10譛
    +11譛
    +12譛
     #
     # Long month names (as in a date)
     #
    diff --git a/share/timedef/ja_JP.eucJP.src b/share/timedef/ja_JP.eucJP.src
    index 299f1a7a32b..218b2e90e4b 100644
    --- a/share/timedef/ja_JP.eucJP.src
    +++ b/share/timedef/ja_JP.eucJP.src
    @@ -4,18 +4,18 @@
     # WARNING: empty lines are essential too
     #
     # Short month names
    - 1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    + 1キ
    + 2キ
    + 3キ
    + 4キ
    + 5キ
    + 6キ
    + 7キ
    + 8キ
    + 9キ
    +10キ
    +11キ
    +12キ
     #
     # Long month names (as in a date)
     #
    
    From 82a1bd6a61ab17504e8362849779aed779dcc6e2 Mon Sep 17 00:00:00 2001
    From: Peter Pentchev 
    Date: Wed, 11 Nov 2009 11:31:02 +0000
    Subject: [PATCH 632/646] Fix the grammar as in the PR, and then some.
    
    PR:		140454
    Submitted by:	Jeremy Huddleston 
    MFC after:	2 weeks
    ---
     lib/libc/locale/isblank.3 | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/lib/libc/locale/isblank.3 b/lib/libc/locale/isblank.3
    index 4cc6bbbce80..6734dcc4523 100644
    --- a/lib/libc/locale/isblank.3
    +++ b/lib/libc/locale/isblank.3
    @@ -50,9 +50,9 @@ For any locale, this includes the following standard characters:
     .It "\&``\et''\t`` ''"
     .El
     .Pp
    -In the "C" locale
    +In the "C" locale, a successful
     .Fn isblank
    -successful test is limited to this characters only.
    +test is limited to these characters only.
     The value of the argument must be representable as an
     .Vt "unsigned char"
     or the value of
    
    From fc03baf4e4963915cb328278671a151633b98507 Mon Sep 17 00:00:00 2001
    From: Peter Pentchev 
    Date: Wed, 11 Nov 2009 11:37:43 +0000
    Subject: [PATCH 633/646] Correct the information about the doceng@ team
     members - Murray Stokely stepped down some time ago, about the same time as
     Giorgos Keramidas joined the team.
    
    PR:		140465
    Submitted by:	Denny Lin 
    MFC after:	2 weeks
    ---
     share/misc/organization.dot | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/share/misc/organization.dot b/share/misc/organization.dot
    index 5b65bed42f5..891097dee53 100644
    --- a/share/misc/organization.dot
    +++ b/share/misc/organization.dot
    @@ -28,7 +28,7 @@ _misc [label="Miscellaneous Hats"]
     core [label="Core Team\ncore@FreeBSD.org\nwilko, brooks, keramida, imp,\ngnn, wes, hrs, murray,\nrwatson"]
     coresecretary [label="Core Team Secretary\ncore-secretary@FreeBSD.org\njoel"]
     doccommitters [label="Doc/www Committers\ndoc-committers@FreeBSD.org"]
    -doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\nnik, blackend, hrs,\nmurray"]
    +doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\nnik, blackend, hrs,\nkeramida"]
     portscommitters [label="Ports Committers\nports-committers@FreeBSD.org"]
     portmgr [label="Port Management Team\nportmgr@FreeBSD.org\nmarcus, kris, erwin,\nlinimon, pav, krion"]
     portmgrsecretary [label="Port Management Team Secretary\nportmgr-secretary@FreeBSD.org\nerwin"]
    
    From 40350c1b232cdf64cf6612bb62a47bdbd6a6ec86 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Wed, 11 Nov 2009 12:55:58 +0000
    Subject: [PATCH 634/646] Add links to zfs(8) and zpool(8) to mount(8) manual
     page.
    
    ---
     sbin/mount/mount.8 | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
    index 104b248f270..3efc9f1f6e5 100644
    --- a/sbin/mount/mount.8
    +++ b/sbin/mount/mount.8
    @@ -527,7 +527,9 @@ support for a particular file system might be provided either on a static
     .Xr mount_smbfs 8 ,
     .Xr mount_udf 8 ,
     .Xr mount_unionfs 8 ,
    -.Xr umount 8
    +.Xr umount 8 ,
    +.Xr zfs 8 ,
    +.Xr zpool 8
     .Sh CAVEATS
     After a successful
     .Nm ,
    
    From 23e62e7654347c8fe8f01c1e99511a6337340d55 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Wed, 11 Nov 2009 13:49:22 +0000
    Subject: [PATCH 635/646] Revert r198873.  Having different VAPPEND semantics
     for VOP_ACCESS(9) and VOP_ACCESSX(9) is not a good idea.
    
    ---
     sys/kern/vfs_default.c | 8 --------
     1 file changed, 8 deletions(-)
    
    diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
    index d37e0662f26..b80d03d0e9e 100644
    --- a/sys/kern/vfs_default.c
    +++ b/sys/kern/vfs_default.c
    @@ -353,14 +353,6 @@ vop_stdaccessx(struct vop_accessx_args *ap)
     	if (accmode == 0)
     		return (0);
     
    -	/*
    -	 * Many VOP_APPEND implementations don't expect VAPPEND without VWRITE
    -	 * being set, e.g. they check whether the filesystem is read-only only
    -	 * when VWRITE is set.  Make sure we don't confuse them.
    -	 */
    -	if (accmode & VAPPEND)
    -		accmode |= VWRITE;
    -
     	return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td));
     }
     
    
    From 6cc16fcb4ee576ae6109b2bbdbde918d16e635e1 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Wed, 11 Nov 2009 14:21:31 +0000
    Subject: [PATCH 636/646] reflect that pg_ps_enabled is a tunable, not just a
     read-only sysctl
    
    Nod from:	jhb
    ---
     sys/amd64/amd64/pmap.c | 2 +-
     sys/i386/i386/pmap.c   | 2 +-
     sys/i386/xen/pmap.c    | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
    index c928294cf6c..44b71f38723 100644
    --- a/sys/amd64/amd64/pmap.c
    +++ b/sys/amd64/amd64/pmap.c
    @@ -183,7 +183,7 @@ static int pat_works = 0;		/* Is page attribute table sane? */
     SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
     
     static int pg_ps_enabled = 1;
    -SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RD, &pg_ps_enabled, 0,
    +SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN, &pg_ps_enabled, 0,
         "Are large page mappings enabled?");
     
     static u_int64_t	KPTphys;	/* phys addr of kernel level 1 */
    diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
    index 74edbbc4994..c32c8f5af3d 100644
    --- a/sys/i386/i386/pmap.c
    +++ b/sys/i386/i386/pmap.c
    @@ -217,7 +217,7 @@ static int pat_works = 0;		/* Is page attribute table sane? */
     SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
     
     static int pg_ps_enabled;
    -SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RD, &pg_ps_enabled, 0,
    +SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN, &pg_ps_enabled, 0,
         "Are large page mappings enabled?");
     
     /*
    diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
    index 5bf1331c145..b25d0ba32ca 100644
    --- a/sys/i386/xen/pmap.c
    +++ b/sys/i386/xen/pmap.c
    @@ -279,7 +279,7 @@ static struct mtx PMAP2mutex;
     
     SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
     static int pg_ps_enabled;
    -SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RD, &pg_ps_enabled, 0,
    +SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN, &pg_ps_enabled, 0,
         "Are large page mappings enabled?");
     
     SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_max, CTLFLAG_RD, &pv_entry_max, 0,
    
    From b181440e36f47a9805c06e85699746418f2bdfae Mon Sep 17 00:00:00 2001
    From: Antoine Brodin 
    Date: Wed, 11 Nov 2009 14:58:48 +0000
    Subject: [PATCH 637/646] Fix off by one in ieee80211_send_action_register
    
    Found by:	phk's FlexeLint in September
    Reviewed by:	rpaulo@
    MFC after:	1 month
    ---
     sys/net80211/ieee80211_action.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/net80211/ieee80211_action.c b/sys/net80211/ieee80211_action.c
    index 5371f6e975d..8c11471c89a 100644
    --- a/sys/net80211/ieee80211_action.c
    +++ b/sys/net80211/ieee80211_action.c
    @@ -105,7 +105,7 @@ ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f)
     		meshlm_send_action[act] = f;
     		return 0;
     	case IEEE80211_ACTION_CAT_MESHPATH:
    -		if (act > N(hwmp_send_action))
    +		if (act >= N(hwmp_send_action))
     			break;
     		hwmp_send_action[act] = f;
     		return 0;
    
    From d673ae81ed134cd0be6ef8fd66593f92e35beedc Mon Sep 17 00:00:00 2001
    From: Antoine Brodin 
    Date: Wed, 11 Nov 2009 15:00:56 +0000
    Subject: [PATCH 638/646] Remove trailing ";" in struct
     ieee80211_beacon_offsets declaration
    
    Found by:	phk's FlexeLint in September
    Reviewed by:	rpaulo@
    MFC after:	1 month
    ---
     sys/net80211/ieee80211_proto.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
    index e036dacea93..c280847763b 100644
    --- a/sys/net80211/ieee80211_proto.h
    +++ b/sys/net80211/ieee80211_proto.h
    @@ -315,7 +315,7 @@ struct ieee80211_beacon_offsets {
     	uint8_t		*bo_ath;	/* start of ATH parameters */
     	uint8_t		*bo_appie;	/* start of AppIE element */
     	uint16_t	bo_appie_len;	/* AppIE length in bytes */
    -	uint16_t	bo_csa_trailer_len;;
    +	uint16_t	bo_csa_trailer_len;
     	uint8_t		*bo_csa;	/* start of CSA element */
     	uint8_t		*bo_meshconf;	/* start of MESHCONF element */
     	uint8_t		*bo_spare[3];
    
    From a087c7295d12a18465f1d1012071e6c3de2b56d3 Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Wed, 11 Nov 2009 15:21:06 +0000
    Subject: [PATCH 639/646] ANSIfy.
    
    MFC after:	1 week
    ---
     lib/libc/net/ip6opt.c | 33 ++++++++-------------------------
     1 file changed, 8 insertions(+), 25 deletions(-)
    
    diff --git a/lib/libc/net/ip6opt.c b/lib/libc/net/ip6opt.c
    index 7b65d0607ce..d999fd48fba 100644
    --- a/lib/libc/net/ip6opt.c
    +++ b/lib/libc/net/ip6opt.c
    @@ -55,8 +55,7 @@ static void inet6_insert_padopt(u_char *p, int len);
      * byte, the length byte, and the option data.
      */
     int
    -inet6_option_space(nbytes)
    -	int nbytes;
    +inet6_option_space(int nbytes)
     {
     	nbytes += 2;	/* we need space for nxt-hdr and length fields */
     	return(CMSG_SPACE((nbytes + 7) & ~7));
    @@ -68,10 +67,7 @@ inet6_option_space(nbytes)
      * success or -1 on an error.
      */
     int
    -inet6_option_init(bp, cmsgp, type)
    -	void *bp;
    -	struct cmsghdr **cmsgp;
    -	int type;
    +inet6_option_init(void *bp, struct cmsghdr **cmsgp, int type)
     {
     	struct cmsghdr *ch = (struct cmsghdr *)bp;
     
    @@ -98,11 +94,8 @@ inet6_option_init(bp, cmsgp, type)
      * earlier.  It must have a value between 0 and 7, inclusive.
      */
     int
    -inet6_option_append(cmsg, typep, multx, plusy)
    -	struct cmsghdr *cmsg;
    -	const u_int8_t *typep;
    -	int multx;
    -	int plusy;
    +inet6_option_append(struct cmsghdr *cmsg, const u_int8_t *typep, int multx,
    +    int plusy)
     {
     	int padlen, optlen, off;
     	u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
    @@ -171,11 +164,7 @@ inet6_option_append(cmsg, typep, multx, plusy)
      * 
      */
     u_int8_t *
    -inet6_option_alloc(cmsg, datalen, multx, plusy)
    -	struct cmsghdr *cmsg;
    -	int datalen;
    -	int multx;
    -	int plusy;
    +inet6_option_alloc(struct cmsghdr *cmsg, int datalen, int multx, int plusy)
     {
     	int padlen, off;
     	u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
    @@ -238,9 +227,7 @@ inet6_option_alloc(cmsg, datalen, multx, plusy)
      * (RFC 2292, 6.3.5)
      */
     int
    -inet6_option_next(cmsg, tptrp)
    -	const struct cmsghdr *cmsg;
    -	u_int8_t **tptrp;
    +inet6_option_next(const struct cmsghdr *cmsg, u_int8_t **tptrp)
     {
     	struct ip6_ext *ip6e;
     	int hdrlen, optlen;
    @@ -296,10 +283,7 @@ inet6_option_next(cmsg, tptrp)
      *       it's a typo. The variable should be type of u_int8_t **.
      */
     int
    -inet6_option_find(cmsg, tptrp, type)
    -	const struct cmsghdr *cmsg;
    -	u_int8_t **tptrp;
    -	int type;
    +inet6_option_find(const struct cmsghdr *cmsg, u_int8_t **tptrp, int type)
     {
     	struct ip6_ext *ip6e;
     	int hdrlen, optlen;
    @@ -352,8 +336,7 @@ inet6_option_find(cmsg, tptrp, type)
      * calculated length and the limitation of the buffer.
      */
     static int
    -ip6optlen(opt, lim)
    -	u_int8_t *opt, *lim;
    +ip6optlen(u_int8_t *opt, u_int8_t *lim)
     {
     	int optlen;
     
    
    From 1bb015c07cb63136c0b7ce7c06939561ba3c9996 Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Wed, 11 Nov 2009 15:43:07 +0000
    Subject: [PATCH 640/646] Create verifier used by FreeBSD NFS client is
     suboptimal because the first part of a verifier is set to the first IP
     address from V_in_ifaddrhead list. This address is typically the loopback
     address making the first part of the verifier practically non-unique. The
     second part of the verifier is initialized to zero making its initial value
     non-unique too.
    
    This commit changes the strategy for create verifier initialization:
    just initialize it to a random value. Also move verifier handling into
    its own function and use a mutex to protect the variable.
    
    This change is a candidate for porting to sys/nfsclient.
    
    Reviewed by:	jhb, rmacklem
    Approved by:	trasz (mentor)
    ---
     sys/fs/nfsclient/nfs_clvnops.c | 39 ++++++++++++++++++++++------------
     1 file changed, 25 insertions(+), 14 deletions(-)
    
    diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
    index 5dc3a593458..c60ae57c878 100644
    --- a/sys/fs/nfsclient/nfs_clvnops.c
    +++ b/sys/fs/nfsclient/nfs_clvnops.c
    @@ -1365,7 +1365,30 @@ nfs_mknod(struct vop_mknod_args *ap)
     	return (nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap));
     }
     
    -static u_long create_verf;
    +static struct mtx nfs_cverf_mtx;
    +MTX_SYSINIT(nfs_cverf_mtx, &nfs_cverf_mtx, "NFS create verifier mutex",
    +    MTX_DEF);
    +
    +static nfsquad_t
    +nfs_get_cverf(void)
    +{
    +	static nfsquad_t cverf;
    +	nfsquad_t ret;
    +	static int cverf_initialized = 0;
    +
    +	mtx_lock(&nfs_cverf_mtx);
    +	if (cverf_initialized == 0) {
    +		cverf.lval[0] = arc4random();
    +		cverf.lval[1] = arc4random();
    +		cverf_initialized = 1;
    +	} else
    +		cverf.qval++;
    +	ret = cverf;
    +	mtx_unlock(&nfs_cverf_mtx);
    +
    +	return (ret);
    +}
    +
     /*
      * nfs file create call
      */
    @@ -1405,19 +1428,7 @@ again:
     	}
     	mtx_unlock(&dnp->n_mtx);
     
    -#ifdef INET
    -	CURVNET_SET(CRED_TO_VNET(cnp->cn_cred));
    -	IN_IFADDR_RLOCK();
    -	if (!TAILQ_EMPTY(&V_in_ifaddrhead))
    -		cverf.lval[0] = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr;
    -	else
    -#endif
    -		cverf.lval[0] = create_verf;
    -#ifdef INET
    -	IN_IFADDR_RUNLOCK();
    -	CURVNET_RESTORE();
    -#endif
    -	cverf.lval[1] = ++create_verf;
    +	cverf = nfs_get_cverf();
     	error = nfsrpc_create(dvp, cnp->cn_nameptr, cnp->cn_namelen,
     	    vap, cverf, fmode, cnp->cn_cred, cnp->cn_thread, &dnfsva, &nfsva,
     	    &nfhp, &attrflag, &dattrflag, NULL);
    
    From 6c2af98cee34f984add5a0fef409fd0ebfd15705 Mon Sep 17 00:00:00 2001
    From: Rene Ladan 
    Date: Wed, 11 Nov 2009 18:28:12 +0000
    Subject: [PATCH 641/646] Synchronize with C.msg revision 199083 and improve
     some existing messages.
    
    Reviewed by:	remko
    Approved by:	remko
    ---
     lib/libc/nls/nl_NL.ISO8859-1.msg | 87 +++++++++++++++++++++-----------
     1 file changed, 57 insertions(+), 30 deletions(-)
    
    diff --git a/lib/libc/nls/nl_NL.ISO8859-1.msg b/lib/libc/nls/nl_NL.ISO8859-1.msg
    index 47103d4931c..2939116fc97 100644
    --- a/lib/libc/nls/nl_NL.ISO8859-1.msg
    +++ b/lib/libc/nls/nl_NL.ISO8859-1.msg
    @@ -26,7 +26,7 @@ $ EBADF
     $ ECHILD
     10 Geen kindprocessen
     $ EDEADLK
    -11 Een deadlock is vermeden
    +11 Een deadlock op een bron is vermeden
     $ ENOMEM
     12 Kan geen geheugen meer verkrijgen
     $ EACCES
    @@ -40,13 +40,13 @@ $ EBUSY
     $ EEXIST
     17 Bestand bestaat reeds
     $ EXDEV
    -18 Verwijzing tussen bestanden op verschillende bestandssystemen
    +18 Verwijzing tussen verschillende apparaten
     $ ENODEV
     19 Bewerking wordt niet ondersteund door dit apparaat
     $ ENOTDIR
     20 Dit is geen map
     $ EISDIR
    -21 Dit is een map 
    +21 Dit is een map
     $ EINVAL
     22 Ongeldig argument
     $ ENFILE
    @@ -62,7 +62,7 @@ $ EFBIG
     $ ENOSPC
     28 Geen ruimte meer op dit apparaat
     $ ESPIPE
    -29 Onuitvoerbare zoekopdracht
    +29 Ongeldige zoekopdracht
     $ EROFS
     30 Van dit bestandssysteem kan alleen worden gelezen
     $ EMLINK
    @@ -84,7 +84,7 @@ $ ENOTSOCK
     $ EDESTADDRREQ
     39 Een bestemmingsadres is vereist
     $ EMSGSIZE
    -40 Te grote bericht
    +40 Te groot bericht
     $ EPROTOTYPE
     41 Protocol past niet bij dit contactpunt
     $ ENOPROTOOPT
    @@ -116,7 +116,7 @@ $ ECONNRESET
     $ ENOBUFS
     55 Geen bufferruimte meer beschikbaar
     $ EISCONN
    -56 Dit contactpunt is al verbonden
    +56 Contactpunt is al verbonden
     $ ENOTCONN
     57 Contactpunt is niet verbonden
     $ ESHUTDOWN
    @@ -136,9 +136,9 @@ $ EHOSTDOWN
     $ EHOSTUNREACH
     65 Bestemming niet bereikbaar
     $ ENOTEMPTY
    -66 Directory is niet leeg
    +66 Map is niet leeg
     $ EPROCLIM
    -67 Te veel taken
    +67 Te veel processen
     $ EUSERS
     68 Te veel gebruikers
     $ EDQUOT
    @@ -160,7 +160,7 @@ $ EPROCUNAVAIL
     $ ENOLCK
     77 Geen sloten beschikbaar
     $ ENOSYS
    -78 Deze systeemfunctie is niet geimplementeerd
    +78 Systeemfunctie is niet geimplementeerd
     $ EFTYPE
     79 Bestandsformaat niet van toepassing
     $ EAUTH
    @@ -173,30 +173,24 @@ $ ENOMSG
     83 Geen bericht van het gewenste type
     $ EOVERFLOW
     84 Waarde te groot om te bewaren in gegevenstype
    -$ EILSEQ
    -85 Ongeldige bytereeks
    -$ ENOTSUP
    -86 Niet ondersteund
     $ ECANCELED
    -87 Bewerking geannuleerd
    -$ EBADMSG
    -88 Verkeerd of defect bericht
    -$ ENODATA
    -89 Geen bericht beschikbaar
    -$ ENOSR
    -90 Geen STREAM-voorraad
    -$ ENOSTR
    -91 Dit is geen STREAM
    -$ ETIME
    -92 STREAM-ioctl verlopen
    +85 Bewerking geannuleerd
    +$ EILSEQ
    +86 Ongeldige bytereeks
     $ ENOATTR
    -93 Attribuut niet gevonden
    +87 Attribuut niet gevonden
    +$ EDOOFUS
    +88 Programmeerfout
    +$ EBADMSG
    +89 Verkeerd of defect bericht
     $ EMULTIHOP
    -94 Multihopverzoek
    +90 Multihopverzoek
     $ ENOLINK
    -95 Verbinding werd verstoord
    +91 Verbinding werd verstoord
     $ EPROTO
    -96 Protocolfout
    +92 Protocolfout
    +$ ENOTCAPABLE
    +93 Onvoldoende mogelijkheden
     $
     $ strsignal() support catalog
     $
    @@ -263,5 +257,38 @@ $ SIGUSR1
     30 Gebruikersignaal 1
     $ SIGUSR2
     31 Gebruikersignaal 2
    -$ SIGPWR
    -32 Stroomuitval/stroominschakeling
    +$
    +$ gai_strerror() support catalog
    +$set 3
    +$ 1 (obsolete)
    +1 Adresfamilie voor hostnaam niet ondersteund
    +$ EAI_AGAIN
    +2 Tijdelijke fout in naamresolutie
    +$ EAI_BADFLAGS
    +3 Ongeldige waarde voor ai_flags
    +$ EAI_FAIL
    +4 Onherstelbare fout in naamresolutie
    +$ EAI_FAMILY
    +5 ai_familie niet ondersteund
    +$ EAI_MEMORY
    +6 Geheugenallocatiefout
    +$ 7 (obsolete)
    +7 Geen adres met hostnaam geassocieerd
    +$ EAI_NONAME
    +8 hostname noch servname gegeven, of onbekend
    +$ EAI_SERVICE
    +9 servname niet ondersteund voor ai_socktype
    +$ EAI_SOCKTYPE
    +10 ai_socktype niet ondersteund
    +$ EAI_SYSTEM
    +11 Systeemfout geretourneerd in errno
    +$ EAI_BADHINTS
    +12 Ongeldige waarde voor hints
    +$ EAI_PROTOCOL
    +13 Opgelost protocol is onbekend
    +$ EAI_OVERFLOW
    +14 Argumentbuffer overstroomd
    +$ 0
    +32766 Succes
    +$ NL_MSGMAX
    +32767 Onbekende fout
    
    From 466727ddbe92af2182c77211f6664fc2a00b6df7 Mon Sep 17 00:00:00 2001
    From: Jack F Vogel 
    Date: Wed, 11 Nov 2009 19:13:40 +0000
    Subject: [PATCH 642/646] With an i386 kernel the igb driver can cause a page
     fault panic on initialization due to a large number of bounce pages being
     allocated. This is due to the dma tag requiring page alignment on mbuf
     mapping. This was removed some time back from the ixgbe driver and is not
     needed here either.
    
    ---
     sys/dev/e1000/if_igb.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
    index e6ad0fccc87..61743dfdc0b 100644
    --- a/sys/dev/e1000/if_igb.c
    +++ b/sys/dev/e1000/if_igb.c
    @@ -2654,7 +2654,7 @@ igb_dma_malloc(struct adapter *adapter, bus_size_t size,
     	int error;
     
     	error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
    -				IGB_DBA_ALIGN, 0,	/* alignment, bounds */
    +				1, 0,			/* alignment, bounds */
     				BUS_SPACE_MAXADDR,	/* lowaddr */
     				BUS_SPACE_MAXADDR,	/* highaddr */
     				NULL, NULL,		/* filter, filterarg */
    @@ -2867,7 +2867,7 @@ igb_allocate_transmit_buffers(struct tx_ring *txr)
     	 * Setup DMA descriptor areas.
     	 */
     	if ((error = bus_dma_tag_create(NULL,		/* parent */
    -			       PAGE_SIZE, 0,		/* alignment, bounds */
    +			       1, 0,			/* alignment, bounds */
     			       BUS_SPACE_MAXADDR,	/* lowaddr */
     			       BUS_SPACE_MAXADDR,	/* highaddr */
     			       NULL, NULL,		/* filter, filterarg */
    @@ -3554,7 +3554,7 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
     	** it may not always use this.
     	*/
     	if ((error = bus_dma_tag_create(NULL,		/* parent */
    -				   PAGE_SIZE, 0,	/* alignment, bounds */
    +				   1, 0,		/* alignment, bounds */
     				   BUS_SPACE_MAXADDR,	/* lowaddr */
     				   BUS_SPACE_MAXADDR,	/* highaddr */
     				   NULL, NULL,		/* filter, filterarg */
    
    From 18ca996c25845e7170ed821954ccd9a80e5b9057 Mon Sep 17 00:00:00 2001
    From: Antoine Brodin 
    Date: Wed, 11 Nov 2009 19:39:45 +0000
    Subject: [PATCH 643/646] - Remove trailing ";" after if statement - Remove #if
     0 section that was never needed/used
    
    Reviewed by:	raj@
    MFC after:	1 month
    ---
     sys/boot/uboot/lib/glue.c | 7 +------
     1 file changed, 1 insertion(+), 6 deletions(-)
    
    diff --git a/sys/boot/uboot/lib/glue.c b/sys/boot/uboot/lib/glue.c
    index 3945b05750e..5a9591c90f0 100644
    --- a/sys/boot/uboot/lib/glue.c
    +++ b/sys/boot/uboot/lib/glue.c
    @@ -467,7 +467,7 @@ ub_stor_type(int type)
     	if (type & DT_STOR_USB)
     		return ("USB");
     
    -	if (type & DT_STOR_MMC);
    +	if (type & DT_STOR_MMC)
     		return ("MMC");
     
     	return ("Unknown");
    @@ -581,11 +581,6 @@ ub_env_enum(const char *last)
     	if (!env)
     		/* no more env. variables to enumerate */
     		return (NULL);
    -#if 0
    -	if (last && strncmp(env, last, strlen(last)) == 0);
    -		/* error, trying to enumerate non existing env. variable */
    -		return NULL;
    -#endif
     
     	/* next enumerated env var */
     	memset(env_name, 0, 256);
    
    From 58fbe5ab67e2016fa4dbdcca7f05a9660386364c Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 11 Nov 2009 20:27:53 +0000
    Subject: [PATCH 644/646] Use a dedicated callout to drive the transmit
     watchdog timer instead of using if_watchdog and if_timer.
    
    Tested by:	gavin
    ---
     sys/dev/bwi/if_bwi.c    | 29 +++++++++++++++++------------
     sys/dev/bwi/if_bwivar.h |  1 +
     2 files changed, 18 insertions(+), 12 deletions(-)
    
    diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
    index 327b7368b77..2604d8389ed 100644
    --- a/sys/dev/bwi/if_bwi.c
    +++ b/sys/dev/bwi/if_bwi.c
    @@ -106,7 +106,7 @@ static void	bwi_start(struct ifnet *);
     static void	bwi_start_locked(struct ifnet *);
     static int	bwi_raw_xmit(struct ieee80211_node *, struct mbuf *,
     			const struct ieee80211_bpf_params *);
    -static void	bwi_watchdog(struct ifnet *);
    +static void	bwi_watchdog(void *);
     static void	bwi_scan_start(struct ieee80211com *);
     static void	bwi_set_channel(struct ieee80211com *);
     static void	bwi_scan_end(struct ieee80211com *);
    @@ -464,10 +464,10 @@ bwi_attach(struct bwi_softc *sc)
     	ifp->if_init = bwi_init;
     	ifp->if_ioctl = bwi_ioctl;
     	ifp->if_start = bwi_start;
    -	ifp->if_watchdog = bwi_watchdog;
     	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
     	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
     	IFQ_SET_READY(&ifp->if_snd);
    +	callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
     
     	/*
     	 * Setup ratesets, phytype, channels and get MAC address
    @@ -581,6 +581,7 @@ bwi_detach(struct bwi_softc *sc)
     	bwi_stop(sc, 1);
     	callout_drain(&sc->sc_led_blink_ch);
     	callout_drain(&sc->sc_calib_ch);
    +	callout_drain(&sc->sc_watchdog_timer);
     	ieee80211_ifdetach(ic);
     
     	for (i = 0; i < sc->sc_nmac; ++i)
    @@ -1295,6 +1296,7 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg)
     	sc->sc_flags &= ~BWI_F_STOP;
     
     	ifp->if_drv_flags |= IFF_DRV_RUNNING;
    +	callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
     
     	/* Enable intrs */
     	bwi_enable_intrs(sc, BWI_INIT_INTRS);
    @@ -1433,7 +1435,7 @@ bwi_start_locked(struct ifnet *ifp)
     	tbd->tbd_idx = idx;
     
     	if (trans)
    -		ifp->if_timer = 5;
    +		sc->sc_tx_timer = 5;
     }
     
     static int
    @@ -1474,7 +1476,7 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
     		if (++tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC)
     			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
     		tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC;
    -		ifp->if_timer = 5;
    +		sc->sc_tx_timer = 5;
     	} else {
     		/* NB: m is reclaimed on encap failure */
     		ieee80211_free_node(ni);
    @@ -1485,17 +1487,20 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
     }
     
     static void
    -bwi_watchdog(struct ifnet *ifp)
    +bwi_watchdog(void *arg)
     {
    -	struct bwi_softc *sc = ifp->if_softc;
    +	struct bwi_softc *sc;
    +	struct ifnet *ifp;
     
    -	BWI_LOCK(sc);
    -	if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
    +	sc = arg;
    +	ifp = sc->sc_ifp;
    +	BWI_ASSERT_LOCKED(sc);
    +	if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) {
     		if_printf(ifp, "watchdog timeout\n");
     		ifp->if_oerrors++;
     		taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
     	}
    -	BWI_UNLOCK(sc);
    +	callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
     }
     
     static void
    @@ -1551,7 +1556,7 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg)
     		bwi_bbp_power_off(sc);
     
     	sc->sc_tx_timer = 0;
    -	ifp->if_timer = 0;
    +	callout_stop(&sc->sc_watchdog_timer);
     	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
     }
     
    @@ -3420,7 +3425,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
     	tb->tb_mbuf = NULL;
     
     	if (tbd->tbd_used == 0)
    -		ifp->if_timer = 0;
    +		sc->sc_tx_timer = 0;
     
     	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     }
    @@ -3922,7 +3927,7 @@ bwi_led_attach(struct bwi_softc *sc)
     			"%dth led, act %d, lowact %d\n", i,
     			led->l_act, led->l_flags & BWI_LED_F_ACTLOW);
     	}
    -	callout_init(&sc->sc_led_blink_ch, CALLOUT_MPSAFE);
    +	callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
     }
     
     static __inline uint16_t
    diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
    index af4b0ea5cc1..476ee137d54 100644
    --- a/sys/dev/bwi/if_bwivar.h
    +++ b/sys/dev/bwi/if_bwivar.h
    @@ -578,6 +578,7 @@ struct bwi_softc {
     	bus_space_handle_t	sc_mem_bh;
     
     	struct callout		sc_calib_ch;
    +	struct callout	sc_watchdog_timer;
     
     	struct bwi_regwin	*sc_cur_regwin;
     	struct bwi_regwin	sc_com_regwin;
    
    From f140aad88c4131d178f535323d00fbcb6f6504bf Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 11 Nov 2009 20:29:40 +0000
    Subject: [PATCH 645/646] More consistent whitespace.
    
    ---
     sys/dev/bwi/if_bwivar.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
    index 476ee137d54..22a1b1ebb03 100644
    --- a/sys/dev/bwi/if_bwivar.h
    +++ b/sys/dev/bwi/if_bwivar.h
    @@ -578,7 +578,7 @@ struct bwi_softc {
     	bus_space_handle_t	sc_mem_bh;
     
     	struct callout		sc_calib_ch;
    -	struct callout	sc_watchdog_timer;
    +	struct callout		sc_watchdog_timer;
     
     	struct bwi_regwin	*sc_cur_regwin;
     	struct bwi_regwin	sc_com_regwin;
    
    From 41c8c6e876843baf55e33637e7a7018cfce80f62 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Wed, 11 Nov 2009 21:30:58 +0000
    Subject: [PATCH 646/646] Add interface description capability as inspired by
     OpenBSD.
    
    MFC after:	3 months
    ---
     contrib/libpcap/inet.c    | 16 +++++++++---
     sbin/ifconfig/ifconfig.8  | 12 ++++++++-
     sbin/ifconfig/ifconfig.c  | 53 +++++++++++++++++++++++++++++++++++++++
     share/man/man4/netintro.4 | 21 +++++++++++++++-
     sys/kern/kern_jail.c      |  1 +
     sys/net/if.c              | 41 ++++++++++++++++++++++++++++++
     sys/net/if.h              |  2 ++
     sys/net/if_var.h          |  3 ++-
     sys/sys/param.h           |  2 +-
     sys/sys/priv.h            |  1 +
     sys/sys/sockio.h          |  2 ++
     11 files changed, 146 insertions(+), 8 deletions(-)
    
    diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c
    index aad87963e78..8955f2c49d6 100644
    --- a/contrib/libpcap/inet.c
    +++ b/contrib/libpcap/inet.c
    @@ -403,22 +403,30 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
     	pcap_addr_t *curaddr, *prevaddr, *nextaddr;
     #ifdef SIOCGIFDESCR
     	struct ifreq ifrdesc;
    +#ifdef __FreeBSD__
    +#define _IFDESCRSIZE 64
    +	char ifdescr[_IFDESCRSIZE];
    +#else
     	char ifdescr[IFDESCRSIZE];
    -	int s;
     #endif
    +	int s;
     
    -#ifdef SIOCGIFDESCR
     	/*
     	 * Get the description for the interface.
     	 */
     	memset(&ifrdesc, 0, sizeof ifrdesc);
     	strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
    +#ifdef __FreeBSD__
    +	ifrdesc.ifr_buffer.buffer = ifdescr;
    +	ifrdesc.ifr_buffer.length = _IFDESCRSIZE;
    +#else
     	ifrdesc.ifr_data = (caddr_t)&ifdescr;
    +#endif
     	s = socket(AF_INET, SOCK_DGRAM, 0);
     	if (s >= 0) {
     		if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 &&
    -		    strlen(ifrdesc.ifr_data) != 0)
    -			description = ifrdesc.ifr_data;
    +		    strlen(ifdescr) != 0)
    +			description = ifdescr;
     		close(s);
     	}
     #endif
    diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
    index 220bd9f415c..211b1ef08be 100644
    --- a/sbin/ifconfig/ifconfig.8
    +++ b/sbin/ifconfig/ifconfig.8
    @@ -28,7 +28,7 @@
     .\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
     .\" $FreeBSD$
     .\"
    -.Dd September 23, 2009
    +.Dd November 11, 2009
     .Dt IFCONFIG 8
     .Os
     .Sh NAME
    @@ -258,6 +258,12 @@ Disable permanently promiscuous mode.
     Another name for the
     .Fl alias
     parameter.
    +.It Cm description Ar value
    +Specify a description of the interface.
    +This can be used to label interfaces in situations where they may
    +otherwise be difficult to distinguish.
    +.It Cm -description
    +Clear the interface description.
     .It Cm down
     Mark an interface
     .Dq down .
    @@ -2512,6 +2518,10 @@ Configure the interface
     to use 100baseTX, full duplex Ethernet media options:
     .Dl # ifconfig xl0 media 100baseTX mediaopt full-duplex
     .Pp
    +Label the em0 interface as an uplink:
    +.Pp
    +.Dl # ifconfig em0 description \&"Uplink to Gigabit Switch 2\&"
    +.Pp
     Create the software network interface
     .Li gif1 :
     .Dl # ifconfig gif1 create
    diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
    index f05374cf4c4..e08bb4f86fa 100644
    --- a/sbin/ifconfig/ifconfig.c
    +++ b/sbin/ifconfig/ifconfig.c
    @@ -83,6 +83,8 @@ static const char rcsid[] =
     struct	ifreq ifr;
     
     char	name[IFNAMSIZ];
    +char	*descr = NULL;
    +size_t	descrlen = 64;
     int	setaddr;
     int	setmask;
     int	doalias;
    @@ -822,6 +824,36 @@ setifname(const char *val, int dummy __unused, int s,
     	free(newname);
     }
     
    +/* ARGSUSED */
    +static void
    +setifdescr(const char *val, int dummy __unused, int s, 
    +    const struct afswtch *afp)
    +{
    +	char *newdescr;
    +
    +	newdescr = strdup(val);
    +	if (newdescr == NULL) {
    +		warn("no memory to set ifdescr");
    +		return;
    +	}
    +	ifr.ifr_buffer.buffer = newdescr;
    +	ifr.ifr_buffer.length = strlen(newdescr);
    +	if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) {
    +		warn("ioctl (set descr)");
    +		free(newdescr);
    +		return;
    +	}
    +	free(newdescr);
    +}
    +
    +/* ARGSUSED */
    +static void
    +unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
    +{
    +
    +	setifdescr("", 0, s, 0);
    +}
    +
     #define	IFFBITS \
     "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
     "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
    @@ -866,6 +898,23 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
     		printf(" mtu %d", ifr.ifr_mtu);
     	putchar('\n');
     
    +	descr = reallocf(descr, descrlen);
    +	if (descr != NULL) {
    +		do {
    +			ifr.ifr_buffer.buffer = descr;
    +			ifr.ifr_buffer.length = descrlen;
    +			if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
    +			    if (strlen(descr) > 0)
    +				printf("\tdescription: %s\n", descr);
    +			    break;
    +			}
    +			if (errno == ENAMETOOLONG) {
    +				descrlen *= 2;
    +				descr = reallocf(descr, descrlen);
    +			}
    +		} while (errno == ENAMETOOLONG);
    +	}
    +
     	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
     		if (ifr.ifr_curcap != 0) {
     			printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
    @@ -1035,6 +1084,10 @@ static struct cmd basic_cmds[] = {
     	DEF_CMD("-arp",		IFF_NOARP,	setifflags),
     	DEF_CMD("debug",	IFF_DEBUG,	setifflags),
     	DEF_CMD("-debug",	-IFF_DEBUG,	setifflags),
    +	DEF_CMD_ARG("description",		setifdescr),
    +	DEF_CMD_ARG("descr",			setifdescr),
    +	DEF_CMD("-description",	0,		unsetifdescr),
    +	DEF_CMD("-descr",	0,		unsetifdescr),
     	DEF_CMD("promisc",	IFF_PPROMISC,	setifflags),
     	DEF_CMD("-promisc",	-IFF_PPROMISC,	setifflags),
     	DEF_CMD("add",		IFF_UP,		notealias),
    diff --git a/share/man/man4/netintro.4 b/share/man/man4/netintro.4
    index f5d479bc18c..aa38429c00c 100644
    --- a/share/man/man4/netintro.4
    +++ b/share/man/man4/netintro.4
    @@ -32,7 +32,7 @@
     .\"     @(#)netintro.4	8.2 (Berkeley) 11/30/93
     .\" $FreeBSD$
     .\"
    -.Dd June 18, 2004
    +.Dd November 11, 2009
     .Dt NETINTRO 4
     .Os
     .Sh NAME
    @@ -277,6 +277,25 @@ and
     fields of the
     .Vt ifreq
     structure, respectively.
    +.It Dv SIOCGIFDESCR
    +Get the interface description, returned in the
    +.Va buffer
    +field of
    +.Va ifru_buffer
    +struct.
    +The user supplied buffer length should defined in the
    +.Va length
    +field of
    +.Va ifru_buffer
    +struct passed in as parameter.
    +.It Dv SIOCSIFDESCR
    +Set the interface description to the value of the
    +.Va buffer
    +field of
    +.Va ifru_buffer
    +struct, with
    +.Va length
    +field specifying its length.
     .It Dv SIOCSIFFLAGS
     Set interface flags field.
     If the interface is marked down,
    diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
    index 0cc330cd5ad..e98c712ed51 100644
    --- a/sys/kern/kern_jail.c
    +++ b/sys/kern/kern_jail.c
    @@ -3467,6 +3467,7 @@ prison_priv_check(struct ucred *cred, int priv)
     	case PRIV_NET_SETIFMTU:
     	case PRIV_NET_SETIFFLAGS:
     	case PRIV_NET_SETIFCAP:
    +	case PRIV_NET_SETIFDESCR:
     	case PRIV_NET_SETIFNAME	:
     	case PRIV_NET_SETIFMETRIC:
     	case PRIV_NET_SETIFPHYS:
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 55de666a636..4ba453af28b 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -463,6 +463,8 @@ if_free_internal(struct ifnet *ifp)
     #ifdef MAC
     	mac_ifnet_destroy(ifp);
     #endif /* MAC */
    +	if (ifp->if_description != NULL)
    +		sbuf_delete(ifp->if_description);
     	IF_AFDATA_DESTROY(ifp);
     	IF_ADDR_LOCK_DESTROY(ifp);
     	ifq_delete(&ifp->if_snd);
    @@ -2090,6 +2092,45 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
     		ifr->ifr_phys = ifp->if_physical;
     		break;
     
    +	case SIOCGIFDESCR:
    +		IF_AFDATA_RLOCK(ifp);
    +		if (ifp->if_description == NULL)
    +			error = ENOMSG;
    +		else
    +			error = copystr(sbuf_data(ifp->if_description),
    +					ifr->ifr_buffer.buffer,
    +					ifr->ifr_buffer.length, NULL);
    +		IF_AFDATA_RUNLOCK(ifp);
    +		break;
    +
    +	case SIOCSIFDESCR:
    +		error = priv_check(td, PRIV_NET_SETIFDESCR);
    +		if (error)
    +			return (error);
    +
    +		IF_AFDATA_WLOCK(ifp);
    +		if (ifp->if_description == NULL) {
    +			ifp->if_description = sbuf_new_auto();
    +			if (ifp->if_description == NULL) {
    +				error = ENOMEM;
    +				IF_AFDATA_WUNLOCK(ifp);
    +				break;
    +			}
    +		} else
    +			sbuf_clear(ifp->if_description);
    +
    +		if (sbuf_copyin(ifp->if_description, ifr->ifr_buffer.buffer,
    +				ifr->ifr_buffer.length) == -1)
    +			error = EFAULT;
    +
    +		if (error == 0) {
    +			sbuf_finish(ifp->if_description);
    +			getmicrotime(&ifp->if_lastchange);
    +		}
    +		IF_AFDATA_WUNLOCK(ifp);
    +
    +		break;
    +
     	case SIOCSIFFLAGS:
     		error = priv_check(td, PRIV_NET_SETIFFLAGS);
     		if (error)
    diff --git a/sys/net/if.h b/sys/net/if.h
    index 857ab7fb460..89f172bce9f 100644
    --- a/sys/net/if.h
    +++ b/sys/net/if.h
    @@ -294,6 +294,7 @@ struct	ifreq {
     		struct	sockaddr ifru_addr;
     		struct	sockaddr ifru_dstaddr;
     		struct	sockaddr ifru_broadaddr;
    +		struct { size_t length; caddr_t	buffer; } ifru_buffer;
     		short	ifru_flags[2];
     		short	ifru_index;
     		int	ifru_jid;
    @@ -307,6 +308,7 @@ struct	ifreq {
     #define	ifr_addr	ifr_ifru.ifru_addr	/* address */
     #define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
     #define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
    +#define	ifr_buffer	ifr_ifru.ifru_buffer	/* user supplied buffer with its length */
     #define	ifr_flags	ifr_ifru.ifru_flags[0]	/* flags (low 16 bits) */
     #define	ifr_flagshigh	ifr_ifru.ifru_flags[1]	/* flags (high 16 bits) */
     #define	ifr_jid		ifr_ifru.ifru_jid	/* jail/vnet */
    diff --git a/sys/net/if_var.h b/sys/net/if_var.h
    index 523b9e8a813..82e7aabdb99 100644
    --- a/sys/net/if_var.h
    +++ b/sys/net/if_var.h
    @@ -198,6 +198,7 @@ struct ifnet {
     	void	*if_pf_kif;
     	void	*if_lagg;		/* lagg glue */
     	u_char	 if_alloctype;		/* if_type at time of allocation */
    +	struct sbuf *if_description;	/* interface description */
     
     	/*
     	 * Spare fields are added so that we can modify sensitive data
    @@ -205,7 +206,7 @@ struct ifnet {
     	 * be used with care where binary compatibility is required.
     	 */
     	char	 if_cspare[3];
    -	void	*if_pspare[8];
    +	void	*if_pspare[7];
     	int	if_ispare[4];
     };
     
    diff --git a/sys/sys/param.h b/sys/sys/param.h
    index 7bfab291c44..a17151c9e4b 100644
    --- a/sys/sys/param.h
    +++ b/sys/sys/param.h
    @@ -58,7 +58,7 @@
      *		in the range 5 to 9.
      */
     #undef __FreeBSD_version
    -#define __FreeBSD_version 900002	/* Master, propagated to newvers */
    +#define __FreeBSD_version 900003	/* Master, propagated to newvers */
     
     #ifndef LOCORE
     #include 
    diff --git a/sys/sys/priv.h b/sys/sys/priv.h
    index c8ccfa62a72..5738fca5d44 100644
    --- a/sys/sys/priv.h
    +++ b/sys/sys/priv.h
    @@ -335,6 +335,7 @@
     #define	PRIV_NET_LAGG		415	/* Administer lagg interface. */
     #define	PRIV_NET_GIF		416	/* Administer gif interface. */
     #define	PRIV_NET_SETIFVNET	417	/* Move interface to vnet. */
    +#define	PRIV_NET_SETIFDESCR	418	/* Set interface description. */
     
     /*
      * 802.11-related privileges.
    diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
    index a5911b7a0d1..2af2467da3b 100644
    --- a/sys/sys/sockio.h
    +++ b/sys/sys/sockio.h
    @@ -82,6 +82,8 @@
     #define	SIOCGIFMAC	_IOWR('i', 38, struct ifreq)	/* get IF MAC label */
     #define	SIOCSIFMAC	 _IOW('i', 39, struct ifreq)	/* set IF MAC label */
     #define	SIOCSIFNAME	 _IOW('i', 40, struct ifreq)	/* set IF name */
    +#define	SIOCSIFDESCR	 _IOW('i', 41, struct ifreq)	/* set ifnet descr */ 
    +#define	SIOCGIFDESCR	_IOWR('i', 42, struct ifreq)	/* get ifnet descr */ 
     
     #define	SIOCADDMULTI	 _IOW('i', 49, struct ifreq)	/* add m'cast addr */
     #define	SIOCDELMULTI	 _IOW('i', 50, struct ifreq)	/* del m'cast addr */